Merge remote-tracking branch 'origin/main' into SP3-1-Rendering
This commit is contained in:
commit
80dc8d0a71
|
@ -47,32 +47,57 @@ namespace SHADE
|
|||
|
||||
void SHEntity::SetParent(SHEntity* newParent) noexcept
|
||||
{
|
||||
(void)newParent;
|
||||
//TODO
|
||||
SHSceneManager::GetCurrentSceneGraph().SetParent(GetEID(), newParent->GetEID());
|
||||
}
|
||||
|
||||
void SHEntity::SetParent(EntityID newParentID) noexcept
|
||||
{
|
||||
(void)newParentID;
|
||||
//TODO
|
||||
SHSceneManager::GetCurrentSceneGraph().SetParent(GetEID(), newParentID);
|
||||
}
|
||||
|
||||
SHEntity* SHEntity::GetParent()const noexcept
|
||||
{
|
||||
//TODO
|
||||
SHSceneNode* parent = SHSceneManager::GetCurrentSceneGraph().GetParent(GetEID());
|
||||
if (parent != nullptr)
|
||||
return SHEntityManager::GetEntityByID(parent->GetEntityID());
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EntityID SHEntity::GetParentEID()const noexcept
|
||||
{
|
||||
SHSceneNode* parent = SHSceneManager::GetCurrentSceneGraph().GetParent(GetEID());
|
||||
if (parent != nullptr)
|
||||
return parent->GetEntityID();
|
||||
else
|
||||
return MAX_EID;
|
||||
}
|
||||
|
||||
|
||||
std::vector<SHEntity*>const& SHEntity::GetChildren()const noexcept
|
||||
{
|
||||
//TODO
|
||||
return std::vector<SHEntity*>{};
|
||||
std::vector<SHEntity*> childrenEntity;
|
||||
|
||||
auto& childrenNodes = SHSceneManager::GetCurrentSceneGraph().GetChildren(GetEID());
|
||||
for (auto& childNode : childrenNodes)
|
||||
{
|
||||
childrenEntity.push_back(SHEntityManager::GetEntityByID(childNode->GetEntityID()));
|
||||
}
|
||||
|
||||
return childrenEntity;
|
||||
}
|
||||
|
||||
std::vector<EntityID>const& SHEntity::GetChildrenID()const noexcept
|
||||
{
|
||||
return std::vector<EntityID>{};
|
||||
std::vector<EntityID> childrenEntity;
|
||||
|
||||
auto& childrenNodes = SHSceneManager::GetCurrentSceneGraph().GetChildren(GetEID());
|
||||
for (auto& childNode : childrenNodes)
|
||||
{
|
||||
childrenEntity.push_back(childNode->GetEntityID());
|
||||
}
|
||||
|
||||
return childrenEntity;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -127,6 +127,13 @@ namespace SHADE
|
|||
***************************************************************************/
|
||||
SHEntity* GetParent()const noexcept;
|
||||
|
||||
/********************************************************************
|
||||
* \brief
|
||||
* Get the entity ID of the parent.
|
||||
* \return
|
||||
* return the entity ID of the parent
|
||||
********************************************************************/
|
||||
EntityID GetParentEID() const noexcept;
|
||||
|
||||
/**************************************************************************
|
||||
* \brief
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "ECS_Base/Entity/SHEntity.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
struct SHEntityCreationEvent
|
||||
{
|
||||
EntityID eid;
|
||||
std::vector<ComponentTypeID> componentTypeIDs;
|
||||
EntityID parentEID;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "ECS_Base/Entity/SHEntity.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
struct SHEntityDestroyedEvent
|
||||
{
|
||||
EntityID eid;
|
||||
};
|
||||
}
|
|
@ -103,6 +103,18 @@ namespace SHADE
|
|||
SHComponentManager::AddComponent(eID, id);
|
||||
}
|
||||
|
||||
|
||||
//Link up with scene graph.
|
||||
|
||||
if (parentEID != MAX_EID)
|
||||
SHSceneManager::GetCurrentSceneGraph().AddNode(eID, SHSceneManager::GetCurrentSceneGraph().GetNode(parentEID));
|
||||
else
|
||||
SHSceneManager::GetCurrentSceneGraph().AddNode(eID);
|
||||
|
||||
//set up event stuff
|
||||
SHEntityCreationEvent event{ eID,componentTypeIDs, parentEID };
|
||||
SHEventManager::BroadcastEvent<SHEntityCreationEvent>(event, SH_ENTITY_CREATION_EVENT);
|
||||
|
||||
//(SHComponentManager::AddComponent<ComponentTypes>(eID), ...);
|
||||
|
||||
//if (entityHandle.IsValid(parentEID) == false)
|
||||
|
@ -134,6 +146,14 @@ namespace SHADE
|
|||
//Call all the children to Destroy themselves first before the parent is destroyed.
|
||||
if (entityVec[eIndex])
|
||||
{
|
||||
auto& children = SHSceneManager::GetCurrentSceneGraph().GetChildren(eID);
|
||||
for (auto& child : children)
|
||||
{
|
||||
DestroyEntity(child->GetEntityID());
|
||||
}
|
||||
|
||||
SHSceneManager::GetCurrentSceneGraph().RemoveNode(eID);
|
||||
|
||||
//auto& children = entityVec[eIndex]->GetChildrenID();
|
||||
//while(!children.empty())
|
||||
//{
|
||||
|
@ -153,6 +173,14 @@ namespace SHADE
|
|||
entityHandle.RemoveHandle(eID);
|
||||
|
||||
entityVec[eIndex].reset(nullptr);
|
||||
|
||||
|
||||
|
||||
|
||||
SHEntityDestroyedEvent event{eID};
|
||||
SHEventManager::BroadcastEvent<SHEntityDestroyedEvent>(event, SH_ENTITY_DESTROYED_EVENT);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
#include "../Components/SHComponent.h"
|
||||
#include "../General/SHHandleGenerator.h"
|
||||
#include "../SHECSMacros.h"
|
||||
#include "ECS_Base/Events/SHEntityCreationEvent.h"
|
||||
#include "ECS_Base/Events/SHEntityDestroyedEvent.h"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
#include "Events/SHEventManager.hpp"
|
||||
#include "SH_API.h"
|
||||
|
||||
namespace SHADE
|
||||
|
@ -125,6 +129,23 @@ namespace SHADE
|
|||
entityVec[eIndex]->name = name;
|
||||
(SHComponentManager::AddComponent<ComponentTypes>(eID), ...);
|
||||
|
||||
//set up event stuff
|
||||
std::vector<ComponentTypeID> typeIDVec;
|
||||
(typeIDVec.push_back(ComponentFamily::GetID<ComponentTypes>()), ...);
|
||||
|
||||
|
||||
//Link up with scene graph.
|
||||
|
||||
if (parentEID != MAX_EID)
|
||||
SHSceneManager::GetCurrentSceneGraph().AddNode(eID, SHSceneManager::GetCurrentSceneGraph().GetNode(parentEID));
|
||||
else
|
||||
SHSceneManager::GetCurrentSceneGraph().AddNode(eID);
|
||||
|
||||
SHEntityCreationEvent event{ eID,typeIDVec,parentEID };
|
||||
SHEventManager::BroadcastEvent<SHEntityCreationEvent>(event, SH_ENTITY_CREATION_EVENT);
|
||||
|
||||
|
||||
|
||||
/*if (entityHandle.IsValid(parentEID) == false)
|
||||
{
|
||||
entityVec[eIndex]->sceneNode.ConnectToRoot();
|
||||
|
@ -135,8 +156,6 @@ namespace SHADE
|
|||
}*/
|
||||
|
||||
|
||||
//Link up with scene graph.
|
||||
|
||||
|
||||
return eID;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace SHADE
|
|||
std::string const GetName() const noexcept;
|
||||
SHRoutineStats const& GetStats()const noexcept;
|
||||
|
||||
virtual void Execute(double dt) noexcept {};
|
||||
virtual void Execute(double dt) noexcept { (void)dt; };
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -30,8 +30,8 @@ namespace SHADE
|
|||
SHLOG_INFO("Test for add and remove component")
|
||||
|
||||
EntityID id1 = SHEntityManager::CreateEntity();
|
||||
EntityID id2 = SHEntityManager::CreateEntity();
|
||||
EntityID id3 = SHEntityManager::CreateEntity();
|
||||
SHEntityManager::CreateEntity();
|
||||
SHEntityManager::CreateEntity();
|
||||
|
||||
|
||||
SHComponentManager::AddComponent<SHComponent_A>(id1);
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace SHADE
|
|||
|
||||
virtual void Execute(double dt) noexcept
|
||||
{
|
||||
|
||||
(void)dt;
|
||||
std::cout << GetName() << " System Version: " << GetSystem()->GetSystemVersion() << std::endl;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -16,7 +16,17 @@ namespace SHADE
|
|||
struct SHEvent
|
||||
{
|
||||
SHEventIdentifier type;
|
||||
SHEventDataPtr dataPtr;
|
||||
SHEventHandle handle;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct SHEventSpec : SHEvent
|
||||
{
|
||||
SHEventSpec(SHEventIdentifier t, SHEventHandle e, std::shared_ptr<const T> dp)
|
||||
:SHEvent{ t, e }, data{ dp } {}
|
||||
|
||||
std::shared_ptr<const T> data;
|
||||
};
|
||||
|
||||
using SHEventPtr = std::shared_ptr<const SHEvent>;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
typedef uint32_t SHEventIdentifier;
|
||||
typedef uint32_t SHEventHandle;
|
||||
typedef void* SHEventDataPtr;
|
||||
|
||||
//Add your event identifiers here:
|
||||
constexpr SHEventIdentifier SH_EXAMPLE_EVENT{0};
|
||||
constexpr SHEventIdentifier SH_ENTITY_DESTROYED_EVENT{ 1 };
|
||||
constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT{ 2 };
|
||||
|
|
|
@ -1,107 +0,0 @@
|
|||
/******************************************************************************
|
||||
* \file SHEventManager.cpp
|
||||
* \author Loh Xiao Qi
|
||||
* \brief Function Implmentations for SHEventManager
|
||||
*
|
||||
* \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 "SHEventManager.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
std::unordered_map<SHEventIdentifier, ResponseVec> SHEventManager::packageReceiverRegistry;
|
||||
std::unordered_map<SHEventHandle, SHEventDataPtr> SHEventManager::dataEventMap;
|
||||
|
||||
SHEventHandle SHEventManager::handleCounter{ 0 };
|
||||
|
||||
/****************************************************************************
|
||||
* \param ListenerConstPtr - Const pointer to listener that sent event.
|
||||
* \param EventType - Templated type for every type of event
|
||||
|
||||
* \brief Receives event from the listeners.
|
||||
****************************************************************************/
|
||||
void SHEventManager::CatchEvent(SHEvent event)
|
||||
{
|
||||
|
||||
// Do something with the event
|
||||
|
||||
Broadcast(event);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* \param ResponseFunction - function pointer from receiver to be passed
|
||||
* into event manager to be called when events are broadcasted.
|
||||
* \param SHEventIdentifier - package type that corresponding subscriber is
|
||||
* subscribing to.
|
||||
|
||||
* \brief Links a function pointer from a subscriber to a particular
|
||||
* package type
|
||||
****************************************************************************/
|
||||
void SHEventManager::SubscribeTo(SHEventIdentifier pkgType, ReceiverPtr receiver)
|
||||
{
|
||||
RegisterReceiverToType(pkgType, receiver);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* SHEventManager::BroadcastEvent(T data, SHEventIdentifier eventType)
|
||||
{
|
||||
SHEventDataPtr ptr = new std::byte[sizeof(data)];
|
||||
|
||||
std::memcpy(ptr, &data, sizeof(data));
|
||||
|
||||
CatchEvent(
|
||||
{
|
||||
eventType,
|
||||
ptr,
|
||||
handleCounter++
|
||||
}
|
||||
);
|
||||
|
||||
return reinterpret_cast<T*>(ptr);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* \param ReceiverPtr - Pointer to receiver
|
||||
* \param ListenerConstPtr - Const pointer to listener that receiver is
|
||||
* subscribing to.
|
||||
|
||||
* \brief Registers receiver as a subscriber to listener in the registry.
|
||||
****************************************************************************/
|
||||
void SHEventManager::RegisterReceiverToType(
|
||||
SHEventIdentifier pkgType, ReceiverPtr receiver)
|
||||
{
|
||||
if (packageReceiverRegistry.contains(pkgType))
|
||||
{
|
||||
packageReceiverRegistry[pkgType].emplace_back(receiver);
|
||||
}
|
||||
else
|
||||
{
|
||||
packageReceiverRegistry.emplace(pkgType, std::vector{ receiver });
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* \param ListenerConstPtr - Const pointer to listener that sent event.
|
||||
* \param EventType - Event data
|
||||
|
||||
* \brief Broadcast event to all receivers that are subscribed to this
|
||||
* listener.
|
||||
****************************************************************************/
|
||||
void SHEventManager::Broadcast(SHEvent const& event)
|
||||
{
|
||||
ResponseVec& receivers{ packageReceiverRegistry[event.type] };
|
||||
for (auto& receiver : receivers)
|
||||
{
|
||||
receiver->Receive(event);
|
||||
}
|
||||
|
||||
//auto& funcs{ ackageReceiverRegistry[event.GetType()] };
|
||||
//for (auto func : funcs)
|
||||
//{
|
||||
// func(event.GetData());
|
||||
//}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/******************************************************************************
|
||||
* \file SHEventManager.h
|
||||
* \file SHEventManager.hpp
|
||||
* \author Loh Xiao Qi
|
||||
* \brief Class declaration for event manager.
|
||||
*
|
||||
|
@ -9,10 +9,9 @@
|
|||
******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "SHpch.h"
|
||||
#include "SHEvent.h"
|
||||
#include "SHEventReceiver.h"
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
|
||||
/******************************************************************************
|
||||
INSTRUCTIONS FOR USE:
|
||||
|
@ -24,11 +23,16 @@
|
|||
3. When ready to send the event, call
|
||||
SHEventManager::BroadcastEvent<ExampleClass>(exampleClass, EVENT_IDENTIFIER);
|
||||
|
||||
Headers required: SHEventManager.h
|
||||
NOTE: If your custom struct to contain data requires a deep copy, please
|
||||
overload the assignment operator accordingly. It is fine to send
|
||||
a single object of a basic type such as int/float.
|
||||
|
||||
Headers required: SHEventManager.hpp
|
||||
|
||||
On Receiver side:
|
||||
1. Create a function with the signature:
|
||||
SHEventHandle FunctionName(SHEvent);
|
||||
SHEventHandle FunctionName(SHEventPtr);
|
||||
|
||||
2. In the init function of the class, copy the below in and replace the
|
||||
necessary:
|
||||
|
||||
|
@ -42,25 +46,71 @@
|
|||
|
||||
3. Note: The EventIdentifier should match all that is defined in
|
||||
SHEventDefines.h so check there. When the receiver catches the event, it
|
||||
needs to know the struct that the broadcaster is using to cast the void*
|
||||
properly.
|
||||
needs to know the struct that the broadcaster is using to cast the event
|
||||
ptr as such:
|
||||
|
||||
Headers required: SHEventManager.h, SHEventReceiver.h
|
||||
reinterpret_cast<std::shared_ptr<SHEventSpec<CustomClass>>>(event)
|
||||
|
||||
4. Inside the new ptr should be a shared pointer of const CustomClass type.
|
||||
|
||||
Headers required: SHEventManager.hpp, SHEventReceiver.h
|
||||
|
||||
If you have any questions/suggestions for improvement lmk.
|
||||
******************************************************************************/
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
using ResponseFunction = std::function<SHEventHandle(SHEvent)>;
|
||||
//using ResponseFunction = std::function<SHEventHandle(SHEventPtr)>;
|
||||
using ReceiverPtr = std::shared_ptr<SHEventReceiver>;
|
||||
using ResponseVec = std::vector<ReceiverPtr>;
|
||||
using StaticResponseVec = std::vector<ResponseFunction>;
|
||||
|
||||
using EventManagerListener = std::function<void(SHEvent)>;
|
||||
|
||||
|
||||
class SHEventManager
|
||||
{
|
||||
private:
|
||||
|
||||
// Registry for broadcasters and subscribers
|
||||
inline static std::unordered_map<SHEventIdentifier, ResponseVec> packageReceiverRegistry;
|
||||
|
||||
inline static SHEventHandle handleCounter {0};
|
||||
|
||||
/****************************************************************************
|
||||
* \param ListenerConstPtr - Const pointer to listener that sent event.
|
||||
* \param EventType - Event data
|
||||
|
||||
* \brief Broadcast event to all receivers that are subscribed to this
|
||||
* listener.
|
||||
****************************************************************************/
|
||||
static void Broadcast(SHEventPtr event)
|
||||
{
|
||||
ResponseVec& receivers{ packageReceiverRegistry[event->type] };
|
||||
for (auto& receiver : receivers)
|
||||
{
|
||||
receiver->Receive(event);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* \param ReceiverPtr - Pointer to receiver
|
||||
* \param ListenerConstPtr - Const pointer to listener that receiver is
|
||||
* subscribing to.
|
||||
|
||||
* \brief Registers receiver as a subscriber to listener in the registry.
|
||||
****************************************************************************/
|
||||
static void RegisterReceiverToType(SHEventIdentifier pkgType, ReceiverPtr receiver)
|
||||
{
|
||||
if (packageReceiverRegistry.find(pkgType) == packageReceiverRegistry.end())
|
||||
{
|
||||
packageReceiverRegistry.emplace(pkgType, std::vector{ receiver });
|
||||
}
|
||||
else
|
||||
{
|
||||
packageReceiverRegistry[pkgType].emplace_back(receiver);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -69,7 +119,13 @@ namespace SHADE
|
|||
|
||||
* \brief Receives event from the listeners.
|
||||
****************************************************************************/
|
||||
static void CatchEvent(SHEvent);
|
||||
static void CatchEvent(SHEventPtr event)
|
||||
{
|
||||
|
||||
// Do something with the event
|
||||
|
||||
Broadcast(event);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* \param ResponseFunction - function pointer from receiver to be passed
|
||||
|
@ -80,37 +136,20 @@ namespace SHADE
|
|||
* \brief Links a function pointer from a subscriber to a particular
|
||||
* package type
|
||||
****************************************************************************/
|
||||
static void SubscribeTo(SHEventIdentifier, ReceiverPtr);
|
||||
static void SubscribeTo(SHEventIdentifier pkgType, ReceiverPtr receiver)
|
||||
{
|
||||
RegisterReceiverToType(pkgType, receiver);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T* BroadcastEvent(T data, SHEventIdentifier eventType);
|
||||
|
||||
private:
|
||||
|
||||
// Registry for broadcasters and subscribers
|
||||
static std::unordered_map<SHEventIdentifier, ResponseVec> packageReceiverRegistry;
|
||||
static std::unordered_map<SHEventHandle, SHEventDataPtr> dataEventMap;
|
||||
|
||||
static SHEventHandle handleCounter;
|
||||
|
||||
/****************************************************************************
|
||||
* \param ListenerConstPtr - Const pointer to listener that sent event.
|
||||
* \param EventType - Event data
|
||||
|
||||
* \brief Broadcast event to all receivers that are subscribed to this
|
||||
* listener.
|
||||
****************************************************************************/
|
||||
static void Broadcast(SHEvent const&);
|
||||
|
||||
/****************************************************************************
|
||||
* \param ReceiverPtr - Pointer to receiver
|
||||
* \param ListenerConstPtr - Const pointer to listener that receiver is
|
||||
* subscribing to.
|
||||
|
||||
* \brief Registers receiver as a subscriber to listener in the registry.
|
||||
****************************************************************************/
|
||||
static void RegisterReceiverToType(SHEventIdentifier, ReceiverPtr);
|
||||
static void BroadcastEvent(T data, SHEventIdentifier eventType)
|
||||
{
|
||||
std::shared_ptr<const T> ptr = std::make_shared<T>(data);
|
||||
|
||||
CatchEvent(
|
||||
std::make_shared<SHEventSpec<T>>(eventType, handleCounter++, ptr)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -8,7 +8,7 @@ namespace SHADE
|
|||
{
|
||||
private:
|
||||
public:
|
||||
virtual void Receive(SHEvent) = 0;
|
||||
virtual void Receive(SHEventPtr) = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
@ -16,16 +16,16 @@ namespace SHADE
|
|||
{
|
||||
private:
|
||||
T* object;
|
||||
SHEventHandle(T::*callback)(SHEvent);
|
||||
SHEventHandle(T::*callback)(SHEventPtr);
|
||||
|
||||
public:
|
||||
SHEventReceiverSpec(T* obj, void(T::* cb)(SHEventDataPtr))
|
||||
SHEventReceiverSpec(T* obj, void(T::* cb)(SHEventPtr))
|
||||
:SHEventReceiver(), object{ obj }, callback{ cb }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Receive(SHEvent evt) override
|
||||
void Receive(SHEventPtr evt) override
|
||||
{
|
||||
(object->*callback)(evt);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#define SH_SCENE_H
|
||||
|
||||
#include <string>
|
||||
#include "SHSceneGraph.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -19,15 +20,19 @@ namespace SHADE
|
|||
class SHScene
|
||||
{
|
||||
private:
|
||||
SHSceneGraph sceneGraph;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
SHScene() = default;
|
||||
|
||||
public:
|
||||
virtual ~SHScene() = default;
|
||||
|
||||
std::string sceneName;
|
||||
|
||||
virtual ~SHScene() = default;
|
||||
SHSceneGraph& GetSceneGraph() noexcept { return sceneGraph; }
|
||||
|
||||
virtual void Load() = 0;
|
||||
virtual void Init() = 0;
|
||||
|
|
|
@ -76,7 +76,10 @@ namespace SHADE
|
|||
|
||||
SHSceneGraph::SHSceneGraph() noexcept
|
||||
: root { nullptr }
|
||||
{}
|
||||
{
|
||||
// The root is set to the maximum entity. It should not be interfaced with.
|
||||
root = AllocateNode(MAX_EID);
|
||||
}
|
||||
|
||||
SHSceneGraph::~SHSceneGraph() noexcept
|
||||
{
|
||||
|
@ -90,6 +93,8 @@ namespace SHADE
|
|||
for (auto* node : entityNodeMap | std::views::values)
|
||||
ReleaseNode(node);
|
||||
|
||||
delete root;
|
||||
|
||||
#ifdef _DEBUG
|
||||
SHLOG_INFO("Scene Graph Destroyed Successfully!")
|
||||
#endif
|
||||
|
@ -99,10 +104,25 @@ namespace SHADE
|
|||
/* Getter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
EntityID SHSceneNode::GetEntityID() const noexcept
|
||||
{
|
||||
return entityID;
|
||||
}
|
||||
|
||||
SHSceneNode* SHSceneNode::GetParent() const noexcept
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
const std::vector<SHSceneNode*>& SHSceneNode::GetChildren() const noexcept
|
||||
{
|
||||
return children;
|
||||
}
|
||||
|
||||
SHSceneNode* SHSceneNode::GetChild(EntityID childID) const noexcept
|
||||
{
|
||||
////////////////////////////////////////
|
||||
// Error handling
|
||||
{
|
||||
if (!SHEntityManager::IsValidEID(childID))
|
||||
{
|
||||
SHLOG_ERROR("Child Entity {} is invalid! Unable to get child from Entity {}", childID, entityID)
|
||||
|
@ -114,7 +134,7 @@ namespace SHADE
|
|||
SHLOG_WARNING("Entity {} has no children!", entityID)
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
||||
// Find child
|
||||
const auto ENTITY_MATCH = [&](const SHSceneNode* node) { return node->GetEntityID() == childID; };
|
||||
|
@ -129,7 +149,7 @@ namespace SHADE
|
|||
return *CHILD_ITER;
|
||||
}
|
||||
|
||||
SHSceneNode* SHSceneGraph::GetRoot() const noexcept
|
||||
const SHSceneNode* SHSceneGraph::GetRoot() const noexcept
|
||||
{
|
||||
if (root != nullptr)
|
||||
return root;
|
||||
|
@ -140,6 +160,8 @@ namespace SHADE
|
|||
|
||||
SHSceneNode* SHSceneGraph::GetNode(EntityID entityID) const noexcept
|
||||
{
|
||||
////////////////////////////////////////
|
||||
// Error handling
|
||||
if (!SHEntityManager::IsValidEID(entityID))
|
||||
{
|
||||
SHLOG_ERROR("Entity {} is invalid! Unable to Get Scene node!", entityID)
|
||||
|
@ -152,12 +174,15 @@ namespace SHADE
|
|||
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to Get Scene node!", entityID)
|
||||
return nullptr;
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
||||
return NODE_ITER->second;
|
||||
}
|
||||
|
||||
SHSceneNode* SHSceneGraph::GetParent(EntityID entityID) const noexcept
|
||||
{
|
||||
////////////////////////////////////////
|
||||
// Error handling
|
||||
if (!SHEntityManager::IsValidEID(entityID))
|
||||
{
|
||||
SHLOG_ERROR("Entity {} is invalid! Unable to get Parent node!", entityID)
|
||||
|
@ -170,13 +195,15 @@ namespace SHADE
|
|||
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to get Parent node!", entityID)
|
||||
return nullptr;
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
||||
return NODE_ITER->second->GetParent();
|
||||
}
|
||||
|
||||
SHSceneNode* SHSceneGraph::GetChild(EntityID entityID, SHSceneNode* childNode) const noexcept
|
||||
{
|
||||
// Error Handling
|
||||
////////////////////////////////////////
|
||||
// Error handling
|
||||
if (!SHEntityManager::IsValidEID(entityID))
|
||||
{
|
||||
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
||||
|
@ -203,12 +230,15 @@ namespace SHADE
|
|||
SHLOG_WARNING("Entity {} is not a child of Entity {}!", childNode->GetEntityID(), entityID)
|
||||
return nullptr;
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
||||
return *CHILD_ITER;
|
||||
}
|
||||
|
||||
SHSceneNode* SHSceneGraph::GetChild(EntityID entityID, EntityID childEntityID) const noexcept
|
||||
{
|
||||
////////////////////////////////////////
|
||||
// Error handling
|
||||
if (!SHEntityManager::IsValidEID(entityID))
|
||||
{
|
||||
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
||||
|
@ -221,14 +251,15 @@ namespace SHADE
|
|||
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
|
||||
return nullptr;
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
||||
return NODE_ITER->second->GetChild(childEntityID);
|
||||
}
|
||||
|
||||
const std::vector<SHSceneNode*>& SHSceneGraph::GetChildren(EntityID entityID) const noexcept
|
||||
{
|
||||
// TODO(Diren): Discuss with team best way to handle this
|
||||
|
||||
////////////////////////////////////////
|
||||
// Error handling
|
||||
if (!SHEntityManager::IsValidEID(entityID))
|
||||
{
|
||||
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
||||
|
@ -241,6 +272,7 @@ namespace SHADE
|
|||
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
|
||||
return root->GetChildren();
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
||||
return NODE_ITER->second->GetChildren();
|
||||
}
|
||||
|
@ -252,11 +284,17 @@ namespace SHADE
|
|||
void SHSceneNode::SetParent(SHSceneNode* parentNode) noexcept
|
||||
{
|
||||
if (parentNode == nullptr)
|
||||
{
|
||||
SHLOG_WARNING("Removing Entity {}'s parent", entityID)
|
||||
}
|
||||
|
||||
// Handle self assignment
|
||||
if (parentNode == parent)
|
||||
return;
|
||||
|
||||
if (parent)
|
||||
parent->RemoveChild(this);
|
||||
|
||||
parent = parentNode;
|
||||
// Update parent's children
|
||||
parent->AddChild(this);
|
||||
|
@ -264,6 +302,8 @@ namespace SHADE
|
|||
|
||||
void SHSceneGraph::SetParent(EntityID entityID, SHSceneNode* parent) const noexcept
|
||||
{
|
||||
////////////////////////////////////////
|
||||
// Error Handling
|
||||
if (!SHEntityManager::IsValidEID(entityID))
|
||||
{
|
||||
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
||||
|
@ -276,12 +316,15 @@ namespace SHADE
|
|||
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
|
||||
return;
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
||||
NODE_ITER->second->SetParent(parent);
|
||||
}
|
||||
|
||||
void SHSceneGraph::SetParent(EntityID entityID, EntityID parent) const noexcept
|
||||
{
|
||||
////////////////////////////////////////
|
||||
// Error Handling
|
||||
if (!SHEntityManager::IsValidEID(entityID))
|
||||
{
|
||||
SHLOG_ERROR("Entity {} is invalid! Unable to set parent of an invalid entity!", entityID)
|
||||
|
@ -301,12 +344,13 @@ namespace SHADE
|
|||
return;
|
||||
}
|
||||
|
||||
auto PARENT_ITER = entityNodeMap.find(entityID);
|
||||
auto PARENT_ITER = entityNodeMap.find(parent);
|
||||
if (PARENT_ITER == entityNodeMap.end())
|
||||
{
|
||||
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to parent to Entity {}", parent, entityID)
|
||||
return;
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
||||
SHSceneNode* currentNode = NODE_ITER->second;
|
||||
currentNode->SetParent(PARENT_ITER->second);
|
||||
|
@ -318,50 +362,69 @@ namespace SHADE
|
|||
|
||||
void SHSceneNode::AddChild(SHSceneNode* newChild) noexcept
|
||||
{
|
||||
////////////////////////////////////////
|
||||
// Error Handling
|
||||
if (newChild == nullptr)
|
||||
{
|
||||
SHLOG_WARNING("Attempting to add a non-existent child to an entity!")
|
||||
return;
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
||||
if (newChild->parent)
|
||||
newChild->parent->RemoveChild(newChild);
|
||||
|
||||
newChild->parent = this;
|
||||
children.emplace_back(newChild);
|
||||
}
|
||||
|
||||
bool SHSceneNode::RemoveChild(EntityID childID) noexcept
|
||||
{
|
||||
////////////////////////////////////////
|
||||
// Error Handling
|
||||
if (!SHEntityManager::IsValidEID(childID))
|
||||
{
|
||||
SHLOG_ERROR("Entity {} is invalid!", childID)
|
||||
return false;
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
||||
SHSceneNode* removedChild = nullptr;
|
||||
const auto ENTITY_MATCH = [&](SHSceneNode* node)
|
||||
auto childIter = std::find_if(children.begin(), children.end(), [&](SHSceneNode* node)
|
||||
{
|
||||
if (node->GetEntityID() == childID)
|
||||
return node->GetEntityID() == childID;
|
||||
});
|
||||
|
||||
if (childIter == children.end())
|
||||
{
|
||||
removedChild = node;
|
||||
return true;
|
||||
SHLOG_WARNING("Unable to remove Entity {} from Entity {} since it is not it's child!", childID, entityID)
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
(*childIter)->parent = nullptr;
|
||||
childIter = children.erase(childIter);
|
||||
|
||||
children.end() = std::remove_if(children.begin(), children.end(), ENTITY_MATCH);
|
||||
removedChild->parent = nullptr;
|
||||
|
||||
return removedChild == nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SHSceneNode::RemoveChild(SHSceneNode* childToRemove) noexcept
|
||||
{
|
||||
////////////////////////////////////////
|
||||
// Error Handling
|
||||
if (childToRemove == nullptr)
|
||||
{
|
||||
SHLOG_WARNING("Attempting to remove non-existent child from Entity {}", entityID)
|
||||
return false;
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
||||
children.end() = std::remove(children.begin(), children.end(), childToRemove);
|
||||
auto childIter = std::find(children.begin(), children.end(), childToRemove);
|
||||
if (childIter == children.end())
|
||||
{
|
||||
SHLOG_WARNING("Unable to remove Entity {} from Entity {} since it is not it's child!", childToRemove->entityID, entityID)
|
||||
return false;
|
||||
}
|
||||
|
||||
childIter = children.erase(childIter);
|
||||
childToRemove->parent = nullptr;
|
||||
|
||||
return true;
|
||||
|
@ -375,14 +438,16 @@ namespace SHADE
|
|||
children.clear();
|
||||
}
|
||||
|
||||
|
||||
SHSceneNode* SHSceneGraph::AddNode(EntityID entityID, SHSceneNode* parent)
|
||||
{
|
||||
////////////////////////////////////////
|
||||
// Error Handling
|
||||
if (!SHEntityManager::IsValidEID(entityID))
|
||||
{
|
||||
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
||||
return nullptr;
|
||||
}
|
||||
////////////////////////////////////////
|
||||
|
||||
if (auto NODE_ITER = entityNodeMap.find(entityID); NODE_ITER != entityNodeMap.end())
|
||||
{
|
||||
|
@ -391,6 +456,10 @@ namespace SHADE
|
|||
}
|
||||
|
||||
SHSceneNode* newNode = AllocateNode(entityID);
|
||||
|
||||
if (parent == nullptr)
|
||||
parent = root;
|
||||
|
||||
newNode->SetParent(parent);
|
||||
|
||||
return newNode;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
// Project Headers
|
||||
#include "ECS_Base/Entity/SHEntity.h"
|
||||
#include "SH_API.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -21,7 +22,7 @@ namespace SHADE
|
|||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
class SHSceneNode
|
||||
class SH_API SHSceneNode
|
||||
{
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -46,9 +47,9 @@ namespace SHADE
|
|||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
[[nodiscard]] EntityID GetEntityID () const noexcept { return entityID ;}
|
||||
[[nodiscard]] SHSceneNode* GetParent () const noexcept { return parent; }
|
||||
[[nodiscard]] std::vector<SHSceneNode*>& GetChildren () noexcept { return children; }
|
||||
[[nodiscard]] EntityID GetEntityID () const noexcept;
|
||||
[[nodiscard]] SHSceneNode* GetParent () const noexcept;
|
||||
[[nodiscard]] const std::vector<SHSceneNode*>& GetChildren () const noexcept;
|
||||
|
||||
[[nodiscard]] SHSceneNode* GetChild (EntityID childID) const noexcept;
|
||||
|
||||
|
@ -75,7 +76,7 @@ namespace SHADE
|
|||
std::vector<SHSceneNode*> children;
|
||||
};
|
||||
|
||||
class SHSceneGraph
|
||||
class SH_API SHSceneGraph
|
||||
{
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -100,7 +101,7 @@ namespace SHADE
|
|||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
[[nodiscard]] SHSceneNode* GetRoot () const noexcept;
|
||||
[[nodiscard]] const SHSceneNode* GetRoot () const noexcept;
|
||||
[[nodiscard]] SHSceneNode* GetNode (EntityID entityID) const noexcept;
|
||||
[[nodiscard]] SHSceneNode* GetParent (EntityID entityID) const noexcept;
|
||||
[[nodiscard]] SHSceneNode* GetChild (EntityID entityID, SHSceneNode* childNode) const noexcept;
|
||||
|
|
|
@ -37,6 +37,12 @@ namespace SHADE
|
|||
std::function<void()> SHSceneManager::newScene = []() {};
|
||||
//void (*SHSceneManager::prevSceneCreate)() = []() {};
|
||||
|
||||
|
||||
SHSceneGraph& SHSceneManager::GetCurrentSceneGraph() noexcept
|
||||
{
|
||||
return currentScene->GetSceneGraph();
|
||||
}
|
||||
|
||||
void SHSceneManager::UpdateSceneManager() noexcept
|
||||
{
|
||||
if (sceneChanged == false)
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
namespace SHADE
|
||||
{
|
||||
|
||||
class SHSceneManager
|
||||
class SH_API SHSceneManager
|
||||
{
|
||||
private:
|
||||
//boolean to check if the scene has been changed
|
||||
|
@ -57,6 +57,15 @@ namespace SHADE
|
|||
//boolean to check if the programme has been terminated.
|
||||
static bool quit;
|
||||
|
||||
/********************************************************************
|
||||
* \brief
|
||||
* Get the scene graph of the current scene.
|
||||
* \return
|
||||
* A reference to the scene graph of the current active scene.
|
||||
********************************************************************/
|
||||
static SHSceneGraph& GetCurrentSceneGraph() noexcept;
|
||||
|
||||
|
||||
/*!*************************************************************************
|
||||
* \brief
|
||||
* Initialize scene manager and loads a default scene
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
erase /s /q *.vcxproj
|
||||
erase /s /q *.vcxproj.filters
|
||||
|
||||
call Premake\premake5 vs2019
|
||||
PAUSE
|
Loading…
Reference in New Issue