diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2024-01-12 10:04:29 -0500 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2024-01-12 10:04:29 -0500 |
| commit | 05a6ca44e40da855a1ddc32cfe799edef74f7bdf (patch) | |
| tree | 2ee0437f49522d46c34d4bcd28115fa549433b54 /src | |
| parent | 8605d88c17851392f99437f6c2c0ea676eac3705 (diff) | |
attempt to save partial scene file if error occurs while saving
Diffstat (limited to 'src')
| -rw-r--r-- | src/game.cpp | 110 |
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) { |
