Changeset View
Changeset View
Standalone View
Standalone View
source/simulation2/system/ComponentManager.cpp
Show All 28 Lines | |||||
#include "simulation2/MessageTypes.h" | #include "simulation2/MessageTypes.h" | ||||
#include "simulation2/system/DynamicSubscription.h" | #include "simulation2/system/DynamicSubscription.h" | ||||
#include "simulation2/system/IComponent.h" | #include "simulation2/system/IComponent.h" | ||||
#include "simulation2/system/ParamNode.h" | #include "simulation2/system/ParamNode.h" | ||||
#include "simulation2/system/SimContext.h" | #include "simulation2/system/SimContext.h" | ||||
#include <string_view> | #include <string_view> | ||||
template<typename Pred> | |||||
struct RecurseFind | |||||
{ | |||||
template<typename Head, typename... Tail> | |||||
IComponent* operator()(Head& head, Tail&... tail) | |||||
{ | |||||
if (m_Pred(head)) | |||||
return &head; | |||||
if constexpr (sizeof...(Tail) == 0) | |||||
return nullptr; | |||||
else | |||||
return (*this)(tail...); | |||||
} | |||||
RecurseFind(Pred pred) : | |||||
m_Pred{pred} | |||||
{} | |||||
Pred m_Pred; | |||||
}; | |||||
template<typename... Types, typename Pred> | |||||
static IComponent* TupleFind(std::tuple<Types...>& tuple, Pred pred) | |||||
{ | |||||
return std::apply(RecurseFind{pred}, tuple); | |||||
} | |||||
/** | /** | ||||
* Used for script-only message types. | * Used for script-only message types. | ||||
*/ | */ | ||||
class CMessageScripted final : public CMessage | class CMessageScripted final : public CMessage | ||||
{ | { | ||||
public: | public: | ||||
virtual int GetType() const { return mtid; } | virtual int GetType() const { return mtid; } | ||||
virtual const char* GetScriptHandlerName() const { return handlerName.c_str(); } | virtual const char* GetScriptHandlerName() const { return handlerName.c_str(); } | ||||
▲ Show 20 Lines • Show All 443 Lines • ▼ Show 20 Lines | for (; iit != m_ComponentsByTypeId.rend(); ++iit) | ||||
std::map<entity_id_t, IComponent*>::iterator eit = iit->second.begin(); | std::map<entity_id_t, IComponent*>::iterator eit = iit->second.begin(); | ||||
for (; eit != iit->second.end(); ++eit) | for (; eit != iit->second.end(); ++eit) | ||||
{ | { | ||||
eit->second->Deinit(); | eit->second->Deinit(); | ||||
m_ComponentTypesById[iit->first].dealloc(eit->second); | m_ComponentTypesById[iit->first].dealloc(eit->second); | ||||
} | } | ||||
} | } | ||||
m_SystemComponents.reset(); | |||||
std::vector<std::unordered_map<entity_id_t, IComponent*> >::iterator ifcit = m_ComponentsByInterface.begin(); | std::vector<std::unordered_map<entity_id_t, IComponent*> >::iterator ifcit = m_ComponentsByInterface.begin(); | ||||
for (; ifcit != m_ComponentsByInterface.end(); ++ifcit) | for (; ifcit != m_ComponentsByInterface.end(); ++ifcit) | ||||
ifcit->clear(); | ifcit->clear(); | ||||
m_ComponentsByTypeId.clear(); | m_ComponentsByTypeId.clear(); | ||||
// Delete all SEntityComponentCaches | // Delete all SEntityComponentCaches | ||||
std::unordered_map<entity_id_t, SEntityComponentCache*>::iterator ccit = m_ComponentCaches.begin(); | std::unordered_map<entity_id_t, SEntityComponentCache*>::iterator ccit = m_ComponentCaches.begin(); | ||||
▲ Show 20 Lines • Show All 242 Lines • ▼ Show 20 Lines | if (ct.type == CT_Script) | ||||
{ | { | ||||
LOGERROR("Script component constructor failed"); | LOGERROR("Script component constructor failed"); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
} | } | ||||
// Construct the new component | // Construct the new component | ||||
// NB: The unit motion manager relies on components not moving in memory once constructed. | // NB: The unit motion manager relies on components not moving in memory once constructed. | ||||
IComponent* component = ct.alloc(m_ScriptInterface, obj); | IComponent* component = [&] | ||||
{ | |||||
if (cid >= CID_TemplateManager && cid < CID_UnknownScript) | |||||
{ | |||||
if (!m_SystemComponents) | |||||
m_SystemComponents.emplace(); | |||||
return TupleFind(*m_SystemComponents, [cid](auto& cmp) | |||||
{ | |||||
return std::remove_reference_t<decltype(cmp)>::typeId == cid; | |||||
}); | |||||
} | |||||
return ct.alloc(m_ScriptInterface, obj); | |||||
}(); | |||||
ENSURE(component); | ENSURE(component); | ||||
component->SetEntityHandle(ent); | component->SetEntityHandle(ent); | ||||
component->SetSimContext(m_SimContext); | component->SetSimContext(m_SimContext); | ||||
// Store a reference to the new component | // Store a reference to the new component | ||||
emap1.insert(std::make_pair(ent.GetId(), component)); | emap1.insert(std::make_pair(ent.GetId(), component)); | ||||
emap2.insert(std::make_pair(ent.GetId(), component)); | emap2.insert(std::make_pair(ent.GetId(), component)); | ||||
▲ Show 20 Lines • Show All 400 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator