Added ECS and Component classes for SHADE_Managed

This commit is contained in:
Kah Wei 2022-09-13 13:51:11 +08:00
parent 4ed417cbea
commit b674805547
10 changed files with 883 additions and 52 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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