diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index 7e5befab..44dfd5c5 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -53,6 +53,7 @@ enum class AssetType : AssetTypeMeta MATERIAL, MESH, SCRIPT, + FONT, MAX_COUNT }; constexpr size_t TYPE_COUNT{ static_cast(AssetType::MAX_COUNT) }; @@ -86,7 +87,8 @@ constexpr std::string_view SCENE_EXTENSION {".shade"}; constexpr std::string_view PREFAB_EXTENSION {".shprefab"}; constexpr std::string_view MATERIAL_EXTENSION {".shmat"}; constexpr std::string_view TEXTURE_EXTENSION {".shtex"}; -constexpr std::string_view MODEL_EXTENSION {".shmodel"}; +constexpr std::string_view MODEL_EXTENSION{ ".shmodel" }; +constexpr std::string_view FONT_EXTENSION{ ".shfont" }; constexpr std::string_view EXTENSIONS[] = { AUDIO_EXTENSION, @@ -99,6 +101,7 @@ constexpr std::string_view EXTENSIONS[] = { MATERIAL_EXTENSION, "dummy", SCRIPT_EXTENSION, + FONT_EXTENSION, AUDIO_WAV_EXTENSION, }; @@ -109,12 +112,14 @@ constexpr std::string_view GLSL_EXTENSION{ ".glsl" }; constexpr std::string_view DDS_EXTENSION{ ".dds" }; constexpr std::string_view FBX_EXTENSION{ ".fbx" }; constexpr std::string_view GLTF_EXTENSION{ ".gltf" }; +constexpr std::string_view TTF_EXTENSION{ ".ttf" }; constexpr std::string_view EXTERNALS[] = { GLSL_EXTENSION, DDS_EXTENSION, FBX_EXTENSION, - GLTF_EXTENSION + GLTF_EXTENSION, + TTF_EXTENSION }; // SHADER IDENTIFIERS @@ -129,11 +134,4 @@ constexpr std::pair SHADER_IDENTIFIERS[ }; constexpr size_t SHADER_TYPE_MAX_COUNT{ 3 }; - -// Error flags -constexpr std::string_view FILE_NOT_FOUND_ERR {"FILE NOT FOUND"}; -constexpr std::string_view META_NOT_FOUND_ERR {"META NOT FOUND"}; -constexpr std::string_view ASSET_NOT_FOUND_ERR {"ASSET NOT FOUND"}; -constexpr std::string_view EXT_DOES_NOT_EXIST {"TYPE DOES NOT HAVE EXTENSION DEFINED"}; - #endif // !SH_ASSET_MACROS_H diff --git a/SHADE_Engine/src/Editor/Command/SHCommandManager.cpp b/SHADE_Engine/src/Editor/Command/SHCommandManager.cpp index 3c0ee5dd..b86f9247 100644 --- a/SHADE_Engine/src/Editor/Command/SHCommandManager.cpp +++ b/SHADE_Engine/src/Editor/Command/SHCommandManager.cpp @@ -10,63 +10,102 @@ namespace SHADE { - SHCommandManager::CommandStack SHCommandManager::undoStack{}; - SHCommandManager::CommandStack SHCommandManager::redoStack{}; + + SHCommandManager::CommandStack SHCommandManager::undoStack(defaultStackSize); + SHCommandManager::CommandStack SHCommandManager::redoStack(defaultStackSize); + SHCommandManager::CommandStack SHCommandManager::secondaryUndoStack(defaultStackSize); + SHCommandManager::CommandStack SHCommandManager::secondaryRedoStack(defaultStackSize); + + SHCommandManager::CommandStackPtr SHCommandManager::pCurrUndoStack(&undoStack); + SHCommandManager::CommandStackPtr SHCommandManager::pCurrRedoStack(&redoStack); void SHCommandManager::PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue) { - redoStack = CommandStack(); + *pCurrRedoStack = CommandStack(defaultStackSize); commandPtr->Execute(); - if (overrideValue && !undoStack.empty()) + if (overrideValue && !pCurrUndoStack->Empty()) { - undoStack.top()->Merge(commandPtr); + pCurrUndoStack->Top()->Merge(commandPtr); } else { - undoStack.push(commandPtr); + pCurrUndoStack->Push(commandPtr); } } void SHCommandManager::RegisterCommand(BaseCommandPtr commandPtr) { - undoStack.push(commandPtr); + pCurrUndoStack->Push(commandPtr); } void SHCommandManager::UndoCommand() { - if (undoStack.empty()) + if (pCurrUndoStack->Empty()) return; - undoStack.top()->Undo(); - redoStack.push(undoStack.top()); - undoStack.pop(); + pCurrUndoStack->Top()->Undo(); + pCurrRedoStack->Push(pCurrUndoStack->Top()); + pCurrUndoStack->Pop(); } void SHCommandManager::RedoCommand() { - if (redoStack.empty()) + if (pCurrRedoStack->Empty()) return; - redoStack.top()->Execute(); - undoStack.push(redoStack.top()); - redoStack.pop(); + pCurrRedoStack->Top()->Execute(); + pCurrUndoStack->Push(pCurrRedoStack->Top()); + pCurrRedoStack->Pop(); } std::size_t SHCommandManager::GetUndoStackSize() { - return undoStack.size(); + return pCurrUndoStack->Size(); } std::size_t SHCommandManager::GetRedoStackSize() { - return redoStack.size(); + return pCurrRedoStack->Size(); } void SHCommandManager::PopLatestCommandFromRedoStack() { - redoStack.pop(); + pCurrRedoStack->Pop(); } void SHCommandManager::PopLatestCommandFromUndoStack() { - undoStack.pop(); + pCurrUndoStack->Pop(); } + + void SHCommandManager::SwapStacks() + { + if (pCurrUndoStack == &undoStack) + { + pCurrUndoStack = &secondaryUndoStack; + } + else + { + secondaryUndoStack.Clear(); + pCurrUndoStack = &undoStack; + } + + if (pCurrRedoStack == &redoStack) + { + pCurrRedoStack = &secondaryRedoStack; + } + else + { + secondaryRedoStack.Clear(); + pCurrRedoStack = &redoStack; + } + } + + void SHCommandManager::ClearAll() + { + undoStack.Clear(); + redoStack.Clear(); + + secondaryUndoStack.Clear(); + secondaryRedoStack.Clear(); + } + }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/Command/SHCommandManager.h b/SHADE_Engine/src/Editor/Command/SHCommandManager.h index a514c464..178347b5 100644 --- a/SHADE_Engine/src/Editor/Command/SHCommandManager.h +++ b/SHADE_Engine/src/Editor/Command/SHCommandManager.h @@ -10,6 +10,7 @@ //#==============================================================# #include "SHCommand.hpp" #include "SH_API.h" +#include "Tools/SHDeque.h" namespace SHADE { @@ -22,7 +23,8 @@ namespace SHADE using BaseCommandPtr = std::shared_ptr; template using SHCommandPtr = std::shared_ptr>; - using CommandStack = std::stack; + using CommandStack = SHDeque; + using CommandStackPtr = CommandStack*; static void PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue = false); static void RegisterCommand(BaseCommandPtr commandPtr); @@ -34,8 +36,17 @@ namespace SHADE static void PopLatestCommandFromRedoStack(); static void PopLatestCommandFromUndoStack(); + static void SwapStacks(); + static void ClearAll(); + + static constexpr CommandStack::SizeType defaultStackSize = 100; private: + static CommandStackPtr pCurrUndoStack; + static CommandStackPtr pCurrRedoStack; + static CommandStack undoStack; + static CommandStack secondaryUndoStack; static CommandStack redoStack; + static CommandStack secondaryRedoStack; }; }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp index 37b8ecd4..37521581 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp @@ -17,7 +17,7 @@ namespace SHADE { SHAssetBrowser::SHAssetBrowser() - :SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder), assetBeingCreated(std::nullopt) + :SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder) { } @@ -34,23 +34,48 @@ namespace SHADE RecursivelyDrawTree(rootFolder); DrawMenuBar(); DrawCurrentFolder(); + DrawAssetBeingCreated(); + } ImGui::End(); + if(refreshQueued) + Refresh(); + } + + void SHAssetBrowser::QueueRefresh() noexcept + { + refreshQueued = true; + } + + void SHAssetBrowser::Refresh() noexcept + { + SHAssetManager::RefreshDirectory(); + rootFolder = SHAssetManager::GetRootFolder(); + refreshQueued = false; } void SHAssetBrowser::DrawMenuBar() { if (ImGui::BeginMenuBar()) { - + if(ImGui::SmallButton(ICON_MD_SYNC)) + { + QueueRefresh(); + } + if(ImGui::SmallButton(ICON_FA_CIRCLE_PLUS)) + { + isAssetBeingCreated = true; + } ImGui::EndMenuBar(); } } + //if !compiled, set genMeta to true + ImRect SHAssetBrowser::RecursivelyDrawTree(FolderPointer folder) { auto const& subFolders = folder->subFolders; - auto const& files = folder->files; + auto files = folder->files; const bool isSelected = std::ranges::find(selectedFolders, folder) != selectedFolders.end(); ImGuiTreeNodeFlags flags = (subFolders.empty() && files.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow; if (isSelected) @@ -62,21 +87,10 @@ namespace SHADE ImGuiID folderID = ImGui::GetItemID(); const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); - if (ImGui::BeginPopupContextItem()) - { - if (ImGui::BeginMenu("Create Asset")) - { - //TODO: Change to rttr type enum align - if (ImGui::Selectable("Material")) - { - assetBeingCreated = { folder, AssetType::MATERIAL, "New Material" }; - ImGui::TreeNodeSetOpen(folderID, true); - isOpen = true; - } - ImGui::EndMenu(); - } - ImGui::EndPopup(); - } + //if (ImGui::BeginPopupContextItem()) + //{ + // ImGui::EndPopup(); + //} if (ImGui::IsItemClicked()) { @@ -100,19 +114,15 @@ namespace SHADE drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); vertLineEnd.y = midPoint; } - for (auto const& file : files) + for (auto& file : files) { - if(file.assetMeta == nullptr) - continue; const float horizontalLineSize = 25.0f; - const ImRect childRect = DrawFile(file.assetMeta); + const ImRect childRect = DrawFile(file); const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f; drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); vertLineEnd.y = midPoint; } drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1); - if(assetBeingCreated.has_value() && std::get<0>(assetBeingCreated.value()) == folder) - DrawAssetBeingCreated(); ImGui::TreePop(); } @@ -148,7 +158,33 @@ namespace SHADE //} } - ImRect SHAssetBrowser::DrawFile(SHAsset const* const asset) noexcept + ImRect SHAssetBrowser::DrawFile(SHFile& file) noexcept + { + if(file.compilable) + { + ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf; + static constexpr std::string_view icon = ICON_MD_FILE_PRESENT; + ImGui::PushID(file.name.data()); + bool const isOpen = ImGui::TreeNodeEx(file.name.data(), flags, "%s %s%s", icon.data(), file.name.data(), file.ext.data()); + const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); + if(ImGui::BeginPopupContextItem()) + { + if(ImGui::Selectable("Compile")) + { + SHAssetManager::CompileAsset(file.path, !file.compiled); + QueueRefresh(); + } + ImGui::EndPopup(); + } + ImGui::TreePop(); + ImGui::PopID(); + return nodeRect; + } + if(file.assetMeta) + DrawAsset(file.assetMeta, file.ext); + } + + ImRect SHAssetBrowser::DrawAsset(SHAsset const* const asset, FileExt const& ext /*= ""*/) noexcept { if (asset == nullptr) return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); @@ -173,7 +209,7 @@ namespace SHADE default:; } - bool const isOpen = ImGui::TreeNodeEx(asset, flags, "%s %s", icon.data(), asset->name.data()); + bool const isOpen = ImGui::TreeNodeEx(asset, flags, "%s %s%s", icon.data(), asset->name.data(), ext.data()); const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); if (SHDragDrop::BeginSource()) { @@ -212,7 +248,6 @@ namespace SHADE case AssetType::MAX_COUNT: break; default:; } - } //TODO: Combine Draw asset and Draw Folder recursive drawing @@ -227,7 +262,7 @@ namespace SHADE for(auto const& subAsset : asset->subAssets) { const float horizontalLineSize = 25.0f; - const ImRect childRect = DrawFile(subAsset); + const ImRect childRect = DrawAsset(subAsset); const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f; drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); vertLineEnd.y = midPoint; @@ -240,19 +275,52 @@ namespace SHADE void SHAssetBrowser::DrawAssetBeingCreated() noexcept { - if (!assetBeingCreated.has_value()) - return; - auto& path = std::get<0>(assetBeingCreated.value()); - auto& type = std::get<1>(assetBeingCreated.value()); - auto& assetName = std::get<2>(assetBeingCreated.value()); - if (ImGui::InputText("##newAssetName", &assetName, ImGuiInputTextFlags_EnterReturnsTrue)) + if(isAssetBeingCreated) + ImGui::OpenPopup(newAssetPopup.data()); + + if(ImGui::BeginPopupModal(newAssetPopup.data(), &isAssetBeingCreated)) { - AssetID assetId = SHAssetManager::CreateNewAsset(type, assetName); - if (auto matInspector = SHEditorWindowManager::GetEditorWindow()) + ImGui::RadioButton("Material", true); + ImGui::SameLine(); + if (ImGui::InputText("##newAssetName", &nameOfAssetBeingCreated, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_AutoSelectAll)) { - matInspector->OpenMaterial(assetId, true); + AssetID assetId = SHAssetManager::CreateNewAsset(AssetType::MATERIAL, nameOfAssetBeingCreated); + if (auto matInspector = SHEditorWindowManager::GetEditorWindow()) + { + matInspector->OpenMaterial(assetId, true); + } + nameOfAssetBeingCreated.clear(); + QueueRefresh(); + isAssetBeingCreated = false; + ImGui::CloseCurrentPopup(); } - assetBeingCreated.reset(); + ImGui::EndPopup(); } + //if (ImGui::BeginMenu("Create Asset")) + //{ + // //TODO: Change to rttr type enum align + // if (ImGui::Selectable("Material")) + // { + // assetBeingCreated = { folder, AssetType::MATERIAL, "NewMaterial" }; + // ImGui::TreeNodeSetOpen(folderID, true); + // isOpen = true; + // } + // ImGui::EndMenu(); + //} + //if (!assetBeingCreated.has_value()) + // return; + //auto& path = std::get<0>(assetBeingCreated.value()); + //auto& type = std::get<1>(assetBeingCreated.value()); + //auto& assetName = std::get<2>(assetBeingCreated.value()); + //if (ImGui::InputText("##newAssetName", &assetName, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_AutoSelectAll)) + //{ + // AssetID assetId = SHAssetManager::CreateNewAsset(type, assetName); + // if (auto matInspector = SHEditorWindowManager::GetEditorWindow()) + // { + // matInspector->OpenMaterial(assetId, true); + // } + // assetBeingCreated.reset(); + // QueueRefresh(); + //} } } diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h index 00023ebe..6d3c5eb4 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h @@ -10,24 +10,29 @@ namespace SHADE class SHAssetBrowser final : public SHEditorWindow { public: - using AssetEntry = std::tuple; SHAssetBrowser(); void Init(); void Update(); - void Refresh(); + void QueueRefresh() noexcept; private: void DrawMenuBar(); ImRect RecursivelyDrawTree(FolderPointer folder); void DrawCurrentFolder(); - ImRect DrawFile(SHAsset const* const asset) noexcept; + ImRect DrawFile(SHFile& file) noexcept; + ImRect DrawAsset(SHAsset const* const asset, FileExt const& ext = "") noexcept; void DrawAssetBeingCreated() noexcept; + void Refresh() noexcept; + FolderPointer rootFolder, prevFolder, currentFolder; - std::optional assetBeingCreated; std::vector selectedFolders; std::vector selectedAssets; static constexpr float tileWidth = 50.0f; + bool refreshQueued = false; + bool isAssetBeingCreated = false; + static constexpr std::string_view newAssetPopup = "Create New Asset"; + std::string nameOfAssetBeingCreated; }; } diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index 2fecae25..dde49838 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -93,13 +93,14 @@ namespace SHADE { EntityID const& eid = editor->selectedEntities[0]; SHEntity* entity = SHEntityManager::GetEntityByID(eid); - if(!entity) + SHSceneNode* entityNode = SHSceneManager::GetCurrentSceneGraph().GetNode(eid); + if(!entity || !entityNode) { ImGui::End(); return; } ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid); - SHEditorWidgets::CheckBox("##IsActive", [entity]()->bool {return entity->GetActive(); }, [entity](bool const& active) {entity->SetActive(active); }); + SHEditorWidgets::CheckBox("##IsActive", [entityNode]()->bool {return entityNode->IsActive(); }, [entityNode](bool const& active) {entityNode->SetActive(active); }); ImGui::SameLine(); ImGui::InputText("##EntityName", &entity->name); diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp index cfb36cd0..ce3ca8b5 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp @@ -223,39 +223,20 @@ namespace SHADE { if(editor->SaveScene()) { - const SHEditorStateChangeEvent STATE_CHANGE_EVENT - { - .previousState = editor->editorState - }; - editor->editorState = SHEditor::State::PLAY; - - SHEventManager::BroadcastEvent(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT); + editor->Play(); } } ImGui::EndDisabled(); ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE); if(ImGui::SmallButton(ICON_MD_PAUSE)) { - const SHEditorStateChangeEvent STATE_CHANGE_EVENT - { - .previousState = editor->editorState - }; - editor->editorState = SHEditor::State::PAUSE; - - SHEventManager::BroadcastEvent(STATE_CHANGE_EVENT, SH_EDITOR_ON_PAUSE_EVENT); + editor->Pause(); } ImGui::EndDisabled(); ImGui::BeginDisabled(editor->editorState == SHEditor::State::STOP); if(ImGui::SmallButton(ICON_MD_STOP)) { - const SHEditorStateChangeEvent STATE_CHANGE_EVENT - { - .previousState = editor->editorState - }; - editor->editorState = SHEditor::State::STOP; - - SHEventManager::BroadcastEvent(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT); - editor->LoadScene(SHSceneManager::GetCurrentSceneAssetID()); + editor->Stop(); } ImGui::EndDisabled(); ImGui::EndMenuBar(); diff --git a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp index d6ef8d19..7b3b5411 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp @@ -40,6 +40,7 @@ namespace SHADE shouldUpdateCamera = false; } ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); + SHEditor* editor = SHSystemManager::GetSystem(); if (Begin()) { @@ -51,7 +52,6 @@ namespace SHADE beginCursorPos = ImGui::GetCursorScreenPos(); viewportMousePos = { mousePos.x - beginCursorPos.x, mousePos.y - beginCursorPos.y }; gfxSystem->GetMousePickSystem()->SetViewportMousePos(viewportMousePos); - ImGui::Image((ImTextureID)descriptorSet, { beginContentRegionAvailable.x, beginContentRegionAvailable.y }); if (ImGui::IsWindowHovered() && ImGui::IsMouseDown(ImGuiMouseButton_Right)) @@ -64,24 +64,25 @@ namespace SHADE shouldUpdateCamera = true; } - if (ImGui::IsWindowFocused() && !ImGui::IsMouseDown(ImGuiMouseButton_Right)) + if (editor->editorState != SHEditor::State::PLAY && ImGui::IsWindowFocused() && !ImGui::IsMouseDown(ImGuiMouseButton_Right)) { - if (ImGui::IsKeyReleased(ImGuiKey_Q)) + if (ImGui::IsKeyReleased(ImGuiKey_W)) { transformGizmo.operation = SHTransformGizmo::Operation::TRANSLATE; } - if (ImGui::IsKeyReleased(ImGuiKey_W)) + if (ImGui::IsKeyReleased(ImGuiKey_E)) { transformGizmo.operation = SHTransformGizmo::Operation::ROTATE; } - if (ImGui::IsKeyReleased(ImGuiKey_E)) + if (ImGui::IsKeyReleased(ImGuiKey_R)) { transformGizmo.operation = SHTransformGizmo::Operation::SCALE; } } } ImGuizmo::SetRect(beginCursorPos.x, beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y); - transformGizmo.Draw(); + if(editor->editorState != SHEditor::State::PLAY) + transformGizmo.Draw(); ImGui::End(); ImGui::PopStyleVar(); } diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index c4ad3459..90655a62 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -168,7 +168,19 @@ namespace SHADE { SHCommandManager::UndoCommand(); } - + if(ImGui::IsKeyReleased(ImGuiKey_F5)) + { + Play(); + } + else if (ImGui::IsKeyReleased(ImGuiKey_F6)) + { + Pause(); + } + else if (ImGui::IsKeyReleased(ImGuiKey_F7)) + { + Stop(); + } + Render(); } @@ -597,6 +609,48 @@ namespace SHADE } } + void SHEditor::Play() + { + if(editorState == State::PLAY) + return; + if (SaveScene()) + { + const SHEditorStateChangeEvent STATE_CHANGE_EVENT + { + .previousState = editorState + }; + editorState = State::PLAY; + SHCommandManager::SwapStacks(); + SHEventManager::BroadcastEvent(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT); + } + } + + void SHEditor::Pause() + { + if (editorState == State::PAUSE) + return; + const SHEditorStateChangeEvent STATE_CHANGE_EVENT + { + .previousState = editorState + }; + editorState = State::PAUSE; + SHEventManager::BroadcastEvent(STATE_CHANGE_EVENT, SH_EDITOR_ON_PAUSE_EVENT); + } + + void SHEditor::Stop() + { + if (editorState == State::STOP) + return; + const SHEditorStateChangeEvent STATE_CHANGE_EVENT + { + .previousState = editorState + }; + editorState = SHEditor::State::STOP; + SHCommandManager::SwapStacks(); + SHEventManager::BroadcastEvent(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT); + LoadScene(SHSceneManager::GetCurrentSceneAssetID()); + } + void SHEditor::NewFrame() { SDL_Event event; diff --git a/SHADE_Engine/src/Editor/SHEditor.h b/SHADE_Engine/src/Editor/SHEditor.h index 0f5a3aaa..0de7796a 100644 --- a/SHADE_Engine/src/Editor/SHEditor.h +++ b/SHADE_Engine/src/Editor/SHEditor.h @@ -184,6 +184,10 @@ namespace SHADE void LoadScene(AssetID const& assetID) noexcept; + void Play(); + void Pause(); + void Stop(); + // List of selected entities std::vector selectedEntities; diff --git a/SHADE_Engine/src/Scene/SHSceneNode.cpp b/SHADE_Engine/src/Scene/SHSceneNode.cpp index b619d464..8dac20bd 100644 --- a/SHADE_Engine/src/Scene/SHSceneNode.cpp +++ b/SHADE_Engine/src/Scene/SHSceneNode.cpp @@ -136,7 +136,7 @@ namespace SHADE for (auto* child : children) { - SetActive(newActiveState); + child->SetActive(newActiveState); } } diff --git a/SHADE_Engine/src/Tools/SHDeque.h b/SHADE_Engine/src/Tools/SHDeque.h new file mode 100644 index 00000000..99df910a --- /dev/null +++ b/SHADE_Engine/src/Tools/SHDeque.h @@ -0,0 +1,69 @@ +#pragma once +#pragma once + +#include "SH_API.h" +#include + +namespace SHADE +{ + template + class SH_API SHDeque + { + public: + using ValueType = T; + using Pointer = T*; + using ValueRef = T&; + using ValueConstRef = T const&; + using SizeType = uint32_t; + using ContainerType = std::deque; + using ContainerTypeConstRef = std::deque; + + SHDeque(SizeType n) : max_size(n) {} + + ContainerTypeConstRef const& GetDeque() const + { + return deque; + } + + void Push(ValueConstRef obj) + { + if (deque.size() < max_size) + deque.push_front(std::move(obj)); + else + { + deque.pop_back(); + deque.push_front(std::move(obj)); + } + } + + bool Empty() + { + return deque.empty(); + } + + void Pop() + { + deque.pop_front(); + } + + ValueConstRef Top() + { + return deque.front(); + } + + SizeType Size() const noexcept + { + return deque.size(); + } + + void Clear() + { + deque.clear(); + } + + private: + int max_size; + ContainerType deque{}; + + }; +} \ No newline at end of file