diff --git a/Assets/Editor/Fonts/fa-solid-900.ttf b/Assets/Editor/Fonts/fa-solid-900.ttf new file mode 100644 index 00000000..f89fc9f8 Binary files /dev/null and b/Assets/Editor/Fonts/fa-solid-900.ttf differ diff --git a/Assets/Editor/Layouts/UserLayout.ini b/Assets/Editor/Layouts/UserLayout.ini index 005c3556..baced6b8 100644 --- a/Assets/Editor/Layouts/UserLayout.ini +++ b/Assets/Editor/Layouts/UserLayout.ini @@ -1,16 +1,16 @@ [Window][MainStatusBar] -Pos=0,1367 -Size=3440,20 +Pos=0,1060 +Size=1920,20 Collapsed=0 [Window][SHEditorMenuBar] Pos=0,48 -Size=3440,1319 +Size=1920,1012 Collapsed=0 [Window][Hierarchy Panel] -Pos=0,170 -Size=646,1197 +Pos=0,142 +Size=387,918 Collapsed=0 DockId=0x00000004,0 @@ -20,14 +20,14 @@ Size=400,400 Collapsed=0 [Window][Inspector] -Pos=3169,48 -Size=271,1319 +Pos=1649,48 +Size=271,1012 Collapsed=0 DockId=0x00000006,0 [Window][Profiler] Pos=0,48 -Size=646,120 +Size=387,92 Collapsed=0 DockId=0x00000003,0 @@ -37,12 +37,18 @@ Size=2519,1319 Collapsed=0 DockId=0x00000002,0 +[Window][ Viewport] +Pos=389,48 +Size=1258,1012 +Collapsed=0 +DockId=0x00000002,0 + [Docking][Data] -DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=0,71 Size=3440,1319 Split=X +DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1992,1036 Split=X - DockNode ID=0x00000001 Parent=0x00000005 SizeRef=646,1036 Split=Y Selected=0x1E6EB881 + DockNode ID=0x00000001 Parent=0x00000005 SizeRef=387,1036 Split=Y Selected=0x1E6EB881 DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE - DockNode ID=0x00000002 Parent=0x00000005 SizeRef=999,1036 CentralNode=1 Selected=0x13926F0B + DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1258,1036 CentralNode=1 Selected=0xB41284E7 DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=271,1036 Selected=0xE7039252 diff --git a/SHADE_Application/premake5.lua b/SHADE_Application/premake5.lua index 35ea2c10..395c3a48 100644 --- a/SHADE_Application/premake5.lua +++ b/SHADE_Application/premake5.lua @@ -37,7 +37,8 @@ project "SHADE_Application" "%{IncludeDir.VULKAN}/include", "%{IncludeDir.spdlog}/include", "%{IncludeDir.tinyddsloader}", - "%{IncludeDir.reactphysics3d}\\include" + "%{IncludeDir.reactphysics3d}\\include", + "%{IncludeDir.yamlcpp}" } externalwarnings "Off" @@ -51,6 +52,7 @@ project "SHADE_Application" { "SHADE_Engine", "SHADE_Managed", + "yaml-cpp", "SDL2.lib", "SDL2main.lib" } diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 9bfd82de..e33bdf8a 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -150,11 +150,10 @@ namespace Sandbox SHSceneManager::SceneUpdate(0.016f); #endif SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f); - editor->PollPicking(); + //editor->PollPicking(); } - // Finish all graphics jobs first - graphicsSystem->AwaitGraphicsExecution(); + graphicsSystem->AwaitGraphicsExecution(); } diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 6b3fee1d..b414ecaf 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -1,4 +1,4 @@ -#include "SBpch.h" + #include "SBpch.h" #include "SBTestScene.h" #include "ECS_Base/Managers/SHSystemManager.h" @@ -15,6 +15,7 @@ #include "Assets/SHAssetManager.h" #include "Camera/SHCameraComponent.h" +#include "Resource/SHResourceManager.h" using namespace SHADE; @@ -41,34 +42,22 @@ namespace Sandbox const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem); //Test Racoon mesh - auto meshes = SHADE::SHAssetManager::GetAllMeshes(); std::vector> handles; - for (auto const& mesh : meshes) + std::vector> texHandles; + for (const auto& asset : SHAssetManager::GetAllAssets()) { - if (mesh.header.meshName == "Cube.012") + switch (asset.type) { - handles.push_back(graphicsSystem->AddMesh( - mesh.header.vertexCount, - mesh.vertexPosition.data(), - mesh.texCoords.data(), - mesh.vertexTangent.data(), - mesh.vertexNormal.data(), - mesh.header.indexCount, - mesh.indices.data() - )); + case AssetType::MESH: + if (asset.name == "Cube.012") + handles.emplace_back(SHResourceManager::LoadOrGet(asset.id)); + break; + case AssetType::TEXTURE: + texHandles.emplace_back(SHResourceManager::LoadOrGet(asset.id)); + break; } } - graphicsSystem->BuildMeshBuffers(); - - // Load Textures - auto textures = SHADE::SHAssetManager::GetAllTextures(); - std::vector> texHandles; - for (const auto& tex : textures) - { - auto texture = graphicsSystem->Add(tex); - texHandles.push_back(texture); - } - graphicsSystem->BuildTextures(); + SHResourceManager::FinaliseChanges(); // Create Materials auto matInst = graphicsSystem->AddOrGetBaseMaterialInstance(); @@ -79,8 +68,8 @@ namespace Sandbox // Create Stress Test Objects static const SHVec3 TEST_OBJ_SCALE = SHVec3::One * 0.5f; - constexpr int NUM_ROWS = 10; - constexpr int NUM_COLS = 10; + constexpr int NUM_ROWS = 0; + constexpr int NUM_COLS = 0; static const SHVec3 TEST_OBJ_SPACING = { 0.1f, 0.1f, 0.1f }; static const SHVec3 TEST_OBJ_START_POS = { -(NUM_COLS / 2 * TEST_OBJ_SPACING.x) + 1.0f, -2.0f, -1.0f }; diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index aa9772dd..956d52e8 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -62,7 +62,12 @@ namespace SHADE } } - AssetPath SHAssetManager::GenerateLocalPath(AssetPath path) noexcept + void SHAssetManager::Unload(AssetID assetId) noexcept + { + // TODO + } + + AssetPath SHAssetManager::GenerateLocalPath(AssetPath path) noexcept { if (!IsRecognised(path.extension().string().c_str())) { diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index 50549e01..2469165a 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -32,6 +32,7 @@ namespace SHADE * \brief Deallocate all memory used by resource data ****************************************************************************/ static void Unload() noexcept; + static void Unload(AssetID assetId) noexcept; /**************************************************************************** * \brief Load all resources that are in the folder diff --git a/SHADE_Engine/src/Camera/SHCameraDirector.h b/SHADE_Engine/src/Camera/SHCameraDirector.h index b1311147..5d09788b 100644 --- a/SHADE_Engine/src/Camera/SHCameraDirector.h +++ b/SHADE_Engine/src/Camera/SHCameraDirector.h @@ -3,7 +3,7 @@ #include "SH_API.h" #include "ECS_Base/Entity/SHEntity.h" #include "Math/SHMatrix.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" namespace SHADE diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.cpp b/SHADE_Engine/src/Camera/SHCameraSystem.cpp index 40b63294..0d86c17a 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.cpp +++ b/SHADE_Engine/src/Camera/SHCameraSystem.cpp @@ -144,6 +144,7 @@ namespace SHADE camera.yaw = SHMath::RadiansToDegrees(rotation.y); camera.roll = SHMath::RadiansToDegrees(rotation.z); camera.position = transform->GetWorldPosition(); + camera.dirtyView = true; } diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.h b/SHADE_Engine/src/Camera/SHCameraSystem.h index dacda574..68071160 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.h +++ b/SHADE_Engine/src/Camera/SHCameraSystem.h @@ -3,7 +3,7 @@ #include "ECS_Base/System/SHSystem.h" #include "SHCameraComponent.h" #include "ECS_Base/System/SHSystemRoutine.h" -#include "Resource/ResourceLibrary.h" +#include "Resource/SHResourceLibrary.h" #include "SHCameraDirector.h" #include "SH_API.h" @@ -16,7 +16,7 @@ namespace SHADE //This is not tied to any entity. Hence this EID should not be used. SHCameraComponent editorCamera; - ResourceLibrary directorLibrary; + SHResourceLibrary directorLibrary; std::vector directorHandleList; public: diff --git a/SHADE_Engine/src/ECS_Base/Components/SHComponent.h b/SHADE_Engine/src/ECS_Base/Components/SHComponent.h index cfcd724c..1c4e5de6 100644 --- a/SHADE_Engine/src/ECS_Base/Components/SHComponent.h +++ b/SHADE_Engine/src/ECS_Base/Components/SHComponent.h @@ -48,6 +48,9 @@ namespace SHADE { } + + + public: //Whether or not this component is active. //Systems using this component should are responsible for checking the active state of the component before running their functionality. @@ -59,7 +62,7 @@ namespace SHADE * \return uint32_t * The entityID that this component belongs to. ***************************************************************************/ - uint32_t GetEID()const + uint32_t GetEID()const noexcept { return this->entityID; } diff --git a/SHADE_Engine/src/Editor/Command/SHCommand.hpp b/SHADE_Engine/src/Editor/Command/SHCommand.hpp index 7a526506..149c8986 100644 --- a/SHADE_Engine/src/Editor/Command/SHCommand.hpp +++ b/SHADE_Engine/src/Editor/Command/SHCommand.hpp @@ -24,6 +24,7 @@ namespace SHADE class SHCommand : SHBaseCommand { public: + using SHCommandPtr = std::unique_ptr; typedef std::function SetterFunction; SHCommand(T const& oldVal, T const& value, SetterFunction setFnc) diff --git a/SHADE_Engine/src/Editor/Command/SHCommandManager.cpp b/SHADE_Engine/src/Editor/Command/SHCommandManager.cpp index ee2d316d..3c0ee5dd 100644 --- a/SHADE_Engine/src/Editor/Command/SHCommandManager.cpp +++ b/SHADE_Engine/src/Editor/Command/SHCommandManager.cpp @@ -13,7 +13,7 @@ namespace SHADE SHCommandManager::CommandStack SHCommandManager::undoStack{}; SHCommandManager::CommandStack SHCommandManager::redoStack{}; - void SHCommandManager::PerformCommand(CommandPtr commandPtr, bool const& overrideValue) + void SHCommandManager::PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue) { redoStack = CommandStack(); commandPtr->Execute(); @@ -27,9 +27,9 @@ namespace SHADE } } - void SHCommandManager::RegisterCommand(CommandPtr commandPtr) + void SHCommandManager::RegisterCommand(BaseCommandPtr commandPtr) { - undoStack.push(commandPtr); + undoStack.push(commandPtr); } void SHCommandManager::UndoCommand() @@ -59,4 +59,14 @@ namespace SHADE { return redoStack.size(); } + + void SHCommandManager::PopLatestCommandFromRedoStack() + { + redoStack.pop(); + } + + void SHCommandManager::PopLatestCommandFromUndoStack() + { + undoStack.pop(); + } }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/Command/SHCommandManager.h b/SHADE_Engine/src/Editor/Command/SHCommandManager.h index 9152c3cb..a514c464 100644 --- a/SHADE_Engine/src/Editor/Command/SHCommandManager.h +++ b/SHADE_Engine/src/Editor/Command/SHCommandManager.h @@ -19,16 +19,21 @@ namespace SHADE //#==============================================================# //|| Type Aliases || //#==============================================================# - using CommandPtr = std::shared_ptr; - using CommandStack = std::stack; + using BaseCommandPtr = std::shared_ptr; + template + using SHCommandPtr = std::shared_ptr>; + using CommandStack = std::stack; - static void PerformCommand(CommandPtr commandPtr, bool const& overrideValue = false); - static void RegisterCommand(CommandPtr commandPtr); + static void PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue = false); + static void RegisterCommand(BaseCommandPtr commandPtr); static void UndoCommand(); static void RedoCommand(); static std::size_t GetUndoStackSize(); static std::size_t GetRedoStackSize(); + static void PopLatestCommandFromRedoStack(); + static void PopLatestCommandFromUndoStack(); + private: static CommandStack undoStack; static CommandStack redoStack; diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp index 30af228b..27e46d98 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp @@ -22,6 +22,7 @@ #include #include "Serialization/SHSerialization.h" +#include "Tools/SHClipboardUtilities.h" namespace SHADE @@ -52,6 +53,7 @@ namespace SHADE if(const auto root = sceneGraph.GetRoot()) { auto const& children = root->GetChildren(); + for (const auto child : children) { RecursivelyDrawEntityNode(child); @@ -79,6 +81,8 @@ namespace SHADE void SHHierarchyPanel::SetScrollTo(EntityID eid) { + if(eid == MAX_EID) + return; scrollTo = eid; } @@ -104,7 +108,7 @@ namespace SHADE } if (ImGui::SmallButton(ICON_MD_ADD_CIRCLE)) { - SHEntityManager::CreateEntity(); + SHCommandManager::PerformCommand(std::make_shared()); } if (ImGui::IsItemHovered()) { @@ -144,23 +148,32 @@ namespace SHADE auto* entity = SHEntityManager::GetEntityByID(currentNode->GetEntityID()); //Draw Node - bool isNodeOpen = ImGui::TreeNodeEx(reinterpret_cast(entity), nodeFlags, "%u: %s", EntityHandleGenerator::GetIndex(eid), entity->name.c_str()); + bool isNodeOpen = ImGui::TreeNodeEx(reinterpret_cast(entity), nodeFlags, "%u: %s", SHEntityManager::GetEntityIndex(eid), entity->name.c_str()); const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); //Check For Begin Drag if (SHDragDrop::BeginSource()) { - ImGui::Text("Moving EID: %zu", eid); - SHDragDrop::SetPayload(DRAG_EID, &eid); + std::string moveLabel = "Moving EID: "; + if(!isSelected) + editor->selectedEntities.push_back(eid); + for(int i = 0; i < static_cast(editor->selectedEntities.size()); ++i) + { + moveLabel.append(std::to_string(editor->selectedEntities[i])); + if(i + 1 < static_cast(editor->selectedEntities.size())) + { + moveLabel.append(", "); + } + } + ImGui::Text(moveLabel.c_str()); + SHDragDrop::SetPayload>(DRAG_EID, &editor->selectedEntities); SHDragDrop::EndSource(); } else if (SHDragDrop::BeginTarget()) //If Received DragDrop { - if (const EntityID* eidPayload = SHDragDrop::AcceptPayload(DRAG_EID)) //If payload is valid + if (const std::vector* eidPayload = SHDragDrop::AcceptPayload>(DRAG_EID)) //If payload is valid { - EntityID const dropEID = *eidPayload; - if(!sceneGraph.GetChild(dropEID, eid)) - sceneGraph.SetParent(dropEID, eid); //Set dropEID parent to eid (belonging to current Node) + ParentSelectedEntities(eid); SHDragDrop::EndTarget(); } } @@ -175,7 +188,15 @@ namespace SHADE } if(ImGui::Selectable("Copy")) { - SHLOG_INFO(SHSerialization::SerializeEntitiesToString(editor->selectedEntities)) + SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(editor->selectedEntities)); + } + if(ImGui::Selectable("Paste")) + { + SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard())); + } + if(ImGui::Selectable("Paste as Child")) + { + SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard(), eid)); } if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data())) { @@ -184,7 +205,7 @@ namespace SHADE if((currentNode->GetParent() != sceneGraph.GetRoot()) && ImGui::Selectable(std::format("{} Unparent Selected", ICON_MD_NORTH_WEST).data())) { - sceneGraph.SetParent(currentNode->GetEntityID(), nullptr); + ParentSelectedEntities(MAX_EID); } ImGui::EndPopup(); } @@ -196,7 +217,15 @@ namespace SHADE { if (!isSelected) { - if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) + if(ImGui::IsKeyDown(ImGuiKey_LeftShift)) + { + if(editor->selectedEntities.size() >= 1) + { + SelectRangeOfEntities(editor->selectedEntities[0], eid); + } + else editor->selectedEntities.clear(); + } + else if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) editor->selectedEntities.clear(); editor->selectedEntities.push_back(eid); }//if not selected @@ -243,4 +272,90 @@ namespace SHADE { SHEntityManager::CreateEntity(MAX_EID, "DefaultChild", parentEID); } + + void SHHierarchyPanel::ParentSelectedEntities(EntityID parentEID) const noexcept + { + auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); + auto const editor = SHSystemManager::GetSystem(); + SHEntityParentCommand::EntityParentData entityParentData; + std::vector parentedEIDS; + for(auto const& eid : editor->selectedEntities) + { + if(sceneGraph.GetChild(eid, parentEID) == nullptr) + { + parentedEIDS.push_back(eid); + if(auto parent = sceneGraph.GetParent(eid)) + entityParentData[eid].oldParentEID = parent->GetEntityID(); + entityParentData[eid].newParentEID = parentEID; + } + } + SHCommandManager::PerformCommand(std::make_shared(parentedEIDS, entityParentData)); + } + + void SHHierarchyPanel::SelectRangeOfEntities(EntityID beginEID, EntityID endEID) + { + bool startSelecting = false; bool endSelecting = false; + auto const editor = SHSystemManager::GetSystem(); + editor->selectedEntities.clear(); + auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); + sceneGraph.Traverse([&](SHSceneNode* nodePtr) + { + auto eid = nodePtr->GetEntityID(); + if(!startSelecting) + { + if(eid == beginEID || eid == endEID) + { + startSelecting = true; + editor->selectedEntities.push_back(eid); + } + } + else + { + if(!endSelecting) + { + editor->selectedEntities.push_back(eid); + if(eid == endEID || eid == beginEID) + { + endSelecting = true; + } + } + } + }); + } + + void SHCreateEntityCommand::Execute() + { + EntityID newEID = SHEntityManager::CreateEntity(eid); + if(eid == MAX_EID) + eid = newEID; + } + + void SHCreateEntityCommand::Undo() + { + SHEntityManager::DestroyEntity(eid); + } + + void SHEntityParentCommand::Execute() + { + auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); + for(auto const& eid : entities) + { + if(entityParentData[eid].newParentEID == MAX_EID) + sceneGraph.SetParent(eid, nullptr); + else + sceneGraph.SetParent(eid, entityParentData[eid].newParentEID); + } + } + + void SHEntityParentCommand::Undo() + { + auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); + for(auto const& eid : entities) + { + if(entityParentData[eid].oldParentEID == MAX_EID) + sceneGraph.SetParent(eid, nullptr); + else + sceneGraph.SetParent(eid, entityParentData[eid].oldParentEID); + } + } }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h index 88983ca9..0cfe6474 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h @@ -10,7 +10,7 @@ #include "imgui_internal.h" #include "ECS_Base/SHECSMacros.h" #include "Editor/EditorWindow/SHEditorWindow.h" - +#include "Editor/Command/SHCommand.hpp" namespace SHADE { class SHSceneNode; @@ -28,8 +28,40 @@ namespace SHADE void DrawMenuBar() const noexcept; ImRect RecursivelyDrawEntityNode(SHSceneNode*); void CreateChildEntity(EntityID parentEID) const noexcept; + void ParentSelectedEntities(EntityID parentEID) const noexcept; + void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID); std::string filter; bool isAnyNodeSelected = false; EntityID scrollTo = MAX_EID; };//class SHHierarchyPanel + + //Might move to a different file + class SHCreateEntityCommand final : public SHBaseCommand + { + public: + void Execute() override; + void Undo() override; + private: + EntityID eid = MAX_EID; + }; + + class SHEntityParentCommand final : public SHBaseCommand + { + public: + struct Data + { + EntityID oldParentEID = MAX_EID; + EntityID newParentEID = MAX_EID; + }; + using EntityParentData = std::unordered_map; + + SHEntityParentCommand(std::vector entityIDs, EntityParentData inEntityParentData):entities(entityIDs),entityParentData(inEntityParentData){} + + void Execute() override; + void Undo() override; + private: + std::vector entities; + std::unordered_map entityParentData; + }; + }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 47fec730..08f5695b 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -10,6 +10,7 @@ //|| SHADE Includes || //#==============================================================# #include "Editor/IconsMaterialDesign.h" +#include "Editor/IconsFontAwesome6.h" #include "ECS_Base/Components/SHComponent.h" #include "Editor/SHEditorWidgets.hpp" #include "Physics/Components/SHColliderComponent.h" @@ -216,7 +217,7 @@ namespace SHADE if (collider.GetType() == SHCollider::Type::BOX) { - SHEditorWidgets::BeginPanel( std::format("{} Box Collider #{}", ICON_MD_VIEW_IN_AR, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); + SHEditorWidgets::BeginPanel( std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); auto box = reinterpret_cast(collider.GetShape()); SHEditorWidgets::DragVec3("Half Extents", { "X", "Y", "Z" }, [box] {return box->GetHalfExtents(); }, [box](SHVec3 const& vec) {box->SetHalfExtents(vec);}); } diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index da09f345..b59ce9cc 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -55,7 +55,11 @@ namespace SHADE { EntityID const& eid = editor->selectedEntities[0]; SHEntity* entity = SHEntityManager::GetEntityByID(eid); - + if(!entity) + { + 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); }); ImGui::SameLine(); diff --git a/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp b/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp index ef2ff8c0..11fcb7c2 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp @@ -3,6 +3,7 @@ #include #include "ECS_Base/Managers/SHSystemManager.h" +#include "Editor/Command/SHCommandManager.h" #include "FRC/SHFramerateController.h" namespace SHADE @@ -38,6 +39,11 @@ namespace SHADE { ImGui::PlotLines("DT", frames.data(), static_cast(frames.size()), 0, nullptr, 0.0f, 16.0f); } + if(ImGui::CollapsingHeader("Command Manager")) + { + ImGui::Text("Undo: %zu", SHCommandManager::GetUndoStackSize()); + ImGui::Text("Redo: %zu", SHCommandManager::GetRedoStackSize()); + } ImGui::End(); } diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp index edbe0faa..b5a691d8 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp @@ -43,9 +43,12 @@ namespace SHADE bool result = ImGui::Begin(windowName.data(), &isOpen, windowFlags); auto wndSize = ImGui::GetWindowSize(); - if(windowSize.x != wndSize.x || windowSize.y != wndSize.y) + auto contentRegionAvail = ImGui::GetContentRegionAvail(); + if( beginContentRegionAvailable.x != contentRegionAvail.x || beginContentRegionAvailable.y != contentRegionAvail.y || windowSize.x != wndSize.x || windowSize.y != wndSize.y) { windowSize = {wndSize.x, wndSize.y}; + beginContentRegionAvailable = {contentRegionAvail.x, contentRegionAvail.y}; + OnResize(); } auto wndPos = ImGui::GetWindowPos(); diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h index f46cd880..239d8223 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h @@ -26,6 +26,10 @@ namespace SHADE bool isOpen; bool isWindowHovered; std::string_view windowName; + SHVec2 windowSize; + SHVec2 windowPos; + SHVec2 viewportMousePos; + SHVec2 beginContentRegionAvailable; protected: virtual bool Begin(); virtual void OnResize(); @@ -33,8 +37,6 @@ namespace SHADE ImGuiWindowFlags windowFlags = 0; ImGuiIO& io; - SHVec2 windowSize; - SHVec2 windowPos; - SHVec2 viewportMousePos; + };//class SHEditorWindow }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp index 420443ae..b06c37c7 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp @@ -1,17 +1,23 @@ #include "SHpch.h" +#include "Editor/SHImGuiHelpers.hpp" #include "SHEditorViewport.h" +#include "ImGuizmo.h" #include "ECS_Base/Managers/SHSystemManager.h" +#include "Editor/IconsMaterialDesign.h" #include "Editor/SHEditor.hpp" #include "Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h" +#include + +constexpr std::string_view windowName = "\xef\x80\x95 Viewport"; namespace SHADE { SHEditorViewport::SHEditorViewport() - :SHEditorWindow("Viewport", ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoScrollbar) + :SHEditorWindow("\xee\x90\x8b Viewport", ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoScrollbar) { } @@ -26,31 +32,30 @@ namespace SHADE SHEditorWindow::Update(); if(Begin()) { + ImGuizmo::SetDrawlist(); DrawMenuBar(); auto gfxSystem = SHSystemManager::GetSystem(); auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0]; auto mousePos = ImGui::GetMousePos(); - auto cursorPos = ImGui::GetCursorScreenPos(); - viewportMousePos = {mousePos.x - cursorPos.x, mousePos.y - cursorPos.y}; + beginCursorPos = ImGui::GetCursorScreenPos(); + viewportMousePos = {mousePos.x - beginCursorPos.x, mousePos.y - beginCursorPos.y}; gfxSystem->GetMousePickSystem ()->SetViewportMousePos (viewportMousePos); - //if (ImGui::IsMouseReleased(ImGuiMouseButton_Left)) - //{ - // auto eid = gfxSystem->GetMousePickSystem ()->GetPickedEntity(); - // if(eid != MAX_EID) - // { - // auto editor = SHSystemManager::GetSystem(); - // editor->selectedEntities.clear(); - // editor->selectedEntities.push_back(eid); - // if (const auto hierarchyPanel = SHEditorWindowManager::GetEditorWindow()) - // { - // hierarchyPanel->SetScrollTo(eid); - // } - // } - //} - ImGui::Image((ImTextureID)descriptorSet, ImGui::GetWindowSize()); + ImGui::Image((ImTextureID)descriptorSet, {beginContentRegionAvailable.x, beginContentRegionAvailable.y}); + + if(ImGui::IsWindowHovered() && ImGui::IsMouseDown(ImGuiMouseButton_Right)) + { + ImGui::SetMouseCursor(ImGuiMouseCursor_None); + ImGui::SetCursorScreenPos(ImGui::GetMousePos()); + ImGui::PushStyleColor(ImGuiCol_Text, ImGuiColors::green); + ImGui::Text(ICON_FA_EYE); + ImGui::PopStyleColor(); + } } + ImGuizmo::SetRect(beginCursorPos.x , beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y); + transformGizmo.Draw(); ImGui::End(); + } void SHEditorViewport::Exit() @@ -66,7 +71,11 @@ namespace SHADE //auto pos = ImGui::GetCursorPos(); //windowCursorPos = {} - gfxSystem->PrepareResize(static_cast(windowSize.x), static_cast(windowSize.y)); + if(beginContentRegionAvailable.x == 0 || beginContentRegionAvailable.y == 0) + { + beginContentRegionAvailable = windowSize; + } + gfxSystem->PrepareResize(static_cast(beginContentRegionAvailable.x), static_cast(beginContentRegionAvailable.y)); } void SHEditorViewport::OnPosChange() @@ -74,10 +83,46 @@ namespace SHADE SHEditorWindow::OnPosChange(); } - void SHEditorViewport::DrawMenuBar() const noexcept + void SHEditorViewport::DrawMenuBar() noexcept { if(ImGui::BeginMenuBar()) { + bool const isTranslate = transformGizmo.operation == SHTransformGizmo::Operation::TRANSLATE; + ImGui::BeginDisabled(isTranslate); + if(isTranslate) + ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_CheckMark]); + if(ImGui::Button(ICON_MD_OPEN_WITH)) + { + transformGizmo.operation = SHTransformGizmo::Operation::TRANSLATE; + } + ImGui::EndDisabled(); + if(isTranslate) + ImGui::PopStyleColor(); + + bool const isRotate = transformGizmo.operation == SHTransformGizmo::Operation::ROTATE; + ImGui::BeginDisabled(isRotate); + if(isRotate) + ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_CheckMark]); + if(ImGui::Button(ICON_MD_AUTORENEW)) + { + transformGizmo.operation = SHTransformGizmo::Operation::ROTATE; + } + ImGui::EndDisabled(); + if(isRotate) + ImGui::PopStyleColor(); + + bool const isScale = transformGizmo.operation == SHTransformGizmo::Operation::SCALE; + ImGui::BeginDisabled(isScale); + if(isScale) + ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_CheckMark]); + if(ImGui::Button(ICON_MD_EXPAND)) + { + transformGizmo.operation = SHTransformGizmo::Operation::SCALE; + } + ImGui::EndDisabled(); + if(isScale) + ImGui::PopStyleColor(); + ImGui::EndMenuBar(); } } diff --git a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.h b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.h index 5f4a5919..80b13285 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.h +++ b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.h @@ -10,6 +10,7 @@ #include "imgui_internal.h" #include "ECS_Base/SHECSMacros.h" #include "Editor/EditorWindow/SHEditorWindow.h" +#include "Editor/Gizmos/SHTransformGizmo.h" namespace SHADE { @@ -20,10 +21,12 @@ namespace SHADE void Init() override; void Update() override; void Exit() override; + SHTransformGizmo transformGizmo; protected: void OnResize() override; void OnPosChange() override; private: - void DrawMenuBar() const noexcept; + void DrawMenuBar() noexcept; + SHVec2 beginCursorPos; };//class SHEditorViewport }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/Gizmos/SHTransformGizmo.cpp b/SHADE_Engine/src/Editor/Gizmos/SHTransformGizmo.cpp new file mode 100644 index 00000000..a53b8c10 --- /dev/null +++ b/SHADE_Engine/src/Editor/Gizmos/SHTransformGizmo.cpp @@ -0,0 +1,85 @@ +#include "SHpch.h" +#include "SHTransformGizmo.h" + +#include "ECS_Base/Managers/SHComponentManager.h" +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Editor/SHEditor.hpp" +#include "Editor/SHImGuiHelpers.hpp" +#include +#include + +#include "Camera/SHCameraSystem.h" +#include "Editor/Command/SHCommandManager.h" +#include "Editor/EditorWindow/ViewportWindow/SHEditorViewport.h" +namespace SHADE +{ + void SHTransformGizmo::Draw() + { + bool justChangedTfm = false; + if (!editorCamera) + { + auto const cameraSystem = SHSystemManager::GetSystem(); + editorCamera = cameraSystem->GetEditorCamera(); + } + auto viewportWindow = SHEditorWindowManager::GetEditorWindow(); + ImGuizmo::SetOrthographic(false); + + SHMatrix view = SHMatrix::Transpose(editorCamera->GetViewMatrix()); + SHMatrix proj = SHMatrix::Transpose(editorCamera->GetProjMatrix()); + proj(1, 1) *= -1; + static SHMatrix gridMat = SHMatrix::Translate(0, -0.5f, 0.f) * SHMatrix::Identity; + //ImGuizmo::DrawGrid(&view._11, &proj._11, &gridMat._11, 100.f); + if (selectedEntityTransformComponent == nullptr) + { + SHEditor* editor = SHSystemManager::GetSystem(); + if (editor->selectedEntities.empty()) + return; + EntityID eid = editor->selectedEntities.back(); + selectedEntityTransformComponent = SHComponentManager::GetComponent_s(eid); + justChangedTfm = true; + } + else + { + SHEditor* editor = SHSystemManager::GetSystem(); + if (editor->selectedEntities.empty()) + return; + EntityID eid = editor->selectedEntities.back(); + auto tfmComponent = SHComponentManager::GetComponent_s(eid); + if (selectedEntityTransformComponent != tfmComponent) + { + selectedEntityTransformComponent = tfmComponent; + justChangedTfm = true; + } + } + if (selectedEntityTransformComponent == nullptr) + return; + + SHMatrix mat = selectedEntityTransformComponent->GetTRS(); + isManipulating = ImGuizmo::Manipulate(&view._11, &proj._11, static_cast(operation), ImGuizmo::MODE::WORLD, &mat._11); + if (!justChangedTfm) + { + if (ImGui::IsItemClicked()) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(selectedEntityTransformComponent->GetTRS(), mat, [tfm = std::move(selectedEntityTransformComponent)](SHMatrix const& mtx) + { + if (!tfm) + return; + SHVec3 translate{}, rotate{}, scale{}; + mtx.Decompose(translate, rotate, scale); + tfm->SetWorldPosition(translate); + tfm->SetWorldRotation(rotate); + tfm->SetWorldScale(scale); + }))); + else if (ImGui::IsItemHovered(ImGuiMouseButton_Left) && ImGui::IsMouseDown(ImGuiMouseButton_Left) && isManipulating) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(selectedEntityTransformComponent->GetTRS(), mat, [tfm = std::move(selectedEntityTransformComponent)](SHMatrix const& mtx) + { + if (!tfm) + return; + SHVec3 translate{}, rotate{}, scale{}; + mtx.Decompose(translate, rotate, scale); + tfm->SetWorldPosition(translate); + tfm->SetWorldRotation(rotate); + tfm->SetWorldScale(scale); + })), true); + } + } +} diff --git a/SHADE_Engine/src/Editor/Gizmos/SHTransformGizmo.h b/SHADE_Engine/src/Editor/Gizmos/SHTransformGizmo.h new file mode 100644 index 00000000..2565575f --- /dev/null +++ b/SHADE_Engine/src/Editor/Gizmos/SHTransformGizmo.h @@ -0,0 +1,48 @@ +#pragma once +#include "Camera/SHCameraComponent.h" +#include "Math/Transform/SHTransformComponent.h" + +namespace SHADE +{ + class SHTransformGizmo + { + public: + enum class Mode + { + WORLD, + LOCAL + }; + + enum class Operation + { + TRANSLATE_X = (1u << 0), + TRANSLATE_Y = (1u << 1), + TRANSLATE_Z = (1u << 2), + ROTATE_X = (1u << 3), + ROTATE_Y = (1u << 4), + ROTATE_Z = (1u << 5), + ROTATE_SCREEN = (1u << 6), + SCALE_X = (1u << 7), + SCALE_Y = (1u << 8), + SCALE_Z = (1u << 9), + BOUNDS = (1u << 10), + SCALE_XU = (1u << 11), + SCALE_YU = (1u << 12), + SCALE_ZU = (1u << 13), + + TRANSLATE = TRANSLATE_X | TRANSLATE_Y | TRANSLATE_Z, + ROTATE = ROTATE_X | ROTATE_Y | ROTATE_Z | ROTATE_SCREEN, + SCALE = SCALE_X | SCALE_Y | SCALE_Z, + SCALEU = SCALE_XU | SCALE_YU | SCALE_ZU, // universal + UNIVERSAL = TRANSLATE | ROTATE | SCALEU + }; + + void Draw(); + bool isManipulating = false; + Mode mode = Mode::WORLD; + Operation operation = Operation::TRANSLATE; + private: + SHTransformComponent* selectedEntityTransformComponent{nullptr}; + SHCameraComponent* editorCamera{nullptr}; + }; +} diff --git a/SHADE_Engine/src/Editor/IconsFontAwesome6.h b/SHADE_Engine/src/Editor/IconsFontAwesome6.h new file mode 100644 index 00000000..77831d94 --- /dev/null +++ b/SHADE_Engine/src/Editor/IconsFontAwesome6.h @@ -0,0 +1,1400 @@ +#pragma once +// Generated by https://github.com/juliettef/IconFontCppHeaders script GenerateIconFontCppHeaders.py for languages C and C++ +// from https://github.com/FortAwesome/Font-Awesome/raw/6.x/metadata/icons.yml +// for use with https://github.com/FortAwesome/Font-Awesome/blob/6.x/webfonts/fa-regular-400.ttf, https://github.com/FortAwesome/Font-Awesome/blob/6.x/webfonts/fa-solid-900.ttf +#pragma once + +#define FONT_ICON_FILE_NAME_FAR "fa-regular-400.ttf" +#define FONT_ICON_FILE_NAME_FAS "fa-solid-900.ttf" + +#define ICON_MIN_FA 0xe005 +#define ICON_MAX_16_FA 0xf8ff +#define ICON_MAX_FA 0xf8ff +#define ICON_FA_0 "0" // U+0030 +#define ICON_FA_1 "1" // U+0031 +#define ICON_FA_2 "2" // U+0032 +#define ICON_FA_3 "3" // U+0033 +#define ICON_FA_4 "4" // U+0034 +#define ICON_FA_5 "5" // U+0035 +#define ICON_FA_6 "6" // U+0036 +#define ICON_FA_7 "7" // U+0037 +#define ICON_FA_8 "8" // U+0038 +#define ICON_FA_9 "9" // U+0039 +#define ICON_FA_A "A" // U+0041 +#define ICON_FA_ADDRESS_BOOK "\xef\x8a\xb9" // U+f2b9 +#define ICON_FA_ADDRESS_CARD "\xef\x8a\xbb" // U+f2bb +#define ICON_FA_ALIGN_CENTER "\xef\x80\xb7" // U+f037 +#define ICON_FA_ALIGN_JUSTIFY "\xef\x80\xb9" // U+f039 +#define ICON_FA_ALIGN_LEFT "\xef\x80\xb6" // U+f036 +#define ICON_FA_ALIGN_RIGHT "\xef\x80\xb8" // U+f038 +#define ICON_FA_ANCHOR "\xef\x84\xbd" // U+f13d +#define ICON_FA_ANCHOR_CIRCLE_CHECK "\xee\x92\xaa" // U+e4aa +#define ICON_FA_ANCHOR_CIRCLE_EXCLAMATION "\xee\x92\xab" // U+e4ab +#define ICON_FA_ANCHOR_CIRCLE_XMARK "\xee\x92\xac" // U+e4ac +#define ICON_FA_ANCHOR_LOCK "\xee\x92\xad" // U+e4ad +#define ICON_FA_ANGLE_DOWN "\xef\x84\x87" // U+f107 +#define ICON_FA_ANGLE_LEFT "\xef\x84\x84" // U+f104 +#define ICON_FA_ANGLE_RIGHT "\xef\x84\x85" // U+f105 +#define ICON_FA_ANGLE_UP "\xef\x84\x86" // U+f106 +#define ICON_FA_ANGLES_DOWN "\xef\x84\x83" // U+f103 +#define ICON_FA_ANGLES_LEFT "\xef\x84\x80" // U+f100 +#define ICON_FA_ANGLES_RIGHT "\xef\x84\x81" // U+f101 +#define ICON_FA_ANGLES_UP "\xef\x84\x82" // U+f102 +#define ICON_FA_ANKH "\xef\x99\x84" // U+f644 +#define ICON_FA_APPLE_WHOLE "\xef\x97\x91" // U+f5d1 +#define ICON_FA_ARCHWAY "\xef\x95\x97" // U+f557 +#define ICON_FA_ARROW_DOWN "\xef\x81\xa3" // U+f063 +#define ICON_FA_ARROW_DOWN_1_9 "\xef\x85\xa2" // U+f162 +#define ICON_FA_ARROW_DOWN_9_1 "\xef\xa2\x86" // U+f886 +#define ICON_FA_ARROW_DOWN_A_Z "\xef\x85\x9d" // U+f15d +#define ICON_FA_ARROW_DOWN_LONG "\xef\x85\xb5" // U+f175 +#define ICON_FA_ARROW_DOWN_SHORT_WIDE "\xef\xa2\x84" // U+f884 +#define ICON_FA_ARROW_DOWN_UP_ACROSS_LINE "\xee\x92\xaf" // U+e4af +#define ICON_FA_ARROW_DOWN_UP_LOCK "\xee\x92\xb0" // U+e4b0 +#define ICON_FA_ARROW_DOWN_WIDE_SHORT "\xef\x85\xa0" // U+f160 +#define ICON_FA_ARROW_DOWN_Z_A "\xef\xa2\x81" // U+f881 +#define ICON_FA_ARROW_LEFT "\xef\x81\xa0" // U+f060 +#define ICON_FA_ARROW_LEFT_LONG "\xef\x85\xb7" // U+f177 +#define ICON_FA_ARROW_POINTER "\xef\x89\x85" // U+f245 +#define ICON_FA_ARROW_RIGHT "\xef\x81\xa1" // U+f061 +#define ICON_FA_ARROW_RIGHT_ARROW_LEFT "\xef\x83\xac" // U+f0ec +#define ICON_FA_ARROW_RIGHT_FROM_BRACKET "\xef\x82\x8b" // U+f08b +#define ICON_FA_ARROW_RIGHT_LONG "\xef\x85\xb8" // U+f178 +#define ICON_FA_ARROW_RIGHT_TO_BRACKET "\xef\x82\x90" // U+f090 +#define ICON_FA_ARROW_RIGHT_TO_CITY "\xee\x92\xb3" // U+e4b3 +#define ICON_FA_ARROW_ROTATE_LEFT "\xef\x83\xa2" // U+f0e2 +#define ICON_FA_ARROW_ROTATE_RIGHT "\xef\x80\x9e" // U+f01e +#define ICON_FA_ARROW_TREND_DOWN "\xee\x82\x97" // U+e097 +#define ICON_FA_ARROW_TREND_UP "\xee\x82\x98" // U+e098 +#define ICON_FA_ARROW_TURN_DOWN "\xef\x85\x89" // U+f149 +#define ICON_FA_ARROW_TURN_UP "\xef\x85\x88" // U+f148 +#define ICON_FA_ARROW_UP "\xef\x81\xa2" // U+f062 +#define ICON_FA_ARROW_UP_1_9 "\xef\x85\xa3" // U+f163 +#define ICON_FA_ARROW_UP_9_1 "\xef\xa2\x87" // U+f887 +#define ICON_FA_ARROW_UP_A_Z "\xef\x85\x9e" // U+f15e +#define ICON_FA_ARROW_UP_FROM_BRACKET "\xee\x82\x9a" // U+e09a +#define ICON_FA_ARROW_UP_FROM_GROUND_WATER "\xee\x92\xb5" // U+e4b5 +#define ICON_FA_ARROW_UP_FROM_WATER_PUMP "\xee\x92\xb6" // U+e4b6 +#define ICON_FA_ARROW_UP_LONG "\xef\x85\xb6" // U+f176 +#define ICON_FA_ARROW_UP_RIGHT_DOTS "\xee\x92\xb7" // U+e4b7 +#define ICON_FA_ARROW_UP_RIGHT_FROM_SQUARE "\xef\x82\x8e" // U+f08e +#define ICON_FA_ARROW_UP_SHORT_WIDE "\xef\xa2\x85" // U+f885 +#define ICON_FA_ARROW_UP_WIDE_SHORT "\xef\x85\xa1" // U+f161 +#define ICON_FA_ARROW_UP_Z_A "\xef\xa2\x82" // U+f882 +#define ICON_FA_ARROWS_DOWN_TO_LINE "\xee\x92\xb8" // U+e4b8 +#define ICON_FA_ARROWS_DOWN_TO_PEOPLE "\xee\x92\xb9" // U+e4b9 +#define ICON_FA_ARROWS_LEFT_RIGHT "\xef\x81\xbe" // U+f07e +#define ICON_FA_ARROWS_LEFT_RIGHT_TO_LINE "\xee\x92\xba" // U+e4ba +#define ICON_FA_ARROWS_ROTATE "\xef\x80\xa1" // U+f021 +#define ICON_FA_ARROWS_SPIN "\xee\x92\xbb" // U+e4bb +#define ICON_FA_ARROWS_SPLIT_UP_AND_LEFT "\xee\x92\xbc" // U+e4bc +#define ICON_FA_ARROWS_TO_CIRCLE "\xee\x92\xbd" // U+e4bd +#define ICON_FA_ARROWS_TO_DOT "\xee\x92\xbe" // U+e4be +#define ICON_FA_ARROWS_TO_EYE "\xee\x92\xbf" // U+e4bf +#define ICON_FA_ARROWS_TURN_RIGHT "\xee\x93\x80" // U+e4c0 +#define ICON_FA_ARROWS_TURN_TO_DOTS "\xee\x93\x81" // U+e4c1 +#define ICON_FA_ARROWS_UP_DOWN "\xef\x81\xbd" // U+f07d +#define ICON_FA_ARROWS_UP_DOWN_LEFT_RIGHT "\xef\x81\x87" // U+f047 +#define ICON_FA_ARROWS_UP_TO_LINE "\xee\x93\x82" // U+e4c2 +#define ICON_FA_ASTERISK "*" // U+002a +#define ICON_FA_AT "@" // U+0040 +#define ICON_FA_ATOM "\xef\x97\x92" // U+f5d2 +#define ICON_FA_AUDIO_DESCRIPTION "\xef\x8a\x9e" // U+f29e +#define ICON_FA_AUSTRAL_SIGN "\xee\x82\xa9" // U+e0a9 +#define ICON_FA_AWARD "\xef\x95\x99" // U+f559 +#define ICON_FA_B "B" // U+0042 +#define ICON_FA_BABY "\xef\x9d\xbc" // U+f77c +#define ICON_FA_BABY_CARRIAGE "\xef\x9d\xbd" // U+f77d +#define ICON_FA_BACKWARD "\xef\x81\x8a" // U+f04a +#define ICON_FA_BACKWARD_FAST "\xef\x81\x89" // U+f049 +#define ICON_FA_BACKWARD_STEP "\xef\x81\x88" // U+f048 +#define ICON_FA_BACON "\xef\x9f\xa5" // U+f7e5 +#define ICON_FA_BACTERIA "\xee\x81\x99" // U+e059 +#define ICON_FA_BACTERIUM "\xee\x81\x9a" // U+e05a +#define ICON_FA_BAG_SHOPPING "\xef\x8a\x90" // U+f290 +#define ICON_FA_BAHAI "\xef\x99\xa6" // U+f666 +#define ICON_FA_BAHT_SIGN "\xee\x82\xac" // U+e0ac +#define ICON_FA_BAN "\xef\x81\x9e" // U+f05e +#define ICON_FA_BAN_SMOKING "\xef\x95\x8d" // U+f54d +#define ICON_FA_BANDAGE "\xef\x91\xa2" // U+f462 +#define ICON_FA_BARCODE "\xef\x80\xaa" // U+f02a +#define ICON_FA_BARS "\xef\x83\x89" // U+f0c9 +#define ICON_FA_BARS_PROGRESS "\xef\xa0\xa8" // U+f828 +#define ICON_FA_BARS_STAGGERED "\xef\x95\x90" // U+f550 +#define ICON_FA_BASEBALL "\xef\x90\xb3" // U+f433 +#define ICON_FA_BASEBALL_BAT_BALL "\xef\x90\xb2" // U+f432 +#define ICON_FA_BASKET_SHOPPING "\xef\x8a\x91" // U+f291 +#define ICON_FA_BASKETBALL "\xef\x90\xb4" // U+f434 +#define ICON_FA_BATH "\xef\x8b\x8d" // U+f2cd +#define ICON_FA_BATTERY_EMPTY "\xef\x89\x84" // U+f244 +#define ICON_FA_BATTERY_FULL "\xef\x89\x80" // U+f240 +#define ICON_FA_BATTERY_HALF "\xef\x89\x82" // U+f242 +#define ICON_FA_BATTERY_QUARTER "\xef\x89\x83" // U+f243 +#define ICON_FA_BATTERY_THREE_QUARTERS "\xef\x89\x81" // U+f241 +#define ICON_FA_BED "\xef\x88\xb6" // U+f236 +#define ICON_FA_BED_PULSE "\xef\x92\x87" // U+f487 +#define ICON_FA_BEER_MUG_EMPTY "\xef\x83\xbc" // U+f0fc +#define ICON_FA_BELL "\xef\x83\xb3" // U+f0f3 +#define ICON_FA_BELL_CONCIERGE "\xef\x95\xa2" // U+f562 +#define ICON_FA_BELL_SLASH "\xef\x87\xb6" // U+f1f6 +#define ICON_FA_BEZIER_CURVE "\xef\x95\x9b" // U+f55b +#define ICON_FA_BICYCLE "\xef\x88\x86" // U+f206 +#define ICON_FA_BINOCULARS "\xef\x87\xa5" // U+f1e5 +#define ICON_FA_BIOHAZARD "\xef\x9e\x80" // U+f780 +#define ICON_FA_BITCOIN_SIGN "\xee\x82\xb4" // U+e0b4 +#define ICON_FA_BLENDER "\xef\x94\x97" // U+f517 +#define ICON_FA_BLENDER_PHONE "\xef\x9a\xb6" // U+f6b6 +#define ICON_FA_BLOG "\xef\x9e\x81" // U+f781 +#define ICON_FA_BOLD "\xef\x80\xb2" // U+f032 +#define ICON_FA_BOLT "\xef\x83\xa7" // U+f0e7 +#define ICON_FA_BOLT_LIGHTNING "\xee\x82\xb7" // U+e0b7 +#define ICON_FA_BOMB "\xef\x87\xa2" // U+f1e2 +#define ICON_FA_BONE "\xef\x97\x97" // U+f5d7 +#define ICON_FA_BONG "\xef\x95\x9c" // U+f55c +#define ICON_FA_BOOK "\xef\x80\xad" // U+f02d +#define ICON_FA_BOOK_ATLAS "\xef\x95\x98" // U+f558 +#define ICON_FA_BOOK_BIBLE "\xef\x99\x87" // U+f647 +#define ICON_FA_BOOK_BOOKMARK "\xee\x82\xbb" // U+e0bb +#define ICON_FA_BOOK_JOURNAL_WHILLS "\xef\x99\xaa" // U+f66a +#define ICON_FA_BOOK_MEDICAL "\xef\x9f\xa6" // U+f7e6 +#define ICON_FA_BOOK_OPEN "\xef\x94\x98" // U+f518 +#define ICON_FA_BOOK_OPEN_READER "\xef\x97\x9a" // U+f5da +#define ICON_FA_BOOK_QURAN "\xef\x9a\x87" // U+f687 +#define ICON_FA_BOOK_SKULL "\xef\x9a\xb7" // U+f6b7 +#define ICON_FA_BOOK_TANAKH "\xef\xa0\xa7" // U+f827 +#define ICON_FA_BOOKMARK "\xef\x80\xae" // U+f02e +#define ICON_FA_BORDER_ALL "\xef\xa1\x8c" // U+f84c +#define ICON_FA_BORDER_NONE "\xef\xa1\x90" // U+f850 +#define ICON_FA_BORDER_TOP_LEFT "\xef\xa1\x93" // U+f853 +#define ICON_FA_BORE_HOLE "\xee\x93\x83" // U+e4c3 +#define ICON_FA_BOTTLE_DROPLET "\xee\x93\x84" // U+e4c4 +#define ICON_FA_BOTTLE_WATER "\xee\x93\x85" // U+e4c5 +#define ICON_FA_BOWL_FOOD "\xee\x93\x86" // U+e4c6 +#define ICON_FA_BOWL_RICE "\xee\x8b\xab" // U+e2eb +#define ICON_FA_BOWLING_BALL "\xef\x90\xb6" // U+f436 +#define ICON_FA_BOX "\xef\x91\xa6" // U+f466 +#define ICON_FA_BOX_ARCHIVE "\xef\x86\x87" // U+f187 +#define ICON_FA_BOX_OPEN "\xef\x92\x9e" // U+f49e +#define ICON_FA_BOX_TISSUE "\xee\x81\x9b" // U+e05b +#define ICON_FA_BOXES_PACKING "\xee\x93\x87" // U+e4c7 +#define ICON_FA_BOXES_STACKED "\xef\x91\xa8" // U+f468 +#define ICON_FA_BRAILLE "\xef\x8a\xa1" // U+f2a1 +#define ICON_FA_BRAIN "\xef\x97\x9c" // U+f5dc +#define ICON_FA_BRAZILIAN_REAL_SIGN "\xee\x91\xac" // U+e46c +#define ICON_FA_BREAD_SLICE "\xef\x9f\xac" // U+f7ec +#define ICON_FA_BRIDGE "\xee\x93\x88" // U+e4c8 +#define ICON_FA_BRIDGE_CIRCLE_CHECK "\xee\x93\x89" // U+e4c9 +#define ICON_FA_BRIDGE_CIRCLE_EXCLAMATION "\xee\x93\x8a" // U+e4ca +#define ICON_FA_BRIDGE_CIRCLE_XMARK "\xee\x93\x8b" // U+e4cb +#define ICON_FA_BRIDGE_LOCK "\xee\x93\x8c" // U+e4cc +#define ICON_FA_BRIDGE_WATER "\xee\x93\x8e" // U+e4ce +#define ICON_FA_BRIEFCASE "\xef\x82\xb1" // U+f0b1 +#define ICON_FA_BRIEFCASE_MEDICAL "\xef\x91\xa9" // U+f469 +#define ICON_FA_BROOM "\xef\x94\x9a" // U+f51a +#define ICON_FA_BROOM_BALL "\xef\x91\x98" // U+f458 +#define ICON_FA_BRUSH "\xef\x95\x9d" // U+f55d +#define ICON_FA_BUCKET "\xee\x93\x8f" // U+e4cf +#define ICON_FA_BUG "\xef\x86\x88" // U+f188 +#define ICON_FA_BUG_SLASH "\xee\x92\x90" // U+e490 +#define ICON_FA_BUGS "\xee\x93\x90" // U+e4d0 +#define ICON_FA_BUILDING "\xef\x86\xad" // U+f1ad +#define ICON_FA_BUILDING_CIRCLE_ARROW_RIGHT "\xee\x93\x91" // U+e4d1 +#define ICON_FA_BUILDING_CIRCLE_CHECK "\xee\x93\x92" // U+e4d2 +#define ICON_FA_BUILDING_CIRCLE_EXCLAMATION "\xee\x93\x93" // U+e4d3 +#define ICON_FA_BUILDING_CIRCLE_XMARK "\xee\x93\x94" // U+e4d4 +#define ICON_FA_BUILDING_COLUMNS "\xef\x86\x9c" // U+f19c +#define ICON_FA_BUILDING_FLAG "\xee\x93\x95" // U+e4d5 +#define ICON_FA_BUILDING_LOCK "\xee\x93\x96" // U+e4d6 +#define ICON_FA_BUILDING_NGO "\xee\x93\x97" // U+e4d7 +#define ICON_FA_BUILDING_SHIELD "\xee\x93\x98" // U+e4d8 +#define ICON_FA_BUILDING_UN "\xee\x93\x99" // U+e4d9 +#define ICON_FA_BUILDING_USER "\xee\x93\x9a" // U+e4da +#define ICON_FA_BUILDING_WHEAT "\xee\x93\x9b" // U+e4db +#define ICON_FA_BULLHORN "\xef\x82\xa1" // U+f0a1 +#define ICON_FA_BULLSEYE "\xef\x85\x80" // U+f140 +#define ICON_FA_BURGER "\xef\xa0\x85" // U+f805 +#define ICON_FA_BURST "\xee\x93\x9c" // U+e4dc +#define ICON_FA_BUS "\xef\x88\x87" // U+f207 +#define ICON_FA_BUS_SIMPLE "\xef\x95\x9e" // U+f55e +#define ICON_FA_BUSINESS_TIME "\xef\x99\x8a" // U+f64a +#define ICON_FA_C "C" // U+0043 +#define ICON_FA_CABLE_CAR "\xef\x9f\x9a" // U+f7da +#define ICON_FA_CAKE_CANDLES "\xef\x87\xbd" // U+f1fd +#define ICON_FA_CALCULATOR "\xef\x87\xac" // U+f1ec +#define ICON_FA_CALENDAR "\xef\x84\xb3" // U+f133 +#define ICON_FA_CALENDAR_CHECK "\xef\x89\xb4" // U+f274 +#define ICON_FA_CALENDAR_DAY "\xef\x9e\x83" // U+f783 +#define ICON_FA_CALENDAR_DAYS "\xef\x81\xb3" // U+f073 +#define ICON_FA_CALENDAR_MINUS "\xef\x89\xb2" // U+f272 +#define ICON_FA_CALENDAR_PLUS "\xef\x89\xb1" // U+f271 +#define ICON_FA_CALENDAR_WEEK "\xef\x9e\x84" // U+f784 +#define ICON_FA_CALENDAR_XMARK "\xef\x89\xb3" // U+f273 +#define ICON_FA_CAMERA "\xef\x80\xb0" // U+f030 +#define ICON_FA_CAMERA_RETRO "\xef\x82\x83" // U+f083 +#define ICON_FA_CAMERA_ROTATE "\xee\x83\x98" // U+e0d8 +#define ICON_FA_CAMPGROUND "\xef\x9a\xbb" // U+f6bb +#define ICON_FA_CANDY_CANE "\xef\x9e\x86" // U+f786 +#define ICON_FA_CANNABIS "\xef\x95\x9f" // U+f55f +#define ICON_FA_CAPSULES "\xef\x91\xab" // U+f46b +#define ICON_FA_CAR "\xef\x86\xb9" // U+f1b9 +#define ICON_FA_CAR_BATTERY "\xef\x97\x9f" // U+f5df +#define ICON_FA_CAR_BURST "\xef\x97\xa1" // U+f5e1 +#define ICON_FA_CAR_ON "\xee\x93\x9d" // U+e4dd +#define ICON_FA_CAR_REAR "\xef\x97\x9e" // U+f5de +#define ICON_FA_CAR_SIDE "\xef\x97\xa4" // U+f5e4 +#define ICON_FA_CAR_TUNNEL "\xee\x93\x9e" // U+e4de +#define ICON_FA_CARAVAN "\xef\xa3\xbf" // U+f8ff +#define ICON_FA_CARET_DOWN "\xef\x83\x97" // U+f0d7 +#define ICON_FA_CARET_LEFT "\xef\x83\x99" // U+f0d9 +#define ICON_FA_CARET_RIGHT "\xef\x83\x9a" // U+f0da +#define ICON_FA_CARET_UP "\xef\x83\x98" // U+f0d8 +#define ICON_FA_CARROT "\xef\x9e\x87" // U+f787 +#define ICON_FA_CART_ARROW_DOWN "\xef\x88\x98" // U+f218 +#define ICON_FA_CART_FLATBED "\xef\x91\xb4" // U+f474 +#define ICON_FA_CART_FLATBED_SUITCASE "\xef\x96\x9d" // U+f59d +#define ICON_FA_CART_PLUS "\xef\x88\x97" // U+f217 +#define ICON_FA_CART_SHOPPING "\xef\x81\xba" // U+f07a +#define ICON_FA_CASH_REGISTER "\xef\x9e\x88" // U+f788 +#define ICON_FA_CAT "\xef\x9a\xbe" // U+f6be +#define ICON_FA_CEDI_SIGN "\xee\x83\x9f" // U+e0df +#define ICON_FA_CENT_SIGN "\xee\x8f\xb5" // U+e3f5 +#define ICON_FA_CERTIFICATE "\xef\x82\xa3" // U+f0a3 +#define ICON_FA_CHAIR "\xef\x9b\x80" // U+f6c0 +#define ICON_FA_CHALKBOARD "\xef\x94\x9b" // U+f51b +#define ICON_FA_CHALKBOARD_USER "\xef\x94\x9c" // U+f51c +#define ICON_FA_CHAMPAGNE_GLASSES "\xef\x9e\x9f" // U+f79f +#define ICON_FA_CHARGING_STATION "\xef\x97\xa7" // U+f5e7 +#define ICON_FA_CHART_AREA "\xef\x87\xbe" // U+f1fe +#define ICON_FA_CHART_BAR "\xef\x82\x80" // U+f080 +#define ICON_FA_CHART_COLUMN "\xee\x83\xa3" // U+e0e3 +#define ICON_FA_CHART_GANTT "\xee\x83\xa4" // U+e0e4 +#define ICON_FA_CHART_LINE "\xef\x88\x81" // U+f201 +#define ICON_FA_CHART_PIE "\xef\x88\x80" // U+f200 +#define ICON_FA_CHART_SIMPLE "\xee\x91\xb3" // U+e473 +#define ICON_FA_CHECK "\xef\x80\x8c" // U+f00c +#define ICON_FA_CHECK_DOUBLE "\xef\x95\xa0" // U+f560 +#define ICON_FA_CHECK_TO_SLOT "\xef\x9d\xb2" // U+f772 +#define ICON_FA_CHEESE "\xef\x9f\xaf" // U+f7ef +#define ICON_FA_CHESS "\xef\x90\xb9" // U+f439 +#define ICON_FA_CHESS_BISHOP "\xef\x90\xba" // U+f43a +#define ICON_FA_CHESS_BOARD "\xef\x90\xbc" // U+f43c +#define ICON_FA_CHESS_KING "\xef\x90\xbf" // U+f43f +#define ICON_FA_CHESS_KNIGHT "\xef\x91\x81" // U+f441 +#define ICON_FA_CHESS_PAWN "\xef\x91\x83" // U+f443 +#define ICON_FA_CHESS_QUEEN "\xef\x91\x85" // U+f445 +#define ICON_FA_CHESS_ROOK "\xef\x91\x87" // U+f447 +#define ICON_FA_CHEVRON_DOWN "\xef\x81\xb8" // U+f078 +#define ICON_FA_CHEVRON_LEFT "\xef\x81\x93" // U+f053 +#define ICON_FA_CHEVRON_RIGHT "\xef\x81\x94" // U+f054 +#define ICON_FA_CHEVRON_UP "\xef\x81\xb7" // U+f077 +#define ICON_FA_CHILD "\xef\x86\xae" // U+f1ae +#define ICON_FA_CHILD_DRESS "\xee\x96\x9c" // U+e59c +#define ICON_FA_CHILD_REACHING "\xee\x96\x9d" // U+e59d +#define ICON_FA_CHILD_RIFLE "\xee\x93\xa0" // U+e4e0 +#define ICON_FA_CHILDREN "\xee\x93\xa1" // U+e4e1 +#define ICON_FA_CHURCH "\xef\x94\x9d" // U+f51d +#define ICON_FA_CIRCLE "\xef\x84\x91" // U+f111 +#define ICON_FA_CIRCLE_ARROW_DOWN "\xef\x82\xab" // U+f0ab +#define ICON_FA_CIRCLE_ARROW_LEFT "\xef\x82\xa8" // U+f0a8 +#define ICON_FA_CIRCLE_ARROW_RIGHT "\xef\x82\xa9" // U+f0a9 +#define ICON_FA_CIRCLE_ARROW_UP "\xef\x82\xaa" // U+f0aa +#define ICON_FA_CIRCLE_CHECK "\xef\x81\x98" // U+f058 +#define ICON_FA_CIRCLE_CHEVRON_DOWN "\xef\x84\xba" // U+f13a +#define ICON_FA_CIRCLE_CHEVRON_LEFT "\xef\x84\xb7" // U+f137 +#define ICON_FA_CIRCLE_CHEVRON_RIGHT "\xef\x84\xb8" // U+f138 +#define ICON_FA_CIRCLE_CHEVRON_UP "\xef\x84\xb9" // U+f139 +#define ICON_FA_CIRCLE_DOLLAR_TO_SLOT "\xef\x92\xb9" // U+f4b9 +#define ICON_FA_CIRCLE_DOT "\xef\x86\x92" // U+f192 +#define ICON_FA_CIRCLE_DOWN "\xef\x8d\x98" // U+f358 +#define ICON_FA_CIRCLE_EXCLAMATION "\xef\x81\xaa" // U+f06a +#define ICON_FA_CIRCLE_H "\xef\x91\xbe" // U+f47e +#define ICON_FA_CIRCLE_HALF_STROKE "\xef\x81\x82" // U+f042 +#define ICON_FA_CIRCLE_INFO "\xef\x81\x9a" // U+f05a +#define ICON_FA_CIRCLE_LEFT "\xef\x8d\x99" // U+f359 +#define ICON_FA_CIRCLE_MINUS "\xef\x81\x96" // U+f056 +#define ICON_FA_CIRCLE_NODES "\xee\x93\xa2" // U+e4e2 +#define ICON_FA_CIRCLE_NOTCH "\xef\x87\x8e" // U+f1ce +#define ICON_FA_CIRCLE_PAUSE "\xef\x8a\x8b" // U+f28b +#define ICON_FA_CIRCLE_PLAY "\xef\x85\x84" // U+f144 +#define ICON_FA_CIRCLE_PLUS "\xef\x81\x95" // U+f055 +#define ICON_FA_CIRCLE_QUESTION "\xef\x81\x99" // U+f059 +#define ICON_FA_CIRCLE_RADIATION "\xef\x9e\xba" // U+f7ba +#define ICON_FA_CIRCLE_RIGHT "\xef\x8d\x9a" // U+f35a +#define ICON_FA_CIRCLE_STOP "\xef\x8a\x8d" // U+f28d +#define ICON_FA_CIRCLE_UP "\xef\x8d\x9b" // U+f35b +#define ICON_FA_CIRCLE_USER "\xef\x8a\xbd" // U+f2bd +#define ICON_FA_CIRCLE_XMARK "\xef\x81\x97" // U+f057 +#define ICON_FA_CITY "\xef\x99\x8f" // U+f64f +#define ICON_FA_CLAPPERBOARD "\xee\x84\xb1" // U+e131 +#define ICON_FA_CLIPBOARD "\xef\x8c\xa8" // U+f328 +#define ICON_FA_CLIPBOARD_CHECK "\xef\x91\xac" // U+f46c +#define ICON_FA_CLIPBOARD_LIST "\xef\x91\xad" // U+f46d +#define ICON_FA_CLIPBOARD_QUESTION "\xee\x93\xa3" // U+e4e3 +#define ICON_FA_CLIPBOARD_USER "\xef\x9f\xb3" // U+f7f3 +#define ICON_FA_CLOCK "\xef\x80\x97" // U+f017 +#define ICON_FA_CLOCK_ROTATE_LEFT "\xef\x87\x9a" // U+f1da +#define ICON_FA_CLONE "\xef\x89\x8d" // U+f24d +#define ICON_FA_CLOSED_CAPTIONING "\xef\x88\x8a" // U+f20a +#define ICON_FA_CLOUD "\xef\x83\x82" // U+f0c2 +#define ICON_FA_CLOUD_ARROW_DOWN "\xef\x83\xad" // U+f0ed +#define ICON_FA_CLOUD_ARROW_UP "\xef\x83\xae" // U+f0ee +#define ICON_FA_CLOUD_BOLT "\xef\x9d\xac" // U+f76c +#define ICON_FA_CLOUD_MEATBALL "\xef\x9c\xbb" // U+f73b +#define ICON_FA_CLOUD_MOON "\xef\x9b\x83" // U+f6c3 +#define ICON_FA_CLOUD_MOON_RAIN "\xef\x9c\xbc" // U+f73c +#define ICON_FA_CLOUD_RAIN "\xef\x9c\xbd" // U+f73d +#define ICON_FA_CLOUD_SHOWERS_HEAVY "\xef\x9d\x80" // U+f740 +#define ICON_FA_CLOUD_SHOWERS_WATER "\xee\x93\xa4" // U+e4e4 +#define ICON_FA_CLOUD_SUN "\xef\x9b\x84" // U+f6c4 +#define ICON_FA_CLOUD_SUN_RAIN "\xef\x9d\x83" // U+f743 +#define ICON_FA_CLOVER "\xee\x84\xb9" // U+e139 +#define ICON_FA_CODE "\xef\x84\xa1" // U+f121 +#define ICON_FA_CODE_BRANCH "\xef\x84\xa6" // U+f126 +#define ICON_FA_CODE_COMMIT "\xef\x8e\x86" // U+f386 +#define ICON_FA_CODE_COMPARE "\xee\x84\xba" // U+e13a +#define ICON_FA_CODE_FORK "\xee\x84\xbb" // U+e13b +#define ICON_FA_CODE_MERGE "\xef\x8e\x87" // U+f387 +#define ICON_FA_CODE_PULL_REQUEST "\xee\x84\xbc" // U+e13c +#define ICON_FA_COINS "\xef\x94\x9e" // U+f51e +#define ICON_FA_COLON_SIGN "\xee\x85\x80" // U+e140 +#define ICON_FA_COMMENT "\xef\x81\xb5" // U+f075 +#define ICON_FA_COMMENT_DOLLAR "\xef\x99\x91" // U+f651 +#define ICON_FA_COMMENT_DOTS "\xef\x92\xad" // U+f4ad +#define ICON_FA_COMMENT_MEDICAL "\xef\x9f\xb5" // U+f7f5 +#define ICON_FA_COMMENT_SLASH "\xef\x92\xb3" // U+f4b3 +#define ICON_FA_COMMENT_SMS "\xef\x9f\x8d" // U+f7cd +#define ICON_FA_COMMENTS "\xef\x82\x86" // U+f086 +#define ICON_FA_COMMENTS_DOLLAR "\xef\x99\x93" // U+f653 +#define ICON_FA_COMPACT_DISC "\xef\x94\x9f" // U+f51f +#define ICON_FA_COMPASS "\xef\x85\x8e" // U+f14e +#define ICON_FA_COMPASS_DRAFTING "\xef\x95\xa8" // U+f568 +#define ICON_FA_COMPRESS "\xef\x81\xa6" // U+f066 +#define ICON_FA_COMPUTER "\xee\x93\xa5" // U+e4e5 +#define ICON_FA_COMPUTER_MOUSE "\xef\xa3\x8c" // U+f8cc +#define ICON_FA_COOKIE "\xef\x95\xa3" // U+f563 +#define ICON_FA_COOKIE_BITE "\xef\x95\xa4" // U+f564 +#define ICON_FA_COPY "\xef\x83\x85" // U+f0c5 +#define ICON_FA_COPYRIGHT "\xef\x87\xb9" // U+f1f9 +#define ICON_FA_COUCH "\xef\x92\xb8" // U+f4b8 +#define ICON_FA_COW "\xef\x9b\x88" // U+f6c8 +#define ICON_FA_CREDIT_CARD "\xef\x82\x9d" // U+f09d +#define ICON_FA_CROP "\xef\x84\xa5" // U+f125 +#define ICON_FA_CROP_SIMPLE "\xef\x95\xa5" // U+f565 +#define ICON_FA_CROSS "\xef\x99\x94" // U+f654 +#define ICON_FA_CROSSHAIRS "\xef\x81\x9b" // U+f05b +#define ICON_FA_CROW "\xef\x94\xa0" // U+f520 +#define ICON_FA_CROWN "\xef\x94\xa1" // U+f521 +#define ICON_FA_CRUTCH "\xef\x9f\xb7" // U+f7f7 +#define ICON_FA_CRUZEIRO_SIGN "\xee\x85\x92" // U+e152 +#define ICON_FA_CUBE "\xef\x86\xb2" // U+f1b2 +#define ICON_FA_CUBES "\xef\x86\xb3" // U+f1b3 +#define ICON_FA_CUBES_STACKED "\xee\x93\xa6" // U+e4e6 +#define ICON_FA_D "D" // U+0044 +#define ICON_FA_DATABASE "\xef\x87\x80" // U+f1c0 +#define ICON_FA_DELETE_LEFT "\xef\x95\x9a" // U+f55a +#define ICON_FA_DEMOCRAT "\xef\x9d\x87" // U+f747 +#define ICON_FA_DESKTOP "\xef\x8e\x90" // U+f390 +#define ICON_FA_DHARMACHAKRA "\xef\x99\x95" // U+f655 +#define ICON_FA_DIAGRAM_NEXT "\xee\x91\xb6" // U+e476 +#define ICON_FA_DIAGRAM_PREDECESSOR "\xee\x91\xb7" // U+e477 +#define ICON_FA_DIAGRAM_PROJECT "\xef\x95\x82" // U+f542 +#define ICON_FA_DIAGRAM_SUCCESSOR "\xee\x91\xba" // U+e47a +#define ICON_FA_DIAMOND "\xef\x88\x99" // U+f219 +#define ICON_FA_DIAMOND_TURN_RIGHT "\xef\x97\xab" // U+f5eb +#define ICON_FA_DICE "\xef\x94\xa2" // U+f522 +#define ICON_FA_DICE_D20 "\xef\x9b\x8f" // U+f6cf +#define ICON_FA_DICE_D6 "\xef\x9b\x91" // U+f6d1 +#define ICON_FA_DICE_FIVE "\xef\x94\xa3" // U+f523 +#define ICON_FA_DICE_FOUR "\xef\x94\xa4" // U+f524 +#define ICON_FA_DICE_ONE "\xef\x94\xa5" // U+f525 +#define ICON_FA_DICE_SIX "\xef\x94\xa6" // U+f526 +#define ICON_FA_DICE_THREE "\xef\x94\xa7" // U+f527 +#define ICON_FA_DICE_TWO "\xef\x94\xa8" // U+f528 +#define ICON_FA_DISEASE "\xef\x9f\xba" // U+f7fa +#define ICON_FA_DISPLAY "\xee\x85\xa3" // U+e163 +#define ICON_FA_DIVIDE "\xef\x94\xa9" // U+f529 +#define ICON_FA_DNA "\xef\x91\xb1" // U+f471 +#define ICON_FA_DOG "\xef\x9b\x93" // U+f6d3 +#define ICON_FA_DOLLAR_SIGN "$" // U+0024 +#define ICON_FA_DOLLY "\xef\x91\xb2" // U+f472 +#define ICON_FA_DONG_SIGN "\xee\x85\xa9" // U+e169 +#define ICON_FA_DOOR_CLOSED "\xef\x94\xaa" // U+f52a +#define ICON_FA_DOOR_OPEN "\xef\x94\xab" // U+f52b +#define ICON_FA_DOVE "\xef\x92\xba" // U+f4ba +#define ICON_FA_DOWN_LEFT_AND_UP_RIGHT_TO_CENTER "\xef\x90\xa2" // U+f422 +#define ICON_FA_DOWN_LONG "\xef\x8c\x89" // U+f309 +#define ICON_FA_DOWNLOAD "\xef\x80\x99" // U+f019 +#define ICON_FA_DRAGON "\xef\x9b\x95" // U+f6d5 +#define ICON_FA_DRAW_POLYGON "\xef\x97\xae" // U+f5ee +#define ICON_FA_DROPLET "\xef\x81\x83" // U+f043 +#define ICON_FA_DROPLET_SLASH "\xef\x97\x87" // U+f5c7 +#define ICON_FA_DRUM "\xef\x95\xa9" // U+f569 +#define ICON_FA_DRUM_STEELPAN "\xef\x95\xaa" // U+f56a +#define ICON_FA_DRUMSTICK_BITE "\xef\x9b\x97" // U+f6d7 +#define ICON_FA_DUMBBELL "\xef\x91\x8b" // U+f44b +#define ICON_FA_DUMPSTER "\xef\x9e\x93" // U+f793 +#define ICON_FA_DUMPSTER_FIRE "\xef\x9e\x94" // U+f794 +#define ICON_FA_DUNGEON "\xef\x9b\x99" // U+f6d9 +#define ICON_FA_E "E" // U+0045 +#define ICON_FA_EAR_DEAF "\xef\x8a\xa4" // U+f2a4 +#define ICON_FA_EAR_LISTEN "\xef\x8a\xa2" // U+f2a2 +#define ICON_FA_EARTH_AFRICA "\xef\x95\xbc" // U+f57c +#define ICON_FA_EARTH_AMERICAS "\xef\x95\xbd" // U+f57d +#define ICON_FA_EARTH_ASIA "\xef\x95\xbe" // U+f57e +#define ICON_FA_EARTH_EUROPE "\xef\x9e\xa2" // U+f7a2 +#define ICON_FA_EARTH_OCEANIA "\xee\x91\xbb" // U+e47b +#define ICON_FA_EGG "\xef\x9f\xbb" // U+f7fb +#define ICON_FA_EJECT "\xef\x81\x92" // U+f052 +#define ICON_FA_ELEVATOR "\xee\x85\xad" // U+e16d +#define ICON_FA_ELLIPSIS "\xef\x85\x81" // U+f141 +#define ICON_FA_ELLIPSIS_VERTICAL "\xef\x85\x82" // U+f142 +#define ICON_FA_ENVELOPE "\xef\x83\xa0" // U+f0e0 +#define ICON_FA_ENVELOPE_CIRCLE_CHECK "\xee\x93\xa8" // U+e4e8 +#define ICON_FA_ENVELOPE_OPEN "\xef\x8a\xb6" // U+f2b6 +#define ICON_FA_ENVELOPE_OPEN_TEXT "\xef\x99\x98" // U+f658 +#define ICON_FA_ENVELOPES_BULK "\xef\x99\xb4" // U+f674 +#define ICON_FA_EQUALS "=" // U+003d +#define ICON_FA_ERASER "\xef\x84\xad" // U+f12d +#define ICON_FA_ETHERNET "\xef\x9e\x96" // U+f796 +#define ICON_FA_EURO_SIGN "\xef\x85\x93" // U+f153 +#define ICON_FA_EXCLAMATION "!" // U+0021 +#define ICON_FA_EXPAND "\xef\x81\xa5" // U+f065 +#define ICON_FA_EXPLOSION "\xee\x93\xa9" // U+e4e9 +#define ICON_FA_EYE "\xef\x81\xae" // U+f06e +#define ICON_FA_EYE_DROPPER "\xef\x87\xbb" // U+f1fb +#define ICON_FA_EYE_LOW_VISION "\xef\x8a\xa8" // U+f2a8 +#define ICON_FA_EYE_SLASH "\xef\x81\xb0" // U+f070 +#define ICON_FA_F "F" // U+0046 +#define ICON_FA_FACE_ANGRY "\xef\x95\x96" // U+f556 +#define ICON_FA_FACE_DIZZY "\xef\x95\xa7" // U+f567 +#define ICON_FA_FACE_FLUSHED "\xef\x95\xb9" // U+f579 +#define ICON_FA_FACE_FROWN "\xef\x84\x99" // U+f119 +#define ICON_FA_FACE_FROWN_OPEN "\xef\x95\xba" // U+f57a +#define ICON_FA_FACE_GRIMACE "\xef\x95\xbf" // U+f57f +#define ICON_FA_FACE_GRIN "\xef\x96\x80" // U+f580 +#define ICON_FA_FACE_GRIN_BEAM "\xef\x96\x82" // U+f582 +#define ICON_FA_FACE_GRIN_BEAM_SWEAT "\xef\x96\x83" // U+f583 +#define ICON_FA_FACE_GRIN_HEARTS "\xef\x96\x84" // U+f584 +#define ICON_FA_FACE_GRIN_SQUINT "\xef\x96\x85" // U+f585 +#define ICON_FA_FACE_GRIN_SQUINT_TEARS "\xef\x96\x86" // U+f586 +#define ICON_FA_FACE_GRIN_STARS "\xef\x96\x87" // U+f587 +#define ICON_FA_FACE_GRIN_TEARS "\xef\x96\x88" // U+f588 +#define ICON_FA_FACE_GRIN_TONGUE "\xef\x96\x89" // U+f589 +#define ICON_FA_FACE_GRIN_TONGUE_SQUINT "\xef\x96\x8a" // U+f58a +#define ICON_FA_FACE_GRIN_TONGUE_WINK "\xef\x96\x8b" // U+f58b +#define ICON_FA_FACE_GRIN_WIDE "\xef\x96\x81" // U+f581 +#define ICON_FA_FACE_GRIN_WINK "\xef\x96\x8c" // U+f58c +#define ICON_FA_FACE_KISS "\xef\x96\x96" // U+f596 +#define ICON_FA_FACE_KISS_BEAM "\xef\x96\x97" // U+f597 +#define ICON_FA_FACE_KISS_WINK_HEART "\xef\x96\x98" // U+f598 +#define ICON_FA_FACE_LAUGH "\xef\x96\x99" // U+f599 +#define ICON_FA_FACE_LAUGH_BEAM "\xef\x96\x9a" // U+f59a +#define ICON_FA_FACE_LAUGH_SQUINT "\xef\x96\x9b" // U+f59b +#define ICON_FA_FACE_LAUGH_WINK "\xef\x96\x9c" // U+f59c +#define ICON_FA_FACE_MEH "\xef\x84\x9a" // U+f11a +#define ICON_FA_FACE_MEH_BLANK "\xef\x96\xa4" // U+f5a4 +#define ICON_FA_FACE_ROLLING_EYES "\xef\x96\xa5" // U+f5a5 +#define ICON_FA_FACE_SAD_CRY "\xef\x96\xb3" // U+f5b3 +#define ICON_FA_FACE_SAD_TEAR "\xef\x96\xb4" // U+f5b4 +#define ICON_FA_FACE_SMILE "\xef\x84\x98" // U+f118 +#define ICON_FA_FACE_SMILE_BEAM "\xef\x96\xb8" // U+f5b8 +#define ICON_FA_FACE_SMILE_WINK "\xef\x93\x9a" // U+f4da +#define ICON_FA_FACE_SURPRISE "\xef\x97\x82" // U+f5c2 +#define ICON_FA_FACE_TIRED "\xef\x97\x88" // U+f5c8 +#define ICON_FA_FAN "\xef\xa1\xa3" // U+f863 +#define ICON_FA_FAUCET "\xee\x80\x85" // U+e005 +#define ICON_FA_FAUCET_DRIP "\xee\x80\x86" // U+e006 +#define ICON_FA_FAX "\xef\x86\xac" // U+f1ac +#define ICON_FA_FEATHER "\xef\x94\xad" // U+f52d +#define ICON_FA_FEATHER_POINTED "\xef\x95\xab" // U+f56b +#define ICON_FA_FERRY "\xee\x93\xaa" // U+e4ea +#define ICON_FA_FILE "\xef\x85\x9b" // U+f15b +#define ICON_FA_FILE_ARROW_DOWN "\xef\x95\xad" // U+f56d +#define ICON_FA_FILE_ARROW_UP "\xef\x95\xb4" // U+f574 +#define ICON_FA_FILE_AUDIO "\xef\x87\x87" // U+f1c7 +#define ICON_FA_FILE_CIRCLE_CHECK "\xee\x96\xa0" // U+e5a0 +#define ICON_FA_FILE_CIRCLE_EXCLAMATION "\xee\x93\xab" // U+e4eb +#define ICON_FA_FILE_CIRCLE_MINUS "\xee\x93\xad" // U+e4ed +#define ICON_FA_FILE_CIRCLE_PLUS "\xee\x92\x94" // U+e494 +#define ICON_FA_FILE_CIRCLE_QUESTION "\xee\x93\xaf" // U+e4ef +#define ICON_FA_FILE_CIRCLE_XMARK "\xee\x96\xa1" // U+e5a1 +#define ICON_FA_FILE_CODE "\xef\x87\x89" // U+f1c9 +#define ICON_FA_FILE_CONTRACT "\xef\x95\xac" // U+f56c +#define ICON_FA_FILE_CSV "\xef\x9b\x9d" // U+f6dd +#define ICON_FA_FILE_EXCEL "\xef\x87\x83" // U+f1c3 +#define ICON_FA_FILE_EXPORT "\xef\x95\xae" // U+f56e +#define ICON_FA_FILE_IMAGE "\xef\x87\x85" // U+f1c5 +#define ICON_FA_FILE_IMPORT "\xef\x95\xaf" // U+f56f +#define ICON_FA_FILE_INVOICE "\xef\x95\xb0" // U+f570 +#define ICON_FA_FILE_INVOICE_DOLLAR "\xef\x95\xb1" // U+f571 +#define ICON_FA_FILE_LINES "\xef\x85\x9c" // U+f15c +#define ICON_FA_FILE_MEDICAL "\xef\x91\xb7" // U+f477 +#define ICON_FA_FILE_PDF "\xef\x87\x81" // U+f1c1 +#define ICON_FA_FILE_PEN "\xef\x8c\x9c" // U+f31c +#define ICON_FA_FILE_POWERPOINT "\xef\x87\x84" // U+f1c4 +#define ICON_FA_FILE_PRESCRIPTION "\xef\x95\xb2" // U+f572 +#define ICON_FA_FILE_SHIELD "\xee\x93\xb0" // U+e4f0 +#define ICON_FA_FILE_SIGNATURE "\xef\x95\xb3" // U+f573 +#define ICON_FA_FILE_VIDEO "\xef\x87\x88" // U+f1c8 +#define ICON_FA_FILE_WAVEFORM "\xef\x91\xb8" // U+f478 +#define ICON_FA_FILE_WORD "\xef\x87\x82" // U+f1c2 +#define ICON_FA_FILE_ZIPPER "\xef\x87\x86" // U+f1c6 +#define ICON_FA_FILL "\xef\x95\xb5" // U+f575 +#define ICON_FA_FILL_DRIP "\xef\x95\xb6" // U+f576 +#define ICON_FA_FILM "\xef\x80\x88" // U+f008 +#define ICON_FA_FILTER "\xef\x82\xb0" // U+f0b0 +#define ICON_FA_FILTER_CIRCLE_DOLLAR "\xef\x99\xa2" // U+f662 +#define ICON_FA_FILTER_CIRCLE_XMARK "\xee\x85\xbb" // U+e17b +#define ICON_FA_FINGERPRINT "\xef\x95\xb7" // U+f577 +#define ICON_FA_FIRE "\xef\x81\xad" // U+f06d +#define ICON_FA_FIRE_BURNER "\xee\x93\xb1" // U+e4f1 +#define ICON_FA_FIRE_EXTINGUISHER "\xef\x84\xb4" // U+f134 +#define ICON_FA_FIRE_FLAME_CURVED "\xef\x9f\xa4" // U+f7e4 +#define ICON_FA_FIRE_FLAME_SIMPLE "\xef\x91\xaa" // U+f46a +#define ICON_FA_FISH "\xef\x95\xb8" // U+f578 +#define ICON_FA_FISH_FINS "\xee\x93\xb2" // U+e4f2 +#define ICON_FA_FLAG "\xef\x80\xa4" // U+f024 +#define ICON_FA_FLAG_CHECKERED "\xef\x84\x9e" // U+f11e +#define ICON_FA_FLAG_USA "\xef\x9d\x8d" // U+f74d +#define ICON_FA_FLASK "\xef\x83\x83" // U+f0c3 +#define ICON_FA_FLASK_VIAL "\xee\x93\xb3" // U+e4f3 +#define ICON_FA_FLOPPY_DISK "\xef\x83\x87" // U+f0c7 +#define ICON_FA_FLORIN_SIGN "\xee\x86\x84" // U+e184 +#define ICON_FA_FOLDER "\xef\x81\xbb" // U+f07b +#define ICON_FA_FOLDER_CLOSED "\xee\x86\x85" // U+e185 +#define ICON_FA_FOLDER_MINUS "\xef\x99\x9d" // U+f65d +#define ICON_FA_FOLDER_OPEN "\xef\x81\xbc" // U+f07c +#define ICON_FA_FOLDER_PLUS "\xef\x99\x9e" // U+f65e +#define ICON_FA_FOLDER_TREE "\xef\xa0\x82" // U+f802 +#define ICON_FA_FONT "\xef\x80\xb1" // U+f031 +#define ICON_FA_FONT_AWESOME "\xef\x8a\xb4" // U+f2b4 +#define ICON_FA_FOOTBALL "\xef\x91\x8e" // U+f44e +#define ICON_FA_FORWARD "\xef\x81\x8e" // U+f04e +#define ICON_FA_FORWARD_FAST "\xef\x81\x90" // U+f050 +#define ICON_FA_FORWARD_STEP "\xef\x81\x91" // U+f051 +#define ICON_FA_FRANC_SIGN "\xee\x86\x8f" // U+e18f +#define ICON_FA_FROG "\xef\x94\xae" // U+f52e +#define ICON_FA_FUTBOL "\xef\x87\xa3" // U+f1e3 +#define ICON_FA_G "G" // U+0047 +#define ICON_FA_GAMEPAD "\xef\x84\x9b" // U+f11b +#define ICON_FA_GAS_PUMP "\xef\x94\xaf" // U+f52f +#define ICON_FA_GAUGE "\xef\x98\xa4" // U+f624 +#define ICON_FA_GAUGE_HIGH "\xef\x98\xa5" // U+f625 +#define ICON_FA_GAUGE_SIMPLE "\xef\x98\xa9" // U+f629 +#define ICON_FA_GAUGE_SIMPLE_HIGH "\xef\x98\xaa" // U+f62a +#define ICON_FA_GAVEL "\xef\x83\xa3" // U+f0e3 +#define ICON_FA_GEAR "\xef\x80\x93" // U+f013 +#define ICON_FA_GEARS "\xef\x82\x85" // U+f085 +#define ICON_FA_GEM "\xef\x8e\xa5" // U+f3a5 +#define ICON_FA_GENDERLESS "\xef\x88\xad" // U+f22d +#define ICON_FA_GHOST "\xef\x9b\xa2" // U+f6e2 +#define ICON_FA_GIFT "\xef\x81\xab" // U+f06b +#define ICON_FA_GIFTS "\xef\x9e\x9c" // U+f79c +#define ICON_FA_GLASS_WATER "\xee\x93\xb4" // U+e4f4 +#define ICON_FA_GLASS_WATER_DROPLET "\xee\x93\xb5" // U+e4f5 +#define ICON_FA_GLASSES "\xef\x94\xb0" // U+f530 +#define ICON_FA_GLOBE "\xef\x82\xac" // U+f0ac +#define ICON_FA_GOLF_BALL_TEE "\xef\x91\x90" // U+f450 +#define ICON_FA_GOPURAM "\xef\x99\xa4" // U+f664 +#define ICON_FA_GRADUATION_CAP "\xef\x86\x9d" // U+f19d +#define ICON_FA_GREATER_THAN ">" // U+003e +#define ICON_FA_GREATER_THAN_EQUAL "\xef\x94\xb2" // U+f532 +#define ICON_FA_GRIP "\xef\x96\x8d" // U+f58d +#define ICON_FA_GRIP_LINES "\xef\x9e\xa4" // U+f7a4 +#define ICON_FA_GRIP_LINES_VERTICAL "\xef\x9e\xa5" // U+f7a5 +#define ICON_FA_GRIP_VERTICAL "\xef\x96\x8e" // U+f58e +#define ICON_FA_GROUP_ARROWS_ROTATE "\xee\x93\xb6" // U+e4f6 +#define ICON_FA_GUARANI_SIGN "\xee\x86\x9a" // U+e19a +#define ICON_FA_GUITAR "\xef\x9e\xa6" // U+f7a6 +#define ICON_FA_GUN "\xee\x86\x9b" // U+e19b +#define ICON_FA_H "H" // U+0048 +#define ICON_FA_HAMMER "\xef\x9b\xa3" // U+f6e3 +#define ICON_FA_HAMSA "\xef\x99\xa5" // U+f665 +#define ICON_FA_HAND "\xef\x89\x96" // U+f256 +#define ICON_FA_HAND_BACK_FIST "\xef\x89\x95" // U+f255 +#define ICON_FA_HAND_DOTS "\xef\x91\xa1" // U+f461 +#define ICON_FA_HAND_FIST "\xef\x9b\x9e" // U+f6de +#define ICON_FA_HAND_HOLDING "\xef\x92\xbd" // U+f4bd +#define ICON_FA_HAND_HOLDING_DOLLAR "\xef\x93\x80" // U+f4c0 +#define ICON_FA_HAND_HOLDING_DROPLET "\xef\x93\x81" // U+f4c1 +#define ICON_FA_HAND_HOLDING_HAND "\xee\x93\xb7" // U+e4f7 +#define ICON_FA_HAND_HOLDING_HEART "\xef\x92\xbe" // U+f4be +#define ICON_FA_HAND_HOLDING_MEDICAL "\xee\x81\x9c" // U+e05c +#define ICON_FA_HAND_LIZARD "\xef\x89\x98" // U+f258 +#define ICON_FA_HAND_MIDDLE_FINGER "\xef\xa0\x86" // U+f806 +#define ICON_FA_HAND_PEACE "\xef\x89\x9b" // U+f25b +#define ICON_FA_HAND_POINT_DOWN "\xef\x82\xa7" // U+f0a7 +#define ICON_FA_HAND_POINT_LEFT "\xef\x82\xa5" // U+f0a5 +#define ICON_FA_HAND_POINT_RIGHT "\xef\x82\xa4" // U+f0a4 +#define ICON_FA_HAND_POINT_UP "\xef\x82\xa6" // U+f0a6 +#define ICON_FA_HAND_POINTER "\xef\x89\x9a" // U+f25a +#define ICON_FA_HAND_SCISSORS "\xef\x89\x97" // U+f257 +#define ICON_FA_HAND_SPARKLES "\xee\x81\x9d" // U+e05d +#define ICON_FA_HAND_SPOCK "\xef\x89\x99" // U+f259 +#define ICON_FA_HANDCUFFS "\xee\x93\xb8" // U+e4f8 +#define ICON_FA_HANDS "\xef\x8a\xa7" // U+f2a7 +#define ICON_FA_HANDS_ASL_INTERPRETING "\xef\x8a\xa3" // U+f2a3 +#define ICON_FA_HANDS_BOUND "\xee\x93\xb9" // U+e4f9 +#define ICON_FA_HANDS_BUBBLES "\xee\x81\x9e" // U+e05e +#define ICON_FA_HANDS_CLAPPING "\xee\x86\xa8" // U+e1a8 +#define ICON_FA_HANDS_HOLDING "\xef\x93\x82" // U+f4c2 +#define ICON_FA_HANDS_HOLDING_CHILD "\xee\x93\xba" // U+e4fa +#define ICON_FA_HANDS_HOLDING_CIRCLE "\xee\x93\xbb" // U+e4fb +#define ICON_FA_HANDS_PRAYING "\xef\x9a\x84" // U+f684 +#define ICON_FA_HANDSHAKE "\xef\x8a\xb5" // U+f2b5 +#define ICON_FA_HANDSHAKE_ANGLE "\xef\x93\x84" // U+f4c4 +#define ICON_FA_HANDSHAKE_SIMPLE "\xef\x93\x86" // U+f4c6 +#define ICON_FA_HANDSHAKE_SIMPLE_SLASH "\xee\x81\x9f" // U+e05f +#define ICON_FA_HANDSHAKE_SLASH "\xee\x81\xa0" // U+e060 +#define ICON_FA_HANUKIAH "\xef\x9b\xa6" // U+f6e6 +#define ICON_FA_HARD_DRIVE "\xef\x82\xa0" // U+f0a0 +#define ICON_FA_HASHTAG "#" // U+0023 +#define ICON_FA_HAT_COWBOY "\xef\xa3\x80" // U+f8c0 +#define ICON_FA_HAT_COWBOY_SIDE "\xef\xa3\x81" // U+f8c1 +#define ICON_FA_HAT_WIZARD "\xef\x9b\xa8" // U+f6e8 +#define ICON_FA_HEAD_SIDE_COUGH "\xee\x81\xa1" // U+e061 +#define ICON_FA_HEAD_SIDE_COUGH_SLASH "\xee\x81\xa2" // U+e062 +#define ICON_FA_HEAD_SIDE_MASK "\xee\x81\xa3" // U+e063 +#define ICON_FA_HEAD_SIDE_VIRUS "\xee\x81\xa4" // U+e064 +#define ICON_FA_HEADING "\xef\x87\x9c" // U+f1dc +#define ICON_FA_HEADPHONES "\xef\x80\xa5" // U+f025 +#define ICON_FA_HEADPHONES_SIMPLE "\xef\x96\x8f" // U+f58f +#define ICON_FA_HEADSET "\xef\x96\x90" // U+f590 +#define ICON_FA_HEART "\xef\x80\x84" // U+f004 +#define ICON_FA_HEART_CIRCLE_BOLT "\xee\x93\xbc" // U+e4fc +#define ICON_FA_HEART_CIRCLE_CHECK "\xee\x93\xbd" // U+e4fd +#define ICON_FA_HEART_CIRCLE_EXCLAMATION "\xee\x93\xbe" // U+e4fe +#define ICON_FA_HEART_CIRCLE_MINUS "\xee\x93\xbf" // U+e4ff +#define ICON_FA_HEART_CIRCLE_PLUS "\xee\x94\x80" // U+e500 +#define ICON_FA_HEART_CIRCLE_XMARK "\xee\x94\x81" // U+e501 +#define ICON_FA_HEART_CRACK "\xef\x9e\xa9" // U+f7a9 +#define ICON_FA_HEART_PULSE "\xef\x88\x9e" // U+f21e +#define ICON_FA_HELICOPTER "\xef\x94\xb3" // U+f533 +#define ICON_FA_HELICOPTER_SYMBOL "\xee\x94\x82" // U+e502 +#define ICON_FA_HELMET_SAFETY "\xef\xa0\x87" // U+f807 +#define ICON_FA_HELMET_UN "\xee\x94\x83" // U+e503 +#define ICON_FA_HIGHLIGHTER "\xef\x96\x91" // U+f591 +#define ICON_FA_HILL_AVALANCHE "\xee\x94\x87" // U+e507 +#define ICON_FA_HILL_ROCKSLIDE "\xee\x94\x88" // U+e508 +#define ICON_FA_HIPPO "\xef\x9b\xad" // U+f6ed +#define ICON_FA_HOCKEY_PUCK "\xef\x91\x93" // U+f453 +#define ICON_FA_HOLLY_BERRY "\xef\x9e\xaa" // U+f7aa +#define ICON_FA_HORSE "\xef\x9b\xb0" // U+f6f0 +#define ICON_FA_HORSE_HEAD "\xef\x9e\xab" // U+f7ab +#define ICON_FA_HOSPITAL "\xef\x83\xb8" // U+f0f8 +#define ICON_FA_HOSPITAL_USER "\xef\xa0\x8d" // U+f80d +#define ICON_FA_HOT_TUB_PERSON "\xef\x96\x93" // U+f593 +#define ICON_FA_HOTDOG "\xef\xa0\x8f" // U+f80f +#define ICON_FA_HOTEL "\xef\x96\x94" // U+f594 +#define ICON_FA_HOURGLASS "\xef\x89\x94" // U+f254 +#define ICON_FA_HOURGLASS_END "\xef\x89\x93" // U+f253 +#define ICON_FA_HOURGLASS_HALF "\xef\x89\x92" // U+f252 +#define ICON_FA_HOURGLASS_START "\xef\x89\x91" // U+f251 +#define ICON_FA_HOUSE "\xef\x80\x95" // U+f015 +#define ICON_FA_HOUSE_CHIMNEY "\xee\x8e\xaf" // U+e3af +#define ICON_FA_HOUSE_CHIMNEY_CRACK "\xef\x9b\xb1" // U+f6f1 +#define ICON_FA_HOUSE_CHIMNEY_MEDICAL "\xef\x9f\xb2" // U+f7f2 +#define ICON_FA_HOUSE_CHIMNEY_USER "\xee\x81\xa5" // U+e065 +#define ICON_FA_HOUSE_CHIMNEY_WINDOW "\xee\x80\x8d" // U+e00d +#define ICON_FA_HOUSE_CIRCLE_CHECK "\xee\x94\x89" // U+e509 +#define ICON_FA_HOUSE_CIRCLE_EXCLAMATION "\xee\x94\x8a" // U+e50a +#define ICON_FA_HOUSE_CIRCLE_XMARK "\xee\x94\x8b" // U+e50b +#define ICON_FA_HOUSE_CRACK "\xee\x8e\xb1" // U+e3b1 +#define ICON_FA_HOUSE_FIRE "\xee\x94\x8c" // U+e50c +#define ICON_FA_HOUSE_FLAG "\xee\x94\x8d" // U+e50d +#define ICON_FA_HOUSE_FLOOD_WATER "\xee\x94\x8e" // U+e50e +#define ICON_FA_HOUSE_FLOOD_WATER_CIRCLE_ARROW_RIGHT "\xee\x94\x8f" // U+e50f +#define ICON_FA_HOUSE_LAPTOP "\xee\x81\xa6" // U+e066 +#define ICON_FA_HOUSE_LOCK "\xee\x94\x90" // U+e510 +#define ICON_FA_HOUSE_MEDICAL "\xee\x8e\xb2" // U+e3b2 +#define ICON_FA_HOUSE_MEDICAL_CIRCLE_CHECK "\xee\x94\x91" // U+e511 +#define ICON_FA_HOUSE_MEDICAL_CIRCLE_EXCLAMATION "\xee\x94\x92" // U+e512 +#define ICON_FA_HOUSE_MEDICAL_CIRCLE_XMARK "\xee\x94\x93" // U+e513 +#define ICON_FA_HOUSE_MEDICAL_FLAG "\xee\x94\x94" // U+e514 +#define ICON_FA_HOUSE_SIGNAL "\xee\x80\x92" // U+e012 +#define ICON_FA_HOUSE_TSUNAMI "\xee\x94\x95" // U+e515 +#define ICON_FA_HOUSE_USER "\xee\x86\xb0" // U+e1b0 +#define ICON_FA_HRYVNIA_SIGN "\xef\x9b\xb2" // U+f6f2 +#define ICON_FA_HURRICANE "\xef\x9d\x91" // U+f751 +#define ICON_FA_I "I" // U+0049 +#define ICON_FA_I_CURSOR "\xef\x89\x86" // U+f246 +#define ICON_FA_ICE_CREAM "\xef\xa0\x90" // U+f810 +#define ICON_FA_ICICLES "\xef\x9e\xad" // U+f7ad +#define ICON_FA_ICONS "\xef\xa1\xad" // U+f86d +#define ICON_FA_ID_BADGE "\xef\x8b\x81" // U+f2c1 +#define ICON_FA_ID_CARD "\xef\x8b\x82" // U+f2c2 +#define ICON_FA_ID_CARD_CLIP "\xef\x91\xbf" // U+f47f +#define ICON_FA_IGLOO "\xef\x9e\xae" // U+f7ae +#define ICON_FA_IMAGE "\xef\x80\xbe" // U+f03e +#define ICON_FA_IMAGE_PORTRAIT "\xef\x8f\xa0" // U+f3e0 +#define ICON_FA_IMAGES "\xef\x8c\x82" // U+f302 +#define ICON_FA_INBOX "\xef\x80\x9c" // U+f01c +#define ICON_FA_INDENT "\xef\x80\xbc" // U+f03c +#define ICON_FA_INDIAN_RUPEE_SIGN "\xee\x86\xbc" // U+e1bc +#define ICON_FA_INDUSTRY "\xef\x89\xb5" // U+f275 +#define ICON_FA_INFINITY "\xef\x94\xb4" // U+f534 +#define ICON_FA_INFO "\xef\x84\xa9" // U+f129 +#define ICON_FA_ITALIC "\xef\x80\xb3" // U+f033 +#define ICON_FA_J "J" // U+004a +#define ICON_FA_JAR "\xee\x94\x96" // U+e516 +#define ICON_FA_JAR_WHEAT "\xee\x94\x97" // U+e517 +#define ICON_FA_JEDI "\xef\x99\xa9" // U+f669 +#define ICON_FA_JET_FIGHTER "\xef\x83\xbb" // U+f0fb +#define ICON_FA_JET_FIGHTER_UP "\xee\x94\x98" // U+e518 +#define ICON_FA_JOINT "\xef\x96\x95" // U+f595 +#define ICON_FA_JUG_DETERGENT "\xee\x94\x99" // U+e519 +#define ICON_FA_K "K" // U+004b +#define ICON_FA_KAABA "\xef\x99\xab" // U+f66b +#define ICON_FA_KEY "\xef\x82\x84" // U+f084 +#define ICON_FA_KEYBOARD "\xef\x84\x9c" // U+f11c +#define ICON_FA_KHANDA "\xef\x99\xad" // U+f66d +#define ICON_FA_KIP_SIGN "\xee\x87\x84" // U+e1c4 +#define ICON_FA_KIT_MEDICAL "\xef\x91\xb9" // U+f479 +#define ICON_FA_KITCHEN_SET "\xee\x94\x9a" // U+e51a +#define ICON_FA_KIWI_BIRD "\xef\x94\xb5" // U+f535 +#define ICON_FA_L "L" // U+004c +#define ICON_FA_LAND_MINE_ON "\xee\x94\x9b" // U+e51b +#define ICON_FA_LANDMARK "\xef\x99\xaf" // U+f66f +#define ICON_FA_LANDMARK_DOME "\xef\x9d\x92" // U+f752 +#define ICON_FA_LANDMARK_FLAG "\xee\x94\x9c" // U+e51c +#define ICON_FA_LANGUAGE "\xef\x86\xab" // U+f1ab +#define ICON_FA_LAPTOP "\xef\x84\x89" // U+f109 +#define ICON_FA_LAPTOP_CODE "\xef\x97\xbc" // U+f5fc +#define ICON_FA_LAPTOP_FILE "\xee\x94\x9d" // U+e51d +#define ICON_FA_LAPTOP_MEDICAL "\xef\xa0\x92" // U+f812 +#define ICON_FA_LARI_SIGN "\xee\x87\x88" // U+e1c8 +#define ICON_FA_LAYER_GROUP "\xef\x97\xbd" // U+f5fd +#define ICON_FA_LEAF "\xef\x81\xac" // U+f06c +#define ICON_FA_LEFT_LONG "\xef\x8c\x8a" // U+f30a +#define ICON_FA_LEFT_RIGHT "\xef\x8c\xb7" // U+f337 +#define ICON_FA_LEMON "\xef\x82\x94" // U+f094 +#define ICON_FA_LESS_THAN "<" // U+003c +#define ICON_FA_LESS_THAN_EQUAL "\xef\x94\xb7" // U+f537 +#define ICON_FA_LIFE_RING "\xef\x87\x8d" // U+f1cd +#define ICON_FA_LIGHTBULB "\xef\x83\xab" // U+f0eb +#define ICON_FA_LINES_LEANING "\xee\x94\x9e" // U+e51e +#define ICON_FA_LINK "\xef\x83\x81" // U+f0c1 +#define ICON_FA_LINK_SLASH "\xef\x84\xa7" // U+f127 +#define ICON_FA_LIRA_SIGN "\xef\x86\x95" // U+f195 +#define ICON_FA_LIST "\xef\x80\xba" // U+f03a +#define ICON_FA_LIST_CHECK "\xef\x82\xae" // U+f0ae +#define ICON_FA_LIST_OL "\xef\x83\x8b" // U+f0cb +#define ICON_FA_LIST_UL "\xef\x83\x8a" // U+f0ca +#define ICON_FA_LITECOIN_SIGN "\xee\x87\x93" // U+e1d3 +#define ICON_FA_LOCATION_ARROW "\xef\x84\xa4" // U+f124 +#define ICON_FA_LOCATION_CROSSHAIRS "\xef\x98\x81" // U+f601 +#define ICON_FA_LOCATION_DOT "\xef\x8f\x85" // U+f3c5 +#define ICON_FA_LOCATION_PIN "\xef\x81\x81" // U+f041 +#define ICON_FA_LOCATION_PIN_LOCK "\xee\x94\x9f" // U+e51f +#define ICON_FA_LOCK "\xef\x80\xa3" // U+f023 +#define ICON_FA_LOCK_OPEN "\xef\x8f\x81" // U+f3c1 +#define ICON_FA_LOCUST "\xee\x94\xa0" // U+e520 +#define ICON_FA_LUNGS "\xef\x98\x84" // U+f604 +#define ICON_FA_LUNGS_VIRUS "\xee\x81\xa7" // U+e067 +#define ICON_FA_M "M" // U+004d +#define ICON_FA_MAGNET "\xef\x81\xb6" // U+f076 +#define ICON_FA_MAGNIFYING_GLASS "\xef\x80\x82" // U+f002 +#define ICON_FA_MAGNIFYING_GLASS_ARROW_RIGHT "\xee\x94\xa1" // U+e521 +#define ICON_FA_MAGNIFYING_GLASS_CHART "\xee\x94\xa2" // U+e522 +#define ICON_FA_MAGNIFYING_GLASS_DOLLAR "\xef\x9a\x88" // U+f688 +#define ICON_FA_MAGNIFYING_GLASS_LOCATION "\xef\x9a\x89" // U+f689 +#define ICON_FA_MAGNIFYING_GLASS_MINUS "\xef\x80\x90" // U+f010 +#define ICON_FA_MAGNIFYING_GLASS_PLUS "\xef\x80\x8e" // U+f00e +#define ICON_FA_MANAT_SIGN "\xee\x87\x95" // U+e1d5 +#define ICON_FA_MAP "\xef\x89\xb9" // U+f279 +#define ICON_FA_MAP_LOCATION "\xef\x96\x9f" // U+f59f +#define ICON_FA_MAP_LOCATION_DOT "\xef\x96\xa0" // U+f5a0 +#define ICON_FA_MAP_PIN "\xef\x89\xb6" // U+f276 +#define ICON_FA_MARKER "\xef\x96\xa1" // U+f5a1 +#define ICON_FA_MARS "\xef\x88\xa2" // U+f222 +#define ICON_FA_MARS_AND_VENUS "\xef\x88\xa4" // U+f224 +#define ICON_FA_MARS_AND_VENUS_BURST "\xee\x94\xa3" // U+e523 +#define ICON_FA_MARS_DOUBLE "\xef\x88\xa7" // U+f227 +#define ICON_FA_MARS_STROKE "\xef\x88\xa9" // U+f229 +#define ICON_FA_MARS_STROKE_RIGHT "\xef\x88\xab" // U+f22b +#define ICON_FA_MARS_STROKE_UP "\xef\x88\xaa" // U+f22a +#define ICON_FA_MARTINI_GLASS "\xef\x95\xbb" // U+f57b +#define ICON_FA_MARTINI_GLASS_CITRUS "\xef\x95\xa1" // U+f561 +#define ICON_FA_MARTINI_GLASS_EMPTY "\xef\x80\x80" // U+f000 +#define ICON_FA_MASK "\xef\x9b\xba" // U+f6fa +#define ICON_FA_MASK_FACE "\xee\x87\x97" // U+e1d7 +#define ICON_FA_MASK_VENTILATOR "\xee\x94\xa4" // U+e524 +#define ICON_FA_MASKS_THEATER "\xef\x98\xb0" // U+f630 +#define ICON_FA_MATTRESS_PILLOW "\xee\x94\xa5" // U+e525 +#define ICON_FA_MAXIMIZE "\xef\x8c\x9e" // U+f31e +#define ICON_FA_MEDAL "\xef\x96\xa2" // U+f5a2 +#define ICON_FA_MEMORY "\xef\x94\xb8" // U+f538 +#define ICON_FA_MENORAH "\xef\x99\xb6" // U+f676 +#define ICON_FA_MERCURY "\xef\x88\xa3" // U+f223 +#define ICON_FA_MESSAGE "\xef\x89\xba" // U+f27a +#define ICON_FA_METEOR "\xef\x9d\x93" // U+f753 +#define ICON_FA_MICROCHIP "\xef\x8b\x9b" // U+f2db +#define ICON_FA_MICROPHONE "\xef\x84\xb0" // U+f130 +#define ICON_FA_MICROPHONE_LINES "\xef\x8f\x89" // U+f3c9 +#define ICON_FA_MICROPHONE_LINES_SLASH "\xef\x94\xb9" // U+f539 +#define ICON_FA_MICROPHONE_SLASH "\xef\x84\xb1" // U+f131 +#define ICON_FA_MICROSCOPE "\xef\x98\x90" // U+f610 +#define ICON_FA_MILL_SIGN "\xee\x87\xad" // U+e1ed +#define ICON_FA_MINIMIZE "\xef\x9e\x8c" // U+f78c +#define ICON_FA_MINUS "\xef\x81\xa8" // U+f068 +#define ICON_FA_MITTEN "\xef\x9e\xb5" // U+f7b5 +#define ICON_FA_MOBILE "\xef\x8f\x8e" // U+f3ce +#define ICON_FA_MOBILE_BUTTON "\xef\x84\x8b" // U+f10b +#define ICON_FA_MOBILE_RETRO "\xee\x94\xa7" // U+e527 +#define ICON_FA_MOBILE_SCREEN "\xef\x8f\x8f" // U+f3cf +#define ICON_FA_MOBILE_SCREEN_BUTTON "\xef\x8f\x8d" // U+f3cd +#define ICON_FA_MONEY_BILL "\xef\x83\x96" // U+f0d6 +#define ICON_FA_MONEY_BILL_1 "\xef\x8f\x91" // U+f3d1 +#define ICON_FA_MONEY_BILL_1_WAVE "\xef\x94\xbb" // U+f53b +#define ICON_FA_MONEY_BILL_TRANSFER "\xee\x94\xa8" // U+e528 +#define ICON_FA_MONEY_BILL_TREND_UP "\xee\x94\xa9" // U+e529 +#define ICON_FA_MONEY_BILL_WAVE "\xef\x94\xba" // U+f53a +#define ICON_FA_MONEY_BILL_WHEAT "\xee\x94\xaa" // U+e52a +#define ICON_FA_MONEY_BILLS "\xee\x87\xb3" // U+e1f3 +#define ICON_FA_MONEY_CHECK "\xef\x94\xbc" // U+f53c +#define ICON_FA_MONEY_CHECK_DOLLAR "\xef\x94\xbd" // U+f53d +#define ICON_FA_MONUMENT "\xef\x96\xa6" // U+f5a6 +#define ICON_FA_MOON "\xef\x86\x86" // U+f186 +#define ICON_FA_MORTAR_PESTLE "\xef\x96\xa7" // U+f5a7 +#define ICON_FA_MOSQUE "\xef\x99\xb8" // U+f678 +#define ICON_FA_MOSQUITO "\xee\x94\xab" // U+e52b +#define ICON_FA_MOSQUITO_NET "\xee\x94\xac" // U+e52c +#define ICON_FA_MOTORCYCLE "\xef\x88\x9c" // U+f21c +#define ICON_FA_MOUND "\xee\x94\xad" // U+e52d +#define ICON_FA_MOUNTAIN "\xef\x9b\xbc" // U+f6fc +#define ICON_FA_MOUNTAIN_CITY "\xee\x94\xae" // U+e52e +#define ICON_FA_MOUNTAIN_SUN "\xee\x94\xaf" // U+e52f +#define ICON_FA_MUG_HOT "\xef\x9e\xb6" // U+f7b6 +#define ICON_FA_MUG_SAUCER "\xef\x83\xb4" // U+f0f4 +#define ICON_FA_MUSIC "\xef\x80\x81" // U+f001 +#define ICON_FA_N "N" // U+004e +#define ICON_FA_NAIRA_SIGN "\xee\x87\xb6" // U+e1f6 +#define ICON_FA_NETWORK_WIRED "\xef\x9b\xbf" // U+f6ff +#define ICON_FA_NEUTER "\xef\x88\xac" // U+f22c +#define ICON_FA_NEWSPAPER "\xef\x87\xaa" // U+f1ea +#define ICON_FA_NOT_EQUAL "\xef\x94\xbe" // U+f53e +#define ICON_FA_NOTE_STICKY "\xef\x89\x89" // U+f249 +#define ICON_FA_NOTES_MEDICAL "\xef\x92\x81" // U+f481 +#define ICON_FA_O "O" // U+004f +#define ICON_FA_OBJECT_GROUP "\xef\x89\x87" // U+f247 +#define ICON_FA_OBJECT_UNGROUP "\xef\x89\x88" // U+f248 +#define ICON_FA_OIL_CAN "\xef\x98\x93" // U+f613 +#define ICON_FA_OIL_WELL "\xee\x94\xb2" // U+e532 +#define ICON_FA_OM "\xef\x99\xb9" // U+f679 +#define ICON_FA_OTTER "\xef\x9c\x80" // U+f700 +#define ICON_FA_OUTDENT "\xef\x80\xbb" // U+f03b +#define ICON_FA_P "P" // U+0050 +#define ICON_FA_PAGER "\xef\xa0\x95" // U+f815 +#define ICON_FA_PAINT_ROLLER "\xef\x96\xaa" // U+f5aa +#define ICON_FA_PAINTBRUSH "\xef\x87\xbc" // U+f1fc +#define ICON_FA_PALETTE "\xef\x94\xbf" // U+f53f +#define ICON_FA_PALLET "\xef\x92\x82" // U+f482 +#define ICON_FA_PANORAMA "\xee\x88\x89" // U+e209 +#define ICON_FA_PAPER_PLANE "\xef\x87\x98" // U+f1d8 +#define ICON_FA_PAPERCLIP "\xef\x83\x86" // U+f0c6 +#define ICON_FA_PARACHUTE_BOX "\xef\x93\x8d" // U+f4cd +#define ICON_FA_PARAGRAPH "\xef\x87\x9d" // U+f1dd +#define ICON_FA_PASSPORT "\xef\x96\xab" // U+f5ab +#define ICON_FA_PASTE "\xef\x83\xaa" // U+f0ea +#define ICON_FA_PAUSE "\xef\x81\x8c" // U+f04c +#define ICON_FA_PAW "\xef\x86\xb0" // U+f1b0 +#define ICON_FA_PEACE "\xef\x99\xbc" // U+f67c +#define ICON_FA_PEN "\xef\x8c\x84" // U+f304 +#define ICON_FA_PEN_CLIP "\xef\x8c\x85" // U+f305 +#define ICON_FA_PEN_FANCY "\xef\x96\xac" // U+f5ac +#define ICON_FA_PEN_NIB "\xef\x96\xad" // U+f5ad +#define ICON_FA_PEN_RULER "\xef\x96\xae" // U+f5ae +#define ICON_FA_PEN_TO_SQUARE "\xef\x81\x84" // U+f044 +#define ICON_FA_PENCIL "\xef\x8c\x83" // U+f303 +#define ICON_FA_PEOPLE_ARROWS "\xee\x81\xa8" // U+e068 +#define ICON_FA_PEOPLE_CARRY_BOX "\xef\x93\x8e" // U+f4ce +#define ICON_FA_PEOPLE_GROUP "\xee\x94\xb3" // U+e533 +#define ICON_FA_PEOPLE_LINE "\xee\x94\xb4" // U+e534 +#define ICON_FA_PEOPLE_PULLING "\xee\x94\xb5" // U+e535 +#define ICON_FA_PEOPLE_ROBBERY "\xee\x94\xb6" // U+e536 +#define ICON_FA_PEOPLE_ROOF "\xee\x94\xb7" // U+e537 +#define ICON_FA_PEPPER_HOT "\xef\xa0\x96" // U+f816 +#define ICON_FA_PERCENT "%" // U+0025 +#define ICON_FA_PERSON "\xef\x86\x83" // U+f183 +#define ICON_FA_PERSON_ARROW_DOWN_TO_LINE "\xee\x94\xb8" // U+e538 +#define ICON_FA_PERSON_ARROW_UP_FROM_LINE "\xee\x94\xb9" // U+e539 +#define ICON_FA_PERSON_BIKING "\xef\xa1\x8a" // U+f84a +#define ICON_FA_PERSON_BOOTH "\xef\x9d\x96" // U+f756 +#define ICON_FA_PERSON_BREASTFEEDING "\xee\x94\xba" // U+e53a +#define ICON_FA_PERSON_BURST "\xee\x94\xbb" // U+e53b +#define ICON_FA_PERSON_CANE "\xee\x94\xbc" // U+e53c +#define ICON_FA_PERSON_CHALKBOARD "\xee\x94\xbd" // U+e53d +#define ICON_FA_PERSON_CIRCLE_CHECK "\xee\x94\xbe" // U+e53e +#define ICON_FA_PERSON_CIRCLE_EXCLAMATION "\xee\x94\xbf" // U+e53f +#define ICON_FA_PERSON_CIRCLE_MINUS "\xee\x95\x80" // U+e540 +#define ICON_FA_PERSON_CIRCLE_PLUS "\xee\x95\x81" // U+e541 +#define ICON_FA_PERSON_CIRCLE_QUESTION "\xee\x95\x82" // U+e542 +#define ICON_FA_PERSON_CIRCLE_XMARK "\xee\x95\x83" // U+e543 +#define ICON_FA_PERSON_DIGGING "\xef\xa1\x9e" // U+f85e +#define ICON_FA_PERSON_DOTS_FROM_LINE "\xef\x91\xb0" // U+f470 +#define ICON_FA_PERSON_DRESS "\xef\x86\x82" // U+f182 +#define ICON_FA_PERSON_DRESS_BURST "\xee\x95\x84" // U+e544 +#define ICON_FA_PERSON_DROWNING "\xee\x95\x85" // U+e545 +#define ICON_FA_PERSON_FALLING "\xee\x95\x86" // U+e546 +#define ICON_FA_PERSON_FALLING_BURST "\xee\x95\x87" // U+e547 +#define ICON_FA_PERSON_HALF_DRESS "\xee\x95\x88" // U+e548 +#define ICON_FA_PERSON_HARASSING "\xee\x95\x89" // U+e549 +#define ICON_FA_PERSON_HIKING "\xef\x9b\xac" // U+f6ec +#define ICON_FA_PERSON_MILITARY_POINTING "\xee\x95\x8a" // U+e54a +#define ICON_FA_PERSON_MILITARY_RIFLE "\xee\x95\x8b" // U+e54b +#define ICON_FA_PERSON_MILITARY_TO_PERSON "\xee\x95\x8c" // U+e54c +#define ICON_FA_PERSON_PRAYING "\xef\x9a\x83" // U+f683 +#define ICON_FA_PERSON_PREGNANT "\xee\x8c\x9e" // U+e31e +#define ICON_FA_PERSON_RAYS "\xee\x95\x8d" // U+e54d +#define ICON_FA_PERSON_RIFLE "\xee\x95\x8e" // U+e54e +#define ICON_FA_PERSON_RUNNING "\xef\x9c\x8c" // U+f70c +#define ICON_FA_PERSON_SHELTER "\xee\x95\x8f" // U+e54f +#define ICON_FA_PERSON_SKATING "\xef\x9f\x85" // U+f7c5 +#define ICON_FA_PERSON_SKIING "\xef\x9f\x89" // U+f7c9 +#define ICON_FA_PERSON_SKIING_NORDIC "\xef\x9f\x8a" // U+f7ca +#define ICON_FA_PERSON_SNOWBOARDING "\xef\x9f\x8e" // U+f7ce +#define ICON_FA_PERSON_SWIMMING "\xef\x97\x84" // U+f5c4 +#define ICON_FA_PERSON_THROUGH_WINDOW "\xee\x96\xa9" // U+e5a9 +#define ICON_FA_PERSON_WALKING "\xef\x95\x94" // U+f554 +#define ICON_FA_PERSON_WALKING_ARROW_LOOP_LEFT "\xee\x95\x91" // U+e551 +#define ICON_FA_PERSON_WALKING_ARROW_RIGHT "\xee\x95\x92" // U+e552 +#define ICON_FA_PERSON_WALKING_DASHED_LINE_ARROW_RIGHT "\xee\x95\x93" // U+e553 +#define ICON_FA_PERSON_WALKING_LUGGAGE "\xee\x95\x94" // U+e554 +#define ICON_FA_PERSON_WALKING_WITH_CANE "\xef\x8a\x9d" // U+f29d +#define ICON_FA_PESETA_SIGN "\xee\x88\xa1" // U+e221 +#define ICON_FA_PESO_SIGN "\xee\x88\xa2" // U+e222 +#define ICON_FA_PHONE "\xef\x82\x95" // U+f095 +#define ICON_FA_PHONE_FLIP "\xef\xa1\xb9" // U+f879 +#define ICON_FA_PHONE_SLASH "\xef\x8f\x9d" // U+f3dd +#define ICON_FA_PHONE_VOLUME "\xef\x8a\xa0" // U+f2a0 +#define ICON_FA_PHOTO_FILM "\xef\xa1\xbc" // U+f87c +#define ICON_FA_PIGGY_BANK "\xef\x93\x93" // U+f4d3 +#define ICON_FA_PILLS "\xef\x92\x84" // U+f484 +#define ICON_FA_PIZZA_SLICE "\xef\xa0\x98" // U+f818 +#define ICON_FA_PLACE_OF_WORSHIP "\xef\x99\xbf" // U+f67f +#define ICON_FA_PLANE "\xef\x81\xb2" // U+f072 +#define ICON_FA_PLANE_ARRIVAL "\xef\x96\xaf" // U+f5af +#define ICON_FA_PLANE_CIRCLE_CHECK "\xee\x95\x95" // U+e555 +#define ICON_FA_PLANE_CIRCLE_EXCLAMATION "\xee\x95\x96" // U+e556 +#define ICON_FA_PLANE_CIRCLE_XMARK "\xee\x95\x97" // U+e557 +#define ICON_FA_PLANE_DEPARTURE "\xef\x96\xb0" // U+f5b0 +#define ICON_FA_PLANE_LOCK "\xee\x95\x98" // U+e558 +#define ICON_FA_PLANE_SLASH "\xee\x81\xa9" // U+e069 +#define ICON_FA_PLANE_UP "\xee\x88\xad" // U+e22d +#define ICON_FA_PLANT_WILT "\xee\x96\xaa" // U+e5aa +#define ICON_FA_PLATE_WHEAT "\xee\x95\x9a" // U+e55a +#define ICON_FA_PLAY "\xef\x81\x8b" // U+f04b +#define ICON_FA_PLUG "\xef\x87\xa6" // U+f1e6 +#define ICON_FA_PLUG_CIRCLE_BOLT "\xee\x95\x9b" // U+e55b +#define ICON_FA_PLUG_CIRCLE_CHECK "\xee\x95\x9c" // U+e55c +#define ICON_FA_PLUG_CIRCLE_EXCLAMATION "\xee\x95\x9d" // U+e55d +#define ICON_FA_PLUG_CIRCLE_MINUS "\xee\x95\x9e" // U+e55e +#define ICON_FA_PLUG_CIRCLE_PLUS "\xee\x95\x9f" // U+e55f +#define ICON_FA_PLUG_CIRCLE_XMARK "\xee\x95\xa0" // U+e560 +#define ICON_FA_PLUS "+" // U+002b +#define ICON_FA_PLUS_MINUS "\xee\x90\xbc" // U+e43c +#define ICON_FA_PODCAST "\xef\x8b\x8e" // U+f2ce +#define ICON_FA_POO "\xef\x8b\xbe" // U+f2fe +#define ICON_FA_POO_STORM "\xef\x9d\x9a" // U+f75a +#define ICON_FA_POOP "\xef\x98\x99" // U+f619 +#define ICON_FA_POWER_OFF "\xef\x80\x91" // U+f011 +#define ICON_FA_PRESCRIPTION "\xef\x96\xb1" // U+f5b1 +#define ICON_FA_PRESCRIPTION_BOTTLE "\xef\x92\x85" // U+f485 +#define ICON_FA_PRESCRIPTION_BOTTLE_MEDICAL "\xef\x92\x86" // U+f486 +#define ICON_FA_PRINT "\xef\x80\xaf" // U+f02f +#define ICON_FA_PUMP_MEDICAL "\xee\x81\xaa" // U+e06a +#define ICON_FA_PUMP_SOAP "\xee\x81\xab" // U+e06b +#define ICON_FA_PUZZLE_PIECE "\xef\x84\xae" // U+f12e +#define ICON_FA_Q "Q" // U+0051 +#define ICON_FA_QRCODE "\xef\x80\xa9" // U+f029 +#define ICON_FA_QUESTION "?" // U+003f +#define ICON_FA_QUOTE_LEFT "\xef\x84\x8d" // U+f10d +#define ICON_FA_QUOTE_RIGHT "\xef\x84\x8e" // U+f10e +#define ICON_FA_R "R" // U+0052 +#define ICON_FA_RADIATION "\xef\x9e\xb9" // U+f7b9 +#define ICON_FA_RADIO "\xef\xa3\x97" // U+f8d7 +#define ICON_FA_RAINBOW "\xef\x9d\x9b" // U+f75b +#define ICON_FA_RANKING_STAR "\xee\x95\xa1" // U+e561 +#define ICON_FA_RECEIPT "\xef\x95\x83" // U+f543 +#define ICON_FA_RECORD_VINYL "\xef\xa3\x99" // U+f8d9 +#define ICON_FA_RECTANGLE_AD "\xef\x99\x81" // U+f641 +#define ICON_FA_RECTANGLE_LIST "\xef\x80\xa2" // U+f022 +#define ICON_FA_RECTANGLE_XMARK "\xef\x90\x90" // U+f410 +#define ICON_FA_RECYCLE "\xef\x86\xb8" // U+f1b8 +#define ICON_FA_REGISTERED "\xef\x89\x9d" // U+f25d +#define ICON_FA_REPEAT "\xef\x8d\xa3" // U+f363 +#define ICON_FA_REPLY "\xef\x8f\xa5" // U+f3e5 +#define ICON_FA_REPLY_ALL "\xef\x84\xa2" // U+f122 +#define ICON_FA_REPUBLICAN "\xef\x9d\x9e" // U+f75e +#define ICON_FA_RESTROOM "\xef\x9e\xbd" // U+f7bd +#define ICON_FA_RETWEET "\xef\x81\xb9" // U+f079 +#define ICON_FA_RIBBON "\xef\x93\x96" // U+f4d6 +#define ICON_FA_RIGHT_FROM_BRACKET "\xef\x8b\xb5" // U+f2f5 +#define ICON_FA_RIGHT_LEFT "\xef\x8d\xa2" // U+f362 +#define ICON_FA_RIGHT_LONG "\xef\x8c\x8b" // U+f30b +#define ICON_FA_RIGHT_TO_BRACKET "\xef\x8b\xb6" // U+f2f6 +#define ICON_FA_RING "\xef\x9c\x8b" // U+f70b +#define ICON_FA_ROAD "\xef\x80\x98" // U+f018 +#define ICON_FA_ROAD_BARRIER "\xee\x95\xa2" // U+e562 +#define ICON_FA_ROAD_BRIDGE "\xee\x95\xa3" // U+e563 +#define ICON_FA_ROAD_CIRCLE_CHECK "\xee\x95\xa4" // U+e564 +#define ICON_FA_ROAD_CIRCLE_EXCLAMATION "\xee\x95\xa5" // U+e565 +#define ICON_FA_ROAD_CIRCLE_XMARK "\xee\x95\xa6" // U+e566 +#define ICON_FA_ROAD_LOCK "\xee\x95\xa7" // U+e567 +#define ICON_FA_ROAD_SPIKES "\xee\x95\xa8" // U+e568 +#define ICON_FA_ROBOT "\xef\x95\x84" // U+f544 +#define ICON_FA_ROCKET "\xef\x84\xb5" // U+f135 +#define ICON_FA_ROTATE "\xef\x8b\xb1" // U+f2f1 +#define ICON_FA_ROTATE_LEFT "\xef\x8b\xaa" // U+f2ea +#define ICON_FA_ROTATE_RIGHT "\xef\x8b\xb9" // U+f2f9 +#define ICON_FA_ROUTE "\xef\x93\x97" // U+f4d7 +#define ICON_FA_RSS "\xef\x82\x9e" // U+f09e +#define ICON_FA_RUBLE_SIGN "\xef\x85\x98" // U+f158 +#define ICON_FA_RUG "\xee\x95\xa9" // U+e569 +#define ICON_FA_RULER "\xef\x95\x85" // U+f545 +#define ICON_FA_RULER_COMBINED "\xef\x95\x86" // U+f546 +#define ICON_FA_RULER_HORIZONTAL "\xef\x95\x87" // U+f547 +#define ICON_FA_RULER_VERTICAL "\xef\x95\x88" // U+f548 +#define ICON_FA_RUPEE_SIGN "\xef\x85\x96" // U+f156 +#define ICON_FA_RUPIAH_SIGN "\xee\x88\xbd" // U+e23d +#define ICON_FA_S "S" // U+0053 +#define ICON_FA_SACK_DOLLAR "\xef\xa0\x9d" // U+f81d +#define ICON_FA_SACK_XMARK "\xee\x95\xaa" // U+e56a +#define ICON_FA_SAILBOAT "\xee\x91\x85" // U+e445 +#define ICON_FA_SATELLITE "\xef\x9e\xbf" // U+f7bf +#define ICON_FA_SATELLITE_DISH "\xef\x9f\x80" // U+f7c0 +#define ICON_FA_SCALE_BALANCED "\xef\x89\x8e" // U+f24e +#define ICON_FA_SCALE_UNBALANCED "\xef\x94\x95" // U+f515 +#define ICON_FA_SCALE_UNBALANCED_FLIP "\xef\x94\x96" // U+f516 +#define ICON_FA_SCHOOL "\xef\x95\x89" // U+f549 +#define ICON_FA_SCHOOL_CIRCLE_CHECK "\xee\x95\xab" // U+e56b +#define ICON_FA_SCHOOL_CIRCLE_EXCLAMATION "\xee\x95\xac" // U+e56c +#define ICON_FA_SCHOOL_CIRCLE_XMARK "\xee\x95\xad" // U+e56d +#define ICON_FA_SCHOOL_FLAG "\xee\x95\xae" // U+e56e +#define ICON_FA_SCHOOL_LOCK "\xee\x95\xaf" // U+e56f +#define ICON_FA_SCISSORS "\xef\x83\x84" // U+f0c4 +#define ICON_FA_SCREWDRIVER "\xef\x95\x8a" // U+f54a +#define ICON_FA_SCREWDRIVER_WRENCH "\xef\x9f\x99" // U+f7d9 +#define ICON_FA_SCROLL "\xef\x9c\x8e" // U+f70e +#define ICON_FA_SCROLL_TORAH "\xef\x9a\xa0" // U+f6a0 +#define ICON_FA_SD_CARD "\xef\x9f\x82" // U+f7c2 +#define ICON_FA_SECTION "\xee\x91\x87" // U+e447 +#define ICON_FA_SEEDLING "\xef\x93\x98" // U+f4d8 +#define ICON_FA_SERVER "\xef\x88\xb3" // U+f233 +#define ICON_FA_SHAPES "\xef\x98\x9f" // U+f61f +#define ICON_FA_SHARE "\xef\x81\xa4" // U+f064 +#define ICON_FA_SHARE_FROM_SQUARE "\xef\x85\x8d" // U+f14d +#define ICON_FA_SHARE_NODES "\xef\x87\xa0" // U+f1e0 +#define ICON_FA_SHEET_PLASTIC "\xee\x95\xb1" // U+e571 +#define ICON_FA_SHEKEL_SIGN "\xef\x88\x8b" // U+f20b +#define ICON_FA_SHIELD "\xef\x84\xb2" // U+f132 +#define ICON_FA_SHIELD_CAT "\xee\x95\xb2" // U+e572 +#define ICON_FA_SHIELD_DOG "\xee\x95\xb3" // U+e573 +#define ICON_FA_SHIELD_HALVED "\xef\x8f\xad" // U+f3ed +#define ICON_FA_SHIELD_HEART "\xee\x95\xb4" // U+e574 +#define ICON_FA_SHIELD_VIRUS "\xee\x81\xac" // U+e06c +#define ICON_FA_SHIP "\xef\x88\x9a" // U+f21a +#define ICON_FA_SHIRT "\xef\x95\x93" // U+f553 +#define ICON_FA_SHOE_PRINTS "\xef\x95\x8b" // U+f54b +#define ICON_FA_SHOP "\xef\x95\x8f" // U+f54f +#define ICON_FA_SHOP_LOCK "\xee\x92\xa5" // U+e4a5 +#define ICON_FA_SHOP_SLASH "\xee\x81\xb0" // U+e070 +#define ICON_FA_SHOWER "\xef\x8b\x8c" // U+f2cc +#define ICON_FA_SHRIMP "\xee\x91\x88" // U+e448 +#define ICON_FA_SHUFFLE "\xef\x81\xb4" // U+f074 +#define ICON_FA_SHUTTLE_SPACE "\xef\x86\x97" // U+f197 +#define ICON_FA_SIGN_HANGING "\xef\x93\x99" // U+f4d9 +#define ICON_FA_SIGNAL "\xef\x80\x92" // U+f012 +#define ICON_FA_SIGNATURE "\xef\x96\xb7" // U+f5b7 +#define ICON_FA_SIGNS_POST "\xef\x89\xb7" // U+f277 +#define ICON_FA_SIM_CARD "\xef\x9f\x84" // U+f7c4 +#define ICON_FA_SINK "\xee\x81\xad" // U+e06d +#define ICON_FA_SITEMAP "\xef\x83\xa8" // U+f0e8 +#define ICON_FA_SKULL "\xef\x95\x8c" // U+f54c +#define ICON_FA_SKULL_CROSSBONES "\xef\x9c\x94" // U+f714 +#define ICON_FA_SLASH "\xef\x9c\x95" // U+f715 +#define ICON_FA_SLEIGH "\xef\x9f\x8c" // U+f7cc +#define ICON_FA_SLIDERS "\xef\x87\x9e" // U+f1de +#define ICON_FA_SMOG "\xef\x9d\x9f" // U+f75f +#define ICON_FA_SMOKING "\xef\x92\x8d" // U+f48d +#define ICON_FA_SNOWFLAKE "\xef\x8b\x9c" // U+f2dc +#define ICON_FA_SNOWMAN "\xef\x9f\x90" // U+f7d0 +#define ICON_FA_SNOWPLOW "\xef\x9f\x92" // U+f7d2 +#define ICON_FA_SOAP "\xee\x81\xae" // U+e06e +#define ICON_FA_SOCKS "\xef\x9a\x96" // U+f696 +#define ICON_FA_SOLAR_PANEL "\xef\x96\xba" // U+f5ba +#define ICON_FA_SORT "\xef\x83\x9c" // U+f0dc +#define ICON_FA_SORT_DOWN "\xef\x83\x9d" // U+f0dd +#define ICON_FA_SORT_UP "\xef\x83\x9e" // U+f0de +#define ICON_FA_SPA "\xef\x96\xbb" // U+f5bb +#define ICON_FA_SPAGHETTI_MONSTER_FLYING "\xef\x99\xbb" // U+f67b +#define ICON_FA_SPELL_CHECK "\xef\xa2\x91" // U+f891 +#define ICON_FA_SPIDER "\xef\x9c\x97" // U+f717 +#define ICON_FA_SPINNER "\xef\x84\x90" // U+f110 +#define ICON_FA_SPLOTCH "\xef\x96\xbc" // U+f5bc +#define ICON_FA_SPOON "\xef\x8b\xa5" // U+f2e5 +#define ICON_FA_SPRAY_CAN "\xef\x96\xbd" // U+f5bd +#define ICON_FA_SPRAY_CAN_SPARKLES "\xef\x97\x90" // U+f5d0 +#define ICON_FA_SQUARE "\xef\x83\x88" // U+f0c8 +#define ICON_FA_SQUARE_ARROW_UP_RIGHT "\xef\x85\x8c" // U+f14c +#define ICON_FA_SQUARE_CARET_DOWN "\xef\x85\x90" // U+f150 +#define ICON_FA_SQUARE_CARET_LEFT "\xef\x86\x91" // U+f191 +#define ICON_FA_SQUARE_CARET_RIGHT "\xef\x85\x92" // U+f152 +#define ICON_FA_SQUARE_CARET_UP "\xef\x85\x91" // U+f151 +#define ICON_FA_SQUARE_CHECK "\xef\x85\x8a" // U+f14a +#define ICON_FA_SQUARE_ENVELOPE "\xef\x86\x99" // U+f199 +#define ICON_FA_SQUARE_FULL "\xef\x91\x9c" // U+f45c +#define ICON_FA_SQUARE_H "\xef\x83\xbd" // U+f0fd +#define ICON_FA_SQUARE_MINUS "\xef\x85\x86" // U+f146 +#define ICON_FA_SQUARE_NFI "\xee\x95\xb6" // U+e576 +#define ICON_FA_SQUARE_PARKING "\xef\x95\x80" // U+f540 +#define ICON_FA_SQUARE_PEN "\xef\x85\x8b" // U+f14b +#define ICON_FA_SQUARE_PERSON_CONFINED "\xee\x95\xb7" // U+e577 +#define ICON_FA_SQUARE_PHONE "\xef\x82\x98" // U+f098 +#define ICON_FA_SQUARE_PHONE_FLIP "\xef\xa1\xbb" // U+f87b +#define ICON_FA_SQUARE_PLUS "\xef\x83\xbe" // U+f0fe +#define ICON_FA_SQUARE_POLL_HORIZONTAL "\xef\x9a\x82" // U+f682 +#define ICON_FA_SQUARE_POLL_VERTICAL "\xef\x9a\x81" // U+f681 +#define ICON_FA_SQUARE_ROOT_VARIABLE "\xef\x9a\x98" // U+f698 +#define ICON_FA_SQUARE_RSS "\xef\x85\x83" // U+f143 +#define ICON_FA_SQUARE_SHARE_NODES "\xef\x87\xa1" // U+f1e1 +#define ICON_FA_SQUARE_UP_RIGHT "\xef\x8d\xa0" // U+f360 +#define ICON_FA_SQUARE_VIRUS "\xee\x95\xb8" // U+e578 +#define ICON_FA_SQUARE_XMARK "\xef\x8b\x93" // U+f2d3 +#define ICON_FA_STAFF_SNAKE "\xee\x95\xb9" // U+e579 +#define ICON_FA_STAIRS "\xee\x8a\x89" // U+e289 +#define ICON_FA_STAMP "\xef\x96\xbf" // U+f5bf +#define ICON_FA_STAPLER "\xee\x96\xaf" // U+e5af +#define ICON_FA_STAR "\xef\x80\x85" // U+f005 +#define ICON_FA_STAR_AND_CRESCENT "\xef\x9a\x99" // U+f699 +#define ICON_FA_STAR_HALF "\xef\x82\x89" // U+f089 +#define ICON_FA_STAR_HALF_STROKE "\xef\x97\x80" // U+f5c0 +#define ICON_FA_STAR_OF_DAVID "\xef\x9a\x9a" // U+f69a +#define ICON_FA_STAR_OF_LIFE "\xef\x98\xa1" // U+f621 +#define ICON_FA_STERLING_SIGN "\xef\x85\x94" // U+f154 +#define ICON_FA_STETHOSCOPE "\xef\x83\xb1" // U+f0f1 +#define ICON_FA_STOP "\xef\x81\x8d" // U+f04d +#define ICON_FA_STOPWATCH "\xef\x8b\xb2" // U+f2f2 +#define ICON_FA_STOPWATCH_20 "\xee\x81\xaf" // U+e06f +#define ICON_FA_STORE "\xef\x95\x8e" // U+f54e +#define ICON_FA_STORE_SLASH "\xee\x81\xb1" // U+e071 +#define ICON_FA_STREET_VIEW "\xef\x88\x9d" // U+f21d +#define ICON_FA_STRIKETHROUGH "\xef\x83\x8c" // U+f0cc +#define ICON_FA_STROOPWAFEL "\xef\x95\x91" // U+f551 +#define ICON_FA_SUBSCRIPT "\xef\x84\xac" // U+f12c +#define ICON_FA_SUITCASE "\xef\x83\xb2" // U+f0f2 +#define ICON_FA_SUITCASE_MEDICAL "\xef\x83\xba" // U+f0fa +#define ICON_FA_SUITCASE_ROLLING "\xef\x97\x81" // U+f5c1 +#define ICON_FA_SUN "\xef\x86\x85" // U+f185 +#define ICON_FA_SUN_PLANT_WILT "\xee\x95\xba" // U+e57a +#define ICON_FA_SUPERSCRIPT "\xef\x84\xab" // U+f12b +#define ICON_FA_SWATCHBOOK "\xef\x97\x83" // U+f5c3 +#define ICON_FA_SYNAGOGUE "\xef\x9a\x9b" // U+f69b +#define ICON_FA_SYRINGE "\xef\x92\x8e" // U+f48e +#define ICON_FA_T "T" // U+0054 +#define ICON_FA_TABLE "\xef\x83\x8e" // U+f0ce +#define ICON_FA_TABLE_CELLS "\xef\x80\x8a" // U+f00a +#define ICON_FA_TABLE_CELLS_LARGE "\xef\x80\x89" // U+f009 +#define ICON_FA_TABLE_COLUMNS "\xef\x83\x9b" // U+f0db +#define ICON_FA_TABLE_LIST "\xef\x80\x8b" // U+f00b +#define ICON_FA_TABLE_TENNIS_PADDLE_BALL "\xef\x91\x9d" // U+f45d +#define ICON_FA_TABLET "\xef\x8f\xbb" // U+f3fb +#define ICON_FA_TABLET_BUTTON "\xef\x84\x8a" // U+f10a +#define ICON_FA_TABLET_SCREEN_BUTTON "\xef\x8f\xba" // U+f3fa +#define ICON_FA_TABLETS "\xef\x92\x90" // U+f490 +#define ICON_FA_TACHOGRAPH_DIGITAL "\xef\x95\xa6" // U+f566 +#define ICON_FA_TAG "\xef\x80\xab" // U+f02b +#define ICON_FA_TAGS "\xef\x80\xac" // U+f02c +#define ICON_FA_TAPE "\xef\x93\x9b" // U+f4db +#define ICON_FA_TARP "\xee\x95\xbb" // U+e57b +#define ICON_FA_TARP_DROPLET "\xee\x95\xbc" // U+e57c +#define ICON_FA_TAXI "\xef\x86\xba" // U+f1ba +#define ICON_FA_TEETH "\xef\x98\xae" // U+f62e +#define ICON_FA_TEETH_OPEN "\xef\x98\xaf" // U+f62f +#define ICON_FA_TEMPERATURE_ARROW_DOWN "\xee\x80\xbf" // U+e03f +#define ICON_FA_TEMPERATURE_ARROW_UP "\xee\x81\x80" // U+e040 +#define ICON_FA_TEMPERATURE_EMPTY "\xef\x8b\x8b" // U+f2cb +#define ICON_FA_TEMPERATURE_FULL "\xef\x8b\x87" // U+f2c7 +#define ICON_FA_TEMPERATURE_HALF "\xef\x8b\x89" // U+f2c9 +#define ICON_FA_TEMPERATURE_HIGH "\xef\x9d\xa9" // U+f769 +#define ICON_FA_TEMPERATURE_LOW "\xef\x9d\xab" // U+f76b +#define ICON_FA_TEMPERATURE_QUARTER "\xef\x8b\x8a" // U+f2ca +#define ICON_FA_TEMPERATURE_THREE_QUARTERS "\xef\x8b\x88" // U+f2c8 +#define ICON_FA_TENGE_SIGN "\xef\x9f\x97" // U+f7d7 +#define ICON_FA_TENT "\xee\x95\xbd" // U+e57d +#define ICON_FA_TENT_ARROW_DOWN_TO_LINE "\xee\x95\xbe" // U+e57e +#define ICON_FA_TENT_ARROW_LEFT_RIGHT "\xee\x95\xbf" // U+e57f +#define ICON_FA_TENT_ARROW_TURN_LEFT "\xee\x96\x80" // U+e580 +#define ICON_FA_TENT_ARROWS_DOWN "\xee\x96\x81" // U+e581 +#define ICON_FA_TENTS "\xee\x96\x82" // U+e582 +#define ICON_FA_TERMINAL "\xef\x84\xa0" // U+f120 +#define ICON_FA_TEXT_HEIGHT "\xef\x80\xb4" // U+f034 +#define ICON_FA_TEXT_SLASH "\xef\xa1\xbd" // U+f87d +#define ICON_FA_TEXT_WIDTH "\xef\x80\xb5" // U+f035 +#define ICON_FA_THERMOMETER "\xef\x92\x91" // U+f491 +#define ICON_FA_THUMBS_DOWN "\xef\x85\xa5" // U+f165 +#define ICON_FA_THUMBS_UP "\xef\x85\xa4" // U+f164 +#define ICON_FA_THUMBTACK "\xef\x82\x8d" // U+f08d +#define ICON_FA_TICKET "\xef\x85\x85" // U+f145 +#define ICON_FA_TICKET_SIMPLE "\xef\x8f\xbf" // U+f3ff +#define ICON_FA_TIMELINE "\xee\x8a\x9c" // U+e29c +#define ICON_FA_TOGGLE_OFF "\xef\x88\x84" // U+f204 +#define ICON_FA_TOGGLE_ON "\xef\x88\x85" // U+f205 +#define ICON_FA_TOILET "\xef\x9f\x98" // U+f7d8 +#define ICON_FA_TOILET_PAPER "\xef\x9c\x9e" // U+f71e +#define ICON_FA_TOILET_PAPER_SLASH "\xee\x81\xb2" // U+e072 +#define ICON_FA_TOILET_PORTABLE "\xee\x96\x83" // U+e583 +#define ICON_FA_TOILETS_PORTABLE "\xee\x96\x84" // U+e584 +#define ICON_FA_TOOLBOX "\xef\x95\x92" // U+f552 +#define ICON_FA_TOOTH "\xef\x97\x89" // U+f5c9 +#define ICON_FA_TORII_GATE "\xef\x9a\xa1" // U+f6a1 +#define ICON_FA_TORNADO "\xef\x9d\xaf" // U+f76f +#define ICON_FA_TOWER_BROADCAST "\xef\x94\x99" // U+f519 +#define ICON_FA_TOWER_CELL "\xee\x96\x85" // U+e585 +#define ICON_FA_TOWER_OBSERVATION "\xee\x96\x86" // U+e586 +#define ICON_FA_TRACTOR "\xef\x9c\xa2" // U+f722 +#define ICON_FA_TRADEMARK "\xef\x89\x9c" // U+f25c +#define ICON_FA_TRAFFIC_LIGHT "\xef\x98\xb7" // U+f637 +#define ICON_FA_TRAILER "\xee\x81\x81" // U+e041 +#define ICON_FA_TRAIN "\xef\x88\xb8" // U+f238 +#define ICON_FA_TRAIN_SUBWAY "\xef\x88\xb9" // U+f239 +#define ICON_FA_TRAIN_TRAM "\xee\x96\xb4" // U+e5b4 +#define ICON_FA_TRANSGENDER "\xef\x88\xa5" // U+f225 +#define ICON_FA_TRASH "\xef\x87\xb8" // U+f1f8 +#define ICON_FA_TRASH_ARROW_UP "\xef\xa0\xa9" // U+f829 +#define ICON_FA_TRASH_CAN "\xef\x8b\xad" // U+f2ed +#define ICON_FA_TRASH_CAN_ARROW_UP "\xef\xa0\xaa" // U+f82a +#define ICON_FA_TREE "\xef\x86\xbb" // U+f1bb +#define ICON_FA_TREE_CITY "\xee\x96\x87" // U+e587 +#define ICON_FA_TRIANGLE_EXCLAMATION "\xef\x81\xb1" // U+f071 +#define ICON_FA_TROPHY "\xef\x82\x91" // U+f091 +#define ICON_FA_TROWEL "\xee\x96\x89" // U+e589 +#define ICON_FA_TROWEL_BRICKS "\xee\x96\x8a" // U+e58a +#define ICON_FA_TRUCK "\xef\x83\x91" // U+f0d1 +#define ICON_FA_TRUCK_ARROW_RIGHT "\xee\x96\x8b" // U+e58b +#define ICON_FA_TRUCK_DROPLET "\xee\x96\x8c" // U+e58c +#define ICON_FA_TRUCK_FAST "\xef\x92\x8b" // U+f48b +#define ICON_FA_TRUCK_FIELD "\xee\x96\x8d" // U+e58d +#define ICON_FA_TRUCK_FIELD_UN "\xee\x96\x8e" // U+e58e +#define ICON_FA_TRUCK_FRONT "\xee\x8a\xb7" // U+e2b7 +#define ICON_FA_TRUCK_MEDICAL "\xef\x83\xb9" // U+f0f9 +#define ICON_FA_TRUCK_MONSTER "\xef\x98\xbb" // U+f63b +#define ICON_FA_TRUCK_MOVING "\xef\x93\x9f" // U+f4df +#define ICON_FA_TRUCK_PICKUP "\xef\x98\xbc" // U+f63c +#define ICON_FA_TRUCK_PLANE "\xee\x96\x8f" // U+e58f +#define ICON_FA_TRUCK_RAMP_BOX "\xef\x93\x9e" // U+f4de +#define ICON_FA_TTY "\xef\x87\xa4" // U+f1e4 +#define ICON_FA_TURKISH_LIRA_SIGN "\xee\x8a\xbb" // U+e2bb +#define ICON_FA_TURN_DOWN "\xef\x8e\xbe" // U+f3be +#define ICON_FA_TURN_UP "\xef\x8e\xbf" // U+f3bf +#define ICON_FA_TV "\xef\x89\xac" // U+f26c +#define ICON_FA_U "U" // U+0055 +#define ICON_FA_UMBRELLA "\xef\x83\xa9" // U+f0e9 +#define ICON_FA_UMBRELLA_BEACH "\xef\x97\x8a" // U+f5ca +#define ICON_FA_UNDERLINE "\xef\x83\x8d" // U+f0cd +#define ICON_FA_UNIVERSAL_ACCESS "\xef\x8a\x9a" // U+f29a +#define ICON_FA_UNLOCK "\xef\x82\x9c" // U+f09c +#define ICON_FA_UNLOCK_KEYHOLE "\xef\x84\xbe" // U+f13e +#define ICON_FA_UP_DOWN "\xef\x8c\xb8" // U+f338 +#define ICON_FA_UP_DOWN_LEFT_RIGHT "\xef\x82\xb2" // U+f0b2 +#define ICON_FA_UP_LONG "\xef\x8c\x8c" // U+f30c +#define ICON_FA_UP_RIGHT_AND_DOWN_LEFT_FROM_CENTER "\xef\x90\xa4" // U+f424 +#define ICON_FA_UP_RIGHT_FROM_SQUARE "\xef\x8d\x9d" // U+f35d +#define ICON_FA_UPLOAD "\xef\x82\x93" // U+f093 +#define ICON_FA_USER "\xef\x80\x87" // U+f007 +#define ICON_FA_USER_ASTRONAUT "\xef\x93\xbb" // U+f4fb +#define ICON_FA_USER_CHECK "\xef\x93\xbc" // U+f4fc +#define ICON_FA_USER_CLOCK "\xef\x93\xbd" // U+f4fd +#define ICON_FA_USER_DOCTOR "\xef\x83\xb0" // U+f0f0 +#define ICON_FA_USER_GEAR "\xef\x93\xbe" // U+f4fe +#define ICON_FA_USER_GRADUATE "\xef\x94\x81" // U+f501 +#define ICON_FA_USER_GROUP "\xef\x94\x80" // U+f500 +#define ICON_FA_USER_INJURED "\xef\x9c\xa8" // U+f728 +#define ICON_FA_USER_LARGE "\xef\x90\x86" // U+f406 +#define ICON_FA_USER_LARGE_SLASH "\xef\x93\xba" // U+f4fa +#define ICON_FA_USER_LOCK "\xef\x94\x82" // U+f502 +#define ICON_FA_USER_MINUS "\xef\x94\x83" // U+f503 +#define ICON_FA_USER_NINJA "\xef\x94\x84" // U+f504 +#define ICON_FA_USER_NURSE "\xef\xa0\xaf" // U+f82f +#define ICON_FA_USER_PEN "\xef\x93\xbf" // U+f4ff +#define ICON_FA_USER_PLUS "\xef\x88\xb4" // U+f234 +#define ICON_FA_USER_SECRET "\xef\x88\x9b" // U+f21b +#define ICON_FA_USER_SHIELD "\xef\x94\x85" // U+f505 +#define ICON_FA_USER_SLASH "\xef\x94\x86" // U+f506 +#define ICON_FA_USER_TAG "\xef\x94\x87" // U+f507 +#define ICON_FA_USER_TIE "\xef\x94\x88" // U+f508 +#define ICON_FA_USER_XMARK "\xef\x88\xb5" // U+f235 +#define ICON_FA_USERS "\xef\x83\x80" // U+f0c0 +#define ICON_FA_USERS_BETWEEN_LINES "\xee\x96\x91" // U+e591 +#define ICON_FA_USERS_GEAR "\xef\x94\x89" // U+f509 +#define ICON_FA_USERS_LINE "\xee\x96\x92" // U+e592 +#define ICON_FA_USERS_RAYS "\xee\x96\x93" // U+e593 +#define ICON_FA_USERS_RECTANGLE "\xee\x96\x94" // U+e594 +#define ICON_FA_USERS_SLASH "\xee\x81\xb3" // U+e073 +#define ICON_FA_USERS_VIEWFINDER "\xee\x96\x95" // U+e595 +#define ICON_FA_UTENSILS "\xef\x8b\xa7" // U+f2e7 +#define ICON_FA_V "V" // U+0056 +#define ICON_FA_VAN_SHUTTLE "\xef\x96\xb6" // U+f5b6 +#define ICON_FA_VAULT "\xee\x8b\x85" // U+e2c5 +#define ICON_FA_VECTOR_SQUARE "\xef\x97\x8b" // U+f5cb +#define ICON_FA_VENUS "\xef\x88\xa1" // U+f221 +#define ICON_FA_VENUS_DOUBLE "\xef\x88\xa6" // U+f226 +#define ICON_FA_VENUS_MARS "\xef\x88\xa8" // U+f228 +#define ICON_FA_VEST "\xee\x82\x85" // U+e085 +#define ICON_FA_VEST_PATCHES "\xee\x82\x86" // U+e086 +#define ICON_FA_VIAL "\xef\x92\x92" // U+f492 +#define ICON_FA_VIAL_CIRCLE_CHECK "\xee\x96\x96" // U+e596 +#define ICON_FA_VIAL_VIRUS "\xee\x96\x97" // U+e597 +#define ICON_FA_VIALS "\xef\x92\x93" // U+f493 +#define ICON_FA_VIDEO "\xef\x80\xbd" // U+f03d +#define ICON_FA_VIDEO_SLASH "\xef\x93\xa2" // U+f4e2 +#define ICON_FA_VIHARA "\xef\x9a\xa7" // U+f6a7 +#define ICON_FA_VIRUS "\xee\x81\xb4" // U+e074 +#define ICON_FA_VIRUS_COVID "\xee\x92\xa8" // U+e4a8 +#define ICON_FA_VIRUS_COVID_SLASH "\xee\x92\xa9" // U+e4a9 +#define ICON_FA_VIRUS_SLASH "\xee\x81\xb5" // U+e075 +#define ICON_FA_VIRUSES "\xee\x81\xb6" // U+e076 +#define ICON_FA_VOICEMAIL "\xef\xa2\x97" // U+f897 +#define ICON_FA_VOLCANO "\xef\x9d\xb0" // U+f770 +#define ICON_FA_VOLLEYBALL "\xef\x91\x9f" // U+f45f +#define ICON_FA_VOLUME_HIGH "\xef\x80\xa8" // U+f028 +#define ICON_FA_VOLUME_LOW "\xef\x80\xa7" // U+f027 +#define ICON_FA_VOLUME_OFF "\xef\x80\xa6" // U+f026 +#define ICON_FA_VOLUME_XMARK "\xef\x9a\xa9" // U+f6a9 +#define ICON_FA_VR_CARDBOARD "\xef\x9c\xa9" // U+f729 +#define ICON_FA_W "W" // U+0057 +#define ICON_FA_WALKIE_TALKIE "\xef\xa3\xaf" // U+f8ef +#define ICON_FA_WALLET "\xef\x95\x95" // U+f555 +#define ICON_FA_WAND_MAGIC "\xef\x83\x90" // U+f0d0 +#define ICON_FA_WAND_MAGIC_SPARKLES "\xee\x8b\x8a" // U+e2ca +#define ICON_FA_WAND_SPARKLES "\xef\x9c\xab" // U+f72b +#define ICON_FA_WAREHOUSE "\xef\x92\x94" // U+f494 +#define ICON_FA_WATER "\xef\x9d\xb3" // U+f773 +#define ICON_FA_WATER_LADDER "\xef\x97\x85" // U+f5c5 +#define ICON_FA_WAVE_SQUARE "\xef\xa0\xbe" // U+f83e +#define ICON_FA_WEIGHT_HANGING "\xef\x97\x8d" // U+f5cd +#define ICON_FA_WEIGHT_SCALE "\xef\x92\x96" // U+f496 +#define ICON_FA_WHEAT_AWN "\xee\x8b\x8d" // U+e2cd +#define ICON_FA_WHEAT_AWN_CIRCLE_EXCLAMATION "\xee\x96\x98" // U+e598 +#define ICON_FA_WHEELCHAIR "\xef\x86\x93" // U+f193 +#define ICON_FA_WHEELCHAIR_MOVE "\xee\x8b\x8e" // U+e2ce +#define ICON_FA_WHISKEY_GLASS "\xef\x9e\xa0" // U+f7a0 +#define ICON_FA_WIFI "\xef\x87\xab" // U+f1eb +#define ICON_FA_WIND "\xef\x9c\xae" // U+f72e +#define ICON_FA_WINDOW_MAXIMIZE "\xef\x8b\x90" // U+f2d0 +#define ICON_FA_WINDOW_MINIMIZE "\xef\x8b\x91" // U+f2d1 +#define ICON_FA_WINDOW_RESTORE "\xef\x8b\x92" // U+f2d2 +#define ICON_FA_WINE_BOTTLE "\xef\x9c\xaf" // U+f72f +#define ICON_FA_WINE_GLASS "\xef\x93\xa3" // U+f4e3 +#define ICON_FA_WINE_GLASS_EMPTY "\xef\x97\x8e" // U+f5ce +#define ICON_FA_WON_SIGN "\xef\x85\x99" // U+f159 +#define ICON_FA_WORM "\xee\x96\x99" // U+e599 +#define ICON_FA_WRENCH "\xef\x82\xad" // U+f0ad +#define ICON_FA_X "X" // U+0058 +#define ICON_FA_X_RAY "\xef\x92\x97" // U+f497 +#define ICON_FA_XMARK "\xef\x80\x8d" // U+f00d +#define ICON_FA_XMARKS_LINES "\xee\x96\x9a" // U+e59a +#define ICON_FA_Y "Y" // U+0059 +#define ICON_FA_YEN_SIGN "\xef\x85\x97" // U+f157 +#define ICON_FA_YIN_YANG "\xef\x9a\xad" // U+f6ad +#define ICON_FA_Z "Z" // U+005a \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index 6b3c3a93..aff1eaad 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -4,6 +4,7 @@ #include "SHpch.h" #include "IconsMaterialDesign.h" +#include "IconsFontAwesome6.h" #include "DragDrop/SHDragDrop.hpp" //#==============================================================# @@ -36,6 +37,7 @@ #include #include #include +#include //#==============================================================# //|| ImGui Backend Includes || @@ -87,10 +89,10 @@ namespace SHADE //Add editor windows SHEditorWindowManager::CreateEditorWindow(); - SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); io = &ImGui::GetIO(); @@ -98,7 +100,7 @@ namespace SHADE io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking io->IniFilename = "../../Assets/Editor/Layouts/UserLayout.ini"; - + io->ConfigWindowsMoveFromTitleBarOnly = true; InitLayout(); InitFonts(); @@ -127,9 +129,13 @@ namespace SHADE for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values) { if(window->isOpen) + { window->Update(); + } } + PollPicking(); + if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z)) { SHCommandManager::RedoCommand(); @@ -165,10 +171,11 @@ namespace SHADE { ImFont* mainFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path - constexpr ImWchar icon_ranges[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 }; ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f; - ImFont* UIFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges); //TODO: Change to config based assets path - + constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; + ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/fa-solid-900.ttf", 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path + constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_MD, 0 }; + ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path io->Fonts->Build(); } @@ -338,7 +345,7 @@ namespace SHADE if (auto gfxSystem = SHSystemManager::GetSystem()) { auto viewportWindow = SHEditorWindowManager::GetEditorWindow(); - if (viewportWindow->isWindowHovered && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + if (viewportWindow->isWindowHovered && !viewportWindow->transformGizmo.isManipulating && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) { EntityID pickedEID = gfxSystem->GetMousePickSystem()->GetPickedEntity(); if(pickedEID == MAX_EID) @@ -366,6 +373,7 @@ namespace SHADE ImGui_ImplVulkan_NewFrame(); ImGui_ImplSDL2_NewFrame(); ImGui::NewFrame(); + ImGuizmo::BeginFrame(); } diff --git a/SHADE_Engine/src/Editor/SHEditor.hpp b/SHADE_Engine/src/Editor/SHEditor.hpp index baa6324e..34405390 100644 --- a/SHADE_Engine/src/Editor/SHEditor.hpp +++ b/SHADE_Engine/src/Editor/SHEditor.hpp @@ -13,9 +13,11 @@ #include "ECS_Base/SHECSMacros.h" #include "ECS_Base/System/SHSystem.h" #include "ECS_Base/System/SHSystemRoutine.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include "EditorWindow/SHEditorWindow.h" #include "Tools/SHLogger.h" +#include "Gizmos/SHTransformGizmo.h" + //#==============================================================# //|| Library Includes || @@ -200,5 +202,7 @@ namespace SHADE SDL_Window* sdlWindow {nullptr}; ImGuiIO* io{nullptr}; + + //SHTransformGizmo transformGizmo; };//class SHEditor }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/SHImGuiHelpers.hpp b/SHADE_Engine/src/Editor/SHImGuiHelpers.hpp index 66eeb8c4..0c7c1ecf 100644 --- a/SHADE_Engine/src/Editor/SHImGuiHelpers.hpp +++ b/SHADE_Engine/src/Editor/SHImGuiHelpers.hpp @@ -15,7 +15,7 @@ //#==============================================================# #ifndef SH_IM_MATH #define IM_VEC2_CLASS_EXTRA \ - ImVec2(const SHADE::SHVec2& vec) {x = vec.x; y = vec.y;} \ + ImVec2(const SHADE::SHVec2& vec) {x = vec.x; y = vec.y;} \ operator SHADE::SHVec2() const {return SHADE::SHVec2(x,y);} #define IM_VEC3_CLASS_EXTRA \ ImVec3(const SHADE::SHVec3& vec) {x = vec.x; y = vec.y; z = vec.z;} \ @@ -43,6 +43,10 @@ namespace SHADE constexpr ImVec4 blue = {0.0f, 0.0f, 1.0f, 1.f}; constexpr ImVec4 white = {1.0f, 1.0f, 1.0f, 1.f}; + constexpr int colors_red = 0; + constexpr int colors_green = 1; + constexpr int colors_blue = 2; + constexpr int colors_white = 3; constexpr ImU32 colors[] = { 0xBB0000FF, // red 0xBB00FF00, // green diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h index e931fec5..aeda7d18 100644 --- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h +++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h @@ -3,7 +3,7 @@ #include "Graphics/SHVulkanIncludes.h" #include "vk_mem_alloc.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" namespace SHADE { diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h index 70a209ee..4c978c34 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h @@ -4,7 +4,7 @@ #include "Graphics/SHVulkanIncludes.h" #include "Graphics/SHVulkanDefines.h" #include "SHCommandPoolResetMode.h" -#include "Resource/ResourceLibrary.h" +#include "Resource/SHResourceLibrary.h" #include "Graphics/Pipeline/SHVkPipelineLayout.h" #include "Graphics/Pipeline/SHPipelineType.h" @@ -37,7 +37,7 @@ namespace SHADE class SHVkCommandBuffer { friend class SHVkCommandPool; - friend class ResourceLibrary; + friend class SHResourceLibrary; static constexpr uint16_t PUSH_CONSTANT_SIZE = 512; diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandPool.cpp b/SHADE_Engine/src/Graphics/Commands/SHVkCommandPool.cpp index e1470898..375ece4d 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandPool.cpp +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandPool.cpp @@ -2,7 +2,7 @@ #include "SHVkCommandPool.h" #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Instance/SHVkInstance.h" -#include "Resource/ResourceLibrary.h" +#include "Resource/SHResourceLibrary.h" #include "Tools/SHLogger.h" namespace SHADE diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandPool.h b/SHADE_Engine/src/Graphics/Commands/SHVkCommandPool.h index 2bb290a7..fcc0ce41 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandPool.h +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandPool.h @@ -6,7 +6,7 @@ #include "Graphics/Queues/SHVkQueue.h" #include "SHCommandPoolResetMode.h" #include "SHVkCommandBuffer.h" -#include "Resource/ResourceLibrary.h" +#include "Resource/SHResourceLibrary.h" namespace SHADE { diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h index 9a533d06..c822829a 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h @@ -2,7 +2,7 @@ // Project Includes #include "Graphics/SHVulkanIncludes.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" namespace SHADE { diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h index 85c3ef97..3f42afcc 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h @@ -4,7 +4,7 @@ // Project Includes #include "Graphics/SHVulkanIncludes.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include "Graphics/Shaders/SHShaderReflected.h" #include "SHDescriptorSetUpdater.h" diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h index 4fffbc96..1639901d 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h @@ -2,7 +2,7 @@ // Project Includes #include "Graphics/SHVulkanIncludes.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" namespace SHADE { diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h index 58d8b398..2aa59941 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h @@ -8,8 +8,8 @@ #include "Graphics/SHVulkanIncludes.h" #include "Graphics/Devices/SHVkPhysicalDevice.h" #include "Graphics/Queues/SHVkQueue.h" -#include "Resource/Handle.h" -#include "Resource/ResourceLibrary.h" +#include "Resource/SHHandle.h" +#include "Resource/SHResourceLibrary.h" #include "Graphics/Swapchain/SHSwapchainParams.h" #include "Graphics/Commands/SHCommandPoolResetMode.h" #include "Graphics/Commands/SHVkCommandPool.h" diff --git a/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.h b/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.h index 47bfcf99..4a02408c 100644 --- a/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.h +++ b/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.h @@ -2,7 +2,7 @@ #define SH_VK_FRAMEBUFFER_H #include "Graphics/SHVulkanIncludes.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include namespace SHADE diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.h b/SHADE_Engine/src/Graphics/Images/SHVkImage.h index 51b71b26..4fb16017 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImage.h +++ b/SHADE_Engine/src/Graphics/Images/SHVkImage.h @@ -3,7 +3,7 @@ #include "SHImageViewDetails.h" #include "Graphics/SHVulkanDefines.h" -#include "Resource/ResourceLibrary.h" +#include "Resource/SHResourceLibrary.h" #include "vk_mem_alloc.h" namespace SHADE diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImageView.h b/SHADE_Engine/src/Graphics/Images/SHVkImageView.h index ae23d7a7..79bb5dca 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImageView.h +++ b/SHADE_Engine/src/Graphics/Images/SHVkImageView.h @@ -2,7 +2,7 @@ #define SH_VK_IMAGE_VIEW_H #include "Graphics/SHVulkanIncludes.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include "SHImageViewDetails.h" namespace SHADE diff --git a/SHADE_Engine/src/Graphics/Images/SHVkSampler.h b/SHADE_Engine/src/Graphics/Images/SHVkSampler.h index bb878a69..3a989553 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkSampler.h +++ b/SHADE_Engine/src/Graphics/Images/SHVkSampler.h @@ -15,7 +15,7 @@ of DigiPen Institute of Technology is prohibited. #include // Project Includes #include "Graphics/SHVulkanIncludes.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" namespace SHADE { diff --git a/SHADE_Engine/src/Graphics/Instance/SHVkInstance.cpp b/SHADE_Engine/src/Graphics/Instance/SHVkInstance.cpp index 6688f9a6..191bc563 100644 --- a/SHADE_Engine/src/Graphics/Instance/SHVkInstance.cpp +++ b/SHADE_Engine/src/Graphics/Instance/SHVkInstance.cpp @@ -15,7 +15,7 @@ namespace SHADE bool SHVkInstance::validationLayersOn; vk::Instance SHVkInstance::vkInstance; SHVkDebugMessenger SHVkInstance::debugMessenger; - ResourceManager SHVkInstance::resourceManager; + SHResourceHub SHVkInstance::resourceManager; /***************************************************************************/ /*! @@ -258,7 +258,7 @@ namespace SHADE return vkInstance; } - ResourceManager& SHVkInstance::GetResourceManager(void) noexcept + SHResourceHub& SHVkInstance::GetResourceManager(void) noexcept { return resourceManager; } diff --git a/SHADE_Engine/src/Graphics/Instance/SHVkInstance.h b/SHADE_Engine/src/Graphics/Instance/SHVkInstance.h index a6fb4f0f..55adc774 100644 --- a/SHADE_Engine/src/Graphics/Instance/SHVkInstance.h +++ b/SHADE_Engine/src/Graphics/Instance/SHVkInstance.h @@ -18,7 +18,7 @@ written consent of DigiPen Institute of Technology is prohibited. #include "Graphics/Debugging/SHVkDebugMessenger.h" #include "Graphics/Devices/SHVkPhysicalDevice.h" #include "Graphics/Devices/SHVkLogicalDevice.h" -#include "Resource/ResourceLibrary.h" +#include "Resource/SHResourceLibrary.h" namespace SHADE @@ -61,7 +61,7 @@ namespace SHADE static SHVkDebugMessenger debugMessenger; //! Resource management for vulkan project - static ResourceManager resourceManager; + static SHResourceHub resourceManager; /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ @@ -85,7 +85,7 @@ namespace SHADE /* Getters and Setters */ /*-----------------------------------------------------------------------*/ static vk::Instance const& GetVkInstance (void) noexcept; - static ResourceManager& GetResourceManager(void) noexcept; + static SHResourceHub& GetResourceManager(void) noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h index 37c57396..193fff0d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h @@ -18,7 +18,7 @@ of DigiPen Institute of Technology is prohibited. // External Dependencies #include "Graphics/SHVulkanIncludes.h" // Project Includes -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include "Graphics/MiddleEnd/Interface/SHMaterial.h" #include "Math/SHMatrix.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h index 8074899d..f299906c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h @@ -15,7 +15,7 @@ of DigiPen Institute of Technology is prohibited. // STL Includes #include // Project Includes -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" namespace SHADE { diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h index 9743e7dc..9877e04e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h @@ -15,7 +15,7 @@ of DigiPen Institute of Technology is prohibited. // External Dependencies #include "Graphics/SHVulkanIncludes.h" // Project Includes -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include "SHBatch.h" #include "Graphics/Pipeline/SHVkPipeline.h" diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index cbf3ad95..0de5af17 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -172,16 +172,16 @@ namespace SHADE // Initialize world render graph worldRenderGraph->Init(device, swapchain); - worldRenderGraph->AddResource("Scene Pre Postprocess", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second); + worldRenderGraph->AddResource("Scene Pre-Process", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second); worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second); worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); - auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene", "Scene Pre Postprocess"}, {}); // no predecessors + auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene", "Scene Pre-Process"}, {}); // no predecessors //First subpass to write to G-Buffer auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write"); - gBufferWriteSubpass->AddColorOutput("Scene Pre Postprocess"); + gBufferWriteSubpass->AddColorOutput("Scene Pre-Process"); gBufferWriteSubpass->AddColorOutput("Entity ID"); gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); @@ -190,7 +190,7 @@ namespace SHADE //sceneLayoutTransitionSubpass->AddGeneralInput("Scene"); auto greyscale = shaderModuleLibrary.GetShaderModule("KirschCs.glsl"); - node->AddNodeCompute (greyscale, {"Scene Pre Postprocess", "Scene"}); + node->AddNodeCompute (greyscale, {"Scene Pre-Process", "Scene"}); // Generate world render graph worldRenderGraph->Generate(); @@ -601,19 +601,19 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Texture Registration Functions */ /*---------------------------------------------------------------------------------*/ - Handle SHGraphicsSystem::Add(const SHTextureAsset& texAsset) + Handle SHGraphicsSystem::AddTexture(const SHTextureAsset& texAsset) { auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams { .maxLod = static_cast(texAsset.mipOffsets.size()) }); return texLibrary.Add(texAsset, sampler); } - SHADE::Handle SHGraphicsSystem::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector mipOffsets) + SHADE::Handle SHGraphicsSystem::AddTexture(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector mipOffsets) { auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams{ .maxLod = static_cast(mipOffsets.size()) }); return texLibrary.Add(pixelCount, pixelData, width, height, format, mipOffsets, sampler); } - void SHGraphicsSystem::Remove(Handle tex) + void SHGraphicsSystem::RemoveTexture(Handle tex) { texLibrary.Remove(tex); } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 7d0fa3ab..870325ac 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -17,7 +17,7 @@ of DigiPen Institute of Technology is prohibited. #include // Project Includes -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include "Graphics/SHVulkanIncludes.h" #include "Graphics/MiddleEnd/PerFrame/SHRenderContext.h" #include "Graphics/RenderGraph/SHRenderGraph.h" @@ -231,8 +231,8 @@ namespace SHADE */ /*******************************************************************************/ - Handle Add(const SHTextureAsset& texAsset); - Handle Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector mipOffsets); + Handle AddTexture(const SHTextureAsset& texAsset); + Handle AddTexture(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector mipOffsets); /*******************************************************************************/ /*! @@ -246,7 +246,7 @@ namespace SHADE */ /*******************************************************************************/ - void Remove(Handle tex); + void RemoveTexture(Handle tex); /***************************************************************************/ /*! @@ -313,7 +313,7 @@ namespace SHADE SHWindow* window = nullptr; // Middle End Resources - ResourceManager resourceManager; + SHResourceHub resourceManager; SHMeshLibrary meshLibrary; SHTextureLibrary texLibrary; SHSamplerCache samplerCache; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h index 348efb07..ec546fd5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h @@ -15,7 +15,7 @@ of DigiPen Institute of Technology is prohibited. // STL Includes #include // Project Includes -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include "SHCommonTypes.h" namespace SHADE diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h index d111acb9..b6fcc830 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h @@ -13,7 +13,7 @@ of DigiPen Institute of Technology is prohibited. // STL Includes #include // Project Includes -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include "Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h" #include "SH_API.h" diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.h index e9923385..72ac1878 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.h @@ -15,8 +15,8 @@ of DigiPen Institute of Technology is prohibited. // STL Includes #include // Project Includes -#include "Resource/Handle.h" -#include "Resource/ResourceLibrary.h" +#include "Resource/SHHandle.h" +#include "Resource/SHResourceLibrary.h" #include "Math/SHMath.h" namespace SHADE @@ -167,7 +167,7 @@ namespace SHADE std::vector meshAddJobs; std::vector> meshRemoveJobs; // Tracking - ResourceLibrary meshes{}; + SHResourceLibrary meshes{}; std::vector> meshOrder; // CPU Storage std::vector vertPosStorage; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h index d3360b87..7a236eaf 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h @@ -1,6 +1,6 @@ #pragma once -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" namespace SHADE { diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h index 3bb7cfda..bc885ca2 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h @@ -12,7 +12,7 @@ of DigiPen Institute of Technology is prohibited. #pragma once // Project Includes -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" //#include "SHTransform.h" #include "ECS_Base/Components/SHComponent.h" #include "Math/SHMatrix.h" diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h index a70e1996..87cf8ee9 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h @@ -17,7 +17,7 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "SHCamera.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include "Graphics/RenderGraph/SHRenderGraph.h" #include "Math/SHMath.h" #include diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp index f47920e0..df9e244e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp @@ -17,7 +17,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/Instance/SHVkInstance.h" #include "Tools/SHLogger.h" #include "SHRenderer.h" -#include "Resource/ResourceLibrary.h" +#include "Resource/SHResourceLibrary.h" #include "Graphics/RenderGraph/SHRenderGraph.h" namespace SHADE @@ -49,7 +49,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Renderer Registration Functions */ /*---------------------------------------------------------------------------------*/ - Handle SHViewport::AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle renderGraph) + Handle SHViewport::AddRenderer(SHResourceHub& resourceManager, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle renderGraph) { // Create the renderer auto renderer = resourceManager.Create(device, numFrames, cmdPools, descriptorPool, cameraDescLayout, GetHandle(), renderGraph); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h index 04b39f00..26c0a6bd 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h @@ -17,7 +17,7 @@ of DigiPen Institute of Technology is prohibited. // External Dependencies #include "Graphics/SHVulkanIncludes.h" // Project Includes -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" namespace SHADE { @@ -28,7 +28,7 @@ namespace SHADE class SHVkCommandBuffer; class SHVkLogicalDevice; class SHVkImageView; - class ResourceManager; + class SHResourceHub; class SHRenderGraph; class SHVkDescriptorPool; class SHVkDescriptorSetLayout; @@ -59,7 +59,7 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Renderers Registration Functions */ /*-----------------------------------------------------------------------------*/ - Handle AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle renderGraph); + Handle AddRenderer(SHResourceHub& resourceManager, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle renderGraph); void RemoveRenderer(Handle renderer); /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.cpp index ed3d27c3..624956da 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.cpp @@ -14,7 +14,7 @@ of DigiPen Institute of Technology is prohibited. #include "SHMaterialInstanceCache.h" #include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" -#include "Resource/ResourceLibrary.h" +#include "Resource/SHResourceLibrary.h" namespace SHADE @@ -22,7 +22,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Usage Functions */ /*---------------------------------------------------------------------------------*/ - SHADE::Handle SHMaterialInstanceCache::CreateOrGet(ResourceManager& manager, Handle material) + SHADE::Handle SHMaterialInstanceCache::CreateOrGet(SHResourceHub& manager, Handle material) { // Check if there is already an existing instance auto matInst = cache.find(material); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h b/SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h index d85cb553..6612faf6 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h @@ -15,7 +15,7 @@ of DigiPen Institute of Technology is prohibited. // STL Includes #include // Project Includes -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" namespace SHADE { @@ -24,7 +24,7 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ class SHMaterial; class SHMaterialInstance; - class ResourceManager; + class SHResourceHub; /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -56,7 +56,7 @@ namespace SHADE */ /***********************************************************************************/ - Handle CreateOrGet(ResourceManager& manager, Handle material); + Handle CreateOrGet(SHResourceHub& manager, Handle material); /***********************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h index c2eb85ec..935a7a4d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h @@ -17,8 +17,8 @@ of DigiPen Institute of Technology is prohibited. // External Dependencies #include "tinyddsloader.h" // Project Includes -#include "Resource/Handle.h" -#include "Resource/ResourceLibrary.h" +#include "Resource/SHHandle.h" +#include "Resource/SHResourceLibrary.h" #include "Math/SHMath.h" #include "Graphics/SHVulkanIncludes.h" @@ -156,7 +156,7 @@ namespace SHADE std::vector addJobs; std::vector> removeJobs; // Tracking - ResourceManager resourceManager; + SHResourceHub resourceManager; std::vector> texOrder; // CPU Storage std::vector, Handle, vk::ImageLayout>> combinedImageSamplers; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHVkSamplerCache.h b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHVkSamplerCache.h index c1529577..1adbcb8c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHVkSamplerCache.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHVkSamplerCache.h @@ -16,7 +16,7 @@ of DigiPen Institute of Technology is prohibited. // External Dependencies #include "Graphics/SHVulkanIncludes.h" // Project Includes -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" namespace SHADE { diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h index 093e03d4..d696e4a3 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h @@ -2,7 +2,7 @@ #define SH_PIPELINE_LAYOUT_PARAMS_H #include "Graphics/SHVulkanIncludes.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include "Graphics/Descriptors/SHVkDescriptorSetLayout.h" namespace SHADE diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h index 9ec18650..7378cc48 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h @@ -3,7 +3,7 @@ #include "SHPipelineState.h" #include "SHPipelineType.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include "Graphics/Pipeline/SHVkPipelineLayout.h" namespace SHADE diff --git a/SHADE_Engine/src/Graphics/Queues/SHVkQueue.h b/SHADE_Engine/src/Graphics/Queues/SHVkQueue.h index 9d865ee9..a647cb72 100644 --- a/SHADE_Engine/src/Graphics/Queues/SHVkQueue.h +++ b/SHADE_Engine/src/Graphics/Queues/SHVkQueue.h @@ -3,7 +3,7 @@ #include "Graphics/SHVulkanIncludes.h" #include "Graphics/SHVulkanDefines.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" namespace SHADE { diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.h b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.h index 20e924cb..845a19a4 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.h @@ -1,6 +1,6 @@ #pragma once -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" namespace SHADE { diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 1c0798f1..4684419a 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -352,7 +352,7 @@ namespace SHADE /***************************************************************************/ void SHRenderGraph::Init(Handle logicalDevice, Handle swapchain) noexcept { - resourceManager = std::make_shared(); + resourceManager = std::make_shared(); renderGraphStorage = resourceManager->Create(); renderGraphStorage->graphResources = resourceManager->Create>>(); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index b445134c..d90b66df 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -2,7 +2,7 @@ #define SH_RENDER_GRAPH_H #include "Graphics/Renderpass/SHVkRenderpass.h" -#include "Resource/ResourceLibrary.h" +#include "Resource/SHResourceLibrary.h" #include "SH_API.h" #include "Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h" #include "Graphics/MiddleEnd/Batching/SHSuperBatch.h" @@ -67,7 +67,7 @@ namespace SHADE std::vector> nodes; //! Resource library for graph handles - std::shared_ptr resourceManager; + std::shared_ptr resourceManager; public: /*-----------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index 335b93e3..16f3f914 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -13,7 +13,7 @@ namespace SHADE { - class ResourceManager; + class SHResourceHub; class SHVkFramebuffer; class SHRenderGraphResource; class SHVkLogicalDevice; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h index e35326f7..ba4cf387 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h @@ -1,6 +1,6 @@ #pragma once -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" #include #include diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h index 832fa772..e2fc5d8d 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h @@ -3,7 +3,7 @@ #include #include "SHAttachmentDescriptionType.h" #include -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include "Graphics/SHVulkanIncludes.h" #include "SH_API.h" diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h index f8123191..54ef705a 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h @@ -1,6 +1,6 @@ #pragma once -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include namespace SHADE @@ -20,7 +20,7 @@ namespace SHADE Handle swapchain; //! Resource manager for creation of objects - std::shared_ptr resourceManager; + std::shared_ptr resourceManager; //! Descriptor pool for the descriptor sets to be created in the subpasses Handle descriptorPool; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index 5e3449c2..af6f3089 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -223,8 +223,7 @@ namespace SHADE exteriorDrawCalls.push_back(newDrawCall); } - - void SHSubpass::Init(ResourceManager& resourceManager) noexcept + void SHSubpass::Init(SHResourceHub& resourceManager) noexcept { superBatch = resourceManager.Create(GetHandle()); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h index 5a9dafb2..166f0d76 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h @@ -3,7 +3,7 @@ #include "SHAttachmentDescriptionType.h" #include #include "SH_API.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include "Graphics/SHVulkanIncludes.h" @@ -103,8 +103,7 @@ namespace SHADE void Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept; void HandleResize (void) noexcept; - - void Init(ResourceManager& resourceManager) noexcept; + void Init(SHResourceHub& resourceManager) noexcept; //void InitComputeBarriers (void) noexcept; void CreateInputDescriptors (void) noexcept; diff --git a/SHADE_Engine/src/Graphics/Renderpass/SHVkAttachDescGen.h b/SHADE_Engine/src/Graphics/Renderpass/SHVkAttachDescGen.h index a44f4f27..8cbf72af 100644 --- a/SHADE_Engine/src/Graphics/Renderpass/SHVkAttachDescGen.h +++ b/SHADE_Engine/src/Graphics/Renderpass/SHVkAttachDescGen.h @@ -2,7 +2,7 @@ #define SH_VK_ATTACHMENT_DESC_GEN_H #include "Graphics/SHVulkanIncludes.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" namespace SHADE { diff --git a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h index 70a04bbf..c265e603 100644 --- a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h +++ b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h @@ -3,7 +3,7 @@ #include "SHVkAttachDescGen.h" #include "SHVkSubpassParams.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include namespace SHADE diff --git a/SHADE_Engine/src/Graphics/Renderpass/SHVkSubpassParams.h b/SHADE_Engine/src/Graphics/Renderpass/SHVkSubpassParams.h index bf789c54..6f722f5a 100644 --- a/SHADE_Engine/src/Graphics/Renderpass/SHVkSubpassParams.h +++ b/SHADE_Engine/src/Graphics/Renderpass/SHVkSubpassParams.h @@ -2,7 +2,7 @@ #define SH_VK_SUBPASS_PARAMS_H #include "Graphics/SHVulkanIncludes.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include namespace SHADE diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.h b/SHADE_Engine/src/Graphics/SHVkUtil.h index ab11b537..de700ea5 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.h +++ b/SHADE_Engine/src/Graphics/SHVkUtil.h @@ -3,7 +3,7 @@ #include "SHVulkanIncludes.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include "Graphics/Pipeline/SHPipelineType.h" namespace SHADE diff --git a/SHADE_Engine/src/Graphics/Shaders/SHVkShaderModule.h b/SHADE_Engine/src/Graphics/Shaders/SHVkShaderModule.h index 2973d734..492710f2 100644 --- a/SHADE_Engine/src/Graphics/Shaders/SHVkShaderModule.h +++ b/SHADE_Engine/src/Graphics/Shaders/SHVkShaderModule.h @@ -2,7 +2,7 @@ #define SH_VK_SHADER_MODULE_H #include "Graphics/SHVulkanIncludes.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" #include "SHShaderReflected.h" #include diff --git a/SHADE_Engine/src/Graphics/Swapchain/SHVkSwapchain.h b/SHADE_Engine/src/Graphics/Swapchain/SHVkSwapchain.h index 28bd7a4e..384665d3 100644 --- a/SHADE_Engine/src/Graphics/Swapchain/SHVkSwapchain.h +++ b/SHADE_Engine/src/Graphics/Swapchain/SHVkSwapchain.h @@ -4,7 +4,7 @@ #include #include #include "Graphics/SHVulkanIncludes.h" -#include "Resource/ResourceLibrary.h" +#include "Resource/SHResourceLibrary.h" #include "Graphics/Swapchain/SHSwapchainParams.h" namespace SHADE diff --git a/SHADE_Engine/src/Graphics/Synchronization/SHVkFence.h b/SHADE_Engine/src/Graphics/Synchronization/SHVkFence.h index 02445d42..7c48a5f6 100644 --- a/SHADE_Engine/src/Graphics/Synchronization/SHVkFence.h +++ b/SHADE_Engine/src/Graphics/Synchronization/SHVkFence.h @@ -2,7 +2,7 @@ #define SH_VK_FENCE_H #include "Graphics/SHVulkanIncludes.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" namespace SHADE { diff --git a/SHADE_Engine/src/Graphics/Synchronization/SHVkSemaphore.h b/SHADE_Engine/src/Graphics/Synchronization/SHVkSemaphore.h index 57f7d7df..f03cad65 100644 --- a/SHADE_Engine/src/Graphics/Synchronization/SHVkSemaphore.h +++ b/SHADE_Engine/src/Graphics/Synchronization/SHVkSemaphore.h @@ -2,7 +2,7 @@ #define SH_VK_SEMAPHORE_H #include "Graphics/SHVulkanIncludes.h" -#include "Resource/Handle.h" +#include "Resource/SHHandle.h" namespace SHADE { diff --git a/SHADE_Engine/src/Graphics/Windowing/Surface/SHVkSurface.h b/SHADE_Engine/src/Graphics/Windowing/Surface/SHVkSurface.h index 0328fecc..bf01dc9c 100644 --- a/SHADE_Engine/src/Graphics/Windowing/Surface/SHVkSurface.h +++ b/SHADE_Engine/src/Graphics/Windowing/Surface/SHVkSurface.h @@ -3,7 +3,7 @@ #include #include "Graphics/SHVulkanIncludes.h" -#include "Resource/ResourceLibrary.h" +#include "Resource/SHResourceLibrary.h" namespace SHADE { diff --git a/SHADE_Engine/src/Input/SHInputManager.cpp b/SHADE_Engine/src/Input/SHInputManager.cpp index 18d9e3e2..c665a9c9 100644 --- a/SHADE_Engine/src/Input/SHInputManager.cpp +++ b/SHADE_Engine/src/Input/SHInputManager.cpp @@ -19,6 +19,10 @@ namespace SHADE /*------------------------------------------------------------------------*/ /* Static defines */ /*------------------------------------------------------------------------*/ + + bool SHInputManager::controllerInUse = false; + + std::map SHInputManager::bindings; unsigned SHInputManager::keyCount = 0; bool SHInputManager::keys[MAX_KEYS]; @@ -41,6 +45,60 @@ namespace SHADE int SHInputManager::mouseWheelVerticalDelta = 0; int SHInputManager::mouseWheelVerticalDeltaPoll = 0; + unsigned char SHInputManager::controllersConnectedCount = 0; + unsigned SHInputManager::controllersInputCount[XUSER_MAX_COUNT]; + unsigned SHInputManager::controllersButtonCount[XUSER_MAX_COUNT]; + short SHInputManager::controllers[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT]; + short SHInputManager::controllersLast[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT]; + double SHInputManager::controllersHeldTime[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT]; + double SHInputManager::controllersReleasedTime[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT]; + + //Internal helper function for splitting between inputs + bool SHInputManager::controllerConsideredHeld(size_t inputIdx, short value) noexcept + { + if (inputIdx >= MAX_CONTROLLER_INPUT) return false; //Bounds check + else + { + if (inputIdx < NUM_CONTROLLER_BUTTON) + { + return static_cast(value); + } + else if (inputIdx < NUM_CONTROLLER_BUTTON + NUM_CONTROLLER_TRIGGER) + { + return (value > XINPUT_GAMEPAD_TRIGGER_THRESHOLD); + } + else if (inputIdx < NUM_CONTROLLER_BUTTON + NUM_CONTROLLER_TRIGGER + NUM_CONTROLLER_TRIGGER) + { + return (std::abs(value) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE); + } + else + { + return (std::abs(value) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE); + } + } + } + + //Internal helper function for getting normalised input value + double SHInputManager::controllerNormalisedValue(size_t inputIdx, short value) noexcept + { + if (inputIdx >= MAX_CONTROLLER_INPUT) return 0.0; //Bounds check + else + { + if (inputIdx < NUM_CONTROLLER_BUTTON) + { + return static_cast(value); + } + else if (inputIdx < NUM_CONTROLLER_BUTTON + NUM_CONTROLLER_TRIGGER) //8-bit triggers, 0 to 255 + { + return static_cast(value) / static_cast(UCHAR_MAX); + } + else //16-bit thumbsticks, -32768 to 32767 + { + return static_cast(value) / static_cast(SHRT_MAX); + } + } + } + void SHInputManager::UpdateInput(double dt) noexcept { //Keyboard and Mouse Buttons//////////////////////////////////////////////// @@ -120,6 +178,273 @@ namespace SHADE mouseWheelVerticalDelta = 0; mouseWheelVerticalDelta = mouseWheelVerticalDeltaPoll; mouseWheelVerticalDeltaPoll = 0; + + //Controllers////////////////////////////////////////////////////////////// + + controllersConnectedCount = 0; + + //Set last controller states + memcpy(controllersLast, controllers, sizeof(controllers)); + + //Reset controller states + SecureZeroMemory(&controllers, sizeof(controllers)); + + //https://learn.microsoft.com/en-us/windows/win32/xinput/getting-started-with-xinput#getting-controller-state + for (DWORD c = 0; c < XUSER_MAX_COUNT; ++c) + { + controllersInputCount[c] = 0; + controllersButtonCount[c] = 0; + + XINPUT_STATE state; + SecureZeroMemory(&state, sizeof(XINPUT_STATE)); + + //Get the state of controller from XInput + DWORD result = XInputGetState(c, &state); + + //Write gamepad data + if (result == ERROR_SUCCESS) + { + ++controllersConnectedCount; + + //DIGITAL BUTTONS/////////////////////////////////////// + + //DPAD UP + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) + { + controllers[c][static_cast(SH_CONTROLLERCODE::DPAD_UP)] = 1; + ++controllersInputCount[c]; + ++controllersButtonCount[c]; + } + else + { + controllers[c][static_cast(SH_CONTROLLERCODE::DPAD_UP)] = 0; + } + + //DPAD DOWN + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) + { + controllers[c][static_cast(SH_CONTROLLERCODE::DPAD_DOWN)] = 1; + ++controllersInputCount[c]; + ++controllersButtonCount[c]; + } + else + { + controllers[c][static_cast(SH_CONTROLLERCODE::DPAD_DOWN)] = 0; + } + + //DPAD LEFT + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) + { + controllers[c][static_cast(SH_CONTROLLERCODE::DPAD_LEFT)] = 1; + ++controllersInputCount[c]; + ++controllersButtonCount[c]; + } + else + { + controllers[c][static_cast(SH_CONTROLLERCODE::DPAD_LEFT)] = 0; + } + + //DPAD RIGHT + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) + { + controllers[c][static_cast(SH_CONTROLLERCODE::DPAD_RIGHT)] = 1; + ++controllersInputCount[c]; + ++controllersButtonCount[c]; + } + else + { + controllers[c][static_cast(SH_CONTROLLERCODE::DPAD_RIGHT)] = 0; + } + + //START + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_START) + { + controllers[c][static_cast(SH_CONTROLLERCODE::START)] = 1; + ++controllersInputCount[c]; + ++controllersButtonCount[c]; + } + else + { + controllers[c][static_cast(SH_CONTROLLERCODE::START)] = 0; + } + + //BACK + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) + { + controllers[c][static_cast(SH_CONTROLLERCODE::BACK)] = 1; + ++controllersInputCount[c]; + ++controllersButtonCount[c]; + } + else + { + controllers[c][static_cast(SH_CONTROLLERCODE::BACK)] = 0; + } + + //LEFT THUMBSTICK BUTTON + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) + { + controllers[c][static_cast(SH_CONTROLLERCODE::LEFT_THUMBSTICK)] = 1; + ++controllersInputCount[c]; + ++controllersButtonCount[c]; + } + else + { + controllers[c][static_cast(SH_CONTROLLERCODE::LEFT_THUMBSTICK)] = 0; + } + + //RIGHT THUMBSTICK BUTTON + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) + { + controllers[c][static_cast(SH_CONTROLLERCODE::RIGHT_THUMBSTICK)] = 1; + ++controllersInputCount[c]; + ++controllersButtonCount[c]; + } + else + { + controllers[c][static_cast(SH_CONTROLLERCODE::RIGHT_THUMBSTICK)] = 0; + } + + //LEFT SHOULDER BUTTON + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) + { + controllers[c][static_cast(SH_CONTROLLERCODE::LEFT_SHOULDER)] = 1; + ++controllersInputCount[c]; + ++controllersButtonCount[c]; + } + else + { + controllers[c][static_cast(SH_CONTROLLERCODE::LEFT_SHOULDER)] = 0; + } + + //RIGHT SHOULDER BUTTON + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) + { + controllers[c][static_cast(SH_CONTROLLERCODE::RIGHT_SHOULDER)] = 1; + ++controllersInputCount[c]; + ++controllersButtonCount[c]; + } + else + { + controllers[c][static_cast(SH_CONTROLLERCODE::RIGHT_SHOULDER)] = 0; + } + + //A + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_A) + { + controllers[c][static_cast(SH_CONTROLLERCODE::A)] = 1; + ++controllersInputCount[c]; + ++controllersButtonCount[c]; + } + else + { + controllers[c][static_cast(SH_CONTROLLERCODE::A)] = 0; + } + + //B + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_B) + { + controllers[c][static_cast(SH_CONTROLLERCODE::B)] = 1; + ++controllersInputCount[c]; + ++controllersButtonCount[c]; + } + else + { + controllers[c][static_cast(SH_CONTROLLERCODE::B)] = 0; + } + + //X + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_X) + { + controllers[c][static_cast(SH_CONTROLLERCODE::X)] = 1; + ++controllersInputCount[c]; + ++controllersButtonCount[c]; + } + else + { + controllers[c][static_cast(SH_CONTROLLERCODE::X)] = 0; + } + + //Y + if (state.Gamepad.wButtons & XINPUT_GAMEPAD_Y) + { + controllers[c][static_cast(SH_CONTROLLERCODE::Y)] = 1; + ++controllersInputCount[c]; + ++controllersButtonCount[c]; + } + else + { + controllers[c][static_cast(SH_CONTROLLERCODE::Y)] = 0; + } + + //8 BIT VALUES (0 - 255)/////////////////////////////////// + + //LEFT TRIGGER + controllers[c][static_cast(SH_CONTROLLERCODE::LEFT_TRIGGER)] = state.Gamepad.bLeftTrigger; + if (state.Gamepad.bLeftTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD) + { + ++controllersInputCount[c]; //Registered as held + } + + //RIGHT TRIGGER + controllers[c][static_cast(SH_CONTROLLERCODE::RIGHT_TRIGGER)] = state.Gamepad.bRightTrigger; + if (state.Gamepad.bRightTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD) + { + ++controllersInputCount[c]; //Registered as held + } + + //16 BIT VALUES (0 - 65535)//////////////////////////////// + + //LEFT THUMBSTICK X + controllers[c][static_cast(SH_CONTROLLERCODE::LEFT_THUMBSTICK_X)] = state.Gamepad.sThumbLX; + if (std::abs(state.Gamepad.sThumbLX) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) + { + ++controllersInputCount[c]; + } + + //LEFT THUMBSTICK Y + controllers[c][static_cast(SH_CONTROLLERCODE::LEFT_THUMBSTICK_Y)] = state.Gamepad.sThumbLY; + if (std::abs(state.Gamepad.sThumbLY) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) + { + ++controllersInputCount[c]; + } + + //RIGHT THUMBSTICK X + controllers[c][static_cast(SH_CONTROLLERCODE::RIGHT_THUMBSTICK_X)] = state.Gamepad.sThumbRX; + if (std::abs(state.Gamepad.sThumbRX) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) + { + ++controllersInputCount[c]; + } + + //RIGHT THUMBSTICK Y + controllers[c][static_cast(SH_CONTROLLERCODE::RIGHT_THUMBSTICK_Y)] = state.Gamepad.sThumbRY; + if (std::abs(state.Gamepad.sThumbRY) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) + { + ++controllersInputCount[c]; + } + } + + //Timers and updating if controller is presently in use + for (size_t i = 0; i < MAX_CONTROLLER_INPUT; ++i) + { + if (controllerConsideredHeld(i, controllers[c][i])) //Considered on + { + controllerInUse = true; + if (!controllerConsideredHeld(i, controllersLast[c][i])) //Just on + { + controllersHeldTime[c][i] = 0.0; //Reset timer + } + controllersHeldTime[c][i] += dt; //Tick up + } + else //Considered off + { + if (controllerConsideredHeld(i, controllersLast[c][i])) //Just off + { + controllersReleasedTime[c][i] = 0.0; //Reset timer + } + controllersReleasedTime[c][i] += dt; //Tick up + } + } + } } bool SHInputManager::AnyKeyDown(SH_KEYCODE* firstDetected) noexcept @@ -161,4 +486,336 @@ namespace SHADE return false; } + //Any controller input being held + //For analog, this means going being deadzone values + bool SHInputManager::AnyControllerInput(SH_CONTROLLERCODE* firstDetected, size_t cNum) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return false; + for (size_t i = 0; i < MAX_CONTROLLER_INPUT; ++i) + { + if (controllerConsideredHeld(i, controllers[cNum][i])) + { + if (firstDetected) *firstDetected = static_cast(i); + return true; + } + } + return false; + } + + bool SHInputManager::AnyControllerInputDown(SH_CONTROLLERCODE* firstDetected, size_t cNum) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return false; + for (size_t i = 0; i < MAX_CONTROLLER_INPUT; ++i) + { + if (controllerConsideredHeld(i, controllers[cNum][i]) && !controllerConsideredHeld(i, controllersLast[cNum][i])) + { + if (firstDetected) *firstDetected = static_cast(i); + return true; + } + } + return false; + } + + bool SHInputManager::AnyControllerInputUp(SH_CONTROLLERCODE* firstDetected, size_t cNum) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return false; + for (size_t i = 0; i < MAX_CONTROLLER_INPUT; ++i) + { + if (!controllerConsideredHeld(i, controllers[cNum][i]) && controllerConsideredHeld(i, controllersLast[cNum][i])) + { + if (firstDetected) *firstDetected = static_cast(i); + return true; + } + } + return false; + } + + bool SHInputManager::AnyControllerButton(SH_CONTROLLERCODE* firstDetected, size_t cNum) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return false; + for (size_t i = 0; i < NUM_CONTROLLER_BUTTON; ++i) + { + if (controllerConsideredHeld(i, controllers[cNum][i])) + { + if (firstDetected) *firstDetected = static_cast(i); + return true; + } + } + return false; + } + + bool SHInputManager::AnyControllerButtonDown(SH_CONTROLLERCODE* firstDetected, size_t cNum) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return false; + for (size_t i = 0; i < NUM_CONTROLLER_BUTTON; ++i) + { + if (controllerConsideredHeld(i, controllers[cNum][i]) && !controllerConsideredHeld(i, controllersLast[cNum][i])) + { + if (firstDetected) *firstDetected = static_cast(i); + return true; + } + } + return false; + } + + bool SHInputManager::AnyControllerButtonUp(SH_CONTROLLERCODE* firstDetected, size_t cNum) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return false; + for (size_t i = 0; i < NUM_CONTROLLER_BUTTON; ++i) + { + if (!controllerConsideredHeld(i, controllers[cNum][i]) && controllerConsideredHeld(i, controllersLast[cNum][i])) + { + if (firstDetected) *firstDetected = static_cast(i); + return true; + } + } + return false; + } + + //Only get of largest magnitude + double SHInputManager::GetBindingAxis(std::string bindingName, size_t cNum) noexcept + { + //Over keycodes, prioritise positive + for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes) + { + if (GetKey(k)) return 1.0; + } + for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes) + { + if (GetKey(k)) return -1.0; + } + + double largestMagnitude = 0.0; + + //Over controllerCodes + for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes) + { + double newValue = 0.0; + if (GetControllerInput(c, &newValue, nullptr, nullptr, cNum)) + if (std::abs(newValue) > std::abs(largestMagnitude)) largestMagnitude = newValue; + } + for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes) + { + double newValue = 0.0; + if (GetControllerInput(c, &newValue, nullptr, nullptr, cNum)) + if (std::abs(newValue) > std::abs(largestMagnitude)) largestMagnitude = -newValue; + } + + return largestMagnitude; + } + + bool SHInputManager::GetBindingPositiveButton(std::string bindingName, size_t cNum) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return false; + + //Over keycodes + for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes) + { + if (GetKey(k)) return true; + } + + //Over controller buttons + for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes) + { + if (GetControllerInput(c, nullptr, nullptr, nullptr, cNum)) return true; + } + + return false; + } + + bool SHInputManager::GetBindingNegativeButton(std::string bindingName, size_t cNum) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return false; + + //Over keycodes + for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes) + { + if (GetKey(k)) return true; + } + + //Over controller buttons + for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes) + { + if (GetControllerInput(c, nullptr, nullptr, nullptr, cNum)) return true; + } + + return false; + } + + bool SHInputManager::GetBindingPositiveButtonDown(std::string bindingName, size_t cNum) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return false; + + //Over keycodes + for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes) + { + if (GetKeyDown(k)) return true; + } + + //Over controller buttons + for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes) + { + if (GetControllerInputDown(c, nullptr, cNum)) return true; + } + + return false; + } + + bool SHInputManager::GetBindingNegativeButtonDown(std::string bindingName, size_t cNum) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return false; + + //Over keycodes + for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes) + { + if (GetKeyDown(k)) return true; + } + + //Over controller buttons + for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes) + { + if (GetControllerInputDown(c, nullptr, cNum)) return true; + } + + return false; + } + + bool SHInputManager::GetBindingPositiveButtonUp(std::string bindingName, size_t cNum) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return false; + + //Over keycodes + for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes) + { + if (GetKeyUp(k)) return true; + } + + //Over controller buttons + for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes) + { + if (GetControllerInputUp(c, nullptr, cNum)) return true; + } + + return false; + } + + bool SHInputManager::GetBindingNegativeButtonUp(std::string bindingName, size_t cNum) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return false; + + //Over keycodes + for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes) + { + if (GetKeyUp(k)) return true; + } + + //Over controller buttons + for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes) + { + if (GetControllerInputUp(c, nullptr, cNum)) return true; + } + + return false; + } + + //Fetches longest hold time + double SHInputManager::GetBindingPositiveHeldTime(std::string bindingName, size_t cNum) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return 0.0; + + double maxHeldTime = 0.0; + + //Over keycodes + for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes) + { + if (GetKeyHeldTime(k) > maxHeldTime) maxHeldTime = GetKeyHeldTime(k); + } + + //Over controller buttons + for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes) + { + if (GetControllerInputHeldTime(c, cNum) > maxHeldTime) maxHeldTime = GetControllerInputHeldTime(c); + } + + return maxHeldTime; + } + + double SHInputManager::GetBindingNegativeHeldTime(std::string bindingName, size_t cNum) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return 0.0; + + double maxHeldTime = 0.0; + + //Over keycodes + for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes) + { + if (GetKeyHeldTime(k) > maxHeldTime) maxHeldTime = GetKeyHeldTime(k); + } + + //Over controller buttons + for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes) + { + if (GetControllerInputHeldTime(c, cNum) > maxHeldTime) maxHeldTime = GetControllerInputHeldTime(c); + } + + return maxHeldTime; + } + + //Fetches shortest release time + double SHInputManager::GetBindingPositiveReleasedTime(std::string bindingName, size_t cNum) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return 0.0; + + double minReleaseTime = _HUGE_ENUF; + + //Over keycodes + for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes) + { + if (GetKeyReleasedTime(k) < minReleaseTime) minReleaseTime = GetKeyReleasedTime(k); + } + + //Over controller buttons + for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes) + { + if (GetControllerInputReleasedTime(c, cNum) < minReleaseTime) minReleaseTime = GetControllerInputReleasedTime(c); + } + + return minReleaseTime; + } + + double SHInputManager::GetBindingNegativeReleasedTime(std::string bindingName, size_t cNum) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return 0.0; + + double minReleaseTime = _HUGE_ENUF; + + //Over keycodes + for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes) + { + if (GetKeyReleasedTime(k) < minReleaseTime) minReleaseTime = GetKeyReleasedTime(k); + } + + //Over controller buttons + for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes) + { + if (GetControllerInputReleasedTime(c, cNum) < minReleaseTime) minReleaseTime = GetControllerInputReleasedTime(c); + } + + return minReleaseTime; + } + + //Only for mouse movement + //Get largest delta + double SHInputManager::GetBindingMouseVelocity(std::string bindingName, size_t cNum) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return 0.0; + + //Mouse velocity + double velX = 0.0; + double velY = 0.0; + GetMouseVelocity(&velX, &velY); + + return bindings[bindingName].mouseXPositiveMultiplier * velX + bindings[bindingName].mouseYPositiveMultiplier * velY; + } + } //namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Input/SHInputManager.h b/SHADE_Engine/src/Input/SHInputManager.h index d3e31004..04e5871d 100644 --- a/SHADE_Engine/src/Input/SHInputManager.h +++ b/SHADE_Engine/src/Input/SHInputManager.h @@ -10,9 +10,12 @@ *********************************************************************/ #pragma once -//#include -//#include "../../SHADE_Managed/src/SHpch.h" +#include +#include +#include +#include "../../SHADE_Managed/src/SHpch.h" #include "SH_API.h" +#pragma comment(lib, "xinput.lib") namespace SHADE { @@ -268,6 +271,58 @@ namespace SHADE OEM_CLEAR }; + enum class SH_CONTROLLERCODE + { + //Digital + DPAD_UP, + DPAD_DOWN, + DPAD_LEFT, + DPAD_RIGHT, + START, + BACK, + LEFT_THUMBSTICK, + RIGHT_THUMBSTICK, + LEFT_SHOULDER, + RIGHT_SHOULDER, + A, + B, + X, + Y, + + //1 Byte Unsigned Analog + LEFT_TRIGGER, + RIGHT_TRIGGER, + + //2 Byte Signed Analog + LEFT_THUMBSTICK_X, + LEFT_THUMBSTICK_Y, + RIGHT_THUMBSTICK_X, + RIGHT_THUMBSTICK_Y + }; + + private: + /*------------------------------------------------------------------------*/ + /* Struct for logical bindings */ + /*------------------------------------------------------------------------*/ + struct SH_API SHLogicalBindingData + { + //Key codes mapped to positive + std::set positiveKeyCodes; + + //Key codes mapped to negative + std::set negativeKeyCodes; + + //Controller Codes mapped to positive + std::set positiveControllerCodes; + + //Controller Codes mapped to negative + std::set negativeControllerCodes; + + //Mouse movement mapped to axes? + double mouseXPositiveMultiplier; + double mouseYPositiveMultiplier; + }; + public: //Updates current state of the input, with dt to be fetched from FRC //TODO should dt be fixed or variable? @@ -392,7 +447,7 @@ namespace SHADE keysToggleLast[static_cast(key)]); } - //Mouse///////////// + //Mouse///////////////////////////////////////////////////// //Get the mouse location with respect to the screen static inline void GetMouseScreenPosition (int* x = nullptr, @@ -428,7 +483,95 @@ namespace SHADE return mouseWheelVerticalDelta; } - //GET INPUT TIMINGS/////////////////////////////////////////////////////////// + /*------------------------------------------------------------------------*/ + /* Input state accessors (KB & M) */ + /*------------------------------------------------------------------------*/ + + //How many controller inputs of any kind are being used now + static inline unsigned GetControllerInputCount(size_t cNum = 0) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return 0; + return controllersInputCount[cNum]; + } + + //How many controller buttons are being pressed now + //Subtract from getControllerInputCount() for analog triggers / thumbsticks + static inline unsigned GetControllerButtonCount(size_t cNum = 0) noexcept + { + if (cNum >= XUSER_MAX_COUNT) return 0; + return controllersButtonCount[cNum]; + } + + //Any controller input being held + //For analog, this means going being deadzone values + //controllerNum should be between 0 and 3 + static bool AnyControllerInput(SH_CONTROLLERCODE* firstDetected = nullptr, size_t controllerNum = 0) noexcept; + + //Any controller input activated in THIS FRAME ONLY + //For analog, this means going being deadzone values + //controllerNum should be between 0 and 3 + static bool AnyControllerInputDown(SH_CONTROLLERCODE* firstDetected = nullptr, size_t controllerNum = 0) noexcept; + + //Any controller input deactivated in THIS FRAME ONLY + //For analog, this means going below deadzone values + //controllerNum should be between 0 and 3 + static bool AnyControllerInputUp(SH_CONTROLLERCODE* firstDetected = nullptr, size_t controllerNum = 0) noexcept; + + //Any DIGITAL controller buttons being held + //controllerNum should be between 0 and 3 + static bool AnyControllerButton(SH_CONTROLLERCODE* firstDetected = nullptr, size_t controllerNum = 0) noexcept; + + //Any DIGITAL controller button activated in THIS FRAME ONLY + //controllerNum should be between 0 and 3 + static bool AnyControllerButtonDown(SH_CONTROLLERCODE* firstDetected = nullptr, size_t controllerNum = 0) noexcept; + + //Any DIGITAL controller button deactivated in THIS FRAME ONLY + //controllerNum should be between 0 and 3 + static bool AnyControllerButtonUp(SH_CONTROLLERCODE* firstDetected = nullptr, size_t controllerNum = 0) noexcept; + + //If controller input is being held in the current frame + //normalisedValue is the value of the input between 0 and 1, relevant for trigger and thumbstick data + //controllerNum should be between 0 and 3 + static inline bool GetControllerInput(SH_CONTROLLERCODE input, + double* normalisedValue = nullptr, + double* heldTime = nullptr, + double* releasedTime = nullptr, + size_t controllerNum = 0) noexcept + { + if (controllerNum >= XUSER_MAX_COUNT) return false; + if (normalisedValue) *normalisedValue = controllerNormalisedValue(static_cast(input), controllers[controllerNum][static_cast(input)]); + if (heldTime) *heldTime = controllersHeldTime[controllerNum][static_cast(input)]; + if (releasedTime) *releasedTime = controllersReleasedTime[controllerNum][static_cast(input)]; + return controllerConsideredHeld(static_cast(input), controllers[controllerNum][static_cast(input)]); + } + + //If controller input was considered to be held down in THIS FRAME ONLY + //controllerNum should be between 0 and 3 + static inline bool GetControllerInputDown(SH_CONTROLLERCODE input, + double* releasedTime = nullptr, + size_t controllerNum = 0) noexcept + { + if (controllerNum >= XUSER_MAX_COUNT) return false; + if (releasedTime) *releasedTime = controllersReleasedTime[controllerNum][static_cast(input)]; + return (controllerConsideredHeld(static_cast(input), controllers[controllerNum][static_cast(input)]) && + !controllerConsideredHeld(static_cast(input), controllersLast[controllerNum][static_cast(input)])); + } + + //If controller input was considered to be released in THIS FRAME ONLY + //controllerNum should be between 0 and 3 + static inline bool GetControllerInputUp(SH_CONTROLLERCODE input, + double* releasedTime = nullptr, + size_t controllerNum = 0) noexcept + { + if (controllerNum >= XUSER_MAX_COUNT) return false; + if (releasedTime) *releasedTime = controllersReleasedTime[controllerNum][static_cast(input)]; + return (!controllerConsideredHeld(static_cast(input), controllers[controllerNum][static_cast(input)]) && + controllerConsideredHeld(static_cast(input), controllersLast[controllerNum][static_cast(input)])); + } + + /*------------------------------------------------------------------------*/ + /* Timing accessors */ + /*------------------------------------------------------------------------*/ //Keyboard///////////// @@ -456,6 +599,191 @@ namespace SHADE return keysToggleOffTime[static_cast(key)]; } + //Controller////////////////////// + + //How long has this controller input been considered to be held down for + static inline double GetControllerInputHeldTime(SH_CONTROLLERCODE code, + size_t controllerNum = 0) noexcept + { + if (controllerNum >= XUSER_MAX_COUNT) return 0.0; + return controllersHeldTime[controllerNum][static_cast(code)]; + } + + //How long has this controller input been considered to be released for + static inline double GetControllerInputReleasedTime(SH_CONTROLLERCODE code, + size_t controllerNum = 0) noexcept + { + if (controllerNum >= XUSER_MAX_COUNT) return 0.0; + return controllersReleasedTime[controllerNum][static_cast(code)]; + } + + /*------------------------------------------------------------------------*/ + /* Binding Functions */ + /*------------------------------------------------------------------------*/ + + //Add a new binding to the map + static inline void BindingsAdd(std::string newBindingName) noexcept + { + bindings.insert({ newBindingName, SHLogicalBindingData() }); + } + + //Remove a binding from the map + //Returns 1 if found and removed, 0 if not found + static inline size_t BindingsRemove(std::string targetBindingName) noexcept + { + return bindings.erase(targetBindingName); + } + + //Clears all bindings from the list + static inline void BindingsClear() noexcept + { + bindings.clear(); + } + + //Get the number of bindings present + static inline size_t BindingsCount() noexcept + { + return bindings.size(); + } + + //Check positive keycodes to binding + static inline std::set const& BindingsGetPositiveKeyCodes(std::string bindingName) noexcept + { + return bindings[bindingName].positiveKeyCodes; + } + + //Add positive SH_KEYCODE to binding + static inline void BindingsAddPositiveKeyCode(std::string targetBindingName, + SH_KEYCODE toAdd) noexcept + { + bindings[targetBindingName].positiveKeyCodes.insert(toAdd); + } + + //Remove positive SH_KEYCODE from binding + //If toRemove found and removed, returns 1. Otherwise, 0. + static inline size_t BindingsRemovePositiveKeyCode(std::string targetBindingName, + SH_KEYCODE toRemove) noexcept + { + return bindings[targetBindingName].positiveKeyCodes.erase(toRemove); + } + + //Check negative keycodes to binding + static inline std::set const& BindingsGetNegativeKeyCodes(std::string bindingName) noexcept + { + return bindings[bindingName].negativeKeyCodes; + } + + //Add negative SH_KEYCODE to binding + static inline void BindingsAddNegativeKeyCode(std::string targetBindingName, + SH_KEYCODE toAdd) noexcept + { + bindings[targetBindingName].negativeKeyCodes.insert(toAdd); + } + + //Remove negative SH_KEYCODE from binding + //If toRemove found and removed, returns 1. Otherwise, 0. + static inline size_t BindingsRemoveNegativeKeyCode(std::string targetBindingName, + SH_KEYCODE toRemove) noexcept + { + return bindings[targetBindingName].negativeKeyCodes.erase(toRemove); + } + + //Check positive controllercodes to binding + static inline std::set const& BindingsGetPositiveControllerCodes(std::string bindingName) noexcept + { + return bindings[bindingName].positiveControllerCodes; + } + + //Add positive SH_CONTROLLERCODE to binding + static inline void BindingsAddPositiveControllerCode(std::string targetBindingName, + SH_CONTROLLERCODE toAdd) noexcept + { + bindings[targetBindingName].positiveControllerCodes.insert(toAdd); + } + + //Remove positive SH_CONTROLLERCODE from binding + //If toRemove found and removed, returns 1. Otherwise, 0. + static inline size_t BindingsRemovePositiveControllerCode(std::string targetBindingName, + SH_CONTROLLERCODE toRemove) noexcept + { + return bindings[targetBindingName].positiveControllerCodes.erase(toRemove); + } + + //Check negative controllercodes to binding + static inline std::set const& BindingsGetNegativeControllerCodes(std::string bindingName) noexcept + { + return bindings[bindingName].negativeControllerCodes; + } + + //Add negative SH_CONTROLLERCODE to binding + static inline void BindingsAddNegativeControllerCode(std::string targetBindingName, + SH_CONTROLLERCODE toAdd) noexcept + { + bindings[targetBindingName].negativeControllerCodes.insert(toAdd); + } + + //Remove negative SH_CONTROLLERCODE from binding + //If toRemove found and removed, returns 1. Otherwise, 0. + static inline size_t BindingsRemoveNegativeControllerCode(std::string targetBindingName, + SH_CONTROLLERCODE toRemove) noexcept + { + return bindings[targetBindingName].negativeControllerCodes.erase(toRemove); + } + + //Mouse movement bindings + + static inline double const BindingsGetMouseXPositiveMultiplier(std::string bindingName) noexcept + { + return bindings[bindingName].mouseXPositiveMultiplier; + } + + static inline void BindingsSetMouseXPositiveMultiplier(std::string bindingName, double newValue) noexcept + { + bindings[bindingName].mouseXPositiveMultiplier = newValue; + } + + static inline double const BindingsGetMouseYPositiveMultiplier(std::string bindingName) noexcept + { + return bindings[bindingName].mouseXPositiveMultiplier; + } + + static inline void BindingsSetMouseYPositiveMultiplier(std::string bindingName, double newValue) noexcept + { + bindings[bindingName].mouseXPositiveMultiplier = newValue; + } + + //Get the axis value of binding, between -1 and 1 + static double GetBindingAxis(std::string bindingName, size_t controllerNumber = 0) noexcept; + + //Whether binding is being held or not + //Does not work for mouse movement + static bool GetBindingPositiveButton(std::string bindingName, size_t controllerNumber = 0) noexcept; + static bool GetBindingNegativeButton(std::string bindingName, size_t controllerNumber = 0) noexcept; + + //Whether binding is pressed down IN THIS FRAME ONLY + //Does not work for mouse movement + static bool GetBindingPositiveButtonDown(std::string bindingName, size_t controllerNumber = 0) noexcept; + static bool GetBindingNegativeButtonDown(std::string bindingName, size_t controllerNumber = 0) noexcept; + + //Whether binding is released IN THIS FRAME ONLY + //Does not work for mouse movement + static bool GetBindingPositiveButtonUp(std::string bindingName, size_t controllerNumber = 0) noexcept; + static bool GetBindingNegativeButtonUp(std::string bindingName, size_t controllerNumber = 0) noexcept; + + //Binding times + + //Does not work for mouse movement + static double GetBindingPositiveHeldTime(std::string bindingName, size_t controllerNumber = 0) noexcept; + static double GetBindingNegativeHeldTime(std::string bindingName, size_t controllerNumber = 0) noexcept; + + //Does not work for mouse movement + static double GetBindingPositiveReleasedTime(std::string bindingName, size_t controllerNumber = 0) noexcept; + static double GetBindingNegativeReleasedTime(std::string bindingName, size_t controllerNumber = 0) noexcept; + + //Binding mouse velocity + //Only for mouse movement + static double GetBindingMouseVelocity(std::string bindingName, size_t controllerNumber = 0) noexcept; + /*------------------------------------------------------------------------*/ /* Other Functions */ /*------------------------------------------------------------------------*/ @@ -482,10 +810,36 @@ namespace SHADE /*------------------------------------------------------------------------*/ static constexpr size_t MAX_KEYS = UCHAR_MAX + 1; + //How many recognised controller inputs there are + //To see the list, see the enum class in this file + static constexpr size_t MAX_CONTROLLER_INPUT = 20; + + //On/off button count + static constexpr size_t NUM_CONTROLLER_BUTTON = 14; + + //8-bit trigger values + static constexpr size_t NUM_CONTROLLER_TRIGGER = 2; + + //16-bit thumbstick values + static constexpr size_t NUM_CONTROLLER_THUMBSTICK = 4; + /*------------------------------------------------------------------------*/ /* Data Members */ /*------------------------------------------------------------------------*/ + //If the last input is from controller(s) or KB/M + //True if from controller(s), False if from KB/M + //Useful for switching control hints between controllers and KB/M + static bool controllerInUse; + + //BINDINGS////////////////////////////////////////////////////////////////// + + //Key is for binding names, they must be unique + //Multiple physical inputs per virtual/logical input are to be added to + //sets inside the logicalBinding values + //TODO make this an array of 4 / 5 users for multiplayer support + static std::map bindings; + //KEYBOARD AND MOUSE BUTTONS//////////////////////////////////////////////// //How many keys are presently being pressed @@ -558,15 +912,48 @@ namespace SHADE //CONTROLLER VARIABLES////////////////////////////////////////////////////// - //OTHER VARIABLES/////////////////////////////////////////////////////////// + //Count how many controllers are presently connected + //Useful for if the game is to decide to take in controller or KB/M input + //Between 0 and 4 (inclusive) + static unsigned char controllersConnectedCount; - //Axis bindings - //X - - //Y + //How many inputs (of any kind) on the controller are being used now + //Includes analog triggers and thumbsticks + static unsigned controllersInputCount[XUSER_MAX_COUNT]; - //Other mappings + //How many DIGITAL buttons on the controller are being pressed now + static unsigned controllersButtonCount[XUSER_MAX_COUNT]; - //Buffer + //Current state of controllers + //First index is for controller number + //Second index is for input type + static short controllers[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT]; + + //State of controllers in the last frame + //First index is for controller number + //Second index is for input type + static short controllersLast[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT]; + + //Held and released times + + //Controller held durations + //Stops ticking up when released + //Will be reset when held again + static double controllersHeldTime[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT]; + + //Key released durations + //Stops ticking up when held + //Will be reset when off again + static double controllersReleasedTime[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT]; + + /*------------------------------------------------------------------------*/ + /* Internal Helper Functions */ + /*------------------------------------------------------------------------*/ + + //Internal helper function for checking if input is considered held or not + static bool controllerConsideredHeld(size_t inputIdx, short value) noexcept; + + //Internal helper function for getting normalised controller value + static double controllerNormalisedValue(size_t inputIdx, short value) noexcept; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Resource/Handle.h b/SHADE_Engine/src/Resource/SHHandle.h similarity index 76% rename from SHADE_Engine/src/Resource/Handle.h rename to SHADE_Engine/src/Resource/SHHandle.h index 9579063c..6acc85ed 100644 --- a/SHADE_Engine/src/Resource/Handle.h +++ b/SHADE_Engine/src/Resource/SHHandle.h @@ -8,8 +8,9 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Forward Declarations */ /*---------------------------------------------------------------------------------*/ + class SHResourceLibraryBase; template - class ResourceLibrary; + class SHResourceLibrary; /*---------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -25,6 +26,20 @@ namespace SHADE using std::runtime_error::runtime_error; }; + /// + /// Exception thrown when a generic Handle is being casted to the wrong type. + /// + class BadHandleCastException : std::runtime_error + { + public: + /*-----------------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------------*/ + BadHandleCastException() + : std::runtime_error("Attempted to cast a generic Handle to the wrong type. ") + {} + }; + /// /// Base implementation of the Handle that is not templated to allow for holding /// generic non-type-specific Handles. @@ -80,7 +95,7 @@ namespace SHADE /// Generic implementation of a Handle object /// /// Type of the handle. - template + template class Handle : public HandleBase { public: @@ -88,6 +103,16 @@ namespace SHADE /* Constructors */ /*-----------------------------------------------------------------------------*/ Handle() = default; + /// + /// Converts a generic/void Handle to a specific type. + /// Runtime type checking is enabled to ensure that Handles are only being casted + /// to the correct type. + /// + /// Generic handle to convert. + /// + /// Thrown if an invalid conversion is made. + /// + explicit Handle(const Handle& genericHandle); ~Handle() = default; /*-----------------------------------------------------------------------------*/ @@ -140,13 +165,48 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ - ResourceLibrary* library = nullptr; + SHResourceLibrary* library = nullptr; /*-----------------------------------------------------------------------------*/ /* Friend Declarations */ /*-----------------------------------------------------------------------------*/ - friend class ResourceLibrary; - }; + friend class SHResourceLibrary; + friend class Handle; + }; + + /// + /// Template Specialization for Handle that represents a type-less Handle. + /// + template<> + class Handle : public HandleBase + { + public: + /*-----------------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------------*/ + Handle() = default; + template + explicit Handle(const Handle& handle); + ~Handle() = default; + + /*-----------------------------------------------------------------------------*/ + /* Overloaded Operators */ + /*-----------------------------------------------------------------------------*/ + template + inline bool operator==(const Handle& rhs) const noexcept; + + protected: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + SHResourceLibraryBase* library = nullptr; + + /*-----------------------------------------------------------------------------*/ + /* Friend Declarations */ + /*-----------------------------------------------------------------------------*/ + template + friend class Handle; + }; /// /// Interface that needs to be implemented by classes that want to store a Handle to @@ -155,7 +215,7 @@ namespace SHADE template class ISelfHandle { - public: + public: /*-----------------------------------------------------------------------------*/ /* Constructors */ /*-----------------------------------------------------------------------------*/ @@ -183,7 +243,7 @@ namespace SHADE /// /// Required to lock usage to ResourceLibrary only. /// Handle to set. - void SetHandle(const ResourceLibrary& rscLib, Handle hdl); + void SetHandle(const SHResourceLibrary& rscLib, Handle hdl); private: /*-----------------------------------------------------------------------------*/ @@ -220,4 +280,4 @@ namespace std }; } -#include "Handle.hpp" \ No newline at end of file +#include "SHHandle.hpp" \ No newline at end of file diff --git a/SHADE_Engine/src/Resource/Handle.hpp b/SHADE_Engine/src/Resource/SHHandle.hpp similarity index 63% rename from SHADE_Engine/src/Resource/Handle.hpp rename to SHADE_Engine/src/Resource/SHHandle.hpp index 45468ec1..53061ac7 100644 --- a/SHADE_Engine/src/Resource/Handle.hpp +++ b/SHADE_Engine/src/Resource/SHHandle.hpp @@ -1,7 +1,7 @@ #pragma once // Primary Header -#include "Handle.h" -#include "ResourceLibrary.h" +#include "SHHandle.h" +#include "SHResourceLibrary.h" namespace SHADE { @@ -20,7 +20,21 @@ namespace SHADE { return id.Raw != INVALID_ID.Raw; } - + + /*---------------------------------------------------------------------------------*/ + /* Handle - Constructors */ + /*---------------------------------------------------------------------------------*/ + template + Handle::Handle(const Handle& genericHandle) + : library { reinterpret_cast*>(genericHandle.library) } + { + id = genericHandle.id; + + // Check if valid + if (library != nullptr && library->GetType() != typeid(T)) + throw BadHandleCastException(); + } + /*---------------------------------------------------------------------------------*/ /* Handle - Usage Functions */ /*---------------------------------------------------------------------------------*/ @@ -63,6 +77,28 @@ namespace SHADE return &library->Get(*this); } + /*---------------------------------------------------------------------------------*/ + /* Handle - Constructors */ + /*---------------------------------------------------------------------------------*/ + template + Handle::Handle(const Handle& handle) + : library{ static_cast(handle.library) } + { + id = handle.id; + } + + /*---------------------------------------------------------------------------------*/ + /* Handle - Overloaded Operators */ + /*---------------------------------------------------------------------------------*/ + template + bool SHADE::Handle::operator==(const Handle& rhs) const noexcept + { + return id.Raw == rhs.id.Raw && library == static_cast(rhs.library); + } + + /*---------------------------------------------------------------------------------*/ + /* ISelfHandle - Constructors */ + /*---------------------------------------------------------------------------------*/ template inline ISelfHandle::ISelfHandle(const ISelfHandle& rhs) : handle { rhs.handle } @@ -73,6 +109,9 @@ namespace SHADE : handle { rhs.handle } {} + /*---------------------------------------------------------------------------------*/ + /* ISelfHandle - Overloaded Operators */ + /*---------------------------------------------------------------------------------*/ template inline ISelfHandle& ISelfHandle::operator=(const ISelfHandle& rhs) { @@ -96,7 +135,7 @@ namespace SHADE return handle; } template - inline void ISelfHandle::SetHandle(const ResourceLibrary&, Handle hdl) + inline void ISelfHandle::SetHandle(const SHResourceLibrary&, Handle hdl) { handle = hdl; } diff --git a/SHADE_Engine/src/Resource/ResourceLibrary.cpp b/SHADE_Engine/src/Resource/SHResourceLibrary.cpp similarity index 87% rename from SHADE_Engine/src/Resource/ResourceLibrary.cpp rename to SHADE_Engine/src/Resource/SHResourceLibrary.cpp index b215b591..db4a8f48 100644 --- a/SHADE_Engine/src/Resource/ResourceLibrary.cpp +++ b/SHADE_Engine/src/Resource/SHResourceLibrary.cpp @@ -1,11 +1,11 @@ #include "SHPch.h" -#include "ResourceLibrary.h" +#include "SHResourceLibrary.h" namespace SHADE { /*-----------------------------------------------------------------------------*/ /* Constructors/Destructors */ /*-----------------------------------------------------------------------------*/ - ResourceManager::~ResourceManager() + SHResourceHub::~SHResourceHub() { // Delete all resources libraries for (auto iter = deleters.rbegin(); iter != deleters.rend(); ++iter) diff --git a/SHADE_Engine/src/Resource/ResourceLibrary.h b/SHADE_Engine/src/Resource/SHResourceLibrary.h similarity index 85% rename from SHADE_Engine/src/Resource/ResourceLibrary.h rename to SHADE_Engine/src/Resource/SHResourceLibrary.h index a5bf0a67..46ae4572 100644 --- a/SHADE_Engine/src/Resource/ResourceLibrary.h +++ b/SHADE_Engine/src/Resource/SHResourceLibrary.h @@ -6,24 +6,42 @@ #include // Project Headers -#include "Handle.h" +#include "SHHandle.h" #include "Resource/SparseSet.h" namespace SHADE { + /// + /// Base class for SHResourceLibrary that holds information about the library type. + /// + class SHResourceLibraryBase + { + public: + /*-----------------------------------------------------------------------------*/ + /* Getter Functions */ + /*-----------------------------------------------------------------------------*/ + inline std::type_index GetType() { return libraryType; } + + protected: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + std::type_index libraryType = typeid(void); + }; + /// /// Generic Resource Library for a specified type of Resource. This object will own /// any resources created using it. /// /// Type of resources that this library stores. template - class ResourceLibrary + class SHResourceLibrary : public SHResourceLibraryBase { public: /*-----------------------------------------------------------------------------*/ /* Constructor */ /*-----------------------------------------------------------------------------*/ - ResourceLibrary(); + SHResourceLibrary(); /*-----------------------------------------------------------------------------*/ /* Usage Functions */ @@ -75,13 +93,13 @@ namespace SHADE /// /// Manages all resources in multiple ResourceLibraries. /// - class ResourceManager final + class SHResourceHub final { public: /*-----------------------------------------------------------------------------*/ /* Constructors/Destructors */ /*-----------------------------------------------------------------------------*/ - ~ResourceManager(); + ~SHResourceHub(); /*-----------------------------------------------------------------------------*/ /* Usage Functions */ @@ -136,10 +154,10 @@ namespace SHADE /* Helper Functions */ /*-----------------------------------------------------------------------------*/ template - ResourceLibrary& getLibrary(); + SHResourceLibrary& getLibrary(); template - const ResourceLibrary& getLibrary() const; + const SHResourceLibrary& getLibrary() const; }; } -#include "ResourceLibrary.hpp" \ No newline at end of file +#include "SHResourceLibrary.hpp" \ No newline at end of file diff --git a/SHADE_Engine/src/Resource/ResourceLibrary.hpp b/SHADE_Engine/src/Resource/SHResourceLibrary.hpp similarity index 79% rename from SHADE_Engine/src/Resource/ResourceLibrary.hpp rename to SHADE_Engine/src/Resource/SHResourceLibrary.hpp index 9aa72ead..411f6bf5 100644 --- a/SHADE_Engine/src/Resource/ResourceLibrary.hpp +++ b/SHADE_Engine/src/Resource/SHResourceLibrary.hpp @@ -1,6 +1,6 @@ #pragma once // Primary Header -#include "ResourceLibrary.h" +#include "SHResourceLibrary.h" // Standard Library #include @@ -10,13 +10,14 @@ namespace SHADE /* ResourceLibrary - Constructor */ /*---------------------------------------------------------------------------------*/ template - ResourceLibrary::ResourceLibrary() + SHResourceLibrary::SHResourceLibrary() { // Type Checking - //static_assert(std::is_copy_assignable_v, "Resource Library's resources must be copy assignable."); - //static_assert(std::is_copy_constructible_v, "Resource Library's resources must be copy constructible."); static_assert(std::is_move_assignable_v, "Resource Library's resources must be move assignable."); static_assert(std::is_move_constructible_v, "Resource Library's resources must be move constructible."); + + // Keep track of the type for conversions + libraryType = typeid(T); } /*---------------------------------------------------------------------------------*/ @@ -24,7 +25,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ template template - Handle ResourceLibrary::Create(Args&&... args) + Handle SHResourceLibrary::Create(Args&&... args) { // Create the handle Handle handle; @@ -55,7 +56,7 @@ namespace SHADE } template - void ResourceLibrary::Free(Handle handle) + void SHResourceLibrary::Free(Handle handle) { assertHandleValid(handle); @@ -63,7 +64,7 @@ namespace SHADE } template - T& ResourceLibrary::Get(Handle handle) + T& SHResourceLibrary::Get(Handle handle) { assertHandleValid(handle); @@ -71,7 +72,7 @@ namespace SHADE } template - const T& ResourceLibrary::Get(Handle handle) const + const T& SHResourceLibrary::Get(Handle handle) const { assertHandleValid(handle); @@ -82,14 +83,14 @@ namespace SHADE /* ResourceLibrary - Helper Functions */ /*---------------------------------------------------------------------------------*/ template - void ResourceLibrary::assertHandleValid(Handle handle) const + void SHResourceLibrary::assertHandleValid(Handle handle) const { if (!handle || handle.id.Data.Version != versionCounts[handle.id.Data.Index]) throw std::invalid_argument("Invalid handle provided!"); } template - inline uint32_t ResourceLibrary::getAvailableFreeIndex() + inline uint32_t SHResourceLibrary::getAvailableFreeIndex() { // Get from the free list if present if (!freeList.empty()) @@ -107,25 +108,25 @@ namespace SHADE /* ResourceManager - Usage Functions */ /*---------------------------------------------------------------------------------*/ template - Handle ResourceManager::Create(Args&&... args) + Handle SHResourceHub::Create(Args&&... args) { return getLibrary().Create(std::forward(args) ...); } template - void ResourceManager::Free(Handle handle) + void SHResourceHub::Free(Handle handle) { getLibrary().Free(handle); } template - T& ResourceManager::Get(Handle handle) + T& SHResourceHub::Get(Handle handle) { return getLibrary().Get(handle); } template - const T& ResourceManager::Get(Handle handle) const + const T& SHResourceHub::Get(Handle handle) const { return getLibrary().Get(handle); } @@ -134,18 +135,18 @@ namespace SHADE /* ResourceManager - Helper Functions */ /*-----------------------------------------------------------------------------*/ template - ResourceLibrary& ResourceManager::getLibrary() + SHResourceLibrary& SHResourceHub::getLibrary() { // Attempt to retrieve the library const std::type_index RSC_TYPE = typeid(T); if (resourceLibs.contains(RSC_TYPE)) { - return *static_cast*>(resourceLibs.at(RSC_TYPE)); + return *static_cast*>(resourceLibs.at(RSC_TYPE)); } else { // Construct library if doesn't exist - ResourceLibrary* lib = new ResourceLibrary(); + SHResourceLibrary* lib = new SHResourceLibrary(); resourceLibs.emplace(RSC_TYPE, static_cast(lib)); // Construct deleter to properly delete objects with void* @@ -156,8 +157,8 @@ namespace SHADE } template - const ResourceLibrary& ResourceManager::getLibrary() const + const SHResourceLibrary& SHResourceHub::getLibrary() const { - return const_cast(this).getLibrary(); + return const_cast(this).getLibrary(); } } diff --git a/SHADE_Engine/src/Resource/SHResourceManager.cpp b/SHADE_Engine/src/Resource/SHResourceManager.cpp new file mode 100644 index 00000000..156c31c7 --- /dev/null +++ b/SHADE_Engine/src/Resource/SHResourceManager.cpp @@ -0,0 +1,95 @@ +/************************************************************************************//*! +\file SHResourceManager.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 21, 2022 +\brief Contains the definition of the functions of the SHResourceManager static + class. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#include "SHpch.h" +// Primary Include +#include "SHResourceManager.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Static Data Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + SHResourceHub SHResourceManager::resourceHub; + std::unordered_map>> SHResourceManager::handlesMap; + std::unordered_map SHResourceManager::assetIdMap; + std::unordered_map> SHResourceManager::typedFreeFuncMap; + std::vector SHResourceManager::loadedAssetData; + + /*-----------------------------------------------------------------------------------*/ + /* Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + void SHResourceManager::Unload(AssetID assetId) + { + // Search each library for the asset ID and try to free it + Handle handle; + for (auto& typedHandleMap : handlesMap) + { + if (typedHandleMap.second.contains(assetId)) + { + // Save handle for later + handle = typedHandleMap.second[assetId]; + // Dispose + typedFreeFuncMap[typedHandleMap.first](assetId); + typedHandleMap.second.erase(assetId); + } + } + + // No handles were found + if (!handle) + return; + + for (auto& typedAssetIdsMap : assetIdMap) + { + if (typedAssetIdsMap.second.contains(handle)) + { + // Dispose + typedAssetIdsMap.second.erase(handle); + } + } + } + + void SHResourceManager::FinaliseChanges() + { + SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem(); + if (gfxSystem == nullptr) + throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed."); + gfxSystem->BuildMeshBuffers(); + gfxSystem->BuildTextures(); + + // Free CPU Resources + for (auto assetId : loadedAssetData) + { + SHAssetManager::Unload(assetId); + } + loadedAssetData.clear(); + } + + /*-----------------------------------------------------------------------------------*/ + /* Query Functions */ + /*-----------------------------------------------------------------------------------*/ + std::optional SHResourceManager::GetAssetID(Handle handle) + { + const Handle GENERIC_HANDLE = Handle(handle); + + // Search each library for the asset ID and try to free it + for (auto& typedAssetIdsMap : assetIdMap) + { + if (typedAssetIdsMap.second.contains(GENERIC_HANDLE)) + { + return typedAssetIdsMap.second[GENERIC_HANDLE]; + } + } + + return {}; + } +} diff --git a/SHADE_Engine/src/Resource/SHResourceManager.h b/SHADE_Engine/src/Resource/SHResourceManager.h new file mode 100644 index 00000000..84f93b10 --- /dev/null +++ b/SHADE_Engine/src/Resource/SHResourceManager.h @@ -0,0 +1,130 @@ +/************************************************************************************//*! +\file SHResourceManager.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 21, 2022 +\brief Contains the definition of the SHResourceManager static class. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +// STL Includes +#include +// Project Includes +#include "SH_API.h" +#include "SHResourceLibrary.h" +#include "Assets/SHAssetMacros.h" + +namespace SHADE +{ + /// + /// Static class responsible for loading and caching runtime resources from their + /// serialised Asset IDs. + /// + class SH_API SHResourceManager + { + public: + /*---------------------------------------------------------------------------------*/ + /* Loading Functions */ + /*---------------------------------------------------------------------------------*/ + /// + /// Loads or retrieves an existing loaded object of the specified type with the + /// specified asset ID. + /// Note that for specific types, the retrieved Handle may not be valid until after + /// FinaliseChanges() is called. + /// + /// + /// Type of resource to load. + /// + /// Asset ID of the resource to load. + /// Handle to a loaded runtime asset. + template + static Handle LoadOrGet(AssetID assetId); + /// + /// Unloads an existing loaded asset. Attempting to unload an invalid Handle will + /// simply do nothing except emit a warning. + /// Faster than the untemplated version. + /// + /// Type of resource to unload. + /// Handle to the resource to unload. + template + static void Unload(Handle assetId); + /// + /// Unloads an existing loaded asset. Attempting to unload an invalid Handle will + /// simply do nothing except emit a warning. + /// Compared to the templated version, this function is slower as it requires + /// searching through the storage of all resource types. + /// + /// Handle to the resource to unload. + static void Unload(AssetID assetId); + /// + /// Needs to be called to finalise all changes to loads. + /// + static void FinaliseChanges(); + + /*---------------------------------------------------------------------------------*/ + /* Query Functions */ + /*---------------------------------------------------------------------------------*/ + /// + /// Retrieves the AssetID associated with a specified Handle. + /// Faster than the untemplated version. + /// + /// Type of resource to get the ID of. + /// Handle to get the AssetID of. + /// + /// AssetID for the specified Handle. If the Handle is invalid, there will be no + /// value. + /// + template + static std::optional GetAssetID(Handle handle); + /// + /// Retrieves the AssetID associated with a specified Handle. + /// Compared to the templated version, this function is slower as it requires + /// searching through the storage of all resource types. + /// + /// Handle to get the AssetID of. + /// + /// AssetID for the specified Handle. If the Handle is invalid, there will be no + /// value. + /// + static std::optional GetAssetID(Handle handle); + + private: + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + using AssetHandleMap = std::unordered_map>; + using HandleAssetMap = std::unordered_map, AssetID>; + using AssetHandleMapRef = std::reference_wrapper; + using HandleAssetMapRef = std::reference_wrapper; + + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + // Handles + static SHResourceHub resourceHub; + static std::unordered_map handlesMap; + static std::unordered_map assetIdMap; + static std::unordered_map> typedFreeFuncMap; + // Pointers to temp CPU resources + static std::vector loadedAssetData; + + /*---------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*---------------------------------------------------------------------------------*/ + /// + /// Retrieves or creates the AssetHandleMap for the specific type if it doesn't exist + /// + /// + /// The type of AssetHandleMap to retrieve. + /// + /// Reference to the AssetHandleMap of the specified type. + template + static std::pair getAssetHandleMap(); + }; +} + +#include "SHResourceManager.hpp" diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp new file mode 100644 index 00000000..54ced715 --- /dev/null +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -0,0 +1,171 @@ +/************************************************************************************//*! +\file SHResourceManager.hpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 21, 2022 +\brief Contains the definition of the function templates of the + SHResourceManager static class. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once +// Primary Include +#include "SHResourceManager.h" +// Project Includes +#include "Assets/SHAssetManager.h" +#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Tools/SHLog.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Loading Functions */ + /*-----------------------------------------------------------------------------------*/ + template + Handle SHResourceManager::LoadOrGet(AssetID assetId) + { + // Check if it is an unsupported type + if (!std::is_same_v && !std::is_same_v) + { + static_assert(true, "Unsupported Resource Type specified for SHResourceManager."); + } + + /* Attempt to get existing loaded asset */ + auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap(); + if (typedHandleMap.get().contains(assetId)) + return Handle(typedHandleMap.get()[assetId]); + + /* Otherwise, we need to load it! */ + // Meshes + if constexpr (std::is_same_v) + { + // Get system + SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem(); + if (gfxSystem == nullptr) + throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed."); + + // Load + const SHMeshAsset* assetData = SHAssetManager::GetMesh(assetId); + if (assetData == nullptr) + { + SHLog::Warning("[SHResourceManager] Attempted to load an asset with an invalid Asset ID."); + return {}; + } + loadedAssetData.emplace_back(assetId); + + Handle meshHandle = gfxSystem->AddMesh + ( + assetData->vertexPosition.size(), + assetData->vertexPosition.data(), + assetData->texCoords.data(), + assetData->vertexTangent.data(), + assetData->vertexNormal.data(), + assetData->indices.size(), + assetData->indices.data() + ); + Handle genericHandle = Handle(meshHandle); + typedHandleMap.get().emplace(assetId, genericHandle); + typedAssetIdMap.get().emplace(genericHandle, assetId); + return meshHandle; + } + // Textures + else if constexpr (std::is_same_v) + { + // Get system + SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem(); + if (gfxSystem == nullptr) + throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed."); + + // Load + const SHTextureAsset* assetData = SHAssetManager::GetTexture(assetId); + if (assetData == nullptr) + { + SHLog::Warning("[SHResourceManager] Attempted to load an asset with an invalid Asset ID."); + return {}; + } + loadedAssetData.emplace_back(assetId); + + Handle texHandle = gfxSystem->AddTexture + ( + assetData->numBytes, + assetData->pixelData, + assetData->width, + assetData->height, + assetData->format, + assetData->mipOffsets + ); + typedHandleMap.get().emplace(assetId, Handle(texHandle)); + return texHandle; + } + } + + template + void SHResourceManager::Unload(Handle assetId) + { + // Check if it is an unsupported type + if (!std::is_same_v && !std::is_same_v) + { + static_assert(true, "Unsupported Resource Type specified for SHResourceManager."); + } + + /* Attempt to get existing loaded asset */ + auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap(); + if (typedHandleMap.get().contains(assetId)) + { + // Dispose + Handle handle = typedHandleMap.get()[assetId]; + Handle typedHandle = static_cast>(handle); + typedHandle.Free(); + typedAssetIdMap.get().erase(handle); + typedHandleMap.get().erase(assetId); + } + else + { + // There's nothing to remove + SHLog::Warning("[SHResourceManager] Attempted to unload an invalid resource. Ignoring."); + } + } + + /*-----------------------------------------------------------------------------------*/ + /* Query Functions */ + /*-----------------------------------------------------------------------------------*/ + template + static std::optional SHResourceManager::GetAssetID(Handle handle) + { + const Handle GENERIC_HANDLE = Handle(handle); + auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap(); + if (typedAssetIdMap.get().contains(GENERIC_HANDLE)) + { + return typedAssetIdMap.GetId()[GENERIC_HANDLE]; + } + + return {}; + } + + /*-----------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------------*/ + template + std::pair SHResourceManager::getAssetHandleMap() + { + const std::type_index TYPE = typeid(ResourceType); + + if (!handlesMap.contains(TYPE)) + { + handlesMap.emplace(TYPE, AssetHandleMap{}); + assetIdMap.emplace(TYPE, HandleAssetMap{}); + typedFreeFuncMap.emplace + ( + TYPE, + [TYPE](AssetID assetId) + { + static_cast>(SHResourceManager::handlesMap[TYPE][assetId]).Free(); + } + ); + } + return std::make_pair(std::ref(handlesMap[TYPE]), std::ref(assetIdMap[TYPE])); + } +} diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index d7a090a4..fea59353 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -115,34 +115,22 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Script Serialisation Functions */ /*---------------------------------------------------------------------------------*/ - std::string SHScriptEngine::SerialiseScripts(EntityID entity) const + bool SHScriptEngine::SerialiseScripts(EntityID entity, YAML::Node& scriptsNode) const { - // Create buffer needed to store serialised script data - constexpr int BUFFER_SIZE = 10240; - std::unique_ptr buffer { new char[BUFFER_SIZE] }; - std::memset(buffer.get(), 0, BUFFER_SIZE); - // Attempt to serialise the script - std::string result; - if (csScriptsSerialise(entity, buffer.get(), BUFFER_SIZE)) - { - result = std::string(buffer.get()); - } - else - { - SHLOG_ERROR("[ScriptEngine] Failed to serialise scripts as string buffer is too small!"); - } + if (csScriptsSerialiseYaml(entity, &scriptsNode)) + return true; - // Return an empty string since we failed to serialise - return result; + SHLOG_ERROR("[ScriptEngine] Failed to serialise scripts for entity #{}.", entity); + return false; } /*-----------------------------------------------------------------------------------*/ /* Script Serialisation Functions */ /*-----------------------------------------------------------------------------------*/ - void SHScriptEngine::DeserialiseScript(EntityID entity, const std::string& yaml) const + bool SHScriptEngine::DeserialiseScripts(EntityID entity, const YAML::Node& scriptsNode) const { - csScriptDeserialise(entity, yaml.c_str()); + return csScriptsDeserialiseYaml(entity, &scriptsNode); } /*-----------------------------------------------------------------------------------*/ @@ -380,30 +368,18 @@ namespace SHADE DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", "RemoveAllScriptsImmediately" ); - /*csScriptsSerialise = dotNet.GetFunctionPtr + csScriptsSerialiseYaml = dotNet.GetFunctionPtr ( DEFAULT_CSHARP_LIB_NAME, DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", "SerialiseScripts" ); - csScriptsSerialiseYaml = dotNet.GetFunctionPtr + csScriptsDeserialiseYaml = dotNet.GetFunctionPtr ( DEFAULT_CSHARP_LIB_NAME, DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", - "SerialiseScriptsYaml" + "DeserialiseScripts" ); - csScriptDeserialise = dotNet.GetFunctionPtr - ( - DEFAULT_CSHARP_LIB_NAME, - DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", - "DeserialiseScript" - ); - csScriptDeserialiseYaml = dotNet.GetFunctionPtr - ( - DEFAULT_CSHARP_LIB_NAME, - DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", - "SerialiseScriptsYaml" - );*/ csEditorRenderScripts = dotNet.GetFunctionPtr ( DEFAULT_CSHARP_LIB_NAME, diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.h b/SHADE_Engine/src/Scripting/SHScriptEngine.h index 60723425..137d978f 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.h +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.h @@ -13,7 +13,8 @@ of DigiPen Institute of Technology is prohibited. // STL Includes #include - +// External Dependencies +#include // Project Headers #include "SH_API.h" #include "SHDotNetRuntime.h" @@ -141,23 +142,26 @@ namespace SHADE /* Script Serialisation Functions */ /*-----------------------------------------------------------------------------*/ /// - /// Generates a JSON string that represents the set of Scripts attached to the - /// specified Entity. + /// Performs serialization of all scripts for the specified entity into the + /// YAML::Node specified. This node will contain all serialised scripts after + /// calling this function. /// - /// The Entity to Serialise. - /// - /// String that represents the set of scripts attached to the specified Entity. - /// - std::string SerialiseScripts(EntityID entity) const; + /// The Entity to Serialise. + /// + /// YAML Node that will store the serialised scripts. + /// + /// True if successfully serialised. + bool SerialiseScripts(EntityID entity, YAML::Node& scriptsNode) const; /// - /// Loads the specified JSON string and creates a Script for the specified Entity - /// based on the specified JSON string. + /// Creates scripts and sets fields for the specified Entity based on the specified + /// YAML node. /// /// The Entity to deserialise a Script on to. - /// - /// The YAML string that represents the Script to load into the Entity. + /// + /// YAML Node that contains the serialised script data. /// - void DeserialiseScript(EntityID entity, const std::string& yaml) const; + /// True if successfully deserialised. + bool DeserialiseScripts(EntityID entity, const YAML::Node& scriptsNode) const; /*-----------------------------------------------------------------------------*/ /* Script Editor Functions */ @@ -207,14 +211,13 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------*/ - using CsFuncPtr = void(*)(void); - using CsScriptManipFuncPtr = bool(*)(EntityID, const char*); - using CsScriptBasicFuncPtr = void(*)(EntityID); - using CsScriptOptionalFuncPtr = void(*)(EntityID, bool); - using CsScriptSerialiseFuncPtr = bool(*)(EntityID, char*, int); - using CsScriptDeserialiseFuncPtr = bool(*)(EntityID, const char*); - using CsScriptSerialiseYamlFuncPtr = bool(*)(EntityID, void*); - using CsScriptEditorFuncPtr = void(*)(EntityID); + using CsFuncPtr = void(*)(void); + using CsScriptManipFuncPtr = bool(*)(EntityID, const char*); + using CsScriptBasicFuncPtr = void(*)(EntityID); + using CsScriptOptionalFuncPtr = void(*)(EntityID, bool); + using CsScriptSerialiseYamlFuncPtr = bool(*)(EntityID, void*); + using CsScriptDeserialiseYamlFuncPtr = bool(*)(EntityID, const void*); + using CsScriptEditorFuncPtr = void(*)(EntityID); /*-----------------------------------------------------------------------------*/ /* Constants */ @@ -228,31 +231,29 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ - SHDotNetRuntime dotNet { false }; + SHDotNetRuntime dotNet { false }; // Function Pointers to CLR Code // - Engine Lifecycle - CsFuncPtr csEngineInit = nullptr; - CsFuncPtr csEngineLoadScripts = nullptr; - CsFuncPtr csEngineUnloadScripts = nullptr; - CsFuncPtr csEngineReloadScripts = nullptr; - CsFuncPtr csEngineExit = nullptr; + CsFuncPtr csEngineInit = nullptr; + CsFuncPtr csEngineLoadScripts = nullptr; + CsFuncPtr csEngineUnloadScripts = nullptr; + CsFuncPtr csEngineReloadScripts = nullptr; + CsFuncPtr csEngineExit = nullptr; // - Scripts Store - CsFuncPtr csScriptsFrameSetUp = nullptr; - CsFuncPtr csScriptsExecuteFixedUpdate = nullptr; - CsFuncPtr csScriptsExecuteUpdate = nullptr; - CsFuncPtr csScriptsExecuteLateUpdate = nullptr; - CsFuncPtr csScriptsFrameCleanUp = nullptr; - CsScriptManipFuncPtr csScriptsAdd = nullptr; - CsScriptBasicFuncPtr csScriptsRemoveAll = nullptr; - CsScriptOptionalFuncPtr csScriptsRemoveAllImmediately = nullptr; - CsScriptSerialiseFuncPtr csScriptsSerialise = nullptr; - CsScriptDeserialiseFuncPtr csScriptDeserialise = nullptr; - CsScriptSerialiseYamlFuncPtr csScriptsSerialiseYaml = nullptr; - CsScriptSerialiseYamlFuncPtr csScriptDeserialiseYaml = nullptr; + CsFuncPtr csScriptsFrameSetUp = nullptr; + CsFuncPtr csScriptsExecuteFixedUpdate = nullptr; + CsFuncPtr csScriptsExecuteUpdate = nullptr; + CsFuncPtr csScriptsExecuteLateUpdate = nullptr; + CsFuncPtr csScriptsFrameCleanUp = nullptr; + CsScriptManipFuncPtr csScriptsAdd = nullptr; + CsScriptBasicFuncPtr csScriptsRemoveAll = nullptr; + CsScriptOptionalFuncPtr csScriptsRemoveAllImmediately = nullptr; + CsScriptSerialiseYamlFuncPtr csScriptsSerialiseYaml = nullptr; + CsScriptDeserialiseYamlFuncPtr csScriptsDeserialiseYaml = nullptr; // - Editor - CsScriptEditorFuncPtr csEditorRenderScripts = nullptr; - CsFuncPtr csEditorUndo = nullptr; - CsFuncPtr csEditorRedo = nullptr; + CsScriptEditorFuncPtr csEditorRenderScripts = nullptr; + CsFuncPtr csEditorUndo = nullptr; + CsFuncPtr csEditorRedo = nullptr; /*-----------------------------------------------------------------------------*/ /* Event Handler Functions */ diff --git a/SHADE_Engine/src/Serialization/SHSerialization.cpp b/SHADE_Engine/src/Serialization/SHSerialization.cpp index e259fbbc..3804db95 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.cpp +++ b/SHADE_Engine/src/Serialization/SHSerialization.cpp @@ -13,6 +13,8 @@ #include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Math/Transform/SHTransformComponent.h" #include "Physics/Components/SHRigidBodyComponent.h" +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Scripting/SHScriptEngine.h" namespace SHADE { @@ -52,11 +54,13 @@ namespace SHADE out << YAML::EndSeq; } - static void DeserializeEntity(YAML::iterator& it, YAML::Node const& node, std::vector& createdEntities, EntityID parentEID = MAX_EID) + static EntityID DeserializeEntity(YAML::iterator& it, YAML::Node const& node, std::vector& createdEntities, EntityID parentEID = MAX_EID) { - if (!node[EIDNode]) - return; - EntityID eid = node[EIDNode].as(); + EntityID eid = MAX_EID; + if(!node) + return eid; + if (node[EIDNode]) + eid = node[EIDNode].as(); std::string name = "Default"; if (node[EntityNameNode]) name = node[EntityNameNode].as(); @@ -77,6 +81,10 @@ namespace SHADE } } } + + // Deserialise scripts + if (node[ScriptsNode]) + SHSystemManager::GetSystem()->DeserialiseScripts(eid, node[ScriptsNode]); } void SHSerialization::DeserializeSceneFromFile(std::filesystem::path const& path) @@ -111,7 +119,11 @@ namespace SHADE { DeserializeEntity(it, (*it), createdEntities); } - + if(createdEntities.empty()) + { + SHLOG_ERROR("Failed to create entities from deserializaiton") + return; + } //Initialize Entity auto entityVecIt = createdEntities.begin(); for (auto it = entities.begin(); it != entities.end(); ++it) @@ -130,17 +142,19 @@ namespace SHADE } } - std::string SHSerialization::SerializeEntitiesToString(std::vector const& entities) + std::string SHSerialization::SerializeEntitiesToString(std::vector const& entities) noexcept { YAML::Emitter out; YAML::Node node; auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); + out << YAML::BeginSeq; for (auto const& eid : entities) { auto entityNode = sceneGraph.GetNode(eid); EmitEntity(entityNode, out); } - return std::basic_string(out.c_str()); + out << YAML::EndSeq; + return std::string(out.c_str()); } void SHSerialization::SerializeEntityToFile(std::filesystem::path const& path) @@ -157,7 +171,7 @@ namespace SHADE node = YAML::Null; return node; } - node.SetStyle(YAML::EmitterStyle::Block); + node.SetStyle(YAML::EmitterStyle::Block); node[EIDNode] = eid; node[EntityNameNode] = entity->name; node[IsActiveNode] = sceneNode->IsActive(); @@ -179,9 +193,38 @@ namespace SHADE components[rttr::type::get().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(rigidbody); } node[ComponentsNode] = components; + + YAML::Node scripts; + SHSystemManager::GetSystem()->SerialiseScripts(eid, scripts); + node[ScriptsNode] = scripts; + return node; } + EntityID SHSerialization::DeserializeEntitiesFromString(std::string const& data, EntityID const& parentEID) noexcept + { + if(data.empty()) + return MAX_EID; + YAML::Node entities = YAML::Load(data.c_str()); + EntityID eid{MAX_EID}; + std::vector createdEntities; + for(auto it = entities.begin(); it != entities.end(); ++it) + { + eid = DeserializeEntity(it, *it, createdEntities, parentEID); + } + if(createdEntities.empty()) + { + SHLOG_ERROR("Failed to create entities from deserializaiton") + return MAX_EID; + } + auto entityVecIt = createdEntities.begin(); + for(auto it = entities.begin(); it != entities.end(); ++it) + { + InitializeEntity(*it, *entityVecIt++); + } + return eid; + } + template, bool> = true> std::optional GetComponentID(YAML::Node const& componentNode) { diff --git a/SHADE_Engine/src/Serialization/SHSerialization.h b/SHADE_Engine/src/Serialization/SHSerialization.h index d247de7a..018bf0c3 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.h +++ b/SHADE_Engine/src/Serialization/SHSerialization.h @@ -21,6 +21,7 @@ namespace SHADE constexpr const char* EIDNode = "EID"; constexpr const char* IsActiveNode = "IsActive"; constexpr const char* NumberOfChildrenNode = "NumberOfChildren"; + constexpr const char* ScriptsNode = "Scripts"; struct SH_API SHSerialization { @@ -28,14 +29,18 @@ namespace SHADE static void SerializeSceneToFile(std::filesystem::path const& path); static std::string SerializeSceneToString(); static void SerializeSceneToEmitter(YAML::Emitter& out); + static void DeserializeSceneFromFile(std::filesystem::path const& path); static void EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out); - static std::string SerializeEntitiesToString(std::vector const& entities); + + static std::string SerializeEntitiesToString(std::vector const& entities) noexcept; static void SerializeEntityToFile(std::filesystem::path const& path); static YAML::Node SerializeEntityToNode(SHSceneNode* sceneNode); + static EntityID DeserializeEntitiesFromString(std::string const& data, EntityID const& parentEID = MAX_EID) noexcept; + static std::vector GetComponentIDList(YAML::Node const& componentsNode); private: static void InitializeEntity(YAML::Node const& entityNode, EntityID const& eid); diff --git a/SHADE_Engine/src/Tools/SHClipboardUtilities.cpp b/SHADE_Engine/src/Tools/SHClipboardUtilities.cpp new file mode 100644 index 00000000..061a5ec6 --- /dev/null +++ b/SHADE_Engine/src/Tools/SHClipboardUtilities.cpp @@ -0,0 +1,49 @@ +#include "SHpch.h" +#include "SHClipboardUtilities.h" + +namespace SHADE +{ + void SHClipboardUtilities::WriteToClipboard(std::string const& str) noexcept + { + if(str.empty()) + return; + HWND const hwnd = GetDesktopWindow(); + OpenClipboard(hwnd); + EmptyClipboard(); + + auto const size = str.size() + 1; + const HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, size); + if(hGlobal) + { + std::memcpy(GlobalLock(hGlobal), str.c_str(), size); + GlobalUnlock(hGlobal); + SetClipboardData(CF_TEXT, hGlobal); + } + else + { + SHLOG_ERROR("Failed to write to clipboard: {}", str.c_str()) + } + CloseClipboard(); + GlobalFree(hGlobal); + } + + std::string const SHClipboardUtilities::GetDataFromClipboard() noexcept + { + HWND const hwnd = GetDesktopWindow(); + if(!OpenClipboard(hwnd)) + { + SHLOG_ERROR("Failed to open clipboard") + return std::string(); + } + + if(HANDLE const dataHandle = GetClipboardData(CF_TEXT); dataHandle) + { + std::string data(static_cast(GlobalLock(dataHandle))); + GlobalUnlock(dataHandle); + CloseClipboard(); + return data; + } + CloseClipboard(); + return std::string(); + } +} diff --git a/SHADE_Engine/src/Tools/SHClipboardUtilities.h b/SHADE_Engine/src/Tools/SHClipboardUtilities.h new file mode 100644 index 00000000..7f3acdbe --- /dev/null +++ b/SHADE_Engine/src/Tools/SHClipboardUtilities.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +namespace SHADE +{ + class SHClipboardUtilities + { + public: + static void WriteToClipboard(std::string const& str) noexcept; + static std::string const GetDataFromClipboard() noexcept; + }; +} \ No newline at end of file diff --git a/SHADE_Managed/src/Scripts/ScriptStore.cxx b/SHADE_Managed/src/Scripts/ScriptStore.cxx index 252ab071..b6bc1815 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.cxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.cxx @@ -26,6 +26,7 @@ of DigiPen Institute of Technology is prohibited. #include "Utility/Convert.hxx" #include "Script.hxx" #include "Engine/Entity.hxx" +#include "Serialisation/ReflectionUtilities.hxx" namespace SHADE { @@ -470,72 +471,90 @@ namespace SHADE } SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") } - bool ScriptStore::SerialiseScripts(Entity entity, System::Text::StringBuilder^ buffer, int bufferSize) + + bool ScriptStore::SerialiseScripts(Entity entity, System::IntPtr yamlNodePtr) { SAFE_NATIVE_CALL_BEGIN - // Create a buffer that we can work with temporarily - System::Text::StringBuilder^ jsonString = gcnew System::Text::StringBuilder(); + // Convert to pointer + YAML::Node* yamlNode = reinterpret_cast(yamlNodePtr.ToPointer()); + // Check if yamlNode is valid + if (yamlNode == nullptr) + { + Debug::LogWarning("[ScriptStore] Attempted to serialise scripts with an invalid YAML Node! Skipping."); + return false; + } + // Check if entity exists, otherwise nothing if (!EntityUtils::IsValid(entity)) - return true; - + { + Debug::LogWarning("[ScriptStore] Attempted to serialise scripts for an invalid Entity! Skipping."); + return false; + } + // Check if entity exists in the script storage - if (!scripts.ContainsKey(entity)) + if (!scripts.ContainsKey(entity)) return true; // Serialise each script + yamlNode->SetStyle(YAML::EmitterStyle::Block); System::Collections::Generic::List^ scriptList = scripts[entity]; - for (int i = 0; i < scriptList->Count; ++i) + for each (Script^ script in scriptList) { - throw gcnew System::NotImplementedException; - //jsonString->Append(ReflectionUtilities::Serialise(scriptList[i])); - - // Only add separator if is not last script - if (i != scriptList->Count - 1) - { - jsonString->Append(",\r\n"); - } + ReflectionUtilities::Serialise(script, *yamlNode); } - // Check if the size is too big - if (jsonString->Length > bufferSize) - return false; - - // Otherwise we copy it over - buffer->Clear(); - buffer->Append(jsonString->ToString()); return true; SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") return false; } - bool ScriptStore::DeserialiseScript(Entity entity, System::String^ yaml) + bool ScriptStore::DeserialiseScripts(Entity entity, System::IntPtr yamlNodePtr) { SAFE_NATIVE_CALL_BEGIN + // Convert to pointer + YAML::Node* yamlNode = reinterpret_cast(yamlNodePtr.ToPointer()); + + // Check if yamlNode is valid + if (yamlNode == nullptr) + { + Debug::LogWarning("[ScriptStore] Attempted to deserialise scripts with an invalid YAML Node! Skipping."); + return false; + } + // Check if entity exists, otherwise nothing if (!EntityUtils::IsValid(entity)) - return false; - - // Get the name of the script - const int FIRST_QUOTE = yaml->IndexOf('\"'); - const int FIRST_COLON = yaml->IndexOf(':'); - if (FIRST_QUOTE < 0 || FIRST_COLON < 0) // No script name, it's invalid - return false; - const int SCRIPT_NAME_START = FIRST_QUOTE + 1; - const int SCRIPT_NAME_END = FIRST_COLON - 1; - System::String^ typeName = yaml->Substring(SCRIPT_NAME_START, SCRIPT_NAME_END - SCRIPT_NAME_START); - - // Create the script - Script^ script; - if (AddScriptViaNameWithRef(entity, typeName, script)) { - // Copy the data in - throw gcnew System::NotImplementedException; - //ReflectionUtilities::Deserialise(json, script); - return true; + Debug::LogWarning("[ScriptStore] Attempted to deserialise scripts for an invalid Entity! Skipping."); + return false; } + // Go through all elements in the node + for (YAML::Node& node : *yamlNode) + { + // Get the name of the script + if (!node["Type"]) + { + Debug::LogWarning("[ScriptStore] Script with no type detected, skipping."); + continue; + } + + System::String^ typeName = Convert::ToCLI(node["Type"].as()); + + // Create + Script^ script; + if (AddScriptViaNameWithRef(entity, typeName, script)) + { + // Copy the data in + ReflectionUtilities::Deserialise(script, node); + } + else + { + Debug::LogWarning("[ScriptStore] Script with unloaded type detected, skipping."); + } + } + return true; + SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") return false; } diff --git a/SHADE_Managed/src/Scripts/ScriptStore.hxx b/SHADE_Managed/src/Scripts/ScriptStore.hxx index cc0c1db5..4a9be721 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.hxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.hxx @@ -17,6 +17,7 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "Engine/Entity.hxx" #include "Script.hxx" +#include "Serialization/SHSerialization.h" namespace SHADE { @@ -237,27 +238,23 @@ namespace SHADE /* Serialisation Functions */ /*-----------------------------------------------------------------------------*/ /// - /// Generates a JSON string that represents the set of Scripts attached - /// to the specified Entity. + /// Populates a YAML node with the scripts for a specified Entity. ///

/// This function should only be called from native unmanaged code. ///
/// The Entity to Serialise. - /// - /// StringBuilder handle that maps to a native char array that will contain the - /// serialised string. - /// - /// - /// The size of the char array. + /// + /// Pointer to a YAML::Node that will be populated with all of the serialised + /// scripts and their associated fields. /// /// /// True if serialisation is successful. False if the buffer is too small for /// the serialised output. /// - static bool SerialiseScripts(Entity entity, System::Text::StringBuilder^ buffer, int bufferSize); + static bool SerialiseScripts(Entity entity, System::IntPtr yamlNode); /// - /// Processes a JSON string that represents a single Script and attaches - /// it onto the specified Entity. + /// Processes a YAML node that contains a list of multiple scripts to be loaded + /// into the specified Entity. ///

/// This function should only be called from native unmanaged code. ///
@@ -265,10 +262,10 @@ namespace SHADE /// The Entity to attach the deserialised Scripts to. /// /// - /// JSON string that describes the Script to serialise. + /// Pointer to the YAML::Node that contains serialized script data. /// /// - static bool DeserialiseScript(Entity entity, System::String^ yaml); + static bool DeserialiseScripts(Entity entity, System::IntPtr yamlNode); private: /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx b/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx index 2a9cc57c..3e963818 100644 --- a/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx +++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx @@ -38,6 +38,11 @@ if (iter != jsonValue.MemberEnd()) \ vec.MEMBER = iter->value.GetDouble(); \ } \ +/*-------------------------------------------------------------------------------------*/ +/* File-Level Constants */ +/*-------------------------------------------------------------------------------------*/ +static const std::string_view SCRIPT_TYPE_YAMLTAG = "Type"; + /*-------------------------------------------------------------------------------------*/ /* Function Definitions */ /*-------------------------------------------------------------------------------------*/ @@ -61,13 +66,14 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Serialisation Functions */ /*---------------------------------------------------------------------------------*/ - void ReflectionUtilities::Serialise(System::Object^ object, YAML::Emitter& yaml) + void ReflectionUtilities::Serialise(System::Object^ object, YAML::Node& scriptListNode) { using namespace System::Reflection; // Create YAML object - yaml << YAML::Key << Convert::ToNative(object->GetType()->FullName); - yaml << YAML::BeginMap; + YAML::Node scriptNode; + scriptNode.SetStyle(YAML::EmitterStyle::Block); + scriptNode[SCRIPT_TYPE_YAMLTAG.data()] = Convert::ToNative(object->GetType()->FullName); // Get all fields System::Collections::Generic::IEnumerable^ fields = GetInstanceFields(object); @@ -78,12 +84,12 @@ namespace SHADE continue; // Serialise - writeFieldIntoYaml(field, object, yaml); + writeFieldIntoYaml(field, object, scriptNode); } - yaml << YAML::EndMap; + scriptListNode.push_back(scriptNode); } - void ReflectionUtilities::Deserialise(YAML::Node& yamlNode, Object^ object) + void ReflectionUtilities::Deserialise(Object^ object, YAML::Node& yamlNode) { using namespace System::Reflection; @@ -117,53 +123,63 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Serialization Helper Functions */ /*---------------------------------------------------------------------------------*/ - void ReflectionUtilities::writeFieldIntoYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Emitter& yaml) + void ReflectionUtilities::writeFieldIntoYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& yamlNode) { - // Field Name - yaml << YAML::Key << Convert::ToNative(fieldInfo->Name); - - // Field Value - yaml << YAML::Value; - if (fieldInsertYaml (fieldInfo, object, yaml) || - fieldInsertYaml (fieldInfo, object, yaml) || - fieldInsertYaml (fieldInfo, object, yaml) || - fieldInsertYaml(fieldInfo, object, yaml) || - fieldInsertYaml(fieldInfo, object, yaml) || - fieldInsertYaml(fieldInfo, object, yaml) || - fieldInsertYaml (fieldInfo, object, yaml) || - fieldInsertYaml (fieldInfo, object, yaml) || - fieldInsertYaml (fieldInfo, object, yaml) || - fieldInsertYaml (fieldInfo, object, yaml)) + // Field YAML Node + YAML::Node fieldNode; + + // Retrieve string for the YAML + const bool PRIMITIVE_SERIALIZED = fieldInsertYaml(fieldInfo, object, fieldNode) || + fieldInsertYaml(fieldInfo, object, fieldNode) || + fieldInsertYaml(fieldInfo, object, fieldNode) || + fieldInsertYaml(fieldInfo, object, fieldNode) || + fieldInsertYaml(fieldInfo, object, fieldNode) || + fieldInsertYaml(fieldInfo, object, fieldNode) || + fieldInsertYaml(fieldInfo, object, fieldNode) || + fieldInsertYaml(fieldInfo, object, fieldNode) || + fieldInsertYaml(fieldInfo, object, fieldNode) || + fieldInsertYaml(fieldInfo, object, fieldNode); + + // Serialization of more complex types + if (!PRIMITIVE_SERIALIZED) { - return; - } - else if (fieldInfo->FieldType->IsSubclassOf(System::Enum::typeid)) - { - yaml << safe_cast(fieldInfo->GetValue(object)); - } - else if (fieldInfo->FieldType == System::String::typeid) - { - System::String^ str = safe_cast(fieldInfo->GetValue(object)); - yaml << Convert::ToNative(str); - } - else if (fieldInfo->FieldType == Vector2::typeid) - { - Vector2 vec = safe_cast(fieldInfo->GetValue(object)); - yaml << YAML::BeginSeq << YAML::Flow << vec.x << vec.y << YAML::EndSeq; - } - else if (fieldInfo->FieldType == Vector3::typeid) - { - Vector3 vec = safe_cast(fieldInfo->GetValue(object)); - yaml << YAML::BeginSeq << YAML::Flow << vec.x << vec.y << vec.z << YAML::EndSeq; - } - else // Not any of the supported types - { - Debug::LogWarning(Convert::ToNative(System::String::Format - ( - "[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for serialization.", - fieldInfo->Name, fieldInfo->FieldType) - )); + if (fieldInfo->FieldType->IsSubclassOf(System::Enum::typeid)) + { + fieldNode = std::to_string(safe_cast(fieldInfo->GetValue(object))); + } + else if (fieldInfo->FieldType == System::String::typeid) + { + System::String^ str = safe_cast(fieldInfo->GetValue(object)); + fieldNode = Convert::ToNative(str); + } + else if (fieldInfo->FieldType == Vector2::typeid) + { + Vector2 vec = safe_cast(fieldInfo->GetValue(object)); + fieldNode.SetStyle(YAML::EmitterStyle::Flow); + fieldNode.push_back(vec.x); + fieldNode.push_back(vec.y); + } + else if (fieldInfo->FieldType == Vector3::typeid) + { + Vector3 vec = safe_cast(fieldInfo->GetValue(object)); + fieldNode.SetStyle(YAML::EmitterStyle::Flow); + fieldNode.push_back(vec.x); + fieldNode.push_back(vec.y); + fieldNode.push_back(vec.z); + } + else // Not any of the supported types + { + Debug::LogWarning(Convert::ToNative(System::String::Format + ( + "[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for serialization.", + fieldInfo->Name, fieldInfo->FieldType) + )); + return; + } } + + // Store the field into YAML + yamlNode[Convert::ToNative(fieldInfo->Name)] = fieldNode; } void ReflectionUtilities::writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node) diff --git a/SHADE_Managed/src/Serialisation/ReflectionUtilities.h++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.h++ index 88469b34..7c39232a 100644 --- a/SHADE_Managed/src/Serialisation/ReflectionUtilities.h++ +++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.h++ @@ -23,11 +23,12 @@ namespace SHADE /* Serialization Helper Functions */ /*---------------------------------------------------------------------------------*/ template - bool ReflectionUtilities::fieldInsertYaml(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, YAML::Emitter& emitter) + bool ReflectionUtilities::fieldInsertYaml(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, YAML::Node& fieldNode) { if (fieldInfo->FieldType == FieldType::typeid) { - emitter << safe_cast(fieldInfo->GetValue(object)); + const FieldType VALUE = safe_cast(fieldInfo->GetValue(object)); + fieldNode = static_cast(VALUE); return true; } @@ -37,7 +38,7 @@ namespace SHADE template bool ReflectionUtilities::fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node) { - return fieldAssignYaml(fieldInfo, object, node); + return fieldAssignYaml>(fieldInfo, object, node); } template diff --git a/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx b/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx index 53f8fa1d..403c913c 100644 --- a/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx +++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx @@ -52,24 +52,24 @@ namespace SHADE /// attribute will be serialised. /// /// The object to serialise. - static void Serialise(System::Object^ object, YAML::Emitter& yaml); + static void Serialise(System::Object^ object, YAML::Node& yamlNode); /// /// Deserialises a YAML node that contains a map of Scripts and copies the /// deserialised data into the specified object if there are matching fields. /// /// - /// The JSON string that contains the data to copy into this PlushieScript - /// object. + /// The JSON string that contains the data to copy into this Script object. /// /// The object to copy deserialised data into. - static void Deserialise(YAML::Node& yamlNode, Object^ object); + static void Deserialise(System::Object^ object, YAML::Node& yamlNode); + private: /*-----------------------------------------------------------------------------*/ /* Serialization Helper Functions */ /*-----------------------------------------------------------------------------*/ - static void writeFieldIntoYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Emitter& yaml); + static void writeFieldIntoYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& yamlNode); template - static bool fieldInsertYaml(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, YAML::Emitter& emitter); + static bool fieldInsertYaml(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, YAML::Node& fieldNode); static void writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node); template static bool fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node); diff --git a/SHADE_Managed/src/Utility/Convert.hxx b/SHADE_Managed/src/Utility/Convert.hxx index b41ffef4..f04cbf4b 100644 --- a/SHADE_Managed/src/Utility/Convert.hxx +++ b/SHADE_Managed/src/Utility/Convert.hxx @@ -91,4 +91,68 @@ namespace SHADE /// Managed copy of a native std::string. static System::String^ ToCLI(const std::string& str); }; + + /// + /// Type Transformer for managed types to native types. + /// + /// + /// Managed type to get the native type for. + /// + template + struct ToNativeType + { + public: + using Value = void; + }; + template<> struct ToNativeType { using Value = int16_t; }; + template<> struct ToNativeType { using Value = int32_t; }; + template<> struct ToNativeType { using Value = int64_t; }; + template<> struct ToNativeType { using Value = uint16_t; }; + template<> struct ToNativeType { using Value = uint32_t; }; + template<> struct ToNativeType { using Value = uint64_t; }; + template<> struct ToNativeType { using Value = int8_t; }; + template<> struct ToNativeType { using Value = bool; }; + template<> struct ToNativeType { using Value = double; }; + template<> struct ToNativeType { using Value = float; }; + + /// + /// Alias for ToNativeType::Value + /// + /// + /// Managed type to get the native type for. + /// + template + using ToNativeType_T = typename ToNativeType::Value; + + /// + /// Type Transformer for native types to managed types. + /// + /// + /// Managed type to get the native type for. + /// + template + struct ToManagedType + { + public: + using Value = void; + }; + template<> struct ToManagedType { using Value = System::Byte; }; + template<> struct ToManagedType { using Value = System::Int16; }; + template<> struct ToManagedType { using Value = System::Int32; }; + template<> struct ToManagedType { using Value = System::Int64; }; + template<> struct ToManagedType { using Value = System::UInt16; }; + template<> struct ToManagedType { using Value = System::UInt32; }; + template<> struct ToManagedType { using Value = System::UInt64; }; + template<> struct ToManagedType { using Value = bool; }; + template<> struct ToManagedType { using Value = double; }; + template<> struct ToManagedType { using Value = float; }; + + /// + /// Alias for ToManagedType::Value + /// + /// + /// Managed type to get the native type for. + /// + template + using ToManagedType_T = typename ToManagedType::Value; }