diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2023-12-07 23:12:47 -0500 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2023-12-07 23:12:47 -0500 |
| commit | 6e76f8342ad4d1f9a576f25bfb992aac6e4d2eee (patch) | |
| tree | 36c17a12914f62ba1a3c2e8863a322be6c14cad4 | |
| parent | b6e7a0c2f7ef0bcb6d5ed0806c851b5312a68b13 (diff) | |
project browser checkpoint
| -rw-r--r-- | editor/editor.cpp | 137 | ||||
| -rw-r--r-- | src/project-settings.hpp | 7 | ||||
| -rw-r--r-- | src/project.cpp | 118 |
3 files changed, 228 insertions, 34 deletions
diff --git a/editor/editor.cpp b/editor/editor.cpp index 8107ee3..2130e0f 100644 --- a/editor/editor.cpp +++ b/editor/editor.cpp @@ -15,20 +15,29 @@ #include "vendor/tinyfiledialogs//tinyfiledialogs.h" #include "imgui.h" +#include <filesystem> #include <future> - -const char *dbgCtrl_CameraLeft = "debug-camera-left"; -const char *dbgCtrl_CameraRight = "debug-camera-right"; -const char *dbgCtrl_CameraForward = "debug-camera-forward"; -const char *dbgCtrl_CameraBack = "debug-camera-back"; -const char *dbgCtrl_CameraUp = "debug-camera-up"; -const char *dbgCtrl_CameraDown = "debug-camera-down"; -const char *dbgCtrl_CameraRotCC = "debug-camera-rot-counter-clockwise"; -const char *dbgCtrl_CameraRotC = "debug-camera-rot-clockwise"; -const char *dbgCtrl_CameraRot = "debug-camera-rot"; -const char *dbgCtrl_CameraButtonMask = "debug-camera-button-mask"; -const char *dbgCtrl_SelectHovered = "debug-select-hovered"; -const char *dbgCtrl_ClearSelection = "debug-clear-selection"; +#include <regex> + +#ifdef WIN32 + // TODO +#else + #include <unistd.h> + #include <sys/wait.h> +#endif + +const char* const dbgCtrl_CameraLeft = "debug-camera-left"; +const char* const dbgCtrl_CameraRight = "debug-camera-right"; +const char* const dbgCtrl_CameraForward = "debug-camera-forward"; +const char* const dbgCtrl_CameraBack = "debug-camera-back"; +const char* const dbgCtrl_CameraUp = "debug-camera-up"; +const char* const dbgCtrl_CameraDown = "debug-camera-down"; +const char* const dbgCtrl_CameraRotCC = "debug-camera-rot-counter-clockwise"; +const char* const dbgCtrl_CameraRotC = "debug-camera-rot-clockwise"; +const char* const dbgCtrl_CameraRot = "debug-camera-rot"; +const char* const dbgCtrl_CameraButtonMask = "debug-camera-button-mask"; +const char* const dbgCtrl_SelectHovered = "debug-select-hovered"; +const char* const dbgCtrl_ClearSelection = "debug-clear-selection"; ThreadPoolHandle threadPoolHandle = ThreadPoolHandle_MAX; @@ -44,6 +53,7 @@ PkeCamera cameraDbg { InputActionSetHandle debugControlsHandle = InputActionSetHandle_MAX; bool shouldSetupEditor = true; bool shouldDisableEditor = false; +bool shouldRebuildProjectDir = true; struct EntityTypeInstanceCreateInfo { EntityHandle entityTypeEntityHandle; @@ -61,6 +71,8 @@ bool shouldOpenSaveSceneDialog = false; bool shouldLoadScene = false; bool shouldSaveScene = false; bool shouldSaveProjectFile = false; +bool shouldRunCurrentScene = false; +bool subProgramRunning = false; glm::vec3 unproject(glm::vec3 windowCoords) { double xDevNorm = (2.0f * windowCoords.x) / Extent.width - 1.0f; @@ -79,6 +91,26 @@ glm::vec3 unproject(glm::vec3 windowCoords) { } void PkeEditor_Tick(double delta) { + if (shouldRunCurrentScene) { + shouldRunCurrentScene = false; + subProgramRunning = true; + PkeThreads_Enqueue(threadPoolHandle, std::packaged_task<void()>( [] { + auto pid = fork(); + if (pid == 0) { + const char *argv[] = { + NULL, + }; + int status = execvp("pke_runtime", const_cast<char **>(argv)); + fprintf(stderr, "pke_runtime exited with a status of %i\n", status); + subProgramRunning = false; + } else { + int status; + waitpid(pid, &status, 0); + fprintf(stdout, "pke_runtime exited cleanly with a status of %i\n", status); + subProgramRunning = false; + } + })); + } if (shouldSetupEditor) { PkeEditor_Setup(); } @@ -389,6 +421,12 @@ void RecordImGuiEditorWrapper() { ImGui::EndMenu(); } + ImGui::Spacing(); + ImGui::BeginDisabled(subProgramRunning); + if (ImGui::Button("▶️")) { + shouldRunCurrentScene = true; + } + ImGui::EndDisabled(); ImGui::EndMainMenuBar(); } @@ -746,6 +784,78 @@ void RecordImGuiProjectSettingsEditor() { ImGui::End(); } +struct fsEntry { + int type = 0; + char *name = nullptr; + char *path = nullptr; + DynArray<fsEntry> children{0, nullptr}; +}; +DynArray<fsEntry> fsEntries{0, nullptr}; +std::regex reg_sceneFile(".+\\.ps[tb]f$", std::regex_constants::icase); +void BuildDirRecursive(const std::filesystem::directory_entry &de, fsEntry *dirFsEntry) { + auto &entry = dirFsEntry == nullptr ? fsEntries.Push() : dirFsEntry->children.Push(); + auto len = strlen(de.path().c_str()) + 1; + entry.path = Pke_New<char>(len); + memset(entry.path, '\0', len); + memcpy(entry.path, de.path().c_str(), len - 1); + len = strlen(de.path().filename().c_str()); + entry.name = Pke_New<char>(len); + memset(entry.name, '\0', len); + memcpy(entry.name, de.path().filename().c_str(), len - 1); + + if (de.is_regular_file()) { + if (std::regex_search(de.path().c_str(), reg_sceneFile)) { + entry.type = 1; + } + } else if (de.is_directory()) { + entry.type = 0; + std::filesystem::directory_iterator di{de.path()}; + for (const std::filesystem::directory_entry &sde : di) { + if (sde.is_directory() + || (sde.is_regular_file() && std::regex_search(sde.path().c_str(), reg_sceneFile)) + ) { + BuildDirRecursive(sde, &entry); + } + } + } +} +void BuildProjectMenuRecursive(fsEntry &entry) { + if (entry.type == 1) { + if (ImGui::Selectable(entry.name, false, ImGuiSelectableFlags_AllowDoubleClick)) { + sceneName = entry.name; + shouldLoadScene = true; + } + } else if (entry.type == 0) { + if (ImGui::TreeNode(entry.name)) { + for (long i = 0; i < entry.children.Count(); ++i) { + BuildProjectMenuRecursive(entry.children[i]); + } + ImGui::TreePop(); + } + } +} +void RecordImGuiProjectBrowser() { + if (!ImGui::Begin("ProjectBrowser")) { + ImGui::End(); + return; + } + if (shouldRebuildProjectDir == true) { + shouldRebuildProjectDir = false; + std::filesystem::directory_iterator di{"."}; + for (const std::filesystem::directory_entry &sde : di) { + if (sde.is_directory() + || (sde.is_regular_file() && std::regex_search(sde.path().c_str(), reg_sceneFile)) + ) { + BuildDirRecursive(sde, nullptr); + } + } + } + for (long i = 0; i < fsEntries.Count(); ++i) { + BuildProjectMenuRecursive(fsEntries[i]); + } + ImGui::End(); +} + void RecordImGuiSceneEditor() { if (!ImGui::Begin("SceneEditorEntityTypes", &pkeSettings.editorSettings.isShowingSceneEditor)) { ImGui::End(); @@ -787,6 +897,7 @@ void PkeEditor_RecordImGui() { if (pkeSettings.isShowingEditor) { RecordImGuiEditorWrapper(); RecordImGuiProjectSettingsEditor(); + RecordImGuiProjectBrowser(); RecordImGuiEntityList(); RecordImGuiSceneEditor(); RecordImGuiUBO(); diff --git a/src/project-settings.hpp b/src/project-settings.hpp index b101372..62ff7d8 100644 --- a/src/project-settings.hpp +++ b/src/project-settings.hpp @@ -1,8 +1,13 @@ #ifndef PKE_PROJECT_SETTINGS_HPP #define PKE_PROJECT_SETTINGS_HPP -struct PkeProjectSettings { +#include "dynamic-array.hpp" +#include "pkstr.hpp" +#include <cstdint> +struct PkeProjectSettings { + const char *defaultSceneName = "default"; + DynArray<cpkstr> scenes{16}; }; extern PkeProjectSettings pkeProjectSettings; diff --git a/src/project.cpp b/src/project.cpp index a71401b..741361c 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -4,32 +4,60 @@ #include "entities.hpp" #include "helpers.hpp" +#include <fstream> #include <ostream> #include <iomanip> const long projReadLineLength = 128; char projReadLine[projReadLineLength]; -const char *PKE_PROJ_DEFAULT_FILENAME = "project.pptf"; - -const char *PKE_PROJ_FILE_BEGIN = ":PKPB:"; -const char *PKE_PROJ_FILE_END = ":PKPE:"; -const char *PKE_PROJ_FILE_VERSION = ":0:"; -const char *PKE_PROJ_FILE_OBJ_END = ""; -const char *PKE_PROJ_FILE_OBJ_ENTITY_TYPE = "EntityType:"; - -const char *PKE_PROJ_FILE_ENTITY_TYPE_MODELS_DIR = "ModelsDir: "; -const char *PKE_PROJ_FILE_ENTITY_TYPE_MODEL_FILE = "ModelFile: "; -const char *PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_TYPE_CODE = "EntityTypeCode: "; -const char *PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_HANDLE = "EntityHandle: "; -const char *PKE_PROJ_FILE_ENTITY_TYPE_STARTING_INSTANCE_COUNT = "StartingInstanceCount: "; -const char *PKE_PROJ_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_VERTEX = "Importer_GLTF::AccessorIndexVertex: "; -const char *PKE_PROJ_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_NORMAL = "Importer_GLTF::AccessorIndexNormal: "; -const char *PKE_PROJ_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_UV = "Importer_GLTF::AccessorIndexUV: "; -const char *PKE_PROJ_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_INDEX = "Importer_GLTF::AccessorIndexIndex: "; -const char *PKE_PROJ_FILE_ENTITY_TYPE_PHYSICS_STARTING_MASS = "BT::StartingMass: "; -const char *PKE_PROJ_FILE_ENTITY_TYPE_PHYSICS_STARTING_COLLISION_LAYER = "BT::StartingCollisionLayer: "; -const char *PKE_PROJ_FILE_ENTITY_TYPE_PHYSICS_STARTING_COLLISION_MASK = "BT::StartingCollisionMask: "; +const char* const PKE_PROJ_DEFAULT_FILENAME = "project.pptf"; + +const char* const PKE_PROJ_FILE_BEGIN = ":PKPB:"; +const char* const PKE_PROJ_FILE_END = ":PKPE:"; +const char* const PKE_PROJ_FILE_VERSION = ":0:"; +const char* const PKE_PROJ_FILE_OBJ_END = ""; +const char* const PKE_PROJ_FILE_OBJ_PROJECT_SETTINGS = "ProjectSettings:"; +const char* const PKE_PROJ_FILE_OBJ_ENTITY_TYPE = "EntityType:"; + +const char* const PKE_PROJ_FILE_PROJ_SETTINGS_DEFAULT_SCENE_NAME = "PkeSet::DefaultSceneName: "; +const char* const PKE_PROJ_FILE_PROJ_SETTINGS_SCENE_COUNT = "PkeSet::SceneCount: "; +const char* const PKE_PROJ_FILE_PROJ_SETTINGS_SCENES_BEGIN = "PkeSet::Scenes: ["; +const char* const PKE_PROJ_FILE_PROJ_SETTINGS_SCENES_END = "PkeSet::Scenes: ]"; + +const char* const PKE_PROJ_FILE_ENTITY_TYPE_MODELS_DIR = "ModelsDir: "; +const char* const PKE_PROJ_FILE_ENTITY_TYPE_MODEL_FILE = "ModelFile: "; +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_STARTING_INSTANCE_COUNT = "StartingInstanceCount: "; +const char* const PKE_PROJ_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_VERTEX = "Importer_GLTF::AccessorIndexVertex: "; +const char* const PKE_PROJ_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_NORMAL = "Importer_GLTF::AccessorIndexNormal: "; +const char* const PKE_PROJ_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_UV = "Importer_GLTF::AccessorIndexUV: "; +const char* const PKE_PROJ_FILE_ENTITY_TYPE_IMPORTER_GLTF_ACCESSOR_INDEX_INDEX = "Importer_GLTF::AccessorIndexIndex: "; +const char* const PKE_PROJ_FILE_ENTITY_TYPE_PHYSICS_STARTING_MASS = "BT::StartingMass: "; +const char* const PKE_PROJ_FILE_ENTITY_TYPE_PHYSICS_STARTING_COLLISION_LAYER = "BT::StartingCollisionLayer: "; +const char* const PKE_PROJ_FILE_ENTITY_TYPE_PHYSICS_STARTING_COLLISION_MASK = "BT::StartingCollisionMask: "; + +/* +void Proj_SerializeProjectSettings(std::ofstream &stream) { + PkeProjectSettings ps{}; + if (strncmp(ps.defaultSceneName, pkeProjectSettings.defaultSceneName, strlen(pkeProjectSettings.defaultSceneName)) != 0) { + stream << PKE_PROJ_FILE_PROJ_SETTINGS_DEFAULT_SCENE_NAME << ps.defaultSceneName << std::endl; + } + if (ps.sceneCount != pkeProjectSettings.sceneCount) { + stream << PKE_PROJ_FILE_PROJ_SETTINGS_SCENE_COUNT << ps.sceneCount << std::endl; + } + if (ps.scenes != nullptr) { + stream << PKE_PROJ_FILE_PROJ_SETTINGS_SCENES_BEGIN << std::endl; + for (long i = 0; i < ps.sceneCount; ++i) { + if (ps.scenes[i].length > 0) { + stream << ps.scenes[i].val << std::endl; + } + } + stream << PKE_PROJ_FILE_PROJ_SETTINGS_SCENES_END << std::endl; + } +} +*/ void Proj_SerializeEntityType(std::ofstream &stream, const EntityType &et) { char handleStr[19] = { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' }; @@ -61,6 +89,44 @@ void Proj_SerializeEntityType(std::ofstream &stream, const EntityType &et) { stream << PKE_PROJ_FILE_ENTITY_TYPE_PHYSICS_STARTING_COLLISION_MASK << static_cast<PhysicsCollision_T>(et.bt.startingCollisionMask) << std::endl; } +/* +void Proj_ParseProjectSettings(std::ifstream &stream) { + while (stream.getline(projReadLine, projReadLineLength)) { + if (strcmp(PKE_PROJ_FILE_OBJ_END, projReadLine) == 0) { + return; + } + if (strncmp(projReadLine, PKE_PROJ_FILE_PROJ_SETTINGS_DEFAULT_SCENE_NAME, strlen(PKE_PROJ_FILE_PROJ_SETTINGS_DEFAULT_SCENE_NAME)) == 0) { + uint64_t prefixLen = strlen(PKE_PROJ_FILE_PROJ_SETTINGS_DEFAULT_SCENE_NAME); + uint64_t len = strlen(projReadLine + prefixLen) + 1; + char *val = Pke_New<char>(len); + memset(reinterpret_cast<void *>(val), '\0', len); + memcpy(val, projReadLine + prefixLen, len); + pkeProjectSettings.defaultSceneName = val; + continue; + } + if (strncmp(projReadLine, PKE_PROJ_FILE_PROJ_SETTINGS_SCENES_BEGIN, strlen(PKE_PROJ_FILE_PROJ_SETTINGS_SCENES_BEGIN)) == 0) { + DynArray<pkstr> sceneFiles{16}; + while (stream.getline(projReadLine, projReadLineLength)) { + if (strcmp(PKE_PROJ_FILE_PROJ_SETTINGS_SCENES_END, projReadLine) == 0) { + pkeProjectSettings.sceneCount = sceneFiles.Count(); + pkeProjectSettings.scenes = Pke_New<cpkstr>(sceneFiles.Count()); + memcpy(reinterpret_cast<void *>(pkeProjectSettings.scenes), reinterpret_cast<void *>(sceneFiles.GetPtr()), sizeof(cpkstr) * sceneFiles.Count()); + break; + } + pkeProjectSettings.sceneCount += 1; + uint64_t len = strlen(projReadLine) + 1; + char *val = Pke_New<char>(len); + memset(val, '\0', len); + memcpy(val, projReadLine, len - 1); + auto &str = sceneFiles.Push(); + str.length = len - 1; + str.val = val; + } + } + } +} +*/ + void Proj_ParseEntityType(std::ifstream &stream) { EntityType et{}; while (stream.getline(projReadLine, projReadLineLength)) { @@ -174,6 +240,12 @@ void PkeProject_Load(const char *filePath) { memset(projReadLine, '\0', projReadLineLength); while (f.getline(projReadLine, projReadLineLength)) { + /* + if (strcmp(PKE_PROJ_FILE_OBJ_PROJECT_SETTINGS, projReadLine) == 0) { + Proj_ParseProjectSettings(f); + continue; + } + */ if (strcmp(PKE_PROJ_FILE_OBJ_ENTITY_TYPE, projReadLine) == 0) { Proj_ParseEntityType(f); continue; @@ -195,6 +267,12 @@ void PkeProject_Save(const char *filePath) { f << PKE_PROJ_FILE_VERSION << std::endl; f << "" << std::endl; + /* + f << PKE_PROJ_FILE_OBJ_PROJECT_SETTINGS << std::endl; + Proj_SerializeProjectSettings(f); + f << PKE_PROJ_FILE_OBJ_END << std::endl; + */ + for (long i = 0; i < GlobalEntityTypes.Count(); ++i) { f << PKE_PROJ_FILE_OBJ_ENTITY_TYPE << std::endl; const auto &et = GlobalEntityTypes[i]; |
