summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2024-01-12 10:04:29 -0500
committerJonathan Bradley <jcb@pikum.xyz>2024-01-12 10:04:29 -0500
commit05a6ca44e40da855a1ddc32cfe799edef74f7bdf (patch)
tree2ee0437f49522d46c34d4bcd28115fa549433b54
parent8605d88c17851392f99437f6c2c0ea676eac3705 (diff)
attempt to save partial scene file if error occurs while saving
-rw-r--r--src/game.cpp110
1 files changed, 71 insertions, 39 deletions
diff --git a/src/game.cpp b/src/game.cpp
index 4d556b2..f1f6612 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -10,6 +10,7 @@
#include "imgui.h"
#include "level-types.hpp"
#include "level.hpp"
+#include "macros.hpp"
#include "math-helpers.hpp"
#include "physics.hpp"
#include "player-input.hpp"
@@ -26,6 +27,7 @@
#include <iomanip>
#include <ostream>
#include <fstream>
+#include <sstream>
#include <thread>
const long readLineLength = 128;
@@ -57,7 +59,7 @@ const char *PKE_FILE_CAMERA_TYPE = "Cam::Type: ";
const char *PKE_FILE_CAMERA_ORIENTATION = "Cam::Orientation: ";
const char *PKE_FILE_CAMERA_IS_PRIMARY = "Cam::IsPrimary: ";
-void SerializeCamera(std::ofstream &stream, const PkeCamera &cam) {
+void SerializeCamera(std::ostringstream &stream, const PkeCamera &cam) {
PkeCamera c{};
if (cam.pos != c.pos) {
stream << PKE_FILE_CAMERA_POS << "["
@@ -89,11 +91,13 @@ void SerializeCamera(std::ofstream &stream, const PkeCamera &cam) {
}
}
-void SerializeInstance(std::ofstream &stream, const CompInstance &comp) {
+void SerializeInstance(std::ostringstream &stream, const CompInstance &comp) {
char handleStr[19] = { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' };
snprintf(handleStr, 19, "0x%016lX", comp.entHandle.hash);
- EntityType *et = EntityType_FindByEntityHandle(comp.entHandle);
- assert(et != nullptr);
+ assert(comp.grBindsHandle != GrBindsHandle_MAX && "instance exists without a GrBinds");
+ CompGrBinds *instGrBinds = ECS_GetGrBinds(comp.grBindsHandle);
+ EntityType *et = EntityType_FindByEntityHandle(instGrBinds->entHandle);
+ assert(et != nullptr && "instance had a GrBinds, but no EntityType could be found");
CompInstance c{};
InstPos baseInst{};
baseInst.posRot = btTransform{};
@@ -236,8 +240,7 @@ void ParseInstance(Entity_Base *parentEntity, std::ifstream &stream) {
instPos.scale = btVector3(1, 1, 1);
instPos.mass = 1.f;
comp.collisionCallback.name[0] = '\0';
- char entTypeCode[21];
- memset(reinterpret_cast<void *>(entTypeCode), '\0', 21);
+ NULL_CHAR_ARR(entTypeCode, 21);
while (stream.getline(readLine, readLineLength)) {
if (strstr(PKE_FILE_OBJ_END, readLine)) {
if (entTypeCode[0] == '\0') {
@@ -350,45 +353,74 @@ void ParseInstance(Entity_Base *parentEntity, std::ifstream &stream) {
}
void Game_SaveSceneFile(const char *sceneFilePath) {
- std::ofstream f(sceneFilePath);
- assert(f.is_open());
-
- f << PKE_FILE_BEGIN << std::endl;
- f << PKE_FILE_VERSION << std::endl;
- f << "" << std::endl;
-
- int64_t cameraBucketCount = PkeCamera_GetBucketCount();
- for (long b = 0; b < cameraBucketCount; ++b) {
- int64_t count;
- auto *cameras = PkeCamera_GetCameras(b, count);
- for (long i = 0; i < count; ++i) {
- const auto &cam = cameras[i];
- if (cam.handle == CameraHandle_MAX)
- continue;
- f << PKE_FILE_OBJ_CAMERA << std::endl;
- SerializeCamera(f, cam);
- f << PKE_FILE_OBJ_END << std::endl;
+ std::ostringstream stream{};
+ bool failed = false;
+
+ try {
+ stream << PKE_FILE_BEGIN << std::endl;
+ stream << PKE_FILE_VERSION << std::endl;
+ stream << "" << std::endl;
+
+ int64_t cameraBucketCount = PkeCamera_GetBucketCount();
+ for (long b = 0; b < cameraBucketCount; ++b) {
+ int64_t count;
+ auto *cameras = PkeCamera_GetCameras(b, count);
+ for (long i = 0; i < count; ++i) {
+ const auto &cam = cameras[i];
+ if (cam.handle == CameraHandle_MAX)
+ continue;
+ stream << PKE_FILE_OBJ_CAMERA << std::endl;
+ SerializeCamera(stream, cam);
+ stream << PKE_FILE_OBJ_END << std::endl;
+ }
}
- }
- int64_t instanceBucketCount = ECS_GetInstances_BucketCount();
- for (long b = 0; b < instanceBucketCount; ++b) {
- uint64_t count;
- auto *instances = ECS_GetInstances(b, count);
- for (long i = 0; i < count; ++i) {
- const auto &instance = instances[i];
- if (instance.entHandle == EntityHandle_MAX)
- continue;
- f << PKE_FILE_OBJ_INSTANCE << std::endl;
- SerializeInstance(f, instance);
- f << PKE_FILE_OBJ_END << std::endl;
+ int64_t instanceBucketCount = ECS_GetInstances_BucketCount();
+ for (long b = 0; b < instanceBucketCount; ++b) {
+ uint64_t count;
+ auto *instances = ECS_GetInstances(b, count);
+ for (long i = 0; i < count; ++i) {
+ const auto &instance = instances[i];
+ if (instance.entHandle == EntityHandle_MAX)
+ continue;
+ stream << PKE_FILE_OBJ_INSTANCE << std::endl;
+ SerializeInstance(stream, instance);
+ stream << PKE_FILE_OBJ_END << std::endl;
+ }
}
+
+ stream << PKE_FILE_END << std::endl;
+ }
+ catch (...) {
+ failed = true;
}
- f << PKE_FILE_END << std::endl;
+ if (failed == false) {
+ std::ofstream f(sceneFilePath);
+ if (f.is_open()) {
+ f << stream.str();
- f.flush();
- f.close();
+ f.flush();
+ f.close();
+ } else {
+ failed = true;
+ }
+ }
+
+ if (failed) {
+ NULL_CHAR_ARR(errFileName, 256);
+ strncpy(errFileName, sceneFilePath, 256);
+ strncpy(errFileName + strlen(sceneFilePath), ".err", 256 - strlen(sceneFilePath));
+ std::ofstream errF(sceneFilePath);
+ if (errF.is_open()) {
+ errF << stream.str();
+ errF.flush();
+ errF.close();
+ fprintf(stderr, "Failed to save scene file '%s', partial output saved to '%s'", sceneFilePath, errFileName);
+ } else {
+ fprintf(stderr, "Failed to save scene file '%s' and also failed to write failed output", sceneFilePath);
+ }
+ }
}
void Game_LoadSceneFile(PkeLevel *level, const char *sceneFilePath) {