Merge branch 'main' into SP3-10-input-management
This commit is contained in:
commit
ed56ad99df
|
@ -1,16 +1,16 @@
|
|||
IncludeDir = {}
|
||||
IncludeDir["assimp"] = "%{wks.location}/Dependencies/assimp"
|
||||
IncludeDir["imgui"] = "%{wks.location}/Dependencies/imgui"
|
||||
IncludeDir["imguizmo"] = "%{wks.location}/Dependencies/imguizmo"
|
||||
IncludeDir["imnodes"] = "%{wks.location}/Dependencies/imnodes"
|
||||
IncludeDir["msdf_atlas_gen"] = "%{wks.location}/Dependencies/msdf"
|
||||
IncludeDir["msdfgen"] = "%{wks.location}/Dependencies/msdf/msdfgen"
|
||||
IncludeDir["spdlog"] = "%{wks.location}/Dependencies/spdlog"
|
||||
IncludeDir["tracy"] = "%{wks.location}/Dependencies/tracy"
|
||||
IncludeDir["VMA"] = "%{wks.location}/Dependencies/VMA"
|
||||
IncludeDir["yamlcpp"] = "%{wks.location}/Dependencies/yamlcpp/include"
|
||||
IncludeDir["RTTR"] = "%{wks.location}/Dependencies/RTTR"
|
||||
IncludeDir["reactphysics3d"] = "%{wks.location}/Dependencies/reactphysics3d"
|
||||
IncludeDir["SDL"] = "%{wks.location}/Dependencies/SDL"
|
||||
IncludeDir["assimp"] = "%{wks.location}\\Dependencies\\assimp"
|
||||
IncludeDir["imgui"] = "%{wks.location}\\Dependencies\\imgui"
|
||||
IncludeDir["imguizmo"] = "%{wks.location}\\Dependencies\\imguizmo"
|
||||
IncludeDir["imnodes"] = "%{wks.location}\\Dependencies\\imnodes"
|
||||
IncludeDir["msdf_atlas_gen"] = "%{wks.location}\\Dependencies\\msdf"
|
||||
IncludeDir["msdfgen"] = "%{wks.location}\\Dependencies\\msdf\\msdfgen"
|
||||
IncludeDir["spdlog"] = "%{wks.location}\\Dependencies\\spdlog"
|
||||
IncludeDir["tracy"] = "%{wks.location}\\Dependencies\\tracy"
|
||||
IncludeDir["VMA"] = "%{wks.location}\\Dependencies\\VMA"
|
||||
IncludeDir["yamlcpp"] = "%{wks.location}\\Dependencies\\yamlcpp\\include"
|
||||
IncludeDir["RTTR"] = "%{wks.location}\\Dependencies\\RTTR"
|
||||
IncludeDir["reactphysics3d"] = "%{wks.location}\\Dependencies\\reactphysics3d"
|
||||
IncludeDir["SDL"] = "%{wks.location}\\Dependencies\\SDL"
|
||||
IncludeDir["VULKAN"] = "$(VULKAN_SDK)"
|
||||
IncludeDir["dotnet"] = "%{wks.location}/Dependencies/dotnet"
|
||||
IncludeDir["dotnet"] = "%{wks.location}\\Dependencies\\dotnet"
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
#include "Math/Transform/SHTransformSystem.h"
|
||||
|
||||
#include "Scenes/SBTestScene.h"
|
||||
|
||||
|
@ -43,28 +44,42 @@ namespace Sandbox
|
|||
|
||||
SDL_Init(SDL_INIT_EVERYTHING);
|
||||
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
|
||||
|
||||
// Create Systems
|
||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHScriptEngine>();
|
||||
// TODO(Diren): Create Physics System here
|
||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHTransformSystem>();
|
||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHGraphicsSystem>();
|
||||
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
|
||||
|
||||
// Create Routines
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::FrameSetUpRoutine>();
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::UpdateRoutine>();
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::LateUpdateRoutine>();
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::FrameCleanUpRoutine>();
|
||||
|
||||
// TODO(Diren): Register Physics System & Routines here
|
||||
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHTransformSystem, SHADE::SHTransformSystem::TransformUpdateRoutine>();
|
||||
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHTransformComponent>();
|
||||
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::BatcherDispatcherRoutine>();
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::BeginRoutine>();
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::RenderRoutine>();
|
||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::EndRoutine>();
|
||||
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRenderable>();
|
||||
|
||||
|
||||
// Set up graphics system and windows
|
||||
graphicsSystem->SetWindow(&window);
|
||||
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
|
||||
//auto [w, h] = window.GetWindowSize();
|
||||
//SDL_SetWindowSize(sdlWindow, w, h);
|
||||
|
||||
SHADE::SHSystemManager::Init();
|
||||
#ifdef SHEDITOR
|
||||
#ifdef SHEDITOR
|
||||
SHADE::SHEditor::Initialise(sdlWindow);
|
||||
#else
|
||||
#endif
|
||||
|
||||
// Set up scripting
|
||||
SHADE::SHScriptEngine::Init();
|
||||
#else
|
||||
#endif
|
||||
|
||||
SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
|
||||
}
|
||||
|
@ -99,11 +114,10 @@ namespace Sandbox
|
|||
|
||||
void SBApplication::Exit(void)
|
||||
{
|
||||
#ifdef SHEDITOR
|
||||
#ifdef SHEDITOR
|
||||
SHADE::SHEditor::Exit();
|
||||
#endif
|
||||
SHSceneManager::Exit();
|
||||
SHADE::SHScriptEngine::Exit();
|
||||
SHADE::SHSystemManager::Exit();
|
||||
SDL_DestroyWindow(sdlWindow);
|
||||
SDL_Quit();
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||
#include "Scripting/SHScriptEngine.h"
|
||||
#include "Math/Transform/SHTransformComponent.h"
|
||||
|
||||
using namespace SHADE;
|
||||
|
||||
|
@ -37,16 +39,23 @@ namespace Sandbox
|
|||
auto matInst = graphicsSystem->AddMaterialInstance();
|
||||
|
||||
// Create entity and add mesh
|
||||
auto entity = SHADE::SHEntityManager::CreateEntity<SHADE::SHRenderable>();
|
||||
auto& renderable = *SHADE::SHComponentManager::GetComponent_s<SHADE::SHRenderable>(entity);
|
||||
testObj = SHADE::SHEntityManager::CreateEntity<SHADE::SHRenderable, SHADE::SHTransformComponent>();
|
||||
auto& renderable = *SHADE::SHComponentManager::GetComponent_s<SHADE::SHRenderable>(testObj);
|
||||
renderable.Mesh = CUBE_MESH;
|
||||
renderable.SetMaterial(matInst);
|
||||
renderable.TransformMatrix.Translate(0.0f, 0.0f, 2.0f);
|
||||
// Create transform
|
||||
auto& transform = *SHADE::SHComponentManager::GetComponent_s<SHADE::SHTransformComponent>(testObj);
|
||||
transform.SetLocalPosition(SHVec3{ 0.0f, 0.0f, 2.0f });
|
||||
|
||||
renderable.TransformMatrix = SHMatrix::Translate(0.0f, 0.0f, 2.0f);
|
||||
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
||||
scriptEngine->AddScript(*SHADE::SHEntityManager::GetEntityByID(testObj), "TestScript");
|
||||
}
|
||||
void SBTestScene::Update(float dt)
|
||||
{
|
||||
(void)dt;
|
||||
|
||||
if (GetKeyState(VK_SPACE) & 0x8000)
|
||||
SHADE::SHEntityManager::DestroyEntity(testObj);
|
||||
}
|
||||
|
||||
void SBTestScene::Render()
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace Sandbox
|
|||
{
|
||||
private:
|
||||
EntityID camera;
|
||||
EntityID testObj;
|
||||
|
||||
|
||||
public:
|
||||
|
|
|
@ -25,22 +25,22 @@ project "SHADE_Engine"
|
|||
|
||||
externalincludedirs
|
||||
{
|
||||
"%{IncludeDir.assimp}/include",
|
||||
"%{IncludeDir.assimp}\\include",
|
||||
"%{IncludeDir.imgui}",
|
||||
"%{IncludeDir.imguizmo}",
|
||||
"%{IncludeDir.imnodes}",
|
||||
"%{IncludeDir.msdf_atlas_gen}",
|
||||
"%{IncludeDir.msdfgen}",
|
||||
"%{IncludeDir.spdlog}/include",
|
||||
"%{IncludeDir.spdlog}\\include",
|
||||
"%{IncludeDir.tracy}",
|
||||
"%{IncludeDir.VMA}/include",
|
||||
"%{IncludeDir.VMA}\\include",
|
||||
"%{IncludeDir.yamlcpp}",
|
||||
"%{IncludeDir.SDL}/include",
|
||||
"%{IncludeDir.RTTR}/include",
|
||||
"%{IncludeDir.reactphysics3d}/include",
|
||||
"%{IncludeDir.VULKAN}/include",
|
||||
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect",
|
||||
"%{IncludeDir.dotnet}/include",
|
||||
"%{IncludeDir.SDL}\\include",
|
||||
"%{IncludeDir.RTTR}\\include",
|
||||
"%{IncludeDir.reactphysics3d}\\include",
|
||||
"%{IncludeDir.VULKAN}\\include",
|
||||
"%{IncludeDir.VULKAN}\\Source\\SPIRV-Reflect",
|
||||
"%{IncludeDir.dotnet}\\include",
|
||||
}
|
||||
|
||||
externalwarnings "Off"
|
||||
|
@ -100,9 +100,9 @@ project "SHADE_Engine"
|
|||
|
||||
postbuildcommands
|
||||
{
|
||||
"xcopy /s /r /y /q \"%{IncludeDir.spdlog}/bin\" \"$(OutDir)\"",
|
||||
"xcopy /r /y /q \"%{IncludeDir.SDL}/lib/SDL2.dll\" \"$(OutDir)\"",
|
||||
"xcopy /s /r /y /q \"%{IncludeDir.dotnet}/bin\" \"$(OutDir)\""
|
||||
"xcopy /s /r /y /q \"%{IncludeDir.spdlog}\\bin\" \"$(OutDir)\"",
|
||||
"xcopy /r /y /q \"%{IncludeDir.SDL}\\lib\\SDL2.dll\" \"$(OutDir)\"",
|
||||
"xcopy /s /r /y /q \"%{IncludeDir.dotnet}\\bin\" \"$(OutDir)\""
|
||||
}
|
||||
|
||||
warnings 'Extra'
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace SHADE
|
|||
SHEventHandle(T::*callback)(SHEventPtr);
|
||||
|
||||
public:
|
||||
SHEventReceiverSpec(T* obj, void(T::* cb)(SHEventPtr))
|
||||
SHEventReceiverSpec(T* obj, SHEventHandle(T::* cb)(SHEventPtr))
|
||||
:SHEventReceiver(), object{ obj }, callback{ cb }
|
||||
{
|
||||
|
||||
|
|
|
@ -21,12 +21,16 @@
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Static Data Member Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHTransformSystem::SHTransformSystem()
|
||||
: SHSystemRoutine { "Transform Routine", false }
|
||||
SHTransformSystem::TransformUpdateRoutine::TransformUpdateRoutine()
|
||||
: SHSystemRoutine { "Transform Update", true }
|
||||
{}
|
||||
|
||||
|
||||
|
@ -34,13 +38,23 @@ namespace SHADE
|
|||
/* Public Function Member Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
void SHTransformSystem::Execute(double dt) noexcept
|
||||
void SHTransformSystem::TransformUpdateRoutine::Execute(double) noexcept
|
||||
{
|
||||
// Get the current scene graph to traverse and update
|
||||
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||
UpdateEntity(SCENE_GRAPH.GetRoot());
|
||||
}
|
||||
|
||||
void SHTransformSystem::Init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SHTransformSystem::Exit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Private Function Member Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -53,18 +67,16 @@ namespace SHADE
|
|||
for (const auto* child : node->GetChildren())
|
||||
{
|
||||
// Active states of entities should sync with scene nodes
|
||||
const bool IS_NODE_ACTIVE = child->isActive;
|
||||
const bool IS_NODE_ACTIVE = child->IsActive();
|
||||
|
||||
#ifdef _DEBUG
|
||||
const bool IS_ENTITY_ACTIVE = SHEntityManager::GetEntityByID(child->GetEntityID())->GetActive();
|
||||
SHASSERT(IS_NODE_ACTIVE == IS_ENTITY_ACTIVE, "Entity and Node active states are not synced!")
|
||||
#endif
|
||||
|
||||
// Anything below is inactive
|
||||
if (!IS_NODE_ACTIVE)
|
||||
{
|
||||
UpdateEntity(child);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
const bool HAS_TRANSFORM = SHComponentManager::HasComponent<SHTransformComponent>(child->GetEntityID());
|
||||
if (!HAS_TRANSFORM)
|
||||
|
@ -90,7 +102,7 @@ namespace SHADE
|
|||
if (parent)
|
||||
{
|
||||
localToWorld = parent->GetTRS();
|
||||
worldToLocal = SHMatrix::Inverse(tf.local.trs);
|
||||
worldToLocal = SHMatrix::Inverse(localToWorld);
|
||||
}
|
||||
|
||||
while (!tf.updateQueue.empty())
|
||||
|
@ -134,6 +146,10 @@ namespace SHADE
|
|||
tf.world.scale = tf.local.scale * (parent ? parent->GetLocalScale() : SHVec3::One);
|
||||
|
||||
tf.world.ComputeTRS();
|
||||
|
||||
// Transpose TRS to column major
|
||||
tf.local.trs.Transpose();
|
||||
tf.world.trs.Transpose();
|
||||
}
|
||||
|
||||
} // namespace SHADE
|
|
@ -21,19 +21,18 @@ namespace SHADE
|
|||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
class SH_API SHTransformSystem : public SHSystemRoutine
|
||||
class SH_API SHTransformSystem final : public SHSystem
|
||||
{
|
||||
public:
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHTransformSystem ();
|
||||
~SHTransformSystem () = default;
|
||||
SHTransformSystem () = default;
|
||||
~SHTransformSystem () override = default;
|
||||
|
||||
SHTransformSystem (const SHTransformSystem&) = delete;
|
||||
SHTransformSystem (SHTransformSystem&&) = delete;
|
||||
SHTransformSystem (const SHTransformSystem&) = delete;
|
||||
SHTransformSystem (SHTransformSystem&&) = delete;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Operator Overloads */
|
||||
|
@ -42,11 +41,43 @@ namespace SHADE
|
|||
SHTransformSystem& operator= (const SHTransformSystem&) = delete;
|
||||
SHTransformSystem& operator= (SHTransformSystem&&) = delete;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* System Routines */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
class SH_API TransformUpdateRoutine final: public SHSystemRoutine
|
||||
{
|
||||
public:
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
|
||||
TransformUpdateRoutine ();
|
||||
~TransformUpdateRoutine () = default;
|
||||
|
||||
TransformUpdateRoutine (const TransformUpdateRoutine&) = delete;
|
||||
TransformUpdateRoutine (TransformUpdateRoutine&&) = delete;
|
||||
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
/* Operator Overloads */
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
|
||||
TransformUpdateRoutine& operator= (const TransformUpdateRoutine&) = delete;
|
||||
TransformUpdateRoutine& operator= (TransformUpdateRoutine&&) = delete;
|
||||
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
|
||||
void Execute(double dt) noexcept override;
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void Execute(double dt) noexcept override;
|
||||
void Init () override;
|
||||
void Exit () override;
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -25,14 +25,14 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHSceneNode::SHSceneNode(EntityID eid, SHSceneNode* parent) noexcept
|
||||
: isActive { true }
|
||||
: active { true }
|
||||
, entityID { eid }
|
||||
, parent { parent }
|
||||
{}
|
||||
|
||||
|
||||
SHSceneNode::SHSceneNode(const SHSceneNode& rhs) noexcept
|
||||
: isActive { rhs.isActive }
|
||||
: active { rhs.active }
|
||||
, entityID { rhs.entityID }
|
||||
, parent { rhs.parent }
|
||||
{
|
||||
|
@ -40,7 +40,7 @@ namespace SHADE
|
|||
}
|
||||
|
||||
SHSceneNode::SHSceneNode(SHSceneNode&& rhs) noexcept
|
||||
: isActive { rhs.isActive }
|
||||
: active { rhs.active }
|
||||
, entityID { rhs.entityID }
|
||||
, parent { rhs.parent }
|
||||
{
|
||||
|
@ -52,9 +52,9 @@ namespace SHADE
|
|||
if (this == &rhs)
|
||||
return *this;
|
||||
|
||||
isActive = rhs.isActive;
|
||||
entityID = rhs.entityID;
|
||||
parent = rhs.parent;
|
||||
active = rhs.active;
|
||||
entityID = rhs.entityID;
|
||||
parent = rhs.parent;
|
||||
|
||||
children.clear();
|
||||
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
|
||||
|
@ -64,9 +64,9 @@ namespace SHADE
|
|||
|
||||
SHSceneNode& SHSceneNode::operator=(SHSceneNode&& rhs) noexcept
|
||||
{
|
||||
isActive = rhs.isActive;
|
||||
entityID = rhs.entityID;
|
||||
parent = rhs.parent;
|
||||
active = rhs.active;
|
||||
entityID = rhs.entityID;
|
||||
parent = rhs.parent;
|
||||
|
||||
children.clear();
|
||||
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
|
||||
|
@ -104,6 +104,11 @@ namespace SHADE
|
|||
/* Getter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
bool SHSceneNode::IsActive() const noexcept
|
||||
{
|
||||
return active;
|
||||
}
|
||||
|
||||
EntityID SHSceneNode::GetEntityID() const noexcept
|
||||
{
|
||||
return entityID;
|
||||
|
@ -154,7 +159,7 @@ namespace SHADE
|
|||
if (root != nullptr)
|
||||
return root;
|
||||
|
||||
SHLOG_WARNING("Scene has no root object!")
|
||||
SHLOG_ERROR("Scene has no root object!")
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -171,7 +176,7 @@ namespace SHADE
|
|||
const auto NODE_ITER = entityNodeMap.find(entityID);
|
||||
if (NODE_ITER == entityNodeMap.end())
|
||||
{
|
||||
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to Get Scene node!", entityID)
|
||||
SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to Get Scene node!", entityID)
|
||||
return nullptr;
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
@ -192,7 +197,7 @@ namespace SHADE
|
|||
const auto NODE_ITER = entityNodeMap.find(entityID);
|
||||
if (NODE_ITER == entityNodeMap.end())
|
||||
{
|
||||
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to get Parent node!", entityID)
|
||||
SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to get Parent node!", entityID)
|
||||
return nullptr;
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
@ -213,7 +218,7 @@ namespace SHADE
|
|||
const auto NODE_ITER = entityNodeMap.find(entityID);
|
||||
if (NODE_ITER == entityNodeMap.end())
|
||||
{
|
||||
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
|
||||
SHLOG_ERROR("Entity {} cannot be found in the scene!", entityID)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -248,7 +253,7 @@ namespace SHADE
|
|||
const auto NODE_ITER = entityNodeMap.find(entityID);
|
||||
if (NODE_ITER == entityNodeMap.end())
|
||||
{
|
||||
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
|
||||
SHLOG_ERROR("Entity {} cannot be found in the scene!", entityID)
|
||||
return nullptr;
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
@ -269,7 +274,7 @@ namespace SHADE
|
|||
const auto NODE_ITER = entityNodeMap.find(entityID);
|
||||
if (NODE_ITER == entityNodeMap.end())
|
||||
{
|
||||
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
|
||||
SHLOG_ERROR("Entity {} cannot be found in the scene!", entityID)
|
||||
return root->GetChildren();
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
@ -277,6 +282,27 @@ namespace SHADE
|
|||
return NODE_ITER->second->GetChildren();
|
||||
}
|
||||
|
||||
bool SHSceneGraph::IsActiveInHierarchy(EntityID entityID) const noexcept
|
||||
{
|
||||
////////////////////////////////////////
|
||||
// Error handling
|
||||
if (!SHEntityManager::IsValidEID(entityID))
|
||||
{
|
||||
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto NODE_ITER = entityNodeMap.find(entityID);
|
||||
if (NODE_ITER == entityNodeMap.end())
|
||||
{
|
||||
SHLOG_ERROR("Entity {} cannot be found in the scene!", entityID)
|
||||
return false;
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
||||
return NODE_ITER->second->IsActive();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Setter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -289,7 +315,7 @@ namespace SHADE
|
|||
}
|
||||
|
||||
// Handle self assignment
|
||||
if (parentNode == parent)
|
||||
if (parent && parentNode->entityID == parent->entityID)
|
||||
return;
|
||||
|
||||
if (parent)
|
||||
|
@ -300,6 +326,16 @@ namespace SHADE
|
|||
parent->AddChild(this);
|
||||
}
|
||||
|
||||
void SHSceneNode::SetActive(bool newActiveState) noexcept
|
||||
{
|
||||
active = newActiveState;
|
||||
|
||||
for (auto* child : children)
|
||||
{
|
||||
SetActive(newActiveState);
|
||||
}
|
||||
}
|
||||
|
||||
void SHSceneGraph::SetParent(EntityID entityID, SHSceneNode* parent) const noexcept
|
||||
{
|
||||
////////////////////////////////////////
|
||||
|
@ -318,6 +354,9 @@ namespace SHADE
|
|||
}
|
||||
////////////////////////////////////////
|
||||
|
||||
if (parent == nullptr)
|
||||
parent = root;
|
||||
|
||||
NODE_ITER->second->SetParent(parent);
|
||||
}
|
||||
|
||||
|
@ -340,14 +379,14 @@ namespace SHADE
|
|||
auto NODE_ITER = entityNodeMap.find(entityID);
|
||||
if (NODE_ITER == entityNodeMap.end())
|
||||
{
|
||||
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to set parent!", entityID)
|
||||
SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to set parent!", entityID)
|
||||
return;
|
||||
}
|
||||
|
||||
auto PARENT_ITER = entityNodeMap.find(parent);
|
||||
if (PARENT_ITER == entityNodeMap.end())
|
||||
{
|
||||
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to parent to Entity {}", parent, entityID)
|
||||
SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to parent to Entity {}", parent, entityID)
|
||||
return;
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
@ -458,9 +497,16 @@ namespace SHADE
|
|||
SHSceneNode* newNode = AllocateNode(entityID);
|
||||
|
||||
if (parent == nullptr)
|
||||
{
|
||||
// Specific handling for root to avoid a warning when removing a non-existent child
|
||||
parent = root;
|
||||
|
||||
newNode->SetParent(parent);
|
||||
newNode->parent = root;
|
||||
root->children.emplace_back(newNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
newNode->SetParent(parent);
|
||||
}
|
||||
|
||||
return newNode;
|
||||
}
|
||||
|
@ -476,7 +522,7 @@ namespace SHADE
|
|||
auto NODE_ITER = entityNodeMap.find(entityID);
|
||||
if (NODE_ITER == entityNodeMap.end())
|
||||
{
|
||||
SHLOG_WARNING("Entity {} does not exist in the scene!", entityID)
|
||||
SHLOG_ERROR("Entity {} does not exist in the scene!", entityID)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,12 +38,6 @@ namespace SHADE
|
|||
friend class SHSceneGraph;
|
||||
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
bool isActive;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -60,6 +54,7 @@ namespace SHADE
|
|||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
[[nodiscard]] bool IsActive () const noexcept;
|
||||
[[nodiscard]] EntityID GetEntityID () const noexcept;
|
||||
[[nodiscard]] SHSceneNode* GetParent () const noexcept;
|
||||
[[nodiscard]] const std::vector<SHSceneNode*>& GetChildren () const noexcept;
|
||||
|
@ -70,7 +65,8 @@ namespace SHADE
|
|||
/* Setter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void SetParent (SHSceneNode* parentNode) noexcept;
|
||||
void SetParent (SHSceneNode* parentNode) noexcept;
|
||||
void SetActive (bool newActiveState) noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
|
@ -88,6 +84,7 @@ namespace SHADE
|
|||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
bool active;
|
||||
EntityID entityID;
|
||||
SHSceneNode* parent;
|
||||
std::vector<SHSceneNode*> children;
|
||||
|
@ -121,12 +118,14 @@ namespace SHADE
|
|||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
[[nodiscard]] const SHSceneNode* GetRoot () const noexcept;
|
||||
[[nodiscard]] SHSceneNode* GetNode (EntityID entityID) const noexcept;
|
||||
[[nodiscard]] SHSceneNode* GetParent (EntityID entityID) const noexcept;
|
||||
[[nodiscard]] SHSceneNode* GetChild (EntityID entityID, SHSceneNode* childNode) const noexcept;
|
||||
[[nodiscard]] SHSceneNode* GetChild (EntityID entityID, EntityID childEntityID) const noexcept;
|
||||
[[nodiscard]] const std::vector<SHSceneNode*>& GetChildren (EntityID entityID) const noexcept;
|
||||
[[nodiscard]] const SHSceneNode* GetRoot () const noexcept;
|
||||
[[nodiscard]] SHSceneNode* GetNode (EntityID entityID) const noexcept;
|
||||
[[nodiscard]] SHSceneNode* GetParent (EntityID entityID) const noexcept;
|
||||
[[nodiscard]] SHSceneNode* GetChild (EntityID entityID, SHSceneNode* childNode) const noexcept;
|
||||
[[nodiscard]] SHSceneNode* GetChild (EntityID entityID, EntityID childEntityID) const noexcept;
|
||||
[[nodiscard]] const std::vector<SHSceneNode*>& GetChildren (EntityID entityID) const noexcept;
|
||||
|
||||
[[nodiscard]] bool IsActiveInHierarchy (EntityID entityID) const noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Setter Functions */
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
#include "SHScene.h"
|
||||
#include <functional>
|
||||
#include "SH_API.h"
|
||||
|
||||
//Project Headers
|
||||
#include "SH_API.h"
|
||||
|
|
|
@ -16,39 +16,27 @@ of DigiPen Institute of Technology is prohibited.
|
|||
// Standard Library
|
||||
#include <fstream> // std::fstream
|
||||
#include <filesystem> // std::filesystem::canonical, std::filesystem::remove
|
||||
#include <memory> // std::shared_ptr
|
||||
// Project Headers
|
||||
#include "Tools/SHLogger.h"
|
||||
#include "Tools/SHStringUtils.h"
|
||||
#include "ECS_Base/Events/SHEntityDestroyedEvent.h"
|
||||
#include "Events/SHEvent.h"
|
||||
#include "Events/SHEventReceiver.h"
|
||||
#include "Events/SHEventManager.hpp"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Static Definitions */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Static Definitions */
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
const std::string SHScriptEngine::DEFAULT_CSHARP_NAMESPACE = std::string("SHADE");
|
||||
SHDotNetRuntime SHScriptEngine::dotNet { false };
|
||||
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineInit = nullptr;
|
||||
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineLoadScripts = nullptr;
|
||||
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineUnloadScripts = nullptr;
|
||||
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineReloadScripts = nullptr;
|
||||
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineExit = nullptr;
|
||||
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsFrameSetUp = nullptr;
|
||||
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsExecuteFixedUpdate = nullptr;
|
||||
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsExecuteUpdate = nullptr;
|
||||
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsExecuteLateUpdate = nullptr;
|
||||
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsFrameCleanUp = nullptr;
|
||||
SHScriptEngine::CsScriptManipFuncPtr SHScriptEngine::csScriptsAdd = nullptr;
|
||||
SHScriptEngine::CsScriptBasicFuncPtr SHScriptEngine::csScriptsRemoveAll = nullptr;
|
||||
SHScriptEngine::CsScriptOptionalFuncPtr SHScriptEngine::csScriptsRemoveAllImmediately = nullptr;
|
||||
SHScriptEngine::CsScriptSerialiseFuncPtr SHScriptEngine::csScriptsSerialise = nullptr;
|
||||
SHScriptEngine::CsScriptDeserialiseFuncPtr SHScriptEngine::csScriptDeserialise = nullptr;
|
||||
SHScriptEngine::CsScriptSerialiseYamlFuncPtr SHScriptEngine::csScriptsSerialiseYaml = nullptr;
|
||||
SHScriptEngine::CsScriptSerialiseYamlFuncPtr SHScriptEngine::csScriptDeserialiseYaml = nullptr;
|
||||
SHScriptEngine::CsScriptEditorFuncPtr SHScriptEngine::csEditorRenderScripts = nullptr;
|
||||
const std::string SHScriptEngine::CSPROJ_DIR = "..\\..\\TempScriptsFolder";
|
||||
const std::string SHScriptEngine::CSPROJ_PATH = std::string(CSPROJ_DIR) + "\\SHADE_Scripting.csproj";
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Lifecycle Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Lifecycle Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void SHScriptEngine::Init()
|
||||
{
|
||||
// Do not allow initialization if already initialised
|
||||
|
@ -72,14 +60,8 @@ namespace SHADE
|
|||
// Initialise the CSharp Engine
|
||||
csEngineInit();
|
||||
|
||||
// Link events
|
||||
// - Entity Destruction
|
||||
/*onEntityDestroy = [this](const SHEntity& e)
|
||||
{
|
||||
csScriptsRemoveAll(e.GetEID());
|
||||
csGOLibNotifyDestroyEntity(e.GetEID());
|
||||
};
|
||||
ECS::OnEntityDestroy += onEntityDestroy;*/
|
||||
// Register entity creation events
|
||||
registerEvents();
|
||||
}
|
||||
void SHScriptEngine::UnloadScriptAssembly()
|
||||
{
|
||||
|
@ -118,9 +100,9 @@ namespace SHADE
|
|||
dotNet.Exit();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Script Manipulation Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Script Manipulation Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
bool SHScriptEngine::AddScript(const SHEntity& entity, const std::string_view& scriptName)
|
||||
{
|
||||
return csScriptsAdd(entity.GetEID(), scriptName.data());
|
||||
|
@ -137,7 +119,7 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
/* Script Serialisation Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
std::string SHScriptEngine::SerialiseScripts(const SHEntity& entity)
|
||||
std::string SHScriptEngine::SerialiseScripts(const SHEntity& entity) const
|
||||
{
|
||||
// Create buffer needed to store serialised script data
|
||||
constexpr int BUFFER_SIZE = 10240;
|
||||
|
@ -159,41 +141,40 @@ namespace SHADE
|
|||
return result;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Script Serialisation Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void SHScriptEngine::DeserialiseScript(const SHEntity& entity, const std::string& yaml)
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Script Serialisation Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void SHScriptEngine::DeserialiseScript(const SHEntity& entity, const std::string& yaml) const
|
||||
{
|
||||
csScriptDeserialise(entity.GetEID(), yaml.c_str());
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Script Editor Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void SHScriptEngine::RenderScriptsInInspector(const SHEntity& entity)
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Script Editor Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void SHScriptEngine::RenderScriptsInInspector(const SHEntity& entity) const
|
||||
{
|
||||
csEditorRenderScripts(entity.GetEID());
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Static Utility Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
bool SHScriptEngine::BuildScriptAssembly(bool debug)
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Static Utility Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
bool SHScriptEngine::BuildScriptAssembly(bool debug) const
|
||||
{
|
||||
constexpr std::string_view BUILD_LOG_PATH = "../Build.log";
|
||||
static const std::string BUILD_LOG_PATH = "../Build.log";
|
||||
|
||||
// Generate csproj file if it doesn't exist
|
||||
static const std::filesystem::path CSPROJ_PATH = "../SHADE_Scripting.csproj";
|
||||
if (!std::filesystem::exists(CSPROJ_PATH))
|
||||
{
|
||||
GenerateScriptsCsProjFile(CSPROJ_PATH);
|
||||
}
|
||||
|
||||
// Prepare directory (delete useless files)
|
||||
deleteFolder("net5.0");
|
||||
deleteFolder("ref");
|
||||
deleteFolder("../SHADE_Scripting");
|
||||
deleteFolder("../obj");
|
||||
deleteFolder(CSPROJ_DIR + "\\net5.0");
|
||||
deleteFolder(CSPROJ_DIR + "\\ref");
|
||||
deleteFolder(CSPROJ_DIR + "\\obj");
|
||||
deleteFolder(CSPROJ_DIR + "\\bin");
|
||||
|
||||
// Attempt to build the assembly
|
||||
std::ostringstream oss;
|
||||
|
@ -203,7 +184,7 @@ namespace SHADE
|
|||
const bool BUILD_SUCCESS = execProcess
|
||||
(
|
||||
L"C:\\Windows\\system32\\cmd.exe",
|
||||
L"/K \"dotnet build \"../SHADE_Scripting.csproj\" -c Debug -o \"./tmp/\" -fl -flp:LogFile=build.log;Verbosity=quiet & exit\""
|
||||
L"/K \"" + generateBuildCommand(debug) + L" & exit\""
|
||||
) == 0;
|
||||
if (BUILD_SUCCESS)
|
||||
{
|
||||
|
@ -221,6 +202,7 @@ namespace SHADE
|
|||
|
||||
// Clean up built files
|
||||
deleteFolder("./tmp");
|
||||
deleteFolder(CSPROJ_DIR + "\\obj");
|
||||
|
||||
// Read the build log and output to the console
|
||||
dumpBuildLog(BUILD_LOG_PATH);
|
||||
|
@ -228,9 +210,9 @@ namespace SHADE
|
|||
deleteFile(BUILD_LOG_PATH);
|
||||
|
||||
return BUILD_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
void SHScriptEngine::GenerateScriptsCsProjFile(const std::filesystem::path& path)
|
||||
void SHScriptEngine::GenerateScriptsCsProjFile(const std::filesystem::path& path) const
|
||||
{
|
||||
// Sample
|
||||
static std::string_view FILE_CONTENTS =
|
||||
|
@ -241,11 +223,11 @@ namespace SHADE
|
|||
<Configurations>Release;Debug</Configurations>\n\
|
||||
</PropertyGroup>\n\
|
||||
<PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n\
|
||||
<OutputPath>.\\bin_Release-x64</OutputPath>\n\
|
||||
<OutputPath>.\\bin\\Release</OutputPath>\n\
|
||||
<PlatformTarget>x64</PlatformTarget>\n\
|
||||
</PropertyGroup>\n\
|
||||
<PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\"> \n\
|
||||
<OutputPath>.\\bin_Debug-x64</OutputPath>\n\
|
||||
<OutputPath>.\\bin\\Debug</OutputPath>\n\
|
||||
<PlatformTarget>x64</PlatformTarget>\n\
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>\n\
|
||||
<Optimize>false</Optimize>\n\
|
||||
|
@ -264,7 +246,8 @@ namespace SHADE
|
|||
</ItemGroup>\n\
|
||||
<ItemGroup>\n\
|
||||
<Reference Include=\"SHADE_Managed\">\n\
|
||||
<HintPath>.\\bin\\SHADE_Managed.dll</HintPath>\n\
|
||||
<HintPath Condition=\"Exists('..\\bin\\Debug\\SHADE_Managed.dll')\">..\\bin\\Debug\\SHADE_Managed.dll</HintPath>\
|
||||
<HintPath Condition=\"Exists('..\\bin\\Release\\SHADE_Managed.dll')\">..\\bin\\Release\\SHADE_Managed.dll</HintPath>\
|
||||
</Reference>\n\
|
||||
</ItemGroup>\n\
|
||||
</Project>";
|
||||
|
@ -279,11 +262,21 @@ namespace SHADE
|
|||
|
||||
// Close
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Event Handler Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHEventHandle SHScriptEngine::onEntityDestroyed(SHEventPtr eventPtr)
|
||||
{
|
||||
auto eventData = reinterpret_cast<const SHEventSpec<SHEntityDestroyedEvent>*>(eventPtr.get());
|
||||
csScriptsRemoveAll(eventData->data->eid);
|
||||
return eventData->handle;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void SHScriptEngine::loadFunctions()
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
@ -401,6 +394,17 @@ namespace SHADE
|
|||
);*/
|
||||
}
|
||||
|
||||
void SHScriptEngine::registerEvents()
|
||||
{
|
||||
// Register for entity destroyed event
|
||||
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> destroyedEventReceiver
|
||||
{
|
||||
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onEntityDestroyed)
|
||||
};
|
||||
ReceiverPtr receiver = std::dynamic_pointer_cast<SHEventReceiver>(destroyedEventReceiver);
|
||||
SHEventManager::SubscribeTo(SH_ENTITY_DESTROYED_EVENT, receiver);
|
||||
}
|
||||
|
||||
void SHScriptEngine::dumpBuildLog(const std::string_view& buildLogPath)
|
||||
{
|
||||
std::ifstream buildLog(buildLogPath);
|
||||
|
@ -423,25 +427,25 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
}
|
||||
void SHScriptEngine::deleteFile(const std::string_view& filePath)
|
||||
void SHScriptEngine::deleteFile(const std::string& filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::filesystem::remove(std::filesystem::canonical(filePath));
|
||||
}
|
||||
catch (...) {} // Ignore deletion failures
|
||||
}
|
||||
|
||||
void SHScriptEngine::deleteFolder(const std::string_view& filePath)
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
std::filesystem::remove_all(std::filesystem::canonical(filePath));
|
||||
}
|
||||
catch (...) {} // Ignore deletion failures
|
||||
std::filesystem::remove(std::filesystem::canonical(filePath));
|
||||
}
|
||||
catch (...) {} // Ignore deletion failures
|
||||
}
|
||||
|
||||
bool SHScriptEngine::fileExists(const std::string_view& filePath)
|
||||
void SHScriptEngine::deleteFolder(const std::string& filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::filesystem::remove_all(std::filesystem::canonical(filePath));
|
||||
}
|
||||
catch (...) {} // Ignore deletion failures
|
||||
}
|
||||
|
||||
bool SHScriptEngine::fileExists(const std::filesystem::path& filePath)
|
||||
{
|
||||
std::error_code error;
|
||||
if (std::filesystem::exists(filePath, error))
|
||||
|
@ -483,8 +487,8 @@ namespace SHADE
|
|||
DWORD status;
|
||||
while (true)
|
||||
{
|
||||
const auto SUCCESS = GetExitCodeProcess(procInfo.hProcess, &status);
|
||||
if (!SUCCESS)
|
||||
const auto EXEC_SUCCESS = GetExitCodeProcess(procInfo.hProcess, &status);
|
||||
if (!EXEC_SUCCESS)
|
||||
{
|
||||
auto err = GetLastError();
|
||||
std::ostringstream oss;
|
||||
|
@ -503,4 +507,12 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
std::wstring SHScriptEngine::generateBuildCommand(bool debug)
|
||||
{
|
||||
std::wostringstream oss;
|
||||
oss << "dotnet build \"" << SHStringUtils::StrToWstr(CSPROJ_PATH) << "\" -c ";
|
||||
oss << debug ? "Debug" : "Release";
|
||||
oss << " -o \"./tmp/\" -fl -flp:LogFile=build.log;Verbosity=quiet";
|
||||
return oss.str();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,10 +15,14 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include <filesystem>
|
||||
|
||||
// Project Headers
|
||||
#include "SH_API.h"
|
||||
#include "SHDotNetRuntime.h"
|
||||
#include "ECS_Base/SHECSMacros.h"
|
||||
#include "ECS_Base/Entity/SHEntity.h"
|
||||
#include "SH_API.h"
|
||||
#include "ECS_Base/System/SHSystem.h"
|
||||
#include "ECS_Base/System/SHSystemRoutine.h"
|
||||
#include "Events/SHEventDefines.h"
|
||||
#include "Events/SHEvent.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -26,13 +30,41 @@ namespace SHADE
|
|||
/// Manages initialisation of the DotNetRuntime and interfacing with CLR code written
|
||||
/// and executed on .NET.
|
||||
/// </summary>
|
||||
class SH_API SHScriptEngine
|
||||
class SH_API SHScriptEngine final : public SHSystem
|
||||
{
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
class SH_API FrameSetUpRoutine final : public SHSystemRoutine
|
||||
{
|
||||
public:
|
||||
FrameSetUpRoutine();
|
||||
void Execute(double dt) noexcept override final;
|
||||
};
|
||||
class SH_API UpdateRoutine final : public SHSystemRoutine
|
||||
{
|
||||
public:
|
||||
UpdateRoutine();
|
||||
void Execute(double dt) noexcept override final;
|
||||
};
|
||||
class SH_API LateUpdateRoutine final : public SHSystemRoutine
|
||||
{
|
||||
public:
|
||||
LateUpdateRoutine();
|
||||
void Execute(double dt) noexcept override final;
|
||||
};
|
||||
class SH_API FrameCleanUpRoutine final : public SHSystemRoutine
|
||||
{
|
||||
public:
|
||||
FrameCleanUpRoutine();
|
||||
void Execute(double dt) noexcept override final;
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Constructor */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
SHScriptEngine() = delete;
|
||||
SHScriptEngine() = default;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Lifecycle Functions */
|
||||
|
@ -41,33 +73,33 @@ namespace SHADE
|
|||
/// Initialises the DotNetRuntime and retrieves function pointers to all
|
||||
/// functions on the CLR used to interface with the engine.
|
||||
/// </summary>
|
||||
static void Init();
|
||||
void Init() override;
|
||||
/// <summary>
|
||||
/// Loads the managed script assembly. Ensure this is only called after
|
||||
/// UnloadScriptAssembly() has been called.
|
||||
/// </summary>
|
||||
static void UnloadScriptAssembly();
|
||||
void UnloadScriptAssembly();
|
||||
/// <summary>
|
||||
/// Unloads the managed script assembly.
|
||||
/// Take note that this will clear all existing scripts, ensure that the scene
|
||||
/// is saved before doing so.
|
||||
/// </summary>
|
||||
static void LoadScriptAssembly();
|
||||
void LoadScriptAssembly();
|
||||
/// <summary>
|
||||
/// Reloads the managed script assembly.
|
||||
/// Take note that this will clear all existing scripts, ensure that the scene
|
||||
/// is saved before doing so.
|
||||
/// </summary>
|
||||
static void ReloadScriptAssembly();
|
||||
void ReloadScriptAssembly();
|
||||
/// <summary>
|
||||
/// Executes the FixedUpdate()s of the Scripts that are attached to
|
||||
/// Entities.
|
||||
/// </summary>
|
||||
static void ExecuteFixedUpdates();
|
||||
void ExecuteFixedUpdates();
|
||||
/// <summary>
|
||||
/// Shuts down the DotNetRuntime.
|
||||
/// </summary>
|
||||
static void Exit();
|
||||
void Exit() override;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Script Manipulation Functions */
|
||||
|
@ -84,14 +116,14 @@ namespace SHADE
|
|||
/// True if successfully added. False otherwise with the error logged to the
|
||||
/// console.
|
||||
/// </returns>
|
||||
static bool AddScript(const SHEntity& entity, const std::string_view& scriptName);
|
||||
bool AddScript(const SHEntity& entity, const std::string_view& scriptName);
|
||||
/// <summary>
|
||||
/// Removes all Scripts attached to the specified Entity. Does not do anything
|
||||
/// if the specified Entity is invalid or does not have any Scripts
|
||||
/// attached.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to remove the scripts from.</param>
|
||||
static void RemoveAllScripts(const SHEntity& entity);
|
||||
void RemoveAllScripts(const SHEntity& entity);
|
||||
/// <summary>
|
||||
/// Removes all Scripts attached to the specified Entity. Unlike
|
||||
/// RemoveAllScripts(), this removes all the scripts immediately.
|
||||
|
@ -103,7 +135,7 @@ namespace SHADE
|
|||
/// Whether or not to call OnDestroy on the scripts. This is ignored if not in
|
||||
/// play mode.
|
||||
/// </param>
|
||||
static void RemoveAllScriptsImmediately(const SHEntity& entity, bool callOnDestroy);
|
||||
void RemoveAllScriptsImmediately(const SHEntity& entity, bool callOnDestroy);
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Script Serialisation Functions */
|
||||
|
@ -116,7 +148,7 @@ namespace SHADE
|
|||
/// <returns>
|
||||
/// String that represents the set of scripts attached to the specified Entity.
|
||||
/// </returns>
|
||||
static std::string SerialiseScripts(const SHEntity& entity);
|
||||
std::string SerialiseScripts(const SHEntity& entity) const;
|
||||
/// <summary>
|
||||
/// Loads the specified JSON string and creates a Script for the specified Entity
|
||||
/// based on the specified JSON string.
|
||||
|
@ -125,7 +157,7 @@ namespace SHADE
|
|||
/// <param name="yaml">
|
||||
/// The YAML string that represents the Script to load into the Entity.
|
||||
/// </param>
|
||||
static void DeserialiseScript(const SHEntity& entity, const std::string& yaml);
|
||||
void DeserialiseScript(const SHEntity& entity, const std::string& yaml) const;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Script Editor Functions */
|
||||
|
@ -138,7 +170,7 @@ namespace SHADE
|
|||
/// rendering code.
|
||||
/// </summary>
|
||||
/// <param name="entity">The Entity to render the Scripts of.</param>
|
||||
static void RenderScriptsInInspector(const SHEntity& entity);
|
||||
void RenderScriptsInInspector(const SHEntity& entity) const;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Static Utility Functions */
|
||||
|
@ -153,12 +185,12 @@ namespace SHADE
|
|||
/// can be debugged.
|
||||
/// </param>
|
||||
/// <returns>Whether or not the build succeeded.</returns>
|
||||
static bool BuildScriptAssembly(bool debug = false);
|
||||
bool BuildScriptAssembly(bool debug = false) const;
|
||||
/// <summary>
|
||||
/// Generates a .csproj file for editing and compiling the C# scripts.
|
||||
/// </summary>
|
||||
/// <param name="path">File path to the generated file.</param>
|
||||
static void GenerateScriptsCsProjFile(const std::filesystem::path& path);
|
||||
void GenerateScriptsCsProjFile(const std::filesystem::path& path) const;
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
@ -178,45 +210,56 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------*/
|
||||
static constexpr std::string_view DEFAULT_CSHARP_LIB_NAME = "SHADE_Managed";
|
||||
static constexpr std::string_view MANAGED_SCRIPT_LIB_NAME = "SHADE_Scripting";
|
||||
static const std::string CSPROJ_DIR;
|
||||
static const std::string CSPROJ_PATH;
|
||||
static const std::string DEFAULT_CSHARP_NAMESPACE;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
static SHDotNetRuntime dotNet;
|
||||
SHDotNetRuntime dotNet { false };
|
||||
// Function Pointers to CLR Code
|
||||
// - Engine Lifecycle
|
||||
static CsFuncPtr csEngineInit;
|
||||
static CsFuncPtr csEngineLoadScripts;
|
||||
static CsFuncPtr csEngineUnloadScripts;
|
||||
static CsFuncPtr csEngineReloadScripts;
|
||||
static CsFuncPtr csEngineExit;
|
||||
CsFuncPtr csEngineInit = nullptr;
|
||||
CsFuncPtr csEngineLoadScripts = nullptr;
|
||||
CsFuncPtr csEngineUnloadScripts = nullptr;
|
||||
CsFuncPtr csEngineReloadScripts = nullptr;
|
||||
CsFuncPtr csEngineExit = nullptr;
|
||||
// - Scripts Store
|
||||
static CsFuncPtr csScriptsFrameSetUp;
|
||||
static CsFuncPtr csScriptsExecuteFixedUpdate;
|
||||
static CsFuncPtr csScriptsExecuteUpdate;
|
||||
static CsFuncPtr csScriptsExecuteLateUpdate;
|
||||
static CsFuncPtr csScriptsFrameCleanUp;
|
||||
static CsScriptManipFuncPtr csScriptsAdd;
|
||||
static CsScriptBasicFuncPtr csScriptsRemoveAll;
|
||||
static CsScriptOptionalFuncPtr csScriptsRemoveAllImmediately;
|
||||
static CsScriptSerialiseFuncPtr csScriptsSerialise;
|
||||
static CsScriptDeserialiseFuncPtr csScriptDeserialise;
|
||||
static CsScriptSerialiseYamlFuncPtr csScriptsSerialiseYaml;
|
||||
static CsScriptSerialiseYamlFuncPtr csScriptDeserialiseYaml;
|
||||
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;
|
||||
// - Editor
|
||||
static CsScriptEditorFuncPtr csEditorRenderScripts;
|
||||
CsScriptEditorFuncPtr csEditorRenderScripts = nullptr;
|
||||
// Delegates
|
||||
/*ECS::EntityEvent::Delegate onEntityCreate;
|
||||
ECS::EntityEvent::Delegate onEntityDestroy;*/
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Event Handler Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
SHEventHandle onEntityDestroyed(SHEventPtr eventPtr);
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Loads all the function pointers to CLR code that we need to execute.
|
||||
/// </summary>
|
||||
static void loadFunctions();
|
||||
void loadFunctions();
|
||||
/// <summary>
|
||||
/// Registers events for the scripting system
|
||||
/// </summary>
|
||||
void registerEvents();
|
||||
/// <summary>
|
||||
/// Reads the file via the specified path that represents a build log of error
|
||||
/// and warning messages.
|
||||
|
@ -230,18 +273,19 @@ namespace SHADE
|
|||
/// Deletes the file as specified by the file path.
|
||||
/// </summary>
|
||||
/// <param name="filePath">File path to the file to delete.</param>
|
||||
static void deleteFile(const std::string_view& filePath);
|
||||
static void deleteFile(const std::string& filePath);
|
||||
/// <summary>
|
||||
/// Deletes the folder and all files in it as specified by the file path.
|
||||
/// </summary>
|
||||
/// <param name="filePath">File path to the file to delete.</param>
|
||||
static void deleteFolder(const std::string_view& filePath);
|
||||
static void deleteFolder(const std::string& filePath);
|
||||
/// <summary>
|
||||
/// Checks if a specified file exists.
|
||||
/// </summary>
|
||||
/// <param name="filePath">File path to the file to check.</param>
|
||||
/// <returns> True if the file exists </returns>
|
||||
static bool fileExists(const std::string_view& filePath);
|
||||
static bool fileExists(const std::filesystem::path& filePath);
|
||||
static DWORD execProcess(const std::wstring& path, const std::wstring& args);
|
||||
static std::wstring generateBuildCommand(bool debug);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/************************************************************************************//*!
|
||||
\file SHScriptEngineRoutines.cpp
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Sep 17, 2021
|
||||
\brief Contains the implementation or functions of SystemRoutines in the
|
||||
SHScriptEngine class.
|
||||
|
||||
Copyright (C) 2021 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.
|
||||
*//*************************************************************************************/
|
||||
// Precompiled Headers
|
||||
#include <SHpch.h>
|
||||
// Primary Header
|
||||
#include "SHScriptEngine.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* System Routine Functions - FrameSetUpRoutine */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHScriptEngine::FrameSetUpRoutine::FrameSetUpRoutine()
|
||||
: SHSystemRoutine("Script Engine Frame Set Up", false)
|
||||
{}
|
||||
void SHScriptEngine::FrameSetUpRoutine::Execute(double) noexcept
|
||||
{
|
||||
reinterpret_cast<SHScriptEngine*>(system)->csScriptsFrameSetUp();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* System Routine Functions - UpdateRoutine */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHScriptEngine::UpdateRoutine::UpdateRoutine()
|
||||
: SHSystemRoutine("Script Engine Update", false)
|
||||
{}
|
||||
void SHScriptEngine::UpdateRoutine::Execute(double) noexcept
|
||||
{
|
||||
reinterpret_cast<SHScriptEngine*>(system)->csScriptsExecuteUpdate();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* System Routine Functions - LateUpdateRoutine */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHScriptEngine::LateUpdateRoutine::LateUpdateRoutine()
|
||||
: SHSystemRoutine("Script Engine Late Update", false)
|
||||
{}
|
||||
void SHScriptEngine::LateUpdateRoutine::Execute(double) noexcept
|
||||
{
|
||||
reinterpret_cast<SHScriptEngine*>(system)->csScriptsExecuteLateUpdate();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* System Routine Functions - FrameCleanUpRoutine */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHScriptEngine::FrameCleanUpRoutine::FrameCleanUpRoutine()
|
||||
: SHSystemRoutine("Script Engine Frame Clean Up", false)
|
||||
{}
|
||||
void SHScriptEngine::FrameCleanUpRoutine::Execute(double) noexcept
|
||||
{
|
||||
reinterpret_cast<SHScriptEngine*>(system)->csScriptsFrameCleanUp();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/************************************************************************************//*!
|
||||
\file SHLog.cpp
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Sep 17, 2022
|
||||
\brief Contains the definition of functions of the SHLog 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.
|
||||
*//*************************************************************************************/
|
||||
// Precompiled Header
|
||||
#include "SHpch.h"
|
||||
// Primary Header
|
||||
#include "SHLog.h"
|
||||
// Project Includes
|
||||
#include "SHLogger.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
void SHLog::Info(const std::string& msg) noexcept
|
||||
{
|
||||
SHLOG_INFO(msg)
|
||||
}
|
||||
|
||||
void SHLog::Warning(const std::string& msg) noexcept
|
||||
{
|
||||
SHLOG_WARNING(msg)
|
||||
}
|
||||
|
||||
|
||||
void SHLog::Error(const std::string& msg) noexcept
|
||||
{
|
||||
SHLOG_ERROR(msg)
|
||||
}
|
||||
|
||||
void SHLog::Critical(const std::string& msg) noexcept
|
||||
{
|
||||
SHLOG_CRITICAL(msg)
|
||||
}
|
||||
|
||||
void SHLog::Floor() noexcept
|
||||
{
|
||||
SHLOG_FLOOR()
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
void SHLog::Trace(const std::string& msg) noexcept
|
||||
{
|
||||
SHLOG_TRACE(msg)
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/************************************************************************************//*!
|
||||
\file SHLog.h
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Sep 17, 2022
|
||||
\brief Contains the SHLog 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.
|
||||
*//*************************************************************************************/
|
||||
|
||||
// Standard Library
|
||||
#include <string>
|
||||
// Project Headers
|
||||
#include "SH_API.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*!************************************************************************************
|
||||
|
||||
\class SHLog
|
||||
|
||||
\brief
|
||||
Static class that contains wrapper functions for SHLogger's macros.
|
||||
|
||||
**************************************************************************************/
|
||||
class SH_API SHLog
|
||||
{
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructor */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
SHLog() = delete;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Logging Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
static void Info(const std::string& msg) noexcept;
|
||||
static void Warning(const std::string& msg) noexcept;
|
||||
static void Error(const std::string& msg) noexcept;
|
||||
static void Critical(const std::string& msg) noexcept;
|
||||
static void Floor() noexcept;
|
||||
#ifdef _DEBUG
|
||||
static void Trace(const std::string& msg) noexcept;
|
||||
#endif
|
||||
};
|
||||
}
|
|
@ -21,6 +21,9 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include <msclr\marshal_cppstd.h>
|
||||
// External Dependencies
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
#include "Scene/SHSceneGraph.h"
|
||||
#include "Tools/SHLog.h"
|
||||
// Project Headers
|
||||
#include "Utility/Convert.hxx"
|
||||
#include "Utility/Debug.hxx"
|
||||
|
@ -124,27 +127,31 @@ namespace SHADE
|
|||
return T();
|
||||
}
|
||||
|
||||
// Get Transform component and get the children list
|
||||
throw gcnew System::NotImplementedException;
|
||||
//Pls::Transform* tf = Pls::ECS::GetComponent<Pls::Transform>(entity);
|
||||
//if (tf == nullptr)
|
||||
// return T();
|
||||
// Get Entity's SceneGraphNode
|
||||
SHSceneNode* sceneGraphNode = SHSceneManager::GetCurrentSceneGraph().GetNode(entity);
|
||||
if (sceneGraphNode == nullptr)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "[ECS_CLI] Failed to retrieve SceneGraphNode of entity #" << entity << ". This should not happen!";
|
||||
SHLog::Warning(oss.str());
|
||||
return T();
|
||||
}
|
||||
|
||||
//// Search direct children first
|
||||
//for (const auto& child : tf->GetChildren())
|
||||
//{
|
||||
// T component = GetComponent<T>(child);
|
||||
// if (component != nullptr)
|
||||
// return component;
|
||||
//}
|
||||
// Search direct children first
|
||||
for (const auto& child : sceneGraphNode->GetChildren())
|
||||
{
|
||||
T component = GetComponent<T>(child->GetEntityID());
|
||||
if (component != nullptr)
|
||||
return component;
|
||||
}
|
||||
|
||||
//// Search their children
|
||||
//for (const auto& child : tf->GetChildren())
|
||||
//{
|
||||
// T script = GetComponentInChildren<T>(child);
|
||||
// if (script != nullptr)
|
||||
// return script;
|
||||
//}
|
||||
// Search their children
|
||||
for (const auto& child : sceneGraphNode->GetChildren())
|
||||
{
|
||||
T component = GetComponentInChildren<T>(child->GetEntityID());
|
||||
if (component != nullptr)
|
||||
return component;
|
||||
}
|
||||
|
||||
// None here
|
||||
return T();
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace SHADE
|
|||
}
|
||||
bool GameObject::IsActiveInHierarchy::get()
|
||||
{
|
||||
throw gcnew System::NotImplementedException();
|
||||
return true; // TODO: Update once we have an equivalent on the Entity object
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -19,7 +19,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
namespace SHADE
|
||||
{
|
||||
///<summary>
|
||||
/// CLR version of the the PlushieEngine's Vector2 class that represents a
|
||||
/// CLR version of the the SHADE Engine's Vector2 class that represents a
|
||||
/// 2-Dimensional Vector. Designed to closely match Unity's Vector2 struct.
|
||||
/// </summary>
|
||||
[System::Runtime::InteropServices::StructLayout(System::Runtime::InteropServices::LayoutKind::Sequential)]
|
||||
|
|
|
@ -20,6 +20,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include <sstream>
|
||||
// External Dependencies
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
#include "Tools/SHLog.h"
|
||||
// Project Headers
|
||||
#include "Utility/Debug.hxx"
|
||||
#include "Utility/Convert.hxx"
|
||||
|
@ -148,34 +149,37 @@ namespace SHADE
|
|||
if (!EntityUtils::IsValid(entity))
|
||||
throw gcnew System::ArgumentException("Invalid Entity provided to get a Script from.");
|
||||
|
||||
|
||||
// Check if entity exists in the script storage
|
||||
if (!scripts.ContainsKey(entity))
|
||||
{
|
||||
return T();
|
||||
}
|
||||
|
||||
// Get Transform component and get the children list
|
||||
throw gcnew System::NotImplementedException;
|
||||
//Pls::Transform* tf = Pls::ECS::GetComponent<Pls::Transform>(Convert::ToNative(entity));
|
||||
//if (tf == nullptr)
|
||||
// return T();
|
||||
// Get Entity's SceneGraphNode
|
||||
SHSceneNode* sceneGraphNode = SHSceneManager::GetCurrentSceneGraph().GetNode(entity);
|
||||
if (sceneGraphNode == nullptr)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "[ECS_CLI] Failed to retrieve SceneGraphNode of entity #" << entity << ". This should not happen!";
|
||||
SHLog::Warning(oss.str());
|
||||
return T();
|
||||
}
|
||||
|
||||
//// Search direct children first
|
||||
//for (const auto& child : tf->GetChildren())
|
||||
//{
|
||||
// T script = GetScript<T>(Convert::ToCLI(child));
|
||||
// if (script != nullptr)
|
||||
// return script;
|
||||
//}
|
||||
// Search direct children first
|
||||
for (const auto& child : sceneGraphNode->GetChildren())
|
||||
{
|
||||
T script = GetScript<T>(child->GetEntityID());
|
||||
if (script != nullptr)
|
||||
return script;
|
||||
}
|
||||
|
||||
//// Search their children
|
||||
//for (const auto& child : tf->GetChildren())
|
||||
//{
|
||||
// T script = GetScriptInChildren<T>(Convert::ToCLI(child));
|
||||
// if (script != nullptr)
|
||||
// return script;
|
||||
//}
|
||||
// Search their children
|
||||
for (const auto& child : sceneGraphNode->GetChildren())
|
||||
{
|
||||
T script = GetScript<T>(child->GetEntityID());
|
||||
if (script != nullptr)
|
||||
return script;
|
||||
}
|
||||
|
||||
// None here
|
||||
return T();
|
||||
|
@ -233,7 +237,6 @@ namespace SHADE
|
|||
if (!EntityUtils::IsValid(entity))
|
||||
throw gcnew System::ArgumentException("Invalid Entity provided to remove a Script from.");
|
||||
|
||||
|
||||
// Check if entity exists in the script storage
|
||||
if (!scripts.ContainsKey(entity))
|
||||
{
|
||||
|
@ -264,7 +267,6 @@ namespace SHADE
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Check if entity exists in the script storage
|
||||
if (!scripts.ContainsKey(entity))
|
||||
{
|
||||
|
@ -286,13 +288,6 @@ namespace SHADE
|
|||
void ScriptStore::RemoveAllScripts(Entity entity)
|
||||
{
|
||||
SAFE_NATIVE_CALL_BEGIN
|
||||
// Check if entity exists
|
||||
if (!EntityUtils::IsValid(entity))
|
||||
{
|
||||
Debug::LogError("[ScriptStore] Attempted to remove Scripts from an invalid Entity!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if entity exists in the script storage
|
||||
if (!scripts.ContainsKey(entity))
|
||||
return;
|
||||
|
@ -309,13 +304,6 @@ namespace SHADE
|
|||
void ScriptStore::RemoveAllScriptsImmediately(Entity entity, bool callOnDestroy)
|
||||
{
|
||||
SAFE_NATIVE_CALL_BEGIN
|
||||
// Check if entity exists
|
||||
if (!EntityUtils::IsValid(entity))
|
||||
{
|
||||
Debug::LogError("[ScriptStore] Attempted to remove Scripts from an invalid Entity!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if entity exists in the script storage
|
||||
if (!scripts.ContainsKey(entity))
|
||||
return;
|
||||
|
@ -384,10 +372,7 @@ namespace SHADE
|
|||
while (disposalQueue.Count > 0)
|
||||
{
|
||||
Script^ script = disposalQueue.Dequeue();
|
||||
/*if (Application::IsPlaying)
|
||||
{
|
||||
script->OnDestroy();
|
||||
}*/
|
||||
script->OnDestroy();
|
||||
auto entity = script->Owner.GetEntity();
|
||||
auto scriptList = scripts[script->Owner.GetEntity()];
|
||||
scriptList->Remove(script);
|
||||
|
@ -495,7 +480,6 @@ namespace SHADE
|
|||
if (!EntityUtils::IsValid(entity))
|
||||
return true;
|
||||
|
||||
|
||||
// Check if entity exists in the script storage
|
||||
if (!scripts.ContainsKey(entity))
|
||||
return true;
|
||||
|
@ -665,7 +649,7 @@ namespace SHADE
|
|||
|
||||
// Entity Validity Check
|
||||
if (nativeEntity == nullptr)
|
||||
throw gcnew System::InvalidOperationException("Attempted to get native Component to an invalid Entity.");
|
||||
return false;
|
||||
|
||||
// Check active state
|
||||
return nativeEntity->GetActive();
|
||||
|
|
|
@ -0,0 +1,242 @@
|
|||
/************************************************************************************//*!
|
||||
\file ReflectionUtilities.cxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Nov 6, 2021
|
||||
\brief Contains the definition of the functions for the ReflectionUtilities
|
||||
managed static class.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
||||
Copyright (C) 2021 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.
|
||||
*//*************************************************************************************/
|
||||
// Precompiled Headers
|
||||
#include "SHpch.h"
|
||||
// Primary Header
|
||||
#include "Serialisation/ReflectionUtilities.hxx"
|
||||
// Project Includes
|
||||
#include "SerializeFieldAttribute.hxx"
|
||||
#include "Utility/Convert.hxx"
|
||||
#include "Math/Vector2.hxx"
|
||||
#include "Math/Vector3.hxx"
|
||||
#include "Utility/Debug.hxx"
|
||||
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
/* Macro Functions */
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Macro expansion that is used in RapidJsonValueToField() to retrieve the specified
|
||||
/// member of a Vector type that is stored into a Vector named "vec".
|
||||
/// </summary>
|
||||
/// <param name="MEMBER">The name of the member to retrieve.</param>
|
||||
#define PRIMITIVE_VECTOR_FIELD_ASSIGN(MEMBER) \
|
||||
iter = jsonValue.FindMember(#MEMBER); \
|
||||
if (iter != jsonValue.MemberEnd()) \
|
||||
{ \
|
||||
vec.MEMBER = iter->value.GetDouble(); \
|
||||
} \
|
||||
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
/* Function Definitions */
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
namespace SHADE
|
||||
{
|
||||
System::Collections::Generic::IEnumerable<System::Reflection::FieldInfo^>^ ReflectionUtilities::GetInstanceFields(System::Object^ object)
|
||||
{
|
||||
using namespace System::Reflection;
|
||||
|
||||
return object->GetType()->GetFields
|
||||
(
|
||||
BindingFlags::Public | BindingFlags::NonPublic | BindingFlags::Instance
|
||||
);
|
||||
}
|
||||
|
||||
bool ReflectionUtilities::FieldIsSerialisable(System::Reflection::FieldInfo^ fieldInfo)
|
||||
{
|
||||
return fieldInfo->IsPublic || fieldInfo->GetCustomAttributes(SerializeField::typeid, true)->Length > 0;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Serialisation Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void ReflectionUtilities::Serialise(System::Object^ object, YAML::Emitter& yaml)
|
||||
{
|
||||
using namespace System::Reflection;
|
||||
|
||||
// Create YAML object
|
||||
yaml << YAML::Key << Convert::ToNative(object->GetType()->FullName);
|
||||
yaml << YAML::BeginMap;
|
||||
|
||||
// Get all fields
|
||||
System::Collections::Generic::IEnumerable<FieldInfo^>^ fields = GetInstanceFields(object);
|
||||
for each (FieldInfo^ field in fields)
|
||||
{
|
||||
// Ignore private and non-SerialiseField
|
||||
if (!FieldIsSerialisable(field))
|
||||
continue;
|
||||
|
||||
// Serialise
|
||||
writeFieldIntoYaml(field, object, yaml);
|
||||
}
|
||||
|
||||
yaml << YAML::EndMap;
|
||||
}
|
||||
void ReflectionUtilities::Deserialise(YAML::Node& yamlNode, Object^ object)
|
||||
{
|
||||
using namespace System::Reflection;
|
||||
|
||||
// Load the YAML
|
||||
if (!yamlNode.IsMap())
|
||||
{
|
||||
// Invalid
|
||||
Debug::LogError
|
||||
(
|
||||
System::String::Format("[ReflectionUtilities] Invalid YAML Node provided for deserialization of \"{0}\" script.",
|
||||
object->GetType()->FullName)
|
||||
);
|
||||
return;
|
||||
}
|
||||
// Get all fields
|
||||
System::Collections::Generic::IEnumerable<FieldInfo^>^ fields = GetInstanceFields(object);
|
||||
for each (FieldInfo^ field in fields)
|
||||
{
|
||||
// Ignore private and non-SerialiseField
|
||||
if (!FieldIsSerialisable(field))
|
||||
continue;
|
||||
|
||||
// Deserialise
|
||||
const std::string FIELD_NAME = Convert::ToNative(field->Name);
|
||||
if (yamlNode[FIELD_NAME])
|
||||
{
|
||||
writeYamlIntoField(field, object, yamlNode[FIELD_NAME]);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Serialization Helper Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void ReflectionUtilities::writeFieldIntoYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Emitter& yaml)
|
||||
{
|
||||
// Field Name
|
||||
yaml << YAML::Key << Convert::ToNative(fieldInfo->Name);
|
||||
|
||||
// Field Value
|
||||
yaml << YAML::Value;
|
||||
if (fieldInsertYaml<System::Int16> (fieldInfo, object, yaml) ||
|
||||
fieldInsertYaml<System::Int32> (fieldInfo, object, yaml) ||
|
||||
fieldInsertYaml<System::Int64> (fieldInfo, object, yaml) ||
|
||||
fieldInsertYaml<System::UInt16>(fieldInfo, object, yaml) ||
|
||||
fieldInsertYaml<System::UInt32>(fieldInfo, object, yaml) ||
|
||||
fieldInsertYaml<System::UInt64>(fieldInfo, object, yaml) ||
|
||||
fieldInsertYaml<System::Byte> (fieldInfo, object, yaml) ||
|
||||
fieldInsertYaml<bool> (fieldInfo, object, yaml) ||
|
||||
fieldInsertYaml<float> (fieldInfo, object, yaml) ||
|
||||
fieldInsertYaml<double> (fieldInfo, object, yaml))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (fieldInfo->FieldType->IsSubclassOf(System::Enum::typeid))
|
||||
{
|
||||
yaml << safe_cast<int>(fieldInfo->GetValue(object));
|
||||
}
|
||||
else if (fieldInfo->FieldType == System::String::typeid)
|
||||
{
|
||||
System::String^ str = safe_cast<System::String^>(fieldInfo->GetValue(object));
|
||||
yaml << Convert::ToNative(str);
|
||||
}
|
||||
else if (fieldInfo->FieldType == Vector2::typeid)
|
||||
{
|
||||
Vector2 vec = safe_cast<Vector2>(fieldInfo->GetValue(object));
|
||||
yaml << YAML::BeginSeq << YAML::Flow << vec.x << vec.y << YAML::EndSeq;
|
||||
}
|
||||
else if (fieldInfo->FieldType == Vector3::typeid)
|
||||
{
|
||||
Vector3 vec = safe_cast<Vector3>(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)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
void ReflectionUtilities::writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node)
|
||||
{
|
||||
if (fieldInfo->FieldType == System::Int16::typeid)
|
||||
{
|
||||
fieldInfo->SetValue(object, node.as<int>());
|
||||
}
|
||||
if (fieldAssignYaml<System::Int16> (fieldInfo, object, node) ||
|
||||
fieldAssignYaml<System::Int32> (fieldInfo, object, node) ||
|
||||
fieldAssignYaml<System::Int64> (fieldInfo, object, node) ||
|
||||
fieldAssignYaml<System::UInt16>(fieldInfo, object, node) ||
|
||||
fieldAssignYaml<System::UInt32>(fieldInfo, object, node) ||
|
||||
fieldAssignYaml<System::UInt64>(fieldInfo, object, node) ||
|
||||
fieldAssignYaml<System::Byte> (fieldInfo, object, node) ||
|
||||
fieldAssignYaml<bool> (fieldInfo, object, node) ||
|
||||
fieldAssignYaml<float> (fieldInfo, object, node) ||
|
||||
fieldAssignYaml<double> (fieldInfo, object, node))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (fieldInfo->FieldType->IsSubclassOf(System::Enum::typeid))
|
||||
{
|
||||
fieldInfo->SetValue(object, node.as<int>());
|
||||
}
|
||||
else if (fieldInfo->FieldType == System::String::typeid)
|
||||
{
|
||||
fieldInfo->SetValue(object, Convert::ToCLI(node.as<std::string>()));
|
||||
}
|
||||
else if (fieldInfo->FieldType == Vector2::typeid)
|
||||
{
|
||||
if (node.IsSequence() && node.size() == 2)
|
||||
{
|
||||
Vector2 vec;
|
||||
vec.x = node[0].as<float>();
|
||||
vec.y = node[1].as<float>();
|
||||
fieldInfo->SetValue(object, vec);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug::LogWarning
|
||||
(
|
||||
System::String::Format("[ReflectionUtilities] Invalid YAML Node provided for deserialization of a Vector2 \"{0}\" field in \"{1}\" script.",
|
||||
fieldInfo->Name, object->GetType()->FullName)
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (fieldInfo->FieldType == Vector3::typeid)
|
||||
{
|
||||
if (node.IsSequence() && node.size() == 3)
|
||||
{
|
||||
Vector3 vec;
|
||||
vec.x = node[0].as<float>();
|
||||
vec.y = node[1].as<float>();
|
||||
vec.z = node[2].as<float>();
|
||||
fieldInfo->SetValue(object, vec);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug::LogWarning
|
||||
(
|
||||
System::String::Format("[ReflectionUtilities] Invalid YAML Node provided for deserialization of a Vector3 \"{0}\" field in \"{1}\" script.",
|
||||
fieldInfo->Name, object->GetType()->FullName)
|
||||
);
|
||||
}
|
||||
}
|
||||
else // Not any of the supported types
|
||||
{
|
||||
Debug::LogWarning(Convert::ToNative(System::String::Format
|
||||
(
|
||||
"[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for deserialisation.",
|
||||
fieldInfo->Name, fieldInfo->FieldType)
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/************************************************************************************//*!
|
||||
\file ReflectionUtilities.h++
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Sep 16, 2022
|
||||
\brief Contains the definition of the template functions of the managed
|
||||
ReflectionUtilities static class.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
||||
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 Header
|
||||
#include "ReflectionUtilities.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Serialization Helper Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
template<typename FieldType>
|
||||
bool ReflectionUtilities::fieldInsertYaml(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, YAML::Emitter& emitter)
|
||||
{
|
||||
if (fieldInfo->FieldType == FieldType::typeid)
|
||||
{
|
||||
emitter << safe_cast<FieldType>(fieldInfo->GetValue(object));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename FieldType>
|
||||
bool ReflectionUtilities::fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node)
|
||||
{
|
||||
return fieldAssignYaml<FieldType, FieldType>(fieldInfo, object, node);
|
||||
}
|
||||
|
||||
template<typename FieldType, typename CastType>
|
||||
bool ReflectionUtilities::fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node)
|
||||
{
|
||||
if (fieldInfo->FieldType == FieldType::typeid)
|
||||
{
|
||||
fieldInfo->SetValue(object, node.as<CastType>());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/************************************************************************************//*!
|
||||
\file ReflectionUtilities.hxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Nov 6, 2021
|
||||
\brief Contains the definition of the managed ReflectionUtilities static class.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
||||
Copyright (C) 2021 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
|
||||
|
||||
// External Dependencies
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains useful static functions for working with Reflection.
|
||||
/// </summary>
|
||||
private ref class ReflectionUtilities abstract sealed
|
||||
{
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Utility Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Retrieves a set of all non-static (instance) fields from a specified object.
|
||||
/// </summary>
|
||||
/// <param name="object">The object to get non-static fields from.</param>
|
||||
/// <returns>Immutable list of non-static fields.</returns>
|
||||
static System::Collections::Generic::IEnumerable<System::Reflection::FieldInfo^>^ GetInstanceFields(System::Object^ object);
|
||||
/// <summary>
|
||||
/// Checks if a specified field is a candidate for serialisation. This means that
|
||||
/// the field is public or private with the [SerialiseField] attribute.
|
||||
/// </summary>
|
||||
/// <param name="fieldInfo">The field to check.</param>
|
||||
/// <returns>
|
||||
/// True if the specified field is a candidate for serialisation.
|
||||
/// </returns>
|
||||
static bool FieldIsSerialisable(System::Reflection::FieldInfo^ fieldInfo);
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Serialisation Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Creates a JSON node that represents the specified object and its associated
|
||||
/// serialisable fields. Public fields and fields marked with the SerialiseField
|
||||
/// attribute will be serialised.
|
||||
/// </summary>
|
||||
/// <param name="object">The object to serialise.</param>
|
||||
static void Serialise(System::Object^ object, YAML::Emitter& yaml);
|
||||
/// <summary>
|
||||
/// Deserialises a YAML node that contains a map of Scripts and copies the
|
||||
/// deserialised data into the specified object if there are matching fields.
|
||||
/// </summary>
|
||||
/// <param name="yamlNode">
|
||||
/// The JSON string that contains the data to copy into this PlushieScript
|
||||
/// object.
|
||||
/// </param>
|
||||
/// <param name="object">The object to copy deserialised data into.</param>
|
||||
static void Deserialise(YAML::Node& yamlNode, Object^ object);
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Serialization Helper Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
static void writeFieldIntoYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Emitter& yaml);
|
||||
template<typename FieldType>
|
||||
static bool fieldInsertYaml(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, YAML::Emitter& emitter);
|
||||
static void writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node);
|
||||
template<typename FieldType>
|
||||
static bool fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node);
|
||||
template<typename FieldType, typename CastType>
|
||||
static bool fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node);
|
||||
};
|
||||
}
|
||||
|
||||
#include "ReflectionUtilities.h++"
|
|
@ -0,0 +1,27 @@
|
|||
/************************************************************************************//*!
|
||||
\file SerializeFieldAttribute.cxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Nov 5, 2021
|
||||
\brief Contains the definition of the functions of the managed SerializeField
|
||||
Attribute class.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
||||
Copyright (C) 2021 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.
|
||||
*//*************************************************************************************/
|
||||
// Precompiled Headers
|
||||
#include "SHpch.h"
|
||||
// Primary Header
|
||||
#include "SerializeFieldAttribute.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
SerializeField::SerializeField()
|
||||
{}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/************************************************************************************//*!
|
||||
\file SerializeFieldAttribute.hxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Nov 5, 2021
|
||||
\brief Contains the definition of the managed SerializeField Attribute class with
|
||||
the declaration of functions for working with it.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
||||
Copyright (C) 2021 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
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple attribute to mark that a field in a Script should be serialised.
|
||||
/// </summary>
|
||||
[System::AttributeUsage(System::AttributeTargets::Field)]
|
||||
public ref class SerializeField : public System::Attribute
|
||||
{
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
SerializeField();
|
||||
};
|
||||
}
|
||||
|
|
@ -18,6 +18,8 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Debug.hxx"
|
||||
// Standard Libraries
|
||||
#include <sstream>
|
||||
// External Libraries
|
||||
#include "Tools/SHLog.h"
|
||||
// Project Headers
|
||||
#include "Convert.hxx"
|
||||
|
||||
|
@ -28,11 +30,11 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
void Debug::Log(const std::string& str)
|
||||
{
|
||||
std::cout << str << std::endl;
|
||||
SHLog::Info(str);
|
||||
}
|
||||
void Debug::Log(System::String^ str)
|
||||
{
|
||||
System::Console::WriteLine(str);
|
||||
{
|
||||
SHLog::Info(Convert::ToNative(str));
|
||||
}
|
||||
|
||||
void Debug::Log(System::String^ str, Object^ owner)
|
||||
|
@ -47,15 +49,15 @@ namespace SHADE
|
|||
{
|
||||
std::ostringstream oss;
|
||||
oss << "[" << throwerName << "] " << Convert::ToNative(str);
|
||||
std::cout << oss.str() << std::endl;
|
||||
Log(oss.str());
|
||||
}
|
||||
void Debug::LogWarning(const std::string& str)
|
||||
{
|
||||
std::cout << str << std::endl;
|
||||
SHLog::Warning(str);
|
||||
}
|
||||
void Debug::LogWarning(System::String^ str)
|
||||
{
|
||||
System::Console::WriteLine(str);
|
||||
{
|
||||
SHLog::Warning(Convert::ToNative(str));
|
||||
}
|
||||
void Debug::LogWarning(System::String^ str, Object^ thrower)
|
||||
{
|
||||
|
@ -69,16 +71,16 @@ namespace SHADE
|
|||
void Debug::LogWarning(System::String^ str, const std::string& throwerName)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "[" << throwerName << "] " << Convert::ToNative(str);
|
||||
std::cout << oss.str() << std::endl;
|
||||
oss << "[" << throwerName << "] " << Convert::ToNative(str);
|
||||
LogWarning(oss.str());
|
||||
}
|
||||
void Debug::LogError(const std::string& str)
|
||||
{
|
||||
std::cout << str << std::endl;
|
||||
SHLog::Error(str);
|
||||
}
|
||||
void Debug::LogError(System::String^ str)
|
||||
{
|
||||
System::Console::WriteLine(str);
|
||||
SHLog::Error(Convert::ToNative(str));
|
||||
}
|
||||
void Debug::LogError(System::String^ str, Object^ thrower)
|
||||
{
|
||||
|
@ -88,7 +90,7 @@ namespace SHADE
|
|||
{
|
||||
std::ostringstream oss;
|
||||
oss << "[" << throwerName << "] -> " << Convert::ToNative(str);
|
||||
std::cout << oss.str() << std::endl;
|
||||
LogError(oss.str());
|
||||
}
|
||||
void Debug::LogError(System::String^ str, System::String^ throwerName)
|
||||
{
|
||||
|
@ -111,12 +113,12 @@ namespace SHADE
|
|||
{
|
||||
std::ostringstream oss;
|
||||
oss << "[" << throwerName << "] Unhandled exception: " << Convert::ToNative(exception->ToString());
|
||||
std::cout << oss.str() << std::endl;
|
||||
LogError(oss.str());
|
||||
}
|
||||
void Debug::LogExceptionNative(const std::exception& exception, const std::string& throwerName)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "[" << throwerName << "] Unhandled exception: " << exception.what();
|
||||
std::cout << oss.str() << std::endl;
|
||||
LogError(oss.str());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
using SHADE;
|
||||
|
||||
public class TestScript : Script
|
||||
{
|
||||
public TestScript(GameObject gameObj) : base(gameObj) {}
|
||||
|
||||
protected override void awake()
|
||||
{
|
||||
Debug.Log("TestScript.Awake()");
|
||||
}
|
||||
protected override void start()
|
||||
{
|
||||
Debug.Log("TestScript.Start()");
|
||||
}
|
||||
protected override void update()
|
||||
{
|
||||
Debug.Log("TestScript.Update()");
|
||||
}
|
||||
protected override void onDestroy()
|
||||
{
|
||||
Debug.Log("TestScript.OnDestroy()");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue