Added ECS and Component classes for SHADE_Managed
This commit is contained in:
parent
4ed417cbea
commit
b674805547
|
@ -60,12 +60,6 @@ namespace SHADE
|
|||
csEngineInit();
|
||||
|
||||
// Link events
|
||||
// - Entity Creation
|
||||
/*onEntityCreate = [this](const SHEntity& e)
|
||||
{
|
||||
csGOLibNotifyNewEntity(e.GetEID());
|
||||
};
|
||||
ECS::OnEntityCreated += onEntityCreate;*/
|
||||
// - Entity Destruction
|
||||
/*onEntityDestroy = [this](const SHEntity& e)
|
||||
{
|
||||
|
@ -384,18 +378,6 @@ namespace SHADE
|
|||
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||
"DeserialiseScript"
|
||||
);
|
||||
csGOLibNotifyNewEntity = dotNet.GetFunctionPtr<CsScriptBasicFuncPtr>
|
||||
(
|
||||
DEFAULT_CSHARP_LIB_NAME,
|
||||
DEFAULT_CSHARP_NAMESPACE + ".GameObjectLibrary",
|
||||
"NotifyNewGameObject"
|
||||
);
|
||||
csGOLibNotifyDestroyEntity = dotNet.GetFunctionPtr<CsScriptBasicFuncPtr>
|
||||
(
|
||||
DEFAULT_CSHARP_LIB_NAME,
|
||||
DEFAULT_CSHARP_NAMESPACE + ".GameObjectLibrary",
|
||||
"NotifyDestroyGameObject"
|
||||
);
|
||||
csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr>
|
||||
(
|
||||
DEFAULT_CSHARP_LIB_NAME,
|
||||
|
|
|
@ -212,9 +212,6 @@ namespace SHADE
|
|||
CsScriptDeserialiseFuncPtr csScriptDeserialise = nullptr;
|
||||
CsScriptSerialiseJsonFuncPtr csScriptsSerialiseJson = nullptr;
|
||||
CsScriptSerialiseJsonFuncPtr csScriptDeserialiseJson = nullptr;
|
||||
// - GameObject Library
|
||||
CsScriptBasicFuncPtr csGOLibNotifyNewEntity = nullptr;
|
||||
CsScriptBasicFuncPtr csGOLibNotifyDestroyEntity = nullptr;
|
||||
// - Editor
|
||||
CsScriptEditorFuncPtr csEditorRenderScripts = nullptr;
|
||||
// Delegates
|
||||
|
@ -255,4 +252,4 @@ namespace SHADE
|
|||
static bool fileExists(const std::string_view& filePath);
|
||||
static DWORD execProcess(const std::wstring& path, const std::wstring& args);
|
||||
};
|
||||
} // namespace PlushieEngine
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Components">
|
||||
<UniqueIdentifier>{6B7DD516-5735-1764-C03C-F0BFAC13B254}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Engine">
|
||||
<UniqueIdentifier>{DBC7D3B0-C769-FE86-B024-12DB9C6585D7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
|
@ -15,6 +18,12 @@
|
|||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\Components\Component.hxx">
|
||||
<Filter>Components</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Engine\ECS.hxx">
|
||||
<Filter>Engine</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Engine\EngineInterface.hxx">
|
||||
<Filter>Engine</Filter>
|
||||
</ClInclude>
|
||||
|
@ -52,6 +61,12 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\AssemblyInfo.cxx" />
|
||||
<ClCompile Include="src\Components\Component.cxx">
|
||||
<Filter>Components</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Engine\ECS.cxx">
|
||||
<Filter>Engine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Engine\EngineInterface.cxx">
|
||||
<Filter>Engine</Filter>
|
||||
</ClCompile>
|
||||
|
@ -87,4 +102,12 @@
|
|||
<Filter>Utility</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="src\Components\Component.h++">
|
||||
<Filter>Components</Filter>
|
||||
</None>
|
||||
<None Include="src\Engine\ECS.h++">
|
||||
<Filter>Engine</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,107 @@
|
|||
/************************************************************************************//*!
|
||||
\file Component.cxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Oct 27, 2021
|
||||
\brief Contains the definition of the functions for the Component 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 "Components/Component.hxx"
|
||||
// External Dependencies
|
||||
#include "Engine/ECS.hxx"
|
||||
// Project Headers
|
||||
#include "Scripts/ScriptStore.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Component Access Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
generic <typename T>
|
||||
T BaseComponent::AddComponent()
|
||||
{
|
||||
return ECS::AddComponent<T>(owner.GetNativeEntity());
|
||||
}
|
||||
generic <typename T>
|
||||
T BaseComponent::GetComponent()
|
||||
{
|
||||
return ECS::GetComponent<T>(owner.GetNativeEntity());
|
||||
}
|
||||
generic <typename T>
|
||||
void BaseComponent::RemoveComponent()
|
||||
{
|
||||
ECS::RemoveComponent<T>(owner.GetNativeEntity());
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Script Access Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
generic <typename T>
|
||||
T BaseComponent::AddScript()
|
||||
{
|
||||
return ScriptStore::AddScript<T>(owner.GetEntity());
|
||||
}
|
||||
generic <typename T>
|
||||
T BaseComponent::GetScript()
|
||||
{
|
||||
return ScriptStore::GetScript<T>(owner.GetEntity());
|
||||
}
|
||||
|
||||
generic <typename T>
|
||||
System::Collections::Generic::IEnumerable<T>^ BaseComponent::GetScripts()
|
||||
{
|
||||
return ScriptStore::GetScripts<T>(owner.GetEntity());
|
||||
}
|
||||
|
||||
generic <typename T>
|
||||
void BaseComponent::RemoveScript()
|
||||
{
|
||||
ScriptStore::RemoveScript<T>(owner.GetEntity());
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
BaseComponent::BaseComponent(Entity entity)
|
||||
: owner { entity }
|
||||
{}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* IEquatable */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
bool BaseComponent::Equals(BaseComponent^ other)
|
||||
{
|
||||
if (other == nullptr)
|
||||
return false;
|
||||
return owner == other->owner;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Object */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
bool BaseComponent::Equals(Object^ o)
|
||||
{
|
||||
try
|
||||
{
|
||||
BaseComponent^ cmp = safe_cast<BaseComponent^>(o);
|
||||
return Equals(cmp);
|
||||
}
|
||||
catch (System::InvalidCastException^)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int BaseComponent::GetHashCode()
|
||||
{
|
||||
return owner.GetHashCode();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/************************************************************************************//*!
|
||||
\file Component.h++
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Oct 27, 2021
|
||||
\brief Contains the definition of templated functions for the managed Component
|
||||
classes.
|
||||
|
||||
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
|
||||
|
||||
// Primary Include
|
||||
#include "Component.hxx"
|
||||
// Project includes
|
||||
#include "Utility/Convert.hxx"
|
||||
#include "Engine/ECS.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
template <typename NativeType>
|
||||
Component<NativeType>::Component(Entity entity)
|
||||
: BaseComponent { entity }
|
||||
{}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
template <typename NativeType>
|
||||
typename Component<NativeType>::NativeComponent* Component<NativeType>::GetNativeComponent()
|
||||
{
|
||||
return ECS::GetNativeComponent<NativeType>(owner.GetEntity());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,200 @@
|
|||
/************************************************************************************//*!
|
||||
\file Component.hxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Oct 27, 2021
|
||||
\brief Contains the definition of the managed Component classes 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
|
||||
|
||||
// External Dependencies
|
||||
#include "Engine/ECS_Base/Components/SHComponent.h"
|
||||
// Project Includes
|
||||
#include "Engine/Entity.hxx"
|
||||
#include "Scripts/Script.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/// <summary>
|
||||
/// Class that serves as the base for a wrapper class to Components in native code.
|
||||
/// </summary>
|
||||
public ref class BaseComponent : public System::IEquatable<BaseComponent^>
|
||||
{
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Properties */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Retrieves the GameObject that this Component belongs to.
|
||||
/// </summary>
|
||||
property GameObject Owner
|
||||
{
|
||||
GameObject get() { return owner; }
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Component Access Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Adds a Component to this GameObject.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the Component to add. </typeparam>
|
||||
/// <returns>Reference to the Component that was added.</returns>
|
||||
generic<typename T> where T : BaseComponent
|
||||
T AddComponent();
|
||||
/// <summary>
|
||||
/// Gets a Component from this GameObject.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the Component to get.</typeparam>
|
||||
/// <returns>
|
||||
/// Reference to the Component or null if this GameObject does not have the
|
||||
/// specified Component.
|
||||
/// </returns>
|
||||
generic<typename T> where T : BaseComponent
|
||||
T GetComponent();
|
||||
/// <summary>
|
||||
/// Removes a Component from this GameObject. If no Component exists to begin
|
||||
/// with, nothing happens.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the Component to get.</typeparam>
|
||||
generic<typename T> where T : BaseComponent
|
||||
void RemoveComponent();
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Script Access Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Adds a PlushieScript of the specified type to this GameObject.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of PlushieScript to add.</typeparam>
|
||||
/// <returns>Reference to the created PlushieScript.</returns>
|
||||
generic<typename T> where T : ref class, PlushieScript
|
||||
T AddScript();
|
||||
/// <summary>
|
||||
/// Retrieves a PlushieScript of the specified type from this GameObject.
|
||||
/// If multiple PlushieScripts of the same specified type are added on the same
|
||||
/// GameObject, this will retrieve the first one added.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of PlushieScript to add.</typeparam>
|
||||
/// <returns>Reference to the PlushieScript to retrieve.</returns>
|
||||
generic<typename T> where T : ref class, PlushieScript
|
||||
T GetScript();
|
||||
/// <summary>
|
||||
/// Retrieves a immutable list of PlushieScripts of the specified type from this
|
||||
/// GameObject.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of PlushieScripts to Get.</typeparam>
|
||||
/// <returns>Immutable list of PlushieScripts of the specified type.</returns>
|
||||
generic<typename T> where T : ref class, PlushieScript
|
||||
System::Collections::Generic::IEnumerable<T>^ GetScripts();
|
||||
/// <summary>
|
||||
/// Removes all PlushieScripts of the specified type from this GameObject.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of PLushieScripts to remove.</typeparam>
|
||||
generic<typename T> where T : ref class, PlushieScript
|
||||
void RemoveScript();
|
||||
|
||||
protected:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Constructor for BaseComponent to tie it to a specific Entity.
|
||||
/// Constructors of derived Components should call this Constructor.
|
||||
/// </summary>
|
||||
/// <param name="entity">Entity that this Component will be tied to.</param>
|
||||
BaseComponent(Entity entity);
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Entity that this Component belongs to.
|
||||
/// </summary>
|
||||
GameObject owner;
|
||||
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* IEquatable */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Compares equality with an object of the same type.
|
||||
/// </summary>
|
||||
/// <param name="other">The object to compare with.</param>
|
||||
/// <returns>True if both objects are the same.</returns>
|
||||
virtual bool Equals(BaseComponent^ other);
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Object */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Compares equality with another unboxed object.
|
||||
/// </summary>
|
||||
/// <param name="o">The unboxed object to compare with.</param>
|
||||
/// <returns>True if both objects are the same.</returns>
|
||||
bool Equals(Object^ o) override;
|
||||
/// <summary>
|
||||
/// Gets a unique hash for this object.
|
||||
/// </summary>
|
||||
/// <returns>Unique hash for this object.</returns>
|
||||
int GetHashCode() override;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// C++ template for the BaseComponent class used to generate common template-able
|
||||
/// functions and types.
|
||||
/// </summary>
|
||||
/// <typeparam name="NativeType">
|
||||
/// Type of the native component that this Component wraps.
|
||||
/// </typeparam>
|
||||
template<typename NativeType>
|
||||
public ref class Component : public BaseComponent
|
||||
{
|
||||
internal:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Type of the native component that this Component wraps.
|
||||
/// </summary>
|
||||
using NativeComponent = NativeType;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Retrieves a pointer to the native unmanaged component that is tied to the
|
||||
/// Entity described by the owner value.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Pointer to the native component. Will be nullptr if it does not exist.
|
||||
/// </returns>
|
||||
/// <exception cref="System.InvalidOperationException">
|
||||
/// Thrown if the internal ID stored by this native component is invalid.
|
||||
/// </exception>
|
||||
/// <exception cref="System.NullReferenceException">
|
||||
/// Thrown if an attempt to retrieve the native component fails.
|
||||
/// </exception>
|
||||
NativeComponent* GetNativeComponent();
|
||||
|
||||
protected:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Constructor for Component to tie it to a specific Entity.
|
||||
/// Constructors of derived Components should call this Constructor.
|
||||
/// </summary>
|
||||
/// <param name="entity">Entity that this Component will be tied to.</param>
|
||||
Component(Entity entity);
|
||||
};
|
||||
}
|
||||
|
||||
#include "Component.h++"
|
|
@ -0,0 +1,255 @@
|
|||
/************************************************************************************//*!
|
||||
\file ECS.cxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Oct 28, 2021
|
||||
\brief Contains the definition of the functions for the ECS 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 "ECS.hxx"
|
||||
// Standard Library
|
||||
#include <sstream>
|
||||
#include <msclr\marshal_cppstd.h>
|
||||
// External Dependencies
|
||||
#include "Engine/ECS_Base/System/SHEntityManager.h"
|
||||
// Project Headers
|
||||
#include "Utility/Convert.hxx"
|
||||
#include "Utility/Debug.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Component Manipulation Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
generic <typename T>
|
||||
T ECS::AddComponent(EntityID entity)
|
||||
{
|
||||
System::Type^ componentType = T::typeid;
|
||||
|
||||
// Check if entity is correct
|
||||
if (!SHEntityManager::IsValidEID(entity))
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "[ECS] Attempted to add Component \""
|
||||
<< msclr::interop::marshal_as<std::string>(componentType->Name)
|
||||
<< "\" to invalid Entity.";
|
||||
Debug::LogError(oss.str());
|
||||
return T();
|
||||
}
|
||||
|
||||
// Add based on the correct component
|
||||
for each(ComponentSet^ type in componentMap)
|
||||
{
|
||||
if (componentType == type->Type)
|
||||
{
|
||||
// Attempt to add
|
||||
type->AddFunction(entity);
|
||||
|
||||
// Return the managed component
|
||||
return createManagedComponent<T>(entity);
|
||||
}
|
||||
}
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "[ECS] Failed to add unsupported Component \""
|
||||
<< Convert::ToNative(componentType->Name)
|
||||
<< "\" to Entity #"
|
||||
<< entity;
|
||||
Debug::LogError(oss.str());
|
||||
return T();
|
||||
}
|
||||
generic <typename T>
|
||||
T ECS::GetComponent(EntityID entity)
|
||||
{
|
||||
System::Type^ componentType = T::typeid;
|
||||
|
||||
// Check if entity is correct
|
||||
if (!SHEntityManager::IsValidEID(entity))
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "[ECS] Attempted to retrieve Component \""
|
||||
<< Convert::ToNative(componentType->Name)
|
||||
<< "\" from invalid Entity.";
|
||||
Debug::LogError(oss.str());
|
||||
return T();
|
||||
}
|
||||
|
||||
// Get based on the correct component
|
||||
for each(ComponentSet^ type in componentMap)
|
||||
{
|
||||
if (componentType == type->Type)
|
||||
{
|
||||
if (type->HasFunction(entity))
|
||||
{
|
||||
return createManagedComponent<T>(entity);
|
||||
}
|
||||
else
|
||||
{
|
||||
return T();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "[ECS] Failed to retrieve unsupported Component \""
|
||||
<< Convert::ToNative(componentType->Name)
|
||||
<< "\" to Entity #"
|
||||
<< entity;
|
||||
Debug::LogError(oss.str());
|
||||
return T();
|
||||
}
|
||||
|
||||
generic <typename T>
|
||||
T ECS::GetComponentInChildren(EntityID entity)
|
||||
{
|
||||
System::Type^ componentType = T::typeid;
|
||||
|
||||
// Check if entity is correct
|
||||
if (!SHEntityManager::IsValidEID(entity))
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "[ECS] Attempted to retrieve Component \""
|
||||
<< Convert::ToNative(componentType->Name)
|
||||
<< "\" from invalid Entity.";
|
||||
Debug::LogError(oss.str());
|
||||
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();
|
||||
|
||||
//// Search direct children first
|
||||
//for (const auto& child : tf->GetChildren())
|
||||
//{
|
||||
// T component = GetComponent<T>(child);
|
||||
// if (component != nullptr)
|
||||
// return component;
|
||||
//}
|
||||
|
||||
//// Search their children
|
||||
//for (const auto& child : tf->GetChildren())
|
||||
//{
|
||||
// T script = GetComponentInChildren<T>(child);
|
||||
// if (script != nullptr)
|
||||
// return script;
|
||||
//}
|
||||
|
||||
// None here
|
||||
return T();
|
||||
}
|
||||
|
||||
generic <typename T>
|
||||
T ECS::EnsureComponent(EntityID entity)
|
||||
{
|
||||
if (HasComponent<T>(entity))
|
||||
{
|
||||
AddComponent<T>(entity);
|
||||
}
|
||||
|
||||
return GetComponent<T>(entity);
|
||||
}
|
||||
generic <typename T>
|
||||
bool ECS::HasComponent(EntityID entity)
|
||||
{
|
||||
System::Type^ componentType = T::typeid;
|
||||
|
||||
// Check if entity is correct
|
||||
if (!SHEntityManager::IsValidEID(entity))
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "[ECS] Attempted to check existence of Component \""
|
||||
<< Convert::ToNative(componentType->Name)
|
||||
<< "\" from invalid Entity.";
|
||||
Debug::LogError(oss.str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add based on the correct component
|
||||
for each(ComponentSet^ type in componentMap)
|
||||
{
|
||||
if (componentType == type->Type)
|
||||
{
|
||||
return type->HasFunction(entity);
|
||||
}
|
||||
}
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "[ECS] Attempted to check existence of unsupported Component \""
|
||||
<< msclr::interop::marshal_as<std::string>(componentType->Name)
|
||||
<< "\" from Entity #"
|
||||
<< entity;
|
||||
Debug::LogError(oss.str());
|
||||
|
||||
return false;
|
||||
}
|
||||
generic <typename T>
|
||||
void ECS::RemoveComponent(EntityID entity)
|
||||
{
|
||||
System::Type^ componentType = T::typeid;
|
||||
|
||||
// Check if entity is correct
|
||||
if (!SHEntityManager::IsValidEID(entity))
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "[ECS] Attempted to remove Component \""
|
||||
<< Convert::ToNative(componentType->Name)
|
||||
<< "\" from invalid Entity.";
|
||||
Debug::LogError(oss.str());
|
||||
}
|
||||
|
||||
// Add based on the correct component
|
||||
for each(ComponentSet^ type in componentMap)
|
||||
{
|
||||
if (componentType == type->Type)
|
||||
{
|
||||
type->RemoveFunction(entity);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "[ECS] Attempted to remove unsupported Component \""
|
||||
<< msclr::interop::marshal_as<std::string>(componentType->Name)
|
||||
<< "\" from Entity #"
|
||||
<< entity;
|
||||
Debug::LogError(oss.str());
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
static ECS::ECS()
|
||||
{
|
||||
// TODO
|
||||
// componentMap.Add(createComponentSet<Transform, Transform>());
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
generic <typename T>
|
||||
T ECS::createManagedComponent(EntityID entity)
|
||||
{
|
||||
using namespace System::Reflection;
|
||||
|
||||
array<System::Object^>^ params = gcnew array<System::Object^>{ Convert::ToCLI(entity) };
|
||||
return safe_cast<T>(Activator::CreateInstance
|
||||
(
|
||||
T::typeid,
|
||||
BindingFlags::Instance | BindingFlags::NonPublic | BindingFlags::CreateInstance,
|
||||
nullptr, params, nullptr)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/************************************************************************************//*!
|
||||
\file ECS.h++
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Oct 27, 2021
|
||||
\brief Contains the definition of templated functions for the managed Component
|
||||
classes.
|
||||
|
||||
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
|
||||
|
||||
// Primary Include
|
||||
#include "ECS.hxx"
|
||||
// External Dependencies
|
||||
#include "Engine/ECS_Base/System/SHComponentManager.h"
|
||||
#include "Engine/ECS_Base/System/SHEntityManager.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Static Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
template <typename NativeComponent>
|
||||
NativeComponent* ECS::GetNativeComponent(Entity entity)
|
||||
{
|
||||
// Get native Entity
|
||||
SHEntity* nativeEntity = SHEntityManager::GetEntityByID(entity);
|
||||
|
||||
// Entity Validity Check
|
||||
if (nativeEntity == nullptr)
|
||||
throw gcnew System::InvalidOperationException("Attempted to get native Component to an invalid Entity.");
|
||||
|
||||
// Null Check
|
||||
NativeComponent* component = SHComponentManager::GetComponent_s<NativeComponent>(nativeEntity);
|
||||
if (component == nullptr)
|
||||
throw gcnew System::NullReferenceException("Attempted to get a native Component that does not exist.");
|
||||
|
||||
return component;
|
||||
}
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
template<typename NativeType, typename ManagedType>
|
||||
ECS::ComponentSet ECS::createComponentSet()
|
||||
{
|
||||
return ComponentSet
|
||||
{
|
||||
ManagedType::typeid,
|
||||
SHComponentManager::AddComponent<NativeType>,
|
||||
SHComponentManager::EnsureComponent<NativeType>,
|
||||
SHComponentManager::HasComponent<NativeType>,
|
||||
SHComponentManager::RemoveComponent<NativeType>
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
/************************************************************************************//*!
|
||||
\file ECS.hxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Oct 28, 2021
|
||||
\brief Contains the definitions of the GameObject managed class which define an
|
||||
abstraction for working with Entities in managed code.
|
||||
|
||||
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 "Engine/ECS_Base/System/SHComponentManager.h"
|
||||
// Project Includes
|
||||
#include "Components/Component.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/// <summary>
|
||||
/// Static class which contains functions that map Pls::ECS's Component manipulation
|
||||
/// functions to managed generic functions.
|
||||
/// </summary>
|
||||
private ref class ECS abstract sealed
|
||||
{
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Component Manipulation Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Adds a Component to the specified Entity.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the Component to add.</typeparam>
|
||||
/// <param name="entity">
|
||||
/// Entity object that should have the specified Component added to.
|
||||
/// </param>
|
||||
/// <returns>Reference to the Component that was added.</returns>
|
||||
generic<typename T> where T : BaseComponent
|
||||
static T AddComponent(EntityID entity);
|
||||
/// <summary>
|
||||
/// Gets a Component from the specified Entity.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the Component to get.</typeparam>
|
||||
/// <param name="entity"> Entity object to get the Component from. </param>
|
||||
/// <returns>
|
||||
/// Reference to the Component or null if the Entity does not have the
|
||||
/// specified Component.
|
||||
/// </returns>
|
||||
generic<typename T> where T : BaseComponent
|
||||
static T GetComponent(EntityID entity);
|
||||
/// <summary>
|
||||
/// Retrieves the first Component from the specified GameObjectt's children that
|
||||
/// matches the specified type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the Component to get.</typeparam>
|
||||
/// <param name="entity"> Entity object to get the Component from. </param>
|
||||
/// <returns>
|
||||
/// Reference to the Component or null if the Entity does not have the
|
||||
/// specified Component.
|
||||
/// </returns>
|
||||
generic<typename T> where T : BaseComponent
|
||||
static T GetComponentInChildren(EntityID entity);
|
||||
/// <summary>
|
||||
/// Ensures a Component on the specified Entity.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the Component to ensure.</typeparam>
|
||||
/// <param name="entity"> Entity object to ensure the Component on. </param>
|
||||
/// <returns>Reference to the Component.</returns>
|
||||
generic<typename T> where T : BaseComponent
|
||||
static T EnsureComponent(EntityID entity);
|
||||
/// <summary>
|
||||
/// Checks if the specified Entity has the specified Component.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the Component to check for.</typeparam>
|
||||
/// <param name="entity">Entity object to check for the Component.</param>
|
||||
/// <returns>
|
||||
/// True if the specified Entity has the specified Component. False otherwise.
|
||||
/// </returns>
|
||||
generic<typename T> where T : BaseComponent
|
||||
static bool HasComponent(EntityID entity);
|
||||
/// <summary>
|
||||
/// Removes a Component from the specified Entity.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the Component to remove.</typeparam>
|
||||
/// <param name="entity">
|
||||
/// Entity object that should have the specified Component removed from/
|
||||
/// </param>
|
||||
generic<typename T> where T : BaseComponent
|
||||
static void RemoveComponent(EntityID entity);
|
||||
|
||||
internal:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Pointer to a function for Component manipulation operations.
|
||||
/// </summary>
|
||||
using ComponentFunc = void(*)(const EntityID&);
|
||||
using ComponentHasFunc = bool(*)(const EntityID&);
|
||||
/// <summary>
|
||||
/// Contains a set of Component related data used for resolving operations for
|
||||
/// each Component.
|
||||
/// </summary>
|
||||
value struct ComponentSet
|
||||
{
|
||||
public:
|
||||
System::Type^ Type;
|
||||
ComponentFunc AddFunction;
|
||||
ComponentHasFunc HasFunction;
|
||||
ComponentFunc RemoveFunction;
|
||||
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Static Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Retrieves a pointer to the native unmanaged component of the specified
|
||||
/// Entity.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Pointer to the native component. Will be nullptr if it does not exist.
|
||||
/// </returns>
|
||||
/// <exception cref="System.InvalidOperationException">
|
||||
/// Thrown if the Entity specified is invalid.
|
||||
/// </exception>
|
||||
/// <exception cref="System.NullReferenceException">
|
||||
/// Thrown if an attempt to retrieve the native component fails.
|
||||
/// </exception>
|
||||
template<typename NativeComponent>
|
||||
static NativeComponent* GetNativeComponent(Entity entity);
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Static constructor to initialize static data
|
||||
/// </summary>
|
||||
static ECS();
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Static Data Members */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
static System::Collections::Generic::List<ComponentSet> componentMap;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Creates a ComponentSet for a pair of Native and Managed Components.
|
||||
/// </summary>
|
||||
/// <typeparam name="NativeType">Type of the Native Component.</typeparam>
|
||||
/// <typeparam name="ManagedType">Type of the Managed Component.</typeparam>
|
||||
/// <returns>ComponentSet for the parameters specified.</returns>
|
||||
template<typename NativeType, typename ManagedType>
|
||||
static ComponentSet createComponentSet();
|
||||
/// <summary>
|
||||
/// Creates an instance of the Managed representation of a Component with a
|
||||
/// native Entity.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of Component to create.</typeparam>
|
||||
/// <param name="entity">Native Entity that this Component is tied to.</param>
|
||||
/// <returns>The created Managed representation of the Component.</returns>
|
||||
generic<typename T> where T : BaseComponent
|
||||
static T createManagedComponent(EntityID entity);
|
||||
};
|
||||
}
|
||||
|
||||
#include "ECS.h++"
|
|
@ -33,8 +33,8 @@ namespace SHADE
|
|||
generic<typename T>
|
||||
T ScriptStore::AddScript(Entity entity)
|
||||
{
|
||||
// Check if entity exists and is a valid GameObject
|
||||
if (!EntityUtils::IsValid(entity) /*|| !GameObjectLibrary::Contains(entity)*/)
|
||||
// Check if entity exists
|
||||
if (!EntityUtils::IsValid(entity))
|
||||
throw gcnew System::ArgumentException("Invalid Entity provided to add a Script to.");
|
||||
|
||||
System::Collections::Generic::List<Script^> ^ entityScriptList;
|
||||
|
@ -113,12 +113,9 @@ namespace SHADE
|
|||
generic<typename T>
|
||||
T ScriptStore::GetScript(Entity entity)
|
||||
{
|
||||
// Check if entity exists and is a valid GameObject
|
||||
if (!EntityUtils::IsValid(entity) /*|| !GameObjectLibrary::Contains(entity)*/)
|
||||
{
|
||||
// Check if entity exists
|
||||
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))
|
||||
|
@ -147,10 +144,8 @@ namespace SHADE
|
|||
T ScriptStore::GetScriptInChildren(Entity entity)
|
||||
{
|
||||
// Check if entity exists and is a valid GameObject
|
||||
if (!EntityUtils::IsValid(entity) /*|| !GameObjectLibrary::Contains(entity)*/)
|
||||
{
|
||||
if (!EntityUtils::IsValid(entity))
|
||||
throw gcnew System::ArgumentException("Invalid Entity provided to get a Script from.");
|
||||
}
|
||||
|
||||
|
||||
// Check if entity exists in the script storage
|
||||
|
@ -189,10 +184,8 @@ namespace SHADE
|
|||
System::Collections::Generic::IEnumerable<T>^ ScriptStore::GetScripts(Entity entity)
|
||||
{
|
||||
// Check if entity exists and is a valid GameObject
|
||||
if (!EntityUtils::IsValid(entity) /*|| !GameObjectLibrary::Contains(entity)*/)
|
||||
{
|
||||
if (!EntityUtils::IsValid(entity))
|
||||
throw gcnew System::ArgumentException("Invalid Entity provided to get a Script from.");
|
||||
}
|
||||
|
||||
// Create a list to store entries
|
||||
System::Collections::Generic::List<T>^ foundScripts = gcnew System::Collections::Generic::List<T>();
|
||||
|
@ -221,8 +214,8 @@ namespace SHADE
|
|||
}
|
||||
System::Collections::Generic::IEnumerable<Script^>^ ScriptStore::GetAllScripts(Entity entity)
|
||||
{
|
||||
// Check if entity exists and is a valid GameObject
|
||||
if (!EntityUtils::IsValid(entity) /*|| !GameObjectLibrary::Contains(entity)*/)
|
||||
// Check if entity exists
|
||||
if (!EntityUtils::IsValid(entity))
|
||||
return nullptr;
|
||||
|
||||
// Check if entity exists in the script storage
|
||||
|
@ -235,8 +228,8 @@ namespace SHADE
|
|||
generic<typename T>
|
||||
void ScriptStore::RemoveScript(Entity entity)
|
||||
{
|
||||
// Check if entity exists and is a valid GameObject
|
||||
if (!EntityUtils::IsValid(entity) /*|| !GameObjectLibrary::Contains(entity)*/)
|
||||
// Check if entity exists
|
||||
if (!EntityUtils::IsValid(entity))
|
||||
throw gcnew System::ArgumentException("Invalid Entity provided to remove a Script from.");
|
||||
|
||||
|
||||
|
@ -263,8 +256,8 @@ namespace SHADE
|
|||
}
|
||||
bool ScriptStore::RemoveScript(Entity entity, Script^ script)
|
||||
{
|
||||
// Check if entity exists and is a valid GameObject
|
||||
if (!EntityUtils::IsValid(entity) /*|| !GameObjectLibrary::Contains(entity)*/)
|
||||
// Check if entity exists
|
||||
if (!EntityUtils::IsValid(entity))
|
||||
{
|
||||
Debug::LogError("[ScriptStore] Attempted to remove a Script from an invalid Entity!");
|
||||
return false;
|
||||
|
@ -292,8 +285,8 @@ namespace SHADE
|
|||
void ScriptStore::RemoveAllScripts(Entity entity)
|
||||
{
|
||||
SAFE_NATIVE_CALL_BEGIN
|
||||
// Check if entity exists and is a valid GameObject
|
||||
if (!EntityUtils::IsValid(entity) /*|| !GameObjectLibrary::Contains(entity)*/)
|
||||
// Check if entity exists
|
||||
if (!EntityUtils::IsValid(entity))
|
||||
{
|
||||
Debug::LogError("[ScriptStore] Attempted to remove Scripts from an invalid Entity!");
|
||||
return;
|
||||
|
@ -315,8 +308,8 @@ namespace SHADE
|
|||
void ScriptStore::RemoveAllScriptsImmediately(Entity entity, bool callOnDestroy)
|
||||
{
|
||||
SAFE_NATIVE_CALL_BEGIN
|
||||
// Check if entity exists and is a valid GameObject
|
||||
if (!EntityUtils::IsValid(entity) /*|| !GameObjectLibrary::Contains(entity)*/)
|
||||
// Check if entity exists
|
||||
if (!EntityUtils::IsValid(entity))
|
||||
{
|
||||
Debug::LogError("[ScriptStore] Attempted to remove Scripts from an invalid Entity!");
|
||||
return;
|
||||
|
@ -393,7 +386,6 @@ namespace SHADE
|
|||
/*if (Application::IsPlaying)
|
||||
{
|
||||
script->OnDestroy();
|
||||
|
||||
}*/
|
||||
auto entity = script->Owner.GetEntity();
|
||||
auto scriptList = scripts[script->Owner.GetEntity()];
|
||||
|
@ -498,8 +490,8 @@ namespace SHADE
|
|||
// Create a buffer that we can work with temporarily
|
||||
System::Text::StringBuilder^ jsonString = gcnew System::Text::StringBuilder();
|
||||
|
||||
// Check if entity exists and is a valid GameObject, otherwise nothing
|
||||
if (!EntityUtils::IsValid(entity) /*|| !GameObjectLibrary::Contains(entity)*/)
|
||||
// Check if entity exists, otherwise nothing
|
||||
if (!EntityUtils::IsValid(entity))
|
||||
return true;
|
||||
|
||||
|
||||
|
@ -511,7 +503,7 @@ namespace SHADE
|
|||
System::Collections::Generic::List<Script^>^ scriptList = scripts[entity];
|
||||
for (int i = 0; i < scriptList->Count; ++i)
|
||||
{
|
||||
throw gcnew System::NotFiniteNumberException;
|
||||
throw gcnew System::NotImplementedException;
|
||||
//jsonString->Append(ReflectionUtilities::Serialise(scriptList[i]));
|
||||
|
||||
// Only add separator if is not last script
|
||||
|
@ -536,8 +528,8 @@ namespace SHADE
|
|||
bool ScriptStore::DeserialiseScript(Entity entity, System::String^ json)
|
||||
{
|
||||
SAFE_NATIVE_CALL_BEGIN
|
||||
// Check if entity exists and is a valid GameObject, otherwise nothing
|
||||
if (!EntityUtils::IsValid(entity)/* || !GameObjectLibrary::Contains(entity)*/)
|
||||
// Check if entity exists, otherwise nothing
|
||||
if (!EntityUtils::IsValid(entity))
|
||||
return false;
|
||||
|
||||
// Get the name of the script
|
||||
|
@ -670,4 +662,4 @@ namespace SHADE
|
|||
// Check active state
|
||||
return Convert::ToNative(entity).isActive;
|
||||
}
|
||||
} // namespace SHADE
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue