Merge branch 'main' into SP3-6-c-scripting

This commit is contained in:
Kah Wei 2022-10-22 21:36:40 +08:00
commit 885f22c984
89 changed files with 2592 additions and 259 deletions

Binary file not shown.

View File

@ -1,48 +0,0 @@
[Window][MainStatusBar]
Pos=0,1060
Size=1920,20
Collapsed=0
[Window][SHEditorMenuBar]
Pos=0,48
Size=1920,1012
Collapsed=0
[Window][Hierarchy Panel]
Pos=0,142
Size=571,918
Collapsed=0
DockId=0x00000004,0
[Window][Debug##Default]
Pos=60,60
Size=400,400
Collapsed=0
[Window][Inspector]
Pos=1649,48
Size=271,1012
Collapsed=0
DockId=0x00000006,0
[Window][Profiler]
Pos=0,48
Size=571,92
Collapsed=0
DockId=0x00000003,0
[Window][Viewport]
Pos=573,48
Size=1074,1012
Collapsed=0
DockId=0x00000002,0
[Docking][Data]
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=571,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=1074,1036 CentralNode=1 Selected=0x13926F0B
DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=271,1036 Selected=0xE7039252

View File

@ -149,11 +149,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();
}

View File

@ -1,4 +1,4 @@
#include "SBpch.h"
#include "SBpch.h"
#include "SBTestScene.h"
#include "ECS_Base/Managers/SHSystemManager.h"
@ -14,6 +14,7 @@
#include "Physics/Components/SHColliderComponent.h"
#include "Assets/SHAssetManager.h"
#include "Resource/SHResourceManager.h"
using namespace SHADE;
@ -40,34 +41,22 @@ namespace Sandbox
const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem);
//Test Racoon mesh
auto meshes = SHADE::SHAssetManager::GetAllMeshes();
std::vector<Handle<SHMesh>> handles;
for (auto const& mesh : meshes)
std::vector<Handle<SHTexture>> 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<SHMesh>(asset.id));
break;
case AssetType::TEXTURE:
texHandles.emplace_back(SHResourceManager::LoadOrGet<SHTexture>(asset.id));
break;
}
}
graphicsSystem->BuildMeshBuffers();
// Load Textures
auto textures = SHADE::SHAssetManager::GetAllTextures();
std::vector<Handle<SHTexture>> 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();
@ -78,8 +67,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 };

View File

@ -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()))
{

View File

@ -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

View File

@ -154,7 +154,6 @@ namespace SHADE
target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw));
target =SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch));
std::cout << "Target vec: " << target.x<<", "<<target.y<<", "<<target.z << std::endl;
target += camera.position;
////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll));

View File

@ -24,6 +24,7 @@ namespace SHADE
class SHCommand : SHBaseCommand
{
public:
using SHCommandPtr = std::unique_ptr<T>;
typedef std::function<void(T const&)> SetterFunction;
SHCommand(T const& oldVal, T const& value, SetterFunction setFnc)

View File

@ -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

View File

@ -19,16 +19,21 @@ namespace SHADE
//#==============================================================#
//|| Type Aliases ||
//#==============================================================#
using CommandPtr = std::shared_ptr<SHBaseCommand>;
using CommandStack = std::stack<CommandPtr>;
using BaseCommandPtr = std::shared_ptr<SHBaseCommand>;
template<typename T>
using SHCommandPtr = std::shared_ptr<SHCommand<T>>;
using CommandStack = std::stack<BaseCommandPtr>;
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;

View File

@ -22,6 +22,7 @@
#include <imgui.h>
#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<SHCreateEntityCommand>());
}
if (ImGui::IsItemHovered())
{
@ -144,23 +148,32 @@ namespace SHADE
auto* entity = SHEntityManager::GetEntityByID(currentNode->GetEntityID());
//Draw Node
bool isNodeOpen = ImGui::TreeNodeEx(reinterpret_cast<void*>(entity), nodeFlags, "%u: %s", EntityHandleGenerator::GetIndex(eid), entity->name.c_str());
bool isNodeOpen = ImGui::TreeNodeEx(reinterpret_cast<void*>(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<EntityID>(DRAG_EID, &eid);
std::string moveLabel = "Moving EID: ";
if(!isSelected)
editor->selectedEntities.push_back(eid);
for(int i = 0; i < static_cast<int>(editor->selectedEntities.size()); ++i)
{
moveLabel.append(std::to_string(editor->selectedEntities[i]));
if(i + 1 < static_cast<int>(editor->selectedEntities.size()))
{
moveLabel.append(", ");
}
}
ImGui::Text(moveLabel.c_str());
SHDragDrop::SetPayload<std::vector<EntityID>>(DRAG_EID, &editor->selectedEntities);
SHDragDrop::EndSource();
}
else if (SHDragDrop::BeginTarget()) //If Received DragDrop
{
if (const EntityID* eidPayload = SHDragDrop::AcceptPayload<EntityID>(DRAG_EID)) //If payload is valid
if (const std::vector<EntityID>* eidPayload = SHDragDrop::AcceptPayload<std::vector<EntityID>>(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<SHEditor>();
SHEntityParentCommand::EntityParentData entityParentData;
std::vector<EntityID> 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<SHEntityParentCommand>(parentedEIDS, entityParentData));
}
void SHHierarchyPanel::SelectRangeOfEntities(EntityID beginEID, EntityID endEID)
{
bool startSelecting = false; bool endSelecting = false;
auto const editor = SHSystemManager::GetSystem<SHEditor>();
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

View File

@ -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<EntityID, Data>;
SHEntityParentCommand(std::vector<EntityID> entityIDs, EntityParentData inEntityParentData):entities(entityIDs),entityParentData(inEntityParentData){}
void Execute() override;
void Undo() override;
private:
std::vector<EntityID> entities;
std::unordered_map<EntityID, Data> entityParentData;
};
}//namespace SHADE

View File

@ -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<SHBoundingBox*>(collider.GetShape());
SHEditorWidgets::DragVec3("Half Extents", { "X", "Y", "Z" }, [box] {return box->GetHalfExtents(); }, [box](SHVec3 const& vec) {box->SetHalfExtents(vec);});
}

View File

@ -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();

View File

@ -3,6 +3,7 @@
#include <imgui.h>
#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<int>(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();
}

View File

@ -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();

View File

@ -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

View File

@ -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 <Editor/IconsFontAwesome6.h>
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<SHGraphicsSystem>();
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<SHEditor>();
// editor->selectedEntities.clear();
// editor->selectedEntities.push_back(eid);
// if (const auto hierarchyPanel = SHEditorWindowManager::GetEditorWindow<SHHierarchyPanel>())
// {
// 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<uint32_t>(windowSize.x), static_cast<uint32_t>(windowSize.y));
if(beginContentRegionAvailable.x == 0 || beginContentRegionAvailable.y == 0)
{
beginContentRegionAvailable = windowSize;
}
gfxSystem->PrepareResize(static_cast<uint32_t>(beginContentRegionAvailable.x), static_cast<uint32_t>(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();
}
}

View File

@ -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

View File

@ -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 <imgui.h>
#include <ImGuizmo.h>
#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<SHCameraSystem>();
editorCamera = cameraSystem->GetEditorCamera();
}
auto viewportWindow = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>();
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<SHEditor>();
if (editor->selectedEntities.empty())
return;
EntityID eid = editor->selectedEntities.back();
selectedEntityTransformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
justChangedTfm = true;
}
else
{
SHEditor* editor = SHSystemManager::GetSystem<SHEditor>();
if (editor->selectedEntities.empty())
return;
EntityID eid = editor->selectedEntities.back();
auto tfmComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(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<ImGuizmo::OPERATION>(operation), ImGuizmo::MODE::WORLD, &mat._11);
if (!justChangedTfm)
{
if (ImGui::IsItemClicked())
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHMatrix>>(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<SHBaseCommand>(std::make_shared<SHCommand<SHMatrix>>(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);
}
}
}

View File

@ -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};
};
}

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@
#include "SHpch.h"
#include "IconsMaterialDesign.h"
#include "IconsFontAwesome6.h"
#include "DragDrop/SHDragDrop.hpp"
//#==============================================================#
@ -36,6 +37,7 @@
#include <imgui.h>
#include <SDL.h>
#include <rttr/registration>
#include <ImGuizmo.h>
//#==============================================================#
//|| ImGui Backend Includes ||
@ -87,10 +89,10 @@ namespace SHADE
//Add editor windows
SHEditorWindowManager::CreateEditorWindow<SHEditorMenuBar>();
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
SHEditorWindowManager::CreateEditorWindow<SHHierarchyPanel>();
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
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<SHGraphicsSystem>())
{
auto viewportWindow = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>();
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();
}

View File

@ -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

View File

@ -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

View File

@ -3,7 +3,7 @@
#include "Graphics/SHVulkanIncludes.h"
#include "vk_mem_alloc.h"
#include "Resource/Handle.h"
#include "Resource/SHHandle.h"
namespace SHADE
{

View File

@ -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"
namespace SHADE
@ -36,7 +36,7 @@ namespace SHADE
class SHVkCommandBuffer
{
friend class SHVkCommandPool;
friend class ResourceLibrary<SHVkCommandBuffer>;
friend class SHResourceLibrary<SHVkCommandBuffer>;
static constexpr uint16_t PUSH_CONSTANT_SIZE = 512;
private:

View File

@ -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

View File

@ -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
{

View File

@ -2,7 +2,7 @@
// Project Includes
#include "Graphics/SHVulkanIncludes.h"
#include "Resource/Handle.h"
#include "Resource/SHHandle.h"
namespace SHADE
{

View File

@ -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"

View File

@ -2,7 +2,7 @@
// Project Includes
#include "Graphics/SHVulkanIncludes.h"
#include "Resource/Handle.h"
#include "Resource/SHHandle.h"
namespace SHADE
{

View File

@ -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"

View File

@ -2,7 +2,7 @@
#define SH_VK_FRAMEBUFFER_H
#include "Graphics/SHVulkanIncludes.h"
#include "Resource/Handle.h"
#include "Resource/SHHandle.h"
#include <span>
namespace SHADE

View File

@ -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

View File

@ -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

View File

@ -15,7 +15,7 @@ of DigiPen Institute of Technology is prohibited.
#include <vector>
// Project Includes
#include "Graphics/SHVulkanIncludes.h"
#include "Resource/Handle.h"
#include "Resource/SHHandle.h"
namespace SHADE
{

View File

@ -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;
}

View File

@ -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;
};
}

View File

@ -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"

View File

@ -15,7 +15,7 @@ of DigiPen Institute of Technology is prohibited.
// STL Includes
#include <vector>
// Project Includes
#include "Resource/Handle.h"
#include "Resource/SHHandle.h"
namespace SHADE
{

View File

@ -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"

View File

@ -585,19 +585,19 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
/* Texture Registration Functions */
/*---------------------------------------------------------------------------------*/
Handle<SHTexture> SHGraphicsSystem::Add(const SHTextureAsset& texAsset)
Handle<SHTexture> SHGraphicsSystem::AddTexture(const SHTextureAsset& texAsset)
{
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams { .maxLod = static_cast<float>(texAsset.mipOffsets.size()) });
return texLibrary.Add(texAsset, sampler);
}
SHADE::Handle<SHADE::SHTexture> SHGraphicsSystem::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets)
SHADE::Handle<SHADE::SHTexture> SHGraphicsSystem::AddTexture(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets)
{
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams{ .maxLod = static_cast<float>(mipOffsets.size()) });
return texLibrary.Add(pixelCount, pixelData, width, height, format, mipOffsets, sampler);
}
void SHGraphicsSystem::Remove(Handle<SHTexture> tex)
void SHGraphicsSystem::RemoveTexture(Handle<SHTexture> tex)
{
texLibrary.Remove(tex);
}

View File

@ -17,7 +17,7 @@ of DigiPen Institute of Technology is prohibited.
#include <array>
// 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<SHTexture> Add(const SHTextureAsset& texAsset);
Handle<SHTexture> Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets);
Handle<SHTexture> AddTexture(const SHTextureAsset& texAsset);
Handle<SHTexture> AddTexture(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets);
/*******************************************************************************/
/*!
@ -246,7 +246,7 @@ namespace SHADE
*/
/*******************************************************************************/
void Remove(Handle<SHTexture> tex);
void RemoveTexture(Handle<SHTexture> tex);
/***************************************************************************/
/*!
@ -313,7 +313,7 @@ namespace SHADE
SHWindow* window = nullptr;
// Middle End Resources
ResourceManager resourceManager;
SHResourceHub resourceManager;
SHMeshLibrary meshLibrary;
SHTextureLibrary texLibrary;
SHSamplerCache samplerCache;

View File

@ -15,7 +15,7 @@ of DigiPen Institute of Technology is prohibited.
// STL Includes
#include <unordered_map>
// Project Includes
#include "Resource/Handle.h"
#include "Resource/SHHandle.h"
#include "SHCommonTypes.h"
namespace SHADE

View File

@ -13,7 +13,7 @@ of DigiPen Institute of Technology is prohibited.
// STL Includes
#include <memory>
// Project Includes
#include "Resource/Handle.h"
#include "Resource/SHHandle.h"
#include "Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h"
#include "SH_API.h"

View File

@ -15,8 +15,8 @@ of DigiPen Institute of Technology is prohibited.
// STL Includes
#include <vector>
// 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<MeshAddJob> meshAddJobs;
std::vector<Handle<SHMesh>> meshRemoveJobs;
// Tracking
ResourceLibrary<SHMesh> meshes{};
SHResourceLibrary<SHMesh> meshes{};
std::vector<Handle<SHMesh>> meshOrder;
// CPU Storage
std::vector<SHMesh::VertexPosition> vertPosStorage;

View File

@ -1,6 +1,6 @@
#pragma once
#include "Resource/Handle.h"
#include "Resource/SHHandle.h"
namespace SHADE
{

View File

@ -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"

View File

@ -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 <vector>

View File

@ -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<SHRenderer> SHViewport::AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHRenderGraph> renderGraph)
Handle<SHRenderer> SHViewport::AddRenderer(SHResourceHub& resourceManager, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHRenderGraph> renderGraph)
{
// Create the renderer
auto renderer = resourceManager.Create<SHRenderer>(device, numFrames, cmdPools, descriptorPool, cameraDescLayout, GetHandle(), renderGraph);

View File

@ -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<SHRenderer> AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHRenderGraph> renderGraph);
Handle<SHRenderer> AddRenderer(SHResourceHub& resourceManager, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHRenderGraph> renderGraph);
void RemoveRenderer(Handle<SHRenderer> renderer);
/*-----------------------------------------------------------------------------*/

View File

@ -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<SHADE::SHMaterialInstance> SHMaterialInstanceCache::CreateOrGet(ResourceManager& manager, Handle<SHMaterial> material)
SHADE::Handle<SHADE::SHMaterialInstance> SHMaterialInstanceCache::CreateOrGet(SHResourceHub& manager, Handle<SHMaterial> material)
{
// Check if there is already an existing instance
auto matInst = cache.find(material);

View File

@ -15,7 +15,7 @@ of DigiPen Institute of Technology is prohibited.
// STL Includes
#include <unordered_map>
// 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<SHMaterialInstance> CreateOrGet(ResourceManager& manager, Handle<SHMaterial> material);
Handle<SHMaterialInstance> CreateOrGet(SHResourceHub& manager, Handle<SHMaterial> material);
/***********************************************************************************/
/*!

View File

@ -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<AddJob> addJobs;
std::vector<Handle<SHTexture>> removeJobs;
// Tracking
ResourceManager resourceManager;
SHResourceHub resourceManager;
std::vector<Handle<SHTexture>> texOrder;
// CPU Storage
std::vector<std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>> combinedImageSamplers;

View File

@ -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
{

View File

@ -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

View File

@ -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

View File

@ -3,7 +3,7 @@
#include "Graphics/SHVulkanIncludes.h"
#include "Graphics/SHVulkanDefines.h"
#include "Resource/Handle.h"
#include "Resource/SHHandle.h"
namespace SHADE
{

View File

@ -1,6 +1,6 @@
#pragma once
#include "Resource/Handle.h"
#include "Resource/SHHandle.h"
namespace SHADE
{

View File

@ -367,7 +367,7 @@ namespace SHADE
, graphResources{}
, resourceManager{nullptr}
{
resourceManager = std::make_shared<ResourceManager>();
resourceManager = std::make_shared<SHResourceHub>();
}
SHRenderGraph::SHRenderGraph(SHRenderGraph&& rhs) noexcept

View File

@ -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"
@ -71,7 +71,7 @@ namespace SHADE
std::unordered_map<std::string, Handle<SHRenderGraphResource>> graphResources;
//! Resource library for graph handles
std::shared_ptr<ResourceManager> resourceManager;
std::shared_ptr<SHResourceHub> resourceManager;
public:
/*-----------------------------------------------------------------------*/

View File

@ -104,7 +104,7 @@ namespace SHADE
*/
/***************************************************************************/
SHRenderGraphNode::SHRenderGraphNode(std::shared_ptr<ResourceManager> rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
SHRenderGraphNode::SHRenderGraphNode(std::shared_ptr<SHResourceHub> rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
: logicalDeviceHdl{ logicalDevice }
, renderpass{}
, framebuffers{}

View File

@ -13,7 +13,7 @@
namespace SHADE
{
class ResourceManager;
class SHResourceHub;
class SHVkFramebuffer;
class SHRenderGraphResource;
class SHVkLogicalDevice;
@ -26,7 +26,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */
/*-----------------------------------------------------------------------*/
std::shared_ptr<ResourceManager> resourceManager;
std::shared_ptr<SHResourceHub> resourceManager;
//! For Vulkan object creation
Handle<SHVkLogicalDevice> logicalDeviceHdl;
@ -88,7 +88,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/
SHRenderGraphNode(std::shared_ptr<ResourceManager> rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept;
SHRenderGraphNode(std::shared_ptr<SHResourceHub> rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept;
SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept;
SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept;

View File

@ -3,7 +3,7 @@
#include <string>
#include "SHAttachmentDescriptionType.h"
#include <vector>
#include "Resource/Handle.h"
#include "Resource/SHHandle.h"
#include "Graphics/SHVulkanIncludes.h"
#include "SH_API.h"

View File

@ -182,7 +182,7 @@ namespace SHADE
exteriorDrawCalls.push_back(newDrawCall);
}
void SHSubpass::Init(ResourceManager& resourceManager) noexcept
void SHSubpass::Init(SHResourceHub& resourceManager) noexcept
{
superBatch = resourceManager.Create<SHSuperBatch>(GetHandle());

View File

@ -3,7 +3,7 @@
#include "SHAttachmentDescriptionType.h"
#include <string>
#include "SH_API.h"
#include "Resource/Handle.h"
#include "Resource/SHHandle.h"
#include "Graphics/SHVulkanIncludes.h"
@ -78,7 +78,7 @@ namespace SHADE
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
void AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept;
void Init(ResourceManager& resourceManager) noexcept;
void Init(SHResourceHub& resourceManager) noexcept;
/*-----------------------------------------------------------------------*/
/* GETTERS AND SETTERS */

View File

@ -1,6 +1,6 @@
#pragma once
#include <Resource/Handle.h>
#include <Resource/SHHandle.h>
namespace SHADE
{

View File

@ -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
{

View File

@ -3,7 +3,7 @@
#include "SHVkAttachDescGen.h"
#include "SHVkSubpassParams.h"
#include "Resource/Handle.h"
#include "Resource/SHHandle.h"
#include <span>
namespace SHADE

View File

@ -2,7 +2,7 @@
#define SH_VK_SUBPASS_PARAMS_H
#include "Graphics/SHVulkanIncludes.h"
#include "Resource/Handle.h"
#include "Resource/SHHandle.h"
#include <span>
namespace SHADE

View File

@ -3,7 +3,7 @@
#include "SHVulkanIncludes.h"
#include "Resource/Handle.h"
#include "Resource/SHHandle.h"
namespace SHADE
{

View File

@ -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 <vector>

View File

@ -4,7 +4,7 @@
#include <cstdint>
#include <vector>
#include "Graphics/SHVulkanIncludes.h"
#include "Resource/ResourceLibrary.h"
#include "Resource/SHResourceLibrary.h"
#include "Graphics/Swapchain/SHSwapchainParams.h"
namespace SHADE

View File

@ -2,7 +2,7 @@
#define SH_VK_FENCE_H
#include "Graphics/SHVulkanIncludes.h"
#include "Resource/Handle.h"
#include "Resource/SHHandle.h"
namespace SHADE
{

View File

@ -2,7 +2,7 @@
#define SH_VK_SEMAPHORE_H
#include "Graphics/SHVulkanIncludes.h"
#include "Resource/Handle.h"
#include "Resource/SHHandle.h"
namespace SHADE
{

View File

@ -3,7 +3,7 @@
#include <windows.h>
#include "Graphics/SHVulkanIncludes.h"
#include "Resource/ResourceLibrary.h"
#include "Resource/SHResourceLibrary.h"
namespace SHADE
{

View File

@ -8,8 +8,9 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
/* Forward Declarations */
/*---------------------------------------------------------------------------------*/
class SHResourceLibraryBase;
template<typename T>
class ResourceLibrary;
class SHResourceLibrary;
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
@ -25,6 +26,20 @@ namespace SHADE
using std::runtime_error::runtime_error;
};
/// <summary>
/// Exception thrown when a generic Handle is being casted to the wrong type.
/// </summary>
class BadHandleCastException : std::runtime_error
{
public:
/*-----------------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------------*/
BadHandleCastException()
: std::runtime_error("Attempted to cast a generic Handle to the wrong type. ")
{}
};
/// <summary>
/// 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
/// </summary>
/// <typeparam name="T">Type of the handle.</typeparam>
template<typename T>
template<typename T = void>
class Handle : public HandleBase
{
public:
@ -88,6 +103,16 @@ namespace SHADE
/* Constructors */
/*-----------------------------------------------------------------------------*/
Handle() = default;
/// <summary>
/// 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.
/// </summary>
/// <param name="genericHandle">Generic handle to convert.</param>
/// <exception cref="std::bad_cast">
/// Thrown if an invalid conversion is made.
/// </exception>
explicit Handle(const Handle<void>& genericHandle);
~Handle() = default;
/*-----------------------------------------------------------------------------*/
@ -140,13 +165,48 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
ResourceLibrary<T>* library = nullptr;
SHResourceLibrary<T>* library = nullptr;
/*-----------------------------------------------------------------------------*/
/* Friend Declarations */
/*-----------------------------------------------------------------------------*/
friend class ResourceLibrary<T>;
};
friend class SHResourceLibrary<T>;
friend class Handle<void>;
};
/// <summary>
/// Template Specialization for Handle that represents a type-less Handle.
/// </summary>
template<>
class Handle<void> : public HandleBase
{
public:
/*-----------------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------------*/
Handle() = default;
template<typename T>
explicit Handle(const Handle<T>& handle);
~Handle() = default;
/*-----------------------------------------------------------------------------*/
/* Overloaded Operators */
/*-----------------------------------------------------------------------------*/
template<typename T>
inline bool operator==(const Handle<T>& rhs) const noexcept;
protected:
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
SHResourceLibraryBase* library = nullptr;
/*-----------------------------------------------------------------------------*/
/* Friend Declarations */
/*-----------------------------------------------------------------------------*/
template<typename T>
friend class Handle;
};
/// <summary>
/// Interface that needs to be implemented by classes that want to store a Handle to
@ -155,7 +215,7 @@ namespace SHADE
template<typename T>
class ISelfHandle
{
public:
public:
/*-----------------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------------*/
@ -183,7 +243,7 @@ namespace SHADE
/// </summary>
/// <param name="rscLib">Required to lock usage to ResourceLibrary only.</param>
/// <param name="hdl">Handle to set.</param>
void SetHandle(const ResourceLibrary<T>& rscLib, Handle<T> hdl);
void SetHandle(const SHResourceLibrary<T>& rscLib, Handle<T> hdl);
private:
/*-----------------------------------------------------------------------------*/
@ -220,4 +280,4 @@ namespace std
};
}
#include "Handle.hpp"
#include "SHHandle.hpp"

View File

@ -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<T> - Constructors */
/*---------------------------------------------------------------------------------*/
template<typename T>
Handle<T>::Handle(const Handle<void>& genericHandle)
: library { reinterpret_cast<SHResourceLibrary<T>*>(genericHandle.library) }
{
id = genericHandle.id;
// Check if valid
if (library != nullptr && library->GetType() != typeid(T))
throw BadHandleCastException();
}
/*---------------------------------------------------------------------------------*/
/* Handle<T> - Usage Functions */
/*---------------------------------------------------------------------------------*/
@ -63,6 +77,28 @@ namespace SHADE
return &library->Get(*this);
}
/*---------------------------------------------------------------------------------*/
/* Handle<void> - Constructors */
/*---------------------------------------------------------------------------------*/
template<typename T>
Handle<void>::Handle(const Handle<T>& handle)
: library{ static_cast<SHResourceLibraryBase*>(handle.library) }
{
id = handle.id;
}
/*---------------------------------------------------------------------------------*/
/* Handle<void> - Overloaded Operators */
/*---------------------------------------------------------------------------------*/
template<typename T>
bool SHADE::Handle<void>::operator==(const Handle<T>& rhs) const noexcept
{
return id.Raw == rhs.id.Raw && library == static_cast<void*>(rhs.library);
}
/*---------------------------------------------------------------------------------*/
/* ISelfHandle<T> - Constructors */
/*---------------------------------------------------------------------------------*/
template<typename T>
inline ISelfHandle<T>::ISelfHandle(const ISelfHandle& rhs)
: handle { rhs.handle }
@ -73,6 +109,9 @@ namespace SHADE
: handle { rhs.handle }
{}
/*---------------------------------------------------------------------------------*/
/* ISelfHandle<T> - Overloaded Operators */
/*---------------------------------------------------------------------------------*/
template<typename T>
inline ISelfHandle<T>& ISelfHandle<T>::operator=(const ISelfHandle& rhs)
{
@ -96,7 +135,7 @@ namespace SHADE
return handle;
}
template<typename T>
inline void ISelfHandle<T>::SetHandle(const ResourceLibrary<T>&, Handle<T> hdl)
inline void ISelfHandle<T>::SetHandle(const SHResourceLibrary<T>&, Handle<T> hdl)
{
handle = hdl;
}

View File

@ -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)

View File

@ -6,24 +6,42 @@
#include <queue>
// Project Headers
#include "Handle.h"
#include "SHHandle.h"
#include "Resource/SparseSet.h"
namespace SHADE
{
/// <summary>
/// Base class for SHResourceLibrary that holds information about the library type.
/// </summary>
class SHResourceLibraryBase
{
public:
/*-----------------------------------------------------------------------------*/
/* Getter Functions */
/*-----------------------------------------------------------------------------*/
inline std::type_index GetType() { return libraryType; }
protected:
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
std::type_index libraryType = typeid(void);
};
/// <summary>
/// Generic Resource Library for a specified type of Resource. This object will own
/// any resources created using it.
/// </summary>
/// <typeparam name="T">Type of resources that this library stores.</typeparam>
template<typename T>
class ResourceLibrary
class SHResourceLibrary : public SHResourceLibraryBase
{
public:
/*-----------------------------------------------------------------------------*/
/* Constructor */
/*-----------------------------------------------------------------------------*/
ResourceLibrary();
SHResourceLibrary();
/*-----------------------------------------------------------------------------*/
/* Usage Functions */
@ -75,13 +93,13 @@ namespace SHADE
/// <summary>
/// Manages all resources in multiple ResourceLibraries.
/// </summary>
class ResourceManager final
class SHResourceHub final
{
public:
/*-----------------------------------------------------------------------------*/
/* Constructors/Destructors */
/*-----------------------------------------------------------------------------*/
~ResourceManager();
~SHResourceHub();
/*-----------------------------------------------------------------------------*/
/* Usage Functions */
@ -136,10 +154,10 @@ namespace SHADE
/* Helper Functions */
/*-----------------------------------------------------------------------------*/
template<typename T>
ResourceLibrary<T>& getLibrary();
SHResourceLibrary<T>& getLibrary();
template<typename T>
const ResourceLibrary<T>& getLibrary() const;
const SHResourceLibrary<T>& getLibrary() const;
};
}
#include "ResourceLibrary.hpp"
#include "SHResourceLibrary.hpp"

View File

@ -1,6 +1,6 @@
#pragma once
// Primary Header
#include "ResourceLibrary.h"
#include "SHResourceLibrary.h"
// Standard Library
#include <utility>
@ -10,13 +10,14 @@ namespace SHADE
/* ResourceLibrary - Constructor */
/*---------------------------------------------------------------------------------*/
template <typename T>
ResourceLibrary<T>::ResourceLibrary()
SHResourceLibrary<T>::SHResourceLibrary()
{
// Type Checking
//static_assert(std::is_copy_assignable_v<T>, "Resource Library's resources must be copy assignable.");
//static_assert(std::is_copy_constructible_v<T>, "Resource Library's resources must be copy constructible.");
static_assert(std::is_move_assignable_v<T>, "Resource Library's resources must be move assignable.");
static_assert(std::is_move_constructible_v<T>, "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 <typename T>
template <typename ... Args>
Handle<T> ResourceLibrary<T>::Create(Args&&... args)
Handle<T> SHResourceLibrary<T>::Create(Args&&... args)
{
// Create the handle
Handle<T> handle;
@ -55,7 +56,7 @@ namespace SHADE
}
template <typename T>
void ResourceLibrary<T>::Free(Handle<T> handle)
void SHResourceLibrary<T>::Free(Handle<T> handle)
{
assertHandleValid(handle);
@ -63,7 +64,7 @@ namespace SHADE
}
template <typename T>
T& ResourceLibrary<T>::Get(Handle<T> handle)
T& SHResourceLibrary<T>::Get(Handle<T> handle)
{
assertHandleValid(handle);
@ -71,7 +72,7 @@ namespace SHADE
}
template <typename T>
const T& ResourceLibrary<T>::Get(Handle<T> handle) const
const T& SHResourceLibrary<T>::Get(Handle<T> handle) const
{
assertHandleValid(handle);
@ -82,14 +83,14 @@ namespace SHADE
/* ResourceLibrary - Helper Functions */
/*---------------------------------------------------------------------------------*/
template <typename T>
void ResourceLibrary<T>::assertHandleValid(Handle<T> handle) const
void SHResourceLibrary<T>::assertHandleValid(Handle<T> handle) const
{
if (!handle || handle.id.Data.Version != versionCounts[handle.id.Data.Index])
throw std::invalid_argument("Invalid handle provided!");
}
template<typename T>
inline uint32_t ResourceLibrary<T>::getAvailableFreeIndex()
inline uint32_t SHResourceLibrary<T>::getAvailableFreeIndex()
{
// Get from the free list if present
if (!freeList.empty())
@ -107,25 +108,25 @@ namespace SHADE
/* ResourceManager - Usage Functions */
/*---------------------------------------------------------------------------------*/
template <typename T, typename ... Args>
Handle<T> ResourceManager::Create(Args&&... args)
Handle<T> SHResourceHub::Create(Args&&... args)
{
return getLibrary<T>().Create(std::forward<Args>(args) ...);
}
template <typename T>
void ResourceManager::Free(Handle<T> handle)
void SHResourceHub::Free(Handle<T> handle)
{
getLibrary<T>().Free(handle);
}
template <typename T>
T& ResourceManager::Get(Handle<T> handle)
T& SHResourceHub::Get(Handle<T> handle)
{
return getLibrary<T>().Get(handle);
}
template <typename T>
const T& ResourceManager::Get(Handle<T> handle) const
const T& SHResourceHub::Get(Handle<T> handle) const
{
return getLibrary<T>().Get(handle);
}
@ -134,18 +135,18 @@ namespace SHADE
/* ResourceManager - Helper Functions */
/*-----------------------------------------------------------------------------*/
template <typename T>
ResourceLibrary<T>& ResourceManager::getLibrary()
SHResourceLibrary<T>& SHResourceHub::getLibrary()
{
// Attempt to retrieve the library
const std::type_index RSC_TYPE = typeid(T);
if (resourceLibs.contains(RSC_TYPE))
{
return *static_cast<ResourceLibrary<T>*>(resourceLibs.at(RSC_TYPE));
return *static_cast<SHResourceLibrary<T>*>(resourceLibs.at(RSC_TYPE));
}
else
{
// Construct library if doesn't exist
ResourceLibrary<T>* lib = new ResourceLibrary<T>();
SHResourceLibrary<T>* lib = new SHResourceLibrary<T>();
resourceLibs.emplace(RSC_TYPE, static_cast<void*>(lib));
// Construct deleter to properly delete objects with void*
@ -156,8 +157,8 @@ namespace SHADE
}
template <typename T>
const ResourceLibrary<T>& ResourceManager::getLibrary() const
const SHResourceLibrary<T>& SHResourceHub::getLibrary() const
{
return const_cast<ResourceManager*>(this).getLibrary<T>();
return const_cast<SHResourceHub*>(this).getLibrary<T>();
}
}

View File

@ -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<std::type_index, std::unordered_map<AssetID, Handle<void>>> SHResourceManager::handlesMap;
std::unordered_map<std::type_index, SHADE::SHResourceManager::HandleAssetMap> SHResourceManager::assetIdMap;
std::unordered_map<std::type_index, std::function<void(AssetID)>> SHResourceManager::typedFreeFuncMap;
std::vector<AssetID> 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<SHGraphicsSystem>();
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<AssetID> SHResourceManager::GetAssetID(Handle<void> 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 {};
}
}

View File

@ -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 <unordered_map>
// Project Includes
#include "SH_API.h"
#include "SHResourceLibrary.h"
#include "Assets/SHAssetMacros.h"
namespace SHADE
{
/// <summary>
/// Static class responsible for loading and caching runtime resources from their
/// serialised Asset IDs.
/// </summary>
class SH_API SHResourceManager
{
public:
/*---------------------------------------------------------------------------------*/
/* Loading Functions */
/*---------------------------------------------------------------------------------*/
/// <summary>
/// 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.
/// </summary>
/// <typeparam name="ResourceType">
/// Type of resource to load.
/// </typeparam>
/// <param name="assetId">Asset ID of the resource to load.</param>
/// <returns>Handle to a loaded runtime asset.</returns>
template<typename ResourceType>
static Handle<ResourceType> LoadOrGet(AssetID assetId);
/// <summary>
/// Unloads an existing loaded asset. Attempting to unload an invalid Handle will
/// simply do nothing except emit a warning.
/// Faster than the untemplated version.
/// </summary>
/// <typeparam name="ResourceType">Type of resource to unload.</typeparam>
/// <param name="assetId">Handle to the resource to unload.</param>
template<typename ResourceType>
static void Unload(Handle<ResourceType> assetId);
/// <summary>
/// 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.
/// </summary>
/// <param name="assetId">Handle to the resource to unload.</param>
static void Unload(AssetID assetId);
/// <summary>
/// Needs to be called to finalise all changes to loads.
/// </summary>
static void FinaliseChanges();
/*---------------------------------------------------------------------------------*/
/* Query Functions */
/*---------------------------------------------------------------------------------*/
/// <summary>
/// Retrieves the AssetID associated with a specified Handle.
/// Faster than the untemplated version.
/// </summary>
/// <typeparam name="ResourceType">Type of resource to get the ID of.</typeparam>
/// <param name="handle">Handle to get the AssetID of.</param>
/// <return>
/// AssetID for the specified Handle. If the Handle is invalid, there will be no
/// value.
/// </return>
template<typename T>
static std::optional<AssetID> GetAssetID(Handle<T> handle);
/// <summary>
/// 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.
/// </summary>
/// <param name="handle">Handle to get the AssetID of.</param>
/// <return>
/// AssetID for the specified Handle. If the Handle is invalid, there will be no
/// value.
/// </return>
static std::optional<AssetID> GetAssetID(Handle<void> handle);
private:
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
using AssetHandleMap = std::unordered_map<AssetID, Handle<void>>;
using HandleAssetMap = std::unordered_map<Handle<void>, AssetID>;
using AssetHandleMapRef = std::reference_wrapper<AssetHandleMap>;
using HandleAssetMapRef = std::reference_wrapper<HandleAssetMap>;
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
// Handles
static SHResourceHub resourceHub;
static std::unordered_map<std::type_index, AssetHandleMap> handlesMap;
static std::unordered_map<std::type_index, HandleAssetMap> assetIdMap;
static std::unordered_map<std::type_index, std::function<void(AssetID)>> typedFreeFuncMap;
// Pointers to temp CPU resources
static std::vector<AssetID> loadedAssetData;
/*---------------------------------------------------------------------------------*/
/* Helper Functions */
/*---------------------------------------------------------------------------------*/
/// <summary>
/// Retrieves or creates the AssetHandleMap for the specific type if it doesn't exist
/// </summary>
/// <typeparam name="ResourceType">
/// The type of AssetHandleMap to retrieve.
/// </typeparam>
/// <returns>Reference to the AssetHandleMap of the specified type.</returns>
template<typename ResourceType>
static std::pair<AssetHandleMapRef, HandleAssetMapRef> getAssetHandleMap();
};
}
#include "SHResourceManager.hpp"

View File

@ -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<typename ResourceType>
Handle<ResourceType> SHResourceManager::LoadOrGet(AssetID assetId)
{
// Check if it is an unsupported type
if (!std::is_same_v<ResourceType, SHMesh> && !std::is_same_v<ResourceType, SHTexture>)
{
static_assert(true, "Unsupported Resource Type specified for SHResourceManager.");
}
/* Attempt to get existing loaded asset */
auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap<ResourceType>();
if (typedHandleMap.get().contains(assetId))
return Handle<ResourceType>(typedHandleMap.get()[assetId]);
/* Otherwise, we need to load it! */
// Meshes
if constexpr (std::is_same_v<ResourceType, SHMesh>)
{
// Get system
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
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<SHMesh> 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<ResourceType, SHTexture>)
{
// Get system
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
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<SHTexture> texHandle = gfxSystem->AddTexture
(
assetData->numBytes,
assetData->pixelData,
assetData->width,
assetData->height,
assetData->format,
assetData->mipOffsets
);
typedHandleMap.get().emplace(assetId, Handle(texHandle));
return texHandle;
}
}
template<typename ResourceType>
void SHResourceManager::Unload(Handle<ResourceType> assetId)
{
// Check if it is an unsupported type
if (!std::is_same_v<ResourceType, SHMesh> && !std::is_same_v<ResourceType, SHTexture>)
{
static_assert(true, "Unsupported Resource Type specified for SHResourceManager.");
}
/* Attempt to get existing loaded asset */
auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap<ResourceType>();
if (typedHandleMap.get().contains(assetId))
{
// Dispose
Handle handle = typedHandleMap.get()[assetId];
Handle<ResourceType> typedHandle = static_cast<Handle<ResourceType>>(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<typename T>
static std::optional<AssetID> SHResourceManager::GetAssetID(Handle<T> handle)
{
const Handle GENERIC_HANDLE = Handle(handle);
auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap<T>();
if (typedAssetIdMap.get().contains(GENERIC_HANDLE))
{
return typedAssetIdMap.GetId()[GENERIC_HANDLE];
}
return {};
}
/*-----------------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------------*/
template<typename ResourceType>
std::pair<SHResourceManager::AssetHandleMapRef, SHResourceManager::HandleAssetMapRef> 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<Handle<ResourceType>>(SHResourceManager::handlesMap[TYPE][assetId]).Free();
}
);
}
return std::make_pair(std::ref(handlesMap[TYPE]), std::ref(assetIdMap[TYPE]));
}
}

View File

@ -54,11 +54,13 @@ namespace SHADE
out << YAML::EndSeq;
}
static void DeserializeEntity(YAML::iterator& it, YAML::Node const& node, std::vector<EntityID>& createdEntities, EntityID parentEID = MAX_EID)
static EntityID DeserializeEntity(YAML::iterator& it, YAML::Node const& node, std::vector<EntityID>& createdEntities, EntityID parentEID = MAX_EID)
{
if (!node[EIDNode])
return;
EntityID eid = node[EIDNode].as<EntityID>();
EntityID eid = MAX_EID;
if(!node)
return eid;
if (node[EIDNode])
eid = node[EIDNode].as<EntityID>();
std::string name = "Default";
if (node[EntityNameNode])
name = node[EntityNameNode].as<std::string>();
@ -117,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)
@ -136,17 +142,19 @@ namespace SHADE
}
}
std::string SHSerialization::SerializeEntitiesToString(std::vector<EntityID> const& entities)
std::string SHSerialization::SerializeEntitiesToString(std::vector<EntityID> 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<char>(out.c_str());
out << YAML::EndSeq;
return std::string(out.c_str());
}
void SHSerialization::SerializeEntityToFile(std::filesystem::path const& path)
@ -193,6 +201,30 @@ namespace SHADE
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<EntityID> 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<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
std::optional<ComponentTypeID> GetComponentID(YAML::Node const& componentNode)
{

View File

@ -29,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<EntityID> const& entities);
static std::string SerializeEntitiesToString(std::vector<EntityID> 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<ComponentTypeID> GetComponentIDList(YAML::Node const& componentsNode);
private:
static void InitializeEntity(YAML::Node const& entityNode, EntityID const& eid);

View File

@ -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<char*>(GlobalLock(dataHandle)));
GlobalUnlock(dataHandle);
CloseClipboard();
return data;
}
CloseClipboard();
return std::string();
}
}

View File

@ -0,0 +1,13 @@
#pragma once
#include <string_view>
namespace SHADE
{
class SHClipboardUtilities
{
public:
static void WriteToClipboard(std::string const& str) noexcept;
static std::string const GetDataFromClipboard() noexcept;
};
}