diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-03-27 11:58:47 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-03-27 11:58:47 -0400 |
| commit | e4604d5b84a71ac3cc8fe1a148d0a6250c7a715c (patch) | |
| tree | 0f768c8b5d0b96cb459f92c7795c6c9353710ed1 /src | |
| parent | 11057d2aa423f9b565f3fead4c260999d1bdb53e (diff) | |
pke: generate uuid and save to project+scene files
Diffstat (limited to 'src')
| -rw-r--r-- | src/components.hpp | 2 | ||||
| -rw-r--r-- | src/ecs.cpp | 9 | ||||
| -rw-r--r-- | src/game.cpp | 41 | ||||
| -rw-r--r-- | src/project.cpp | 10 | ||||
| -rw-r--r-- | src/scene.cpp | 15 |
5 files changed, 62 insertions, 15 deletions
diff --git a/src/components.hpp b/src/components.hpp index 326b0e6..f4e7c7f 100644 --- a/src/components.hpp +++ b/src/components.hpp @@ -28,6 +28,7 @@ constexpr LevelHandle LevelHandle_MAX = LevelHandle{ pk_handle_MAX_constexpr }; struct Entity_Base { EntityHandle handle = EntityHandle_MAX; EntityHandle parentHandle = EntityHandle_MAX; + pk_uuid uuid = pk_uuid_max; bool isMarkedForRemoval = false; }; @@ -65,6 +66,7 @@ struct CompInstance { EntityHandle entHandle = EntityHandle_MAX; GrBindsHandle grBindsHandle = GrBindsHandle_MAX; InstanceHandle instanceHandle = InstanceHandle_MAX; + pk_uuid uuid = pk_uuid_max; uint32_t index = ECS_UNSET_VAL_32; PhysicsCollision physicsLayer = PhysicsCollision{1}; PhysicsCollision physicsMask = PhysicsCollision{1}; diff --git a/src/ecs.cpp b/src/ecs.cpp index 4174bd0..048669d 100644 --- a/src/ecs.cpp +++ b/src/ecs.cpp @@ -5,6 +5,7 @@ #include "game-settings.hpp" #include "math-helpers.hpp" #include "physics.hpp" +#include "pk.h" #include "window.hpp" #include <btBulletDynamicsCommon.h> @@ -68,6 +69,10 @@ void ECS_Init() { } Entity_Base *ECS_CreateGenericEntity() { + /* 2025-03-26 - JCB + * The only place this is called immediately calls ECS_CreateEntity afterwards. + * There is no need to generate a uuid + */ pk_handle newHandle{Buckets_NewHandle(ecs.bc.generics)}; return &ecs.bc.generics.buckets[newHandle.bucketIndex][newHandle.itemIndex]; } @@ -78,6 +83,7 @@ EntityHandle ECS_CreateEntity(Entity_Base *entity, Entity_Base *parentEntity) { EntityHandle entityHandle{Buckets_NewHandle(ecs.bc.entityPtrs)}; entity->handle = entityHandle; if (parentEntity) entity->parentHandle = parentEntity->handle; + if (entity->uuid == pk_uuid_max || entity->uuid == pk_uuid_zed) entity->uuid = pk_uuid_new_v7(); ecs.bc.entityPtrs.buckets[entityHandle.bucketIndex][entityHandle.itemIndex] = entity; return entityHandle; } @@ -443,6 +449,9 @@ CompInstance *ECS_CreateInstance(Entity_Base *entity, CompGrBinds *entityTypeGrB new (comp) CompInstance{}; comp->entHandle = entity->handle; comp->instanceHandle = instanceHandle; + // TODO this should be passed in - currently generating a new one each time + // Consider making a Component_Base that has a UUID, and pass in similar to ECS_CreateEntity + if (comp->uuid == pk_uuid_zed || comp->uuid == pk_uuid_max) comp->uuid = pk_uuid_new_v7(); if (entityTypeGrBinds != nullptr) { comp->grBindsHandle = entityTypeGrBinds->grBindsHandle; diff --git a/src/game.cpp b/src/game.cpp index 2edea8c..630495a 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -54,6 +54,7 @@ const char *PKE_FILE_OBJ_CAMERA = "Camera:"; const char *PKE_FILE_INSTANCE_HANDLE = "Inst::InstHandle: "; const char *PKE_FILE_INSTANCE_ENTITY_HANDLE = "EntityHandle: "; const char *PKE_FILE_INSTANCE_ENTITY_TYPE_CODE = "EntityTypeCode: "; +const char *PKE_FILE_INSTANCE_UUID = "UUID: "; const char *PKE_FILE_INSTANCE_POS_POS = "InstPos::Pos: "; const char *PKE_FILE_INSTANCE_POS_ROT = "InstPos::Rot: "; const char *PKE_FILE_INSTANCE_POS_SCALE = "InstPos::Scale: "; @@ -68,6 +69,7 @@ const char *PKE_FILE_CAMERA_POS = "Cam::Pos: "; const char *PKE_FILE_CAMERA_ROT = "Cam::Rot: "; const char *PKE_FILE_CAMERA_TARGET = "Cam::Target: "; const char *PKE_FILE_CAMERA_TYPE = "Cam::Type: "; +const char *PKE_FILE_CAMERA_UUID = "Cam::UUID: "; const char *PKE_FILE_CAMERA_ORIENTATION = "Cam::Orientation: "; const char *PKE_FILE_CAMERA_INSTANCE_HANDLE = "Cam::InstanceHandle: "; const char *PKE_FILE_CAMERA_TARGET_INSTANCE_HANDLE = "Cam::TargetInstanceHandle: "; @@ -76,6 +78,9 @@ const char *PKE_FILE_CAMERA_IS_PRIMARY = "Cam::IsPrimary: "; void SerializeCamera(std::ostream &stream, const PkeCamera &cam) { NULL_CHAR_ARR(handleStr, 23); PkeCamera c{}; + if (cam.uuid != pk_uuid_zed && cam.uuid != pk_uuid_max) { + stream << PKE_FILE_CAMERA_UUID << cam.uuid << std::endl; + } if (cam.type != c.type) { stream << PKE_FILE_CAMERA_TYPE << int(static_cast<PkeCameraType_T>(cam.type)) << std::endl; } @@ -115,6 +120,9 @@ void SerializeInstance(std::ostream &stream, const CompInstance &comp) { snprintf(handleStr, 22, "0x%08X 0x%08X", comp.instanceHandle.bucketIndex, comp.instanceHandle.itemIndex); stream << PKE_FILE_INSTANCE_HANDLE << handleStr << std::endl; } + if (comp.uuid != pk_uuid_zed && comp.uuid != pk_uuid_max) { + stream << PKE_FILE_INSTANCE_UUID << comp.uuid << std::endl; + } if (et != nullptr) { stream << PKE_FILE_INSTANCE_ENTITY_TYPE_CODE << et->entityTypeCode.val << std::endl; } else if (PkeCamera_Get(comp.entHandle)) { @@ -286,8 +294,17 @@ void DeserializeInstance(Entity_Base *parentEntity, std::istream &stream) { if (skipEntCreate == false) { if (etPtr != nullptr && etPtr->createInstanceCallback.func != nullptr) { - typedef Entity_Base *CreateInst(); - entity = reinterpret_cast<CreateInst*>(etPtr->createInstanceCallback.func)(); + /* TODO 2025-03-27 JCB + * We have not yet defined what the appropriate callback signature + * for creating an entity instance is. + * What should be passed as arguments? What would need to be passed + * that couldn't be accessed globally? + * Consider changing this callback to trigger after creating a + * generic instance, rather than *creating* it. + */ + // typedef Entity_Base *CreateInst(); + // entity = reinterpret_cast<CreateInst*>(etPtr->createInstanceCallback.func)(); + fprintf(stderr, "[%s] Attempted to call EntityType::createInstanceCallback and we have not yet defined a valid function signature", __FILE__); } else { entity = EntityType_CreateGenericInstance(etPtr, parentEntity, &comp, &mapping.newInstance); fprintf(stdout ,"[Game::DeserializeInstance] Debug: entTypeCode '%s' does not have a registered callback func to handle instance creation.\n", entTypeCode); @@ -444,21 +461,23 @@ void Game_SaveSceneFile(const char *sceneFilePath) { } stream << PKE_FILE_END << std::endl; - } - catch (...) { - failed = true; + } catch (std::exception e) { + fprintf(stderr, "[%s][Game_SaveSceneFile] Failed to serialize scene file: %s\n", __FILE__, e.what()); + failed = false; + } catch (...) { + fprintf(stderr, "[%s][Game_SaveSceneFile] Failed to serialize scene file, uncaught exception.\n", __FILE__); + failed = false; } if (failed == false) { std::ofstream f(sceneFilePath); - if (f.is_open()) { - f << stream.str(); - - f.flush(); - f.close(); - } else { + if (!f.is_open()) { failed = true; + } else { + f << stream.str(); } + f.flush(); + f.close(); } if (failed) { diff --git a/src/project.cpp b/src/project.cpp index e8679c8..d371f68 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -29,6 +29,7 @@ const char* const PKE_PROJ_FILE_PROJ_SETTINGS_SCENES_END = "PkeSet::Scenes: ]"; const char* const PKE_PROJ_FILE_ENTITY_TYPE_MODEL_ASSET_KEY = "ModelAssetKey: "; const char* const PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_TYPE_CODE = "EntityTypeCode: "; const char* const PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_HANDLE = "EntityHandle: "; +const char* const PKE_PROJ_FILE_ENTITY_TYPE_UUID = "UUID: "; const char* const PKE_PROJ_FILE_ENTITY_TYPE_CREATE_INSTANCE_CALLBACK_SIGNATURE = "InstanceCreateCallbackSignature: "; const char* const PKE_PROJ_FILE_ENTITY_TYPE_COLLISION_CALLBACK_SIGNATURE = "CollisionCallbackSignature: "; const char* const PKE_PROJ_FILE_ENTITY_TYPE_DETAILS_BEGIN = "EntityHandleDetails: {"; @@ -77,6 +78,9 @@ void Proj_SerializeEntityType(std::ostream &stream, const EntityType &et) { stream << PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_TYPE_CODE << et.entityTypeCode.val << std::endl; if (et.handle != e.handle) stream << PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_HANDLE << handleStr << std::endl; + if (et.uuid != pk_uuid_zed && et.uuid != pk_uuid_max) { + stream << PKE_PROJ_FILE_ENTITY_TYPE_UUID << et.uuid << std::endl; + } if (et.createInstanceCallback.name[0] != '\0') { stream << PKE_PROJ_FILE_ENTITY_TYPE_CREATE_INSTANCE_CALLBACK_SIGNATURE << et.createInstanceCallback.name << std::endl; } @@ -404,7 +408,11 @@ void PkeProject_Save(const char *filePath) { } stream << PKE_PROJ_FILE_END << std::endl; + } catch (std::exception e) { + fprintf(stderr, "[%s][PkeProject_Save] Failed to serialize project file: %s\n", __FILE__, e.what()); + failed = false; } catch (...) { + fprintf(stderr, "[%s][PkeProject_Save] Failed to serialize project file, uncaught exception.\n", __FILE__); failed = false; } @@ -412,6 +420,8 @@ void PkeProject_Save(const char *filePath) { std::ofstream f(saveFilePath); if (!f.is_open()) { failed = true; + } else { + f << stream.str(); } f.flush(); f.close(); diff --git a/src/scene.cpp b/src/scene.cpp index 0e5a22c..f4df916 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -2,7 +2,10 @@ #include "scene.hpp" #include "bucketed-array.hpp" #include "ecs.hpp" -#include <cstring> + +#include <string.h> + +#include <filesystem> struct pke_scene_master { BucketContainer<pke_scene, SceneHandle> bc; @@ -17,7 +20,11 @@ void pke_scene_master_teardown() { } pke_scene *pke_scene_create(const char *scene_name) { - struct pke_scene *scene = pke_scene_get_by_name(scene_name); + NULL_CHAR_ARR(safe_scene_name, SCENE_NAME_MAX_LEN); + size_t offset; + std::filesystem::path p(scene_name); + sprintf(safe_scene_name, "%.15s", p.stem().c_str()); + struct pke_scene *scene = pke_scene_get_by_name(safe_scene_name); if (scene != nullptr) { fprintf(stderr, "[pke_scene_create] failed to create scene: pke_scene::name already in use."); return nullptr; @@ -31,9 +38,9 @@ pke_scene *pke_scene_create(const char *scene_name) { ECS_CreateEntity(scene); scene->scene_handle = scene_handle; - size_t offset = (strlen(scene_name) > SCENE_NAME_MAX_LEN ? strlen(scene_name) - SCENE_NAME_MAX_LEN : 0); + offset = (strlen(safe_scene_name) > SCENE_NAME_MAX_LEN ? strlen(safe_scene_name) - SCENE_NAME_MAX_LEN : 0); for (int i = 0; i < SCENE_NAME_MAX_LEN; ++i) { - scene->name[i] = scene_name[i + offset]; + scene->name[i] = safe_scene_name[i + offset]; } return scene; } |
