Merge pull request #27 from SHADE-DP/SP3-5-ECS

SP3-5 ECS

System manager rework. Added system routines
This commit is contained in:
XiaoQiDigipen 2022-09-16 14:15:23 +08:00 committed by GitHub
commit e976dee601
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 688 additions and 302 deletions

View File

@ -9,8 +9,7 @@
*********************************************************************/
#ifndef SH_COMPONENT_H
#define SH_COMPONENT_H
#pragma once
#include "SHpch.h"
#include "../SHECSMacros.h"
@ -119,4 +118,3 @@ namespace SHADE
};
}
#endif

View File

@ -14,7 +14,7 @@
#include "SHpch.h"
#include "SHComponentGroup.h"
#include "../System/SHComponentManager.h"
#include "../Managers/SHComponentManager.h"
namespace SHADE

View File

@ -12,9 +12,7 @@
consent of DigiPen Institute of Technology is prohibited.
*********************************************************************/
#ifndef SH_COMPONENT_GROUP
#define SH_COMPONENT_GROUP
#pragma once
#include "../SHECSMacros.h"
#include "../General/SHFamily.h"
@ -180,6 +178,3 @@ namespace SHADE
};
}
#endif

View File

@ -9,9 +9,9 @@
*********************************************************************/
#include "SHpch.h"
#include "SHEntity.h"
#include "../System/SHEntityManager.h"
#include "../Managers/SHEntityManager.h"
//#include "Scene/SHSceneGraph.h"
#include "../System/SHComponentManager.h"
#include "../Managers/SHComponentManager.h"
namespace SHADE
{
@ -39,6 +39,10 @@ namespace SHADE
SHComponentManager::SetActive(entityID, active);
}
bool SHEntity::GetActive(void) const noexcept
{
return isActive;
}
void SHEntity::SetParent(SHEntity* newParent) noexcept
@ -53,20 +57,20 @@ namespace SHADE
//TODO
}
SHEntity* SHEntity::GetParent() noexcept
SHEntity* SHEntity::GetParent()const noexcept
{
//TODO
return nullptr;
}
std::vector<SHEntity*>const& SHEntity::GetChildren() noexcept
std::vector<SHEntity*>const& SHEntity::GetChildren()const noexcept
{
//TODO
return std::vector<SHEntity*>{};
}
std::vector<EntityID>const& SHEntity::GetChildrenID() noexcept
std::vector<EntityID>const& SHEntity::GetChildrenID()const noexcept
{
return std::vector<EntityID>{};
}

View File

@ -8,12 +8,11 @@
consent of DigiPen Institute of Technology is prohibited.
*********************************************************************/
#ifndef SH_ENTITY_H
#define SH_ENTITY_H
#pragma once
#include "../SHECSMacros.h"
#include "../Components/SHComponent.h"
#include "../System/SHComponentManager.h"
#include "../Managers/SHComponentManager.h"
//#include "../../Scene/SHSceneNode.h"
#include "SH_API.h"
@ -64,7 +63,7 @@ namespace SHADE
* Returns nullptr if the entity does not have such Component.
***************************************************************************/
template<typename T>
std::enable_if_t<std::is_base_of_v<SHComponent, T>, T*> GetComponent() noexcept
std::enable_if_t<std::is_base_of_v<SHComponent, T>, T*> GetComponent()const noexcept
{
return SHComponentManager::GetComponent_s<T>(entityID);
@ -92,6 +91,7 @@ namespace SHADE
***************************************************************************/
virtual void SetActive(bool active) noexcept;
bool GetActive(void)const noexcept;
/**************************************************************************
@ -125,7 +125,7 @@ namespace SHADE
* Returns a pointer to the parent entity.
* Returns a nullptr if the parent node is the root node.
***************************************************************************/
SHEntity* GetParent() noexcept;
SHEntity* GetParent()const noexcept;
/**************************************************************************
@ -134,7 +134,7 @@ namespace SHADE
* \return
* Return a vector of SHEntity pointers of the children belonging to this entity.
***************************************************************************/
std::vector<SHEntity*>const& GetChildren() noexcept;
std::vector<SHEntity*>const& GetChildren()const noexcept;
/**************************************************************************
* \brief
@ -142,11 +142,13 @@ namespace SHADE
* \return
* return a vector of EntityID of the children belonging to this entity.
***************************************************************************/
std::vector<EntityID>const& GetChildrenID() noexcept;
std::vector<EntityID>const& GetChildrenID()const noexcept;
//Name of the entity. This name is non-unique and only used for the editor.
std::string name;
bool isActive;
private:
@ -157,8 +159,10 @@ namespace SHADE
EntityID entityID;
//Entity active state. This should only be set using the SetActive function which will
//set the active state of all components of this entity.
bool isActive;
};
}
#endif

View File

@ -11,8 +11,7 @@
consent of DigiPen Institute of Technology is prohibited.
*********************************************************************/
#ifndef SH_FAMILY_H
#define SH_FAMILY_H
#pragma once
#include "../SHECSMacros.h"
@ -82,7 +81,3 @@ namespace SHADE
ComponentTypeID SHFamilyID<BaseClass>::currentID = 0;
}
#endif

View File

@ -11,8 +11,7 @@
or disclosure of this file or its contents without the prior written
consent of DigiPen Institute of Technology is prohibited.
*********************************************************************/
#ifndef SH_HANDLE_GENERATOR_H
#define SH_HANDLE_GENERATOR_H
#pragma once
#include <vector>
#include <iostream>
@ -300,6 +299,3 @@ namespace SHADE
typedef SHHandleGenerator<EntityID, EntityIndex> EntityHandleGenerator;
}
#endif

View File

@ -10,8 +10,7 @@
consent of DigiPen Institute of Technology is prohibited.
*********************************************************************/
#ifndef SH_SPARSE_BASE_H
#define SH_SPARSE_BASE_H
#pragma once
#include "../SHECSMacros.h"
@ -45,6 +44,3 @@ namespace SHADE
};
}
#endif

View File

@ -9,8 +9,7 @@
or disclosure of this file or its contents without the prior written
consent of DigiPen Institute of Technology is prohibited.
*********************************************************************/
#ifndef SH_SPARSE_SET_H
#define SH_SPARSE_SET_H
#pragma once
#include "../SHECSMacros.h"
#include "../General/SHSparseBase.h"
@ -352,5 +351,3 @@ namespace SHADE
};
}
#endif

View File

@ -10,8 +10,7 @@
consent of DigiPen Institute of Technology is prohibited.
*********************************************************************/
#ifndef SH_SPARSE_SET_CONTAINER_H
#define SH_SPARSE_SET_CONTAINER_H
#pragma once
#include "SHSparseSet.h"
#include "SHFamily.h"
@ -243,6 +242,3 @@ namespace SHADE
};
}
#endif

View File

@ -12,8 +12,7 @@
consent of DigiPen Institute of Technology is prohibited.
*********************************************************************/
#ifndef SH_ENGINE_H
#define SH_ENGINE_H
#pragma once
#include "../General/SHSparseSetContainer.h"
#include "../Components/SHComponent.h"
@ -26,6 +25,8 @@
namespace SHADE
{
typedef SHFamilyID<SHComponent> ComponentFamily;
class SH_API SHComponentManager
{
private:
@ -39,6 +40,8 @@ namespace SHADE
/**************************************************************************
* \brief
* This is called by the SHSceneNode friend class to change the parent
@ -226,7 +229,7 @@ namespace SHADE
* \return
* none
***************************************************************************/
static void AddComponent(EntityID entityID, uint32_t componentTypeID) noexcept
static void AddComponent(EntityID entityID, ComponentTypeID componentTypeID) noexcept
{
componentSet.GetSparseSet_ID(componentTypeID)->Add(EntityHandleGenerator::GetIndex(entityID));
@ -278,7 +281,7 @@ namespace SHADE
* \return bool
* True if the entity has a component of specified type.
***************************************************************************/
static bool HasComponent_ID(EntityID entityID, uint32_t componentTypeID) noexcept;
static bool HasComponent_ID(EntityID entityID, ComponentTypeID componentTypeID) noexcept;
/*!*************************************************************************
@ -363,7 +366,7 @@ namespace SHADE
* \return
*
***************************************************************************/
static void SwapInDenseByIndexHash_ID(EntityIndex index, EntityID hash, uint32_t componentTypeID) noexcept;
static void SwapInDenseByIndexHash_ID(EntityIndex index, EntityID hash, ComponentTypeID componentTypeID) noexcept;
@ -386,7 +389,7 @@ namespace SHADE
* \return
* The number of components in the component sparse set.
***************************************************************************/
static EntityIndex ComponentCount_ID(uint32_t componentTypeID)
static EntityIndex ComponentCount_ID(ComponentTypeID componentTypeID)
{
return componentSet.GetSparseSet_ID(componentTypeID)->Count();
}
@ -403,9 +406,9 @@ namespace SHADE
static void SetActive(EntityID entityID, bool active) noexcept;
template<typename... T>
static std::enable_if_t<(... && std::is_base_of_v<SHComponent, T>), uint32_t> CreateComponentGroup(uint32_t numOwningComponents)
static std::enable_if_t<(... && std::is_base_of_v<SHComponent, T>), uint32_t> CreateComponentGroup(ComponentTypeID numOwningComponents)
{
std::vector<uint32_t> templateIDs{ (SHFamilyID<SHComponent>::GetID<T>())... };
std::vector<ComponentTypeID> templateIDs{ (ComponentFamily::GetID<T>())... };
for (auto& g : componentGroups)
{
@ -422,11 +425,11 @@ namespace SHADE
}
SHComponentGroup grp;
for (uint32_t i = 0; i < numOwningComponents; ++i)
for (ComponentTypeID i = 0; i < numOwningComponents; ++i)
{
grp.ownedComponentTypes.push_back(templateIDs[i]);
}
for (uint32_t i = 0; i < templateIDs.size(); ++i)
for (ComponentTypeID i = 0; i < templateIDs.size(); ++i)
{
grp.componentTypeIDs.push_back(templateIDs[i]);
}
@ -473,6 +476,3 @@ namespace SHADE
}
#endif

View File

@ -52,63 +52,20 @@ namespace SHADE
return entityHandle.GetIndex(entityID);
}
EntityID SHEntityManager::CreateEntity(std::vector<uint32_t>const& componentTypeIDs, std::string const& name,EntityID parentEID)
{
EntityID eID = entityHandle.GetNewHandle();
EntityIndex eIndex = entityHandle.GetIndex(eID);
if (eIndex > entityVec.size())
{
assert("FATAL ERROR: EntityIndex out of range in Entity Creation");
}
else if (eIndex == entityVec.size())
{
entityVec.emplace_back(std::make_unique<SHEntity>());
}
else
{
if (!entityVec[eIndex])
{
//There is still an entity stored there.Something went wrong
assert("FATAL ERROR: Entity Creation error. Entity Index Conflict");
}
//Reset it to a newly constructed entity
entityVec[eIndex].reset(new SHEntity());
}
entityVec[eIndex]->entityID = eID;
entityVec[eIndex]->name = name;
for (auto& id : componentTypeIDs)
{
SHComponentManager::AddComponent(eID, id);
}
//(SHComponentManager::AddComponent<ComponentTypes>(eID), ...);
/*if (entityHandle.IsValid(parentEID) == false)
{
entityVec[eIndex]->sceneNode.ConnectToRoot();
}
else
{
entityVec[eIndex]->SetParent(parentEID);
}*/
//TODO Link to Scene graph.
return eID;
}
EntityID SHEntityManager::CreateEntity(std::vector<uint32_t>const& componentTypeIDs, EntityID desiredEID, std::string const& name, EntityID parentEID)
{
EntityID eID ;
EntityID eID;
if (desiredEID == MAX_EID)
{
eID = entityHandle.GetNewHandle();
}
else
{
if (entityHandle.ClaimHandle(desiredEID) == true)
eID = desiredEID;
else
eID = entityHandle.GetNewHandle();
}
EntityIndex eIndex = entityHandle.GetIndex(eID);

View File

@ -12,9 +12,7 @@
or disclosure of this file or its contents without the prior written
consent of DigiPen Institute of Technology is prohibited.
*********************************************************************/
#ifndef SH_ENTITY_MANAGER_H
#define SH_ENTITY_MANAGER_H
#pragma once
#include <vector>
#include <memory>
@ -82,55 +80,21 @@ namespace SHADE
* EntityID of the new Entity
***************************************************************************/
template<typename ...ComponentTypes>
static std::enable_if_t<(... && std::is_base_of_v<SHComponent, ComponentTypes>), EntityID> CreateEntity(std::string const& name = "Default", EntityID parentEID = MAX_EID)
{
EntityID eID = entityHandle.GetNewHandle();
EntityIndex eIndex = entityHandle.GetIndex(eID);
if (eIndex > entityVec.size())
{
assert("FATAL ERROR: EntityIndex out of range in Entity Creation");
}
else if (eIndex == entityVec.size())
{
entityVec.emplace_back(std::make_unique<SHEntity>());
}
else
{
if (!entityVec[eIndex])
{
//There is still an entity stored there.Something went wrong
assert("FATAL ERROR: Entity Creation error. Entity Index Conflict");
}
//Reset it to a newly constructed entity
entityVec[eIndex].reset(new SHEntity());
}
entityVec[eIndex]->entityID = eID;
entityVec[eIndex]->name = name;
(SHComponentManager::AddComponent<ComponentTypes>(eID),...);
/*if (entityHandle.IsValid(parentEID) == false)
{
entityVec[eIndex]->sceneNode.ConnectToRoot();
}
else
{
entityVec[eIndex]->SetParent(parentEID);
}*/
//TODO Link up with Scene graph
return eID;
}
template<typename ...ComponentTypes>
static std::enable_if_t<(... && std::is_base_of_v<SHComponent, ComponentTypes>), EntityID> CreateEntity(EntityID desiredEID, std::string const& name = "Default", EntityID parentEID = MAX_EID)
static std::enable_if_t<(... && std::is_base_of_v<SHComponent, ComponentTypes>), EntityID> CreateEntity(EntityID desiredEID = MAX_EID, std::string const& name = "Default", EntityID parentEID = MAX_EID)
{
EntityID eID;
if (desiredEID == MAX_EID)
{
eID = entityHandle.GetNewHandle();
}
else
{
if (entityHandle.ClaimHandle(desiredEID) == true)
eID = desiredEID;
else
eID = entityHandle.GetNewHandle();
}
EntityIndex eIndex = entityHandle.GetIndex(eID);
if (eIndex > entityVec.size())
{
@ -180,21 +144,6 @@ namespace SHADE
/**************************************************************************
* \brief
* Create Entity using a vector of ComponentTypeIDs.
* \param componentTypeIDs
* Vector of ComponentTypeIDs. This assumes that CreateSparseSet is called
* for these ComponentTypes.
* \param name
* Name of the Entity (this is not unique)
* \param parentEID
* The entity ID of the parent. This does not call UpdateHierarchy hence
* the parent of the entity is not updated until UpdateHierarchy is called.
* \return
* EntityID of the new Entity
***************************************************************************/
static EntityID CreateEntity(std::vector<ComponentTypeID>const& componentTypeIDs,std::string const& name = "Default", EntityID parentEID = MAX_EID);
/**************************************************************************
* \brief
@ -210,7 +159,7 @@ namespace SHADE
* \return
* EntityID of the new Entity
***************************************************************************/
static EntityID CreateEntity(std::vector<ComponentTypeID>const& componentTypeIDs, EntityID desiredEID, std::string const& name = "Default", EntityID parentEID = MAX_EID);
static EntityID CreateEntity(std::vector<ComponentTypeID>const& componentTypeIDs, EntityID desiredEID = MAX_EID, std::string const& name = "Default", EntityID parentEID = MAX_EID);
/**************************************************************************
* \brief
@ -248,7 +197,3 @@ namespace SHADE
}
#endif

View File

@ -0,0 +1,77 @@
/*********************************************************************
* \file SHSystemManager.cpp
* \author Daniel Chua Yee Chen
* \brief Implementation for the SHSystemManager class.
* SHSystemManager is the interface class where users of the engine create
* the systems that gives the components their functionality. This also
* ensures that the Init and Exit functions are ran at the appropriate time
*
* \copyright 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.
*********************************************************************/
#include "SHpch.h"
#include "SHSystemManager.h"
#include <iostream>
#include <chrono>
#include <ratio>
#include <ctime>
namespace SHADE
{
SHSystemManager::SystemContainer SHSystemManager::systemContainer;
SHSystemManager::SystemRoutineContainer SHSystemManager::systemRoutineContainer;
void SHSystemManager::Init() noexcept
{
for (auto& system : systemContainer)
{
system.second->Init();
#ifdef _DEBUG
std::cout << system.first << " Init" << std::endl;
#endif
}
}
void SHSystemManager::RunRoutines(bool editorPause, double deltaTime) noexcept
{
for (auto& routine : systemRoutineContainer)
{
if (editorPause == true)
{
if (routine.get()->IsRunInEditorPause)
{
std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
routine.get()->Execute(deltaTime);
std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
routine.get()->stats.executionTime = std::chrono::duration<double, std::milli>(end - start).count();
}
}
else
{
std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
routine.get()->Execute(deltaTime);
std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
routine.get()->stats.executionTime = std::chrono::duration<double, std::milli>(end - start).count();
}
}
}
void SHSystemManager::Exit() noexcept
{
systemRoutineContainer.clear();
for (SystemContainer::reverse_iterator it = systemContainer.rbegin(); it != systemContainer.rend(); ++it)
{
(*it).second->Exit();
//delete system.second;
}
systemContainer.clear();
}
}

View File

@ -10,29 +10,32 @@
consent of DigiPen Institute of Technology is prohibited.
*********************************************************************/
#ifndef SH_SYSTEM_MANAGER_H
#define SH_SYSTEM_MANAGER_H
#pragma once
#include <unordered_map>
#include <map>
#include <memory>
#include <string>
#include <cassert>
#include <climits>
#include "../System/SHSystem.h"
#include "../General/SHFamily.h"
#include "../System/SHSystemRoutine.h"
namespace SHADE
{
typedef SHFamilyID<SHSystem> SystemFamily;
class SHSystemManager
{
//type definition for the container we use to store our system
using SystemContainer = std::unordered_map<std::string, std::unique_ptr<SHSystem>>;
using SystemContainer = std::map<SystemID, std::unique_ptr<SHSystem>>;
using SystemRoutineContainer = std::vector<std::unique_ptr<SHSystemRoutine>>;
private:
static SystemContainer systemContainer;
static SystemRoutineContainer systemRoutineContainer;
public:
/*!*************************************************************************
@ -52,15 +55,21 @@ namespace SHADE
* none
***************************************************************************/
template<typename T>
static std::enable_if_t<std::is_base_of_v<SHSystem, T>, void> CreateSystem(std::string const& name)
static std::enable_if_t<std::is_base_of_v<SHSystem, T>, SystemID> CreateSystem()
{
if (systemContainer.find(name) != systemContainer.end())
SystemTypeID typeID = SystemFamily::GetID<T>();
SystemVersionID version = 0;
SystemID id = ((SystemID)version << sizeof(SystemVersionID) * CHAR_BIT) + typeID;
while (systemContainer.find(id) != systemContainer.end())
{
assert("System Creation Error: System with the same name already exist.");
++version;
id = ((SystemID)version << sizeof(SystemVersionID) * CHAR_BIT) + typeID;
}
systemContainer.emplace(id, std::make_unique<T>());
systemContainer[id].get()->systemID = id;
systemContainer.emplace(name, std::make_unique<T>());
return id;
}
@ -72,7 +81,21 @@ namespace SHADE
* \return
* Base System pointer.
***************************************************************************/
static SHSystem* GetSystem(std::string name);
template<typename T>
static std::enable_if_t<std::is_base_of_v<SHSystem, T>, T*> GetSystem(SystemVersionID version = 0)
{
SystemTypeID typeID = SystemFamily::GetID<T>();
SystemID id = ((SystemID)version << sizeof(SystemVersionID) * CHAR_BIT) + typeID;
if (systemContainer.find(id) == systemContainer.end())
{
std::cout << "System Manager error: System Version " << version << " does not exit." << std::endl;
return nullptr;
}
return (T*)systemContainer.find(id)->second.get();
}
/**************************************************************************
* \brief
@ -82,6 +105,20 @@ namespace SHADE
***************************************************************************/
static void Init() noexcept;
static void RunRoutines(bool editorPause, double deltaTime) noexcept;
template<typename SystemType, typename RoutineType>
static void RegisterRoutine(SystemVersionID version = 0) noexcept
{
SHSystem* system = GetSystem<SystemType>(version);
if (system == nullptr)
return;
systemRoutineContainer.emplace_back(std::make_unique<RoutineType>());
systemRoutineContainer.back().get()->system = system;
}
/**************************************************************************
* \brief
* Call the Exit function of all systems.
@ -96,7 +133,3 @@ namespace SHADE
};
}
#endif

View File

@ -9,6 +9,10 @@
typedef uint32_t EntityID;
typedef uint16_t EntityIndex;
typedef uint32_t ComponentTypeID;
typedef uint32_t SystemTypeID;
typedef uint32_t SystemVersionID;
typedef uint64_t SystemID;
const EntityIndex MAX_EID = 51000;

View File

@ -0,0 +1,21 @@
#include "SHpch.h"
#include "SHFixedSystemRoutine.h"
#include "../SHECSMacros.h"
namespace SHADE
{
void SHFixedSystemRoutine::Execute(double dt) noexcept
{
accumulatedTime += dt;
int counter = 0;
while (accumulatedTime >= fixedTimeStep)
{
++counter;
accumulatedTime -= fixedTimeStep;
FixedExecute(fixedTimeStep);
}
stats.numSteps = counter;
}
}

View File

@ -0,0 +1,31 @@
#pragma once
#include "SHSystemRoutine.h"
#define DEFAULT_FIXED_STEP 1.0/60.0
namespace SHADE
{
class SHFixedSystemRoutine: public SHSystemRoutine
{
private:
double accumulatedTime;
double fixedTimeStep;
protected:
SHFixedSystemRoutine(double timeStep = DEFAULT_FIXED_STEP, std::string routineName = "Default Fixed Routine Name", bool editorPause = false)
:SHSystemRoutine(routineName, editorPause), accumulatedTime(0.0), fixedTimeStep(timeStep){}
public:
~SHFixedSystemRoutine() = default;
virtual void Execute(double dt) noexcept;
virtual void FixedExecute(double dt) noexcept {};
};
}

View File

@ -0,0 +1,28 @@
#pragma once
#include <string>
#include <iostream>
namespace SHADE
{
struct SHRoutineStats
{
SHRoutineStats(std::string name)
:name(name)
{
}
std::string name;
double executionTime;
int numSteps{1};
//friend std::ostream& operator<<(std::ostream& os, const SHRoutineStats& stats);
};
//std::ostream& operator<<(std::ostream& os, const SHRoutineStats& stats)
//{
// os << stats.name << ": Execution Time: " << stats.executionTime << " Number of steps: " << stats.numSteps << std::endl;
// return os;
//}
}

View File

@ -8,13 +8,20 @@
consent of DigiPen Institute of Technology is prohibited.
*********************************************************************/
#ifndef SH_SYSTEM_H
#define SH_SYSTEM_H
#pragma once
#include "../SHECSMacros.h"
namespace SHADE
{
class SHSystemManager;
class SHSystem
{
private:
SystemID systemID;
protected:
/*!*************************************************************************
* \brief
@ -22,6 +29,9 @@ namespace SHADE
***************************************************************************/
SHSystem()= default;
public:
/*!*************************************************************************
* \brief
@ -35,13 +45,13 @@ namespace SHADE
***************************************************************************/
virtual void Init() = 0;
/*!*************************************************************************
* \brief
* Pure virtual Run function. Derived class must implement this
* \param dt
* Delta time
***************************************************************************/
virtual void Run(float dt) = 0;
///*!*************************************************************************
// * \brief
// * Pure virtual Run function. Derived class must implement this
// * \param dt
// * Delta time
//***************************************************************************/
//virtual void Run(float dt) = 0;
/*!*************************************************************************
* \brief
@ -49,7 +59,14 @@ namespace SHADE
***************************************************************************/
virtual void Exit() = 0;
};
}
friend class SHSystemManager;
#endif
inline SystemID GetSystemID(void) const noexcept { return systemID; }
inline SystemVersionID GetSystemVersion(void) const noexcept { return static_cast<SystemVersionID>(systemID >> sizeof(SystemVersionID) * CHAR_BIT); }
};
}

View File

@ -1,57 +0,0 @@
/*********************************************************************
* \file SHSystemManager.cpp
* \author Daniel Chua Yee Chen
* \brief Implementation for the SHSystemManager class.
* SHSystemManager is the interface class where users of the engine create
* the systems that gives the components their functionality. This also
* ensures that the Init and Exit functions are ran at the appropriate time
*
* \copyright 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.
*********************************************************************/
#include "SHpch.h"
#include "SHSystemManager.h"
#include <iostream>
namespace SHADE
{
SHSystemManager::SystemContainer SHSystemManager::systemContainer;
SHSystem* SHSystemManager::GetSystem(std::string name)
{
if (systemContainer.find(name) == systemContainer.end())
{
assert("Get System Error: No system with such name exist.");
return nullptr;
}
return systemContainer.find(name)->second.get();
}
void SHSystemManager::Init() noexcept
{
for (auto& system : systemContainer)
{
system.second->Init();
#ifdef _DEBUG
std::cout << system.first << " Init" << std::endl;
#endif
}
}
void SHSystemManager::Exit() noexcept
{
for (auto& system : systemContainer)
{
system.second->Exit();
//delete system.second;
}
systemContainer.clear();
}
}

View File

@ -0,0 +1,23 @@
#include "SHpch.h"
#include "SHSystemRoutine.h"
namespace SHADE
{
SHSystem* SHSystemRoutine::GetSystem() const noexcept
{
return system;
}
std::string const SHSystemRoutine::GetName()const noexcept
{
return name;
}
SHRoutineStats const& SHSystemRoutine::GetStats()const noexcept
{
return stats;
}
}

View File

@ -0,0 +1,53 @@
#pragma once
#include "../SHECSMacros.h"
#include "SHRoutineStats.h"
#include "SHSystem.h"
#include <string>
namespace SHADE
{
class SHSystemManager;
class SHSystemRoutine
{
friend class SHSystemManager;
protected:
SHSystemRoutine(std::string routineName = "Default Routine Name", bool editorPause = false)
:system(nullptr), name(routineName), stats(routineName),IsRunInEditorPause(editorPause){};
SHSystem* system;
std::string name;
SHRoutineStats stats;
//Whether or not this routine should run when the editor is still in pause
bool IsRunInEditorPause;
public:
~SHSystemRoutine() = default;
SHSystem* GetSystem()const noexcept;
std::string const GetName() const noexcept;
SHRoutineStats const& GetStats()const noexcept;
virtual void Execute(double dt) noexcept {};
};
}

View File

@ -0,0 +1,181 @@
#include "SHpch.h"
#include "SHECSUnitTest.h"
#include "../Managers/SHComponentManager.h"
#include "../Managers/SHEntityManager.h"
#include "../Managers/SHSystemManager.h"
#include "SHTestComponents.h"
#include "SHTestSystems.h"
#include "Tools/SHLogger.h"
namespace SHADE
{
void SHECSUnitTest::TestAll(void) noexcept
{
TestBasicEntityCreate();
TestEntityCreateTemplate();
TestEntityDestroy();
TestSystemRoutine();
}
void SHECSUnitTest::TestBasicEntityCreate(void) noexcept
{
SHComponentManager::CreateComponentSparseSet<SHComponent_A>();
SHComponentManager::CreateComponentSparseSet<SHComponent_B>();
SHComponentManager::CreateComponentSparseSet<SHComponent_C>();
SHLOG_INFO("Test for add and remove component")
EntityID id1 = SHEntityManager::CreateEntity();
EntityID id2 = SHEntityManager::CreateEntity();
EntityID id3 = SHEntityManager::CreateEntity();
SHComponentManager::AddComponent<SHComponent_A>(id1);
}
void SHECSUnitTest::TestEntityCreateTemplate(void) noexcept
{
std::cout << "\nTest2" << std::endl;
//Test entity Creation.
SHComponentManager::CreateComponentSparseSet<SHComponent_A>();
SHComponentManager::CreateComponentSparseSet<SHComponent_B>();
SHComponentManager::CreateComponentSparseSet<SHComponent_C>();
for (size_t i = 0; i < 10000; ++i)
{
switch (i % 3)
{
case 0:
{
SHEntityManager::CreateEntity<SHComponent_A, SHComponent_B>();
}break;
case 1:
{
SHEntityManager::CreateEntity<SHComponent_A, SHComponent_C>();
}break;
case 2:
{
SHEntityManager::CreateEntity<SHComponent_A>();
}break;
default:
break;
}
}
auto& denseA = SHComponentManager::GetDense<SHComponent_A>();
auto& denseB = SHComponentManager::GetDense<SHComponent_B>();
auto& denseC = SHComponentManager::GetDense<SHComponent_C>();
std::cout << "Test Entity Creation" << std::endl;
std::cout << "dense A size: " << denseA.size() << ((denseA.size() == 10000) ? " Success" : " Failure") << std::endl;
std::cout << "dense B size: " << denseB.size() << ((denseB.size() == 3334) ? " Success" : " Failure") << std::endl;
std::cout << "dense C size: " << denseC.size() << ((denseC.size() == 3333) ? " Success" : " Failure") << std::endl;
std::cout << "Number of entities: " << SHEntityManager::GetEntityCount() << (SHEntityManager::GetEntityCount() == 10000 ? " Success" : " Failure") << std::endl;
SHEntityManager::DestroyAllEntity();
std::cout << std::endl << "Test Destroy All Entity" << std::endl;
std::cout << "dense A size: " << denseA.size() << ((denseA.size() == 0) ? " Success" : " Failure") << std::endl;
std::cout << "dense B size: " << denseB.size() << ((denseB.size() == 0) ? " Success" : " Failure") << std::endl;
std::cout << "dense C size: " << denseC.size() << ((denseC.size() == 0) ? " Success" : " Failure") << std::endl;
std::cout << "Number of entities: " << SHEntityManager::GetEntityCount() << (SHEntityManager::GetEntityCount() == 0 ? " Success" : " Failure") << std::endl;
}
void SHECSUnitTest::TestEntityDestroy(void) noexcept
{
std::cout << "\nTest3" << std::endl;
SHComponentManager::CreateComponentSparseSet<SHComponent_A>();
SHComponentManager::CreateComponentSparseSet<SHComponent_B>();
SHComponentManager::CreateComponentSparseSet<SHComponent_C>();
for (size_t i = 0; i < 10000; ++i)
{
switch (i % 3)
{
case 0:
{
SHEntityManager::CreateEntity<SHComponent_A, SHComponent_B>();
}break;
case 1:
{
SHEntityManager::CreateEntity<SHComponent_A, SHComponent_C>();
}break;
case 2:
{
SHEntityManager::CreateEntity<SHComponent_A>();
}break;
default:
break;
}
}
SHEntityManager::DestroyEntity(5000);
SHEntityManager::DestroyEntity(5001);
auto& denseA = SHComponentManager::GetDense<SHComponent_A>();
auto& denseB = SHComponentManager::GetDense<SHComponent_B>();
auto& denseC = SHComponentManager::GetDense<SHComponent_C>();
std::cout << "Test Entity Deletion" << std::endl;
std::cout << "dense A size: " << denseA.size() << ((denseA.size() == 9998) ? " Success" : " Failure") << std::endl;
std::cout << "dense B size: " << denseB.size() << ((denseB.size() == 3333) ? " Success" : " Failure") << std::endl;
std::cout << "dense C size: " << denseC.size() << ((denseC.size() == 3333) ? " Success" : " Failure") << std::endl;
std::cout << "Number of entities: " << SHEntityManager::GetEntityCount() << (SHEntityManager::GetEntityCount() == 9998 ? " Success" : " Failure") << std::endl;
std::cout << std::endl << "Test Entity Recreation" << std::endl;
EntityID id = SHEntityManager::CreateEntity<SHComponent_C>();
std::cout << "dense A size: " << denseA.size() << ((denseA.size() == 9998) ? " Success" : " Failure") << std::endl;
std::cout << "dense B size: " << denseB.size() << ((denseB.size() == 3333) ? " Success" : " Failure") << std::endl;
std::cout << "dense C size: " << denseC.size() << ((denseC.size() == 3334) ? " Success" : " Failure") << std::endl;
std::cout << "Entity ID: " << id << " EntityIndex: " << EntityHandleGenerator::GetIndex(id) << (EntityHandleGenerator::GetIndex(id) == 5001 ? " Success" : " Failure") << std::endl;
std::cout << "Number of entities: " << SHEntityManager::GetEntityCount() << (SHEntityManager::GetEntityCount() == 9999 ? " Success" : " Failure") << std::endl;
SHEntityManager::DestroyAllEntity();
std::cout << std::endl << "Check Destroy All Entity" << std::endl;
std::cout << "dense A size: " << denseA.size() << ((denseA.size() == 0) ? " Success" : " Failure") << std::endl;
std::cout << "dense B size: " << denseB.size() << ((denseB.size() == 0) ? " Success" : " Failure") << std::endl;
std::cout << "dense C size: " << denseC.size() << ((denseC.size() == 0) ? " Success" : " Failure") << std::endl;
std::cout << "Number of entities: " << SHEntityManager::GetEntityCount() << (SHEntityManager::GetEntityCount() == 0 ? " Success" : " Failure") << std::endl;
}
void SHECSUnitTest::TestSystemRoutine(void) noexcept
{
SHSystemManager::CreateSystem<SHTestSystem>();
SHSystemManager::CreateSystem<SHTestSystem>();
SHSystemManager::RegisterRoutine<SHTestSystem, SHTestSystem::SHTestRoutine>(1);
SHSystemManager::RunRoutines(false, 1.0 / 120.0);
SHSystemManager::Exit();
}
}

View File

@ -0,0 +1,22 @@
#pragma once
namespace SHADE
{
class SHECSUnitTest
{
public:
SHECSUnitTest() = delete;
~SHECSUnitTest() = delete;
static void TestBasicEntityCreate(void) noexcept;
static void TestEntityCreateTemplate(void) noexcept;
static void TestEntityDestroy(void) noexcept;
static void TestSystemRoutine(void) noexcept;
static void TestAll(void) noexcept;
};
}

View File

@ -0,0 +1,30 @@
#pragma once
#include "../Components/SHComponent.h"
namespace SHADE
{
class SHComponent_A :public SHComponent
{
public:
int value{};
};
class SHComponent_B :public SHComponent
{
public:
float x{};
float y{};
float z{};
};
class SHComponent_C :public SHComponent
{
public:
std::string value{};
};
}

View File

@ -0,0 +1,40 @@
#pragma once
#include <string>
#include "../System/SHSystem.h"
#include "../System/SHSystemRoutine.h"
namespace SHADE
{
class SHTestSystem : public SHSystem
{
public:
SHTestSystem() {};
~SHTestSystem() {};
std::string test{ "Test system" };
void Init() {};
void Exit() {};
class SHTestRoutine : public SHSystemRoutine
{
public:
SHTestRoutine()
:SHSystemRoutine("Test System Routine", false) {}
virtual void Execute(double dt) noexcept
{
std::cout << GetName() << " System Version: " << GetSystem()->GetSystemVersion() << std::endl;
}
};
};
}

View File

@ -14,7 +14,7 @@
#include "SHSceneGraph.h"
// Project Headers
#include "ECS_Base/System/SHEntityManager.h"
#include "ECS_Base/Managers/SHEntityManager.h"
#include "Tools/SHLogger.h"
#include "Tools/SHException.h"

View File

@ -10,11 +10,11 @@
*********************************************************************/
#include "SHpch.h"
#include "SHSceneManager.h"
#include "ECS_Base/System/SHComponentManager.h"
#include "ECS_Base/Managers/SHComponentManager.h"
//#include "Input/SHInputManager.h"
//#include "Rendering/Window/SHRenderingWindow.h"
#include "ECS_Base/System/SHEntityManager.h"
#include "ECS_Base/System/SHSystemManager.h"
#include "ECS_Base/Managers/SHEntityManager.h"
#include "ECS_Base/Managers/SHSystemManager.h"
//#include "FRC/SHFrameRateController.h"
//#include "ECS_Base/System/SHApplication.h"

View File

@ -20,7 +20,7 @@ of DigiPen Institute of Technology is prohibited.
#include <sstream>
#include <msclr\marshal_cppstd.h>
// External Dependencies
#include "ECS_Base/System/SHEntityManager.h"
#include "ECS_Base/Managers/SHEntityManager.h"
// Project Headers
#include "Utility/Convert.hxx"
#include "Utility/Debug.hxx"

View File

@ -17,8 +17,8 @@ of DigiPen Institute of Technology is prohibited.
// Primary Include
#include "ECS.hxx"
// External Dependencies
#include "ECS_Base/System/SHComponentManager.h"
#include "ECS_Base/System/SHEntityManager.h"
#include "ECS_Base/Managers/SHComponentManager.h"
#include "ECS_Base/Managers/SHEntityManager.h"
namespace SHADE
{

View File

@ -15,7 +15,7 @@ of DigiPen Institute of Technology is prohibited.
#pragma once
// External Dependencies
#include "ECS_Base/System/SHComponentManager.h"
#include "ECS_Base/Managers/SHComponentManager.h"
// Project Includes
#include "Components/Component.hxx"

View File

@ -17,7 +17,7 @@ of DigiPen Institute of Technology is prohibited.
// Primary Header
#include "Entity.hxx"
// External Dependencies
#include "ECS_Base/System/SHEntityManager.h"
#include "ECS_Base/Managers/SHEntityManager.h"
namespace SHADE
{

View File

@ -16,7 +16,7 @@ of DigiPen Institute of Technology is prohibited.
// Primary Header
#include "GameObject.hxx"
// External Dependencies
#include "ECS_Base/System/SHEntityManager.h"
#include "ECS_Base/Managers/SHEntityManager.h"
// Project Headers
#include "ECS.hxx"
#include "Scripts/ScriptStore.hxx"
@ -52,7 +52,7 @@ namespace SHADE
}
bool GameObject::IsActiveSelf::get()
{
return GetNativeEntity().isActive;
return GetNativeEntity().GetActive();
}
bool GameObject::IsActiveInHierarchy::get()
{
@ -68,7 +68,7 @@ namespace SHADE
}
void GameObject::SetActive(bool active)
{
GetNativeEntity().isActive = active;
GetNativeEntity().SetActive(active);
}
/*---------------------------------------------------------------------------------*/

View File

@ -19,7 +19,7 @@ of DigiPen Institute of Technology is prohibited.
// Standard Libraries
#include <sstream>
// External Dependencies
#include "ECS_Base/System/SHEntityManager.h"
#include "ECS_Base/Managers/SHEntityManager.h"
// Project Headers
#include "Utility/Debug.hxx"
#include "Utility/Convert.hxx"
@ -668,6 +668,6 @@ namespace SHADE
throw gcnew System::InvalidOperationException("Attempted to get native Component to an invalid Entity.");
// Check active state
return nativeEntity->isActive;
return nativeEntity->GetActive();
}
}

View File

@ -17,7 +17,7 @@ of DigiPen Institute of Technology is prohibited.
// Primary Header
#include "Convert.hxx"
// External Dependencies
#include "ECS_Base/System//SHEntityManager.h"
#include "ECS_Base/Managers/SHEntityManager.h"
#include <msclr/marshal_cppstd.h>
namespace SHADE