← Back to file list Raw

src/CComponentsManager.cpp

#include "CComponentsManager.h"
#include "CEngine.h"
#include "CScriptingManager.h"
CComponentsManager::~CComponentsManager()
{
//Trace([](CComponent* comp) { comp->DeInit(); });
}
void CComponentsManager::Add(std::unique_ptr<CComponent>&& comp)
{
std::string type = comp->GetType();
AddCache(type, comp->GetTypeInfo(), comp.get());
Items[type] = std::move(comp);
OnComponentAdd(type);
auto man = CEngine::GetInstance()->Components.GetComponentTyped<CScriptingManager>();
if(man)
{
man->CallHook(type + "_add");
}
}
bool CComponentsManager::IsComponentPresent(const std::string& type) const
{
return Items.find(type) != Items.end();
}
void CComponentsManager::AddCache(const std::string& name, std::type_index _type, CComponent* _component)
{
hashCache.emplace(_type.hash_code(), _component);
nameCache.emplace(name, _component);
}
void CComponentsManager::RemoveCache(CComponent* component)
{
auto it_h = std::find_if(hashCache.begin(), hashCache.end(), [component](auto& kv) -> bool { return kv.second == component; });
auto it_n = std::find_if(nameCache.begin(), nameCache.end(), [component](auto& kv) -> bool { return kv.second == component; });
if(it_h != hashCache.end()) { hashCache.erase(it_h); }
if(it_n != nameCache.end()) { nameCache.erase(it_n); }
}
void CComponentsManager::DeleteComponent(const std::string& type)
{
auto it = Items.find(type);
if(it != Items.end())
{
it->second->DeInit();
RemoveCache(it->second.get());
Items.erase(it);
}
}
std::unique_ptr<CComponent>& CComponentsManager::GetComponent(const std::string& type)
{
auto it = Items.find(type);
if (it == Items.end()) { throw std::runtime_error("No such component"); }
return it->second;
}
CComponent* CComponentsManager::GetComponentRaw(const std::string& type)
{
auto it = Items.find(type);
if (it == Items.end()) { return nullptr; }
return it->second.get();
}
void CComponentsManager::CreateComponent(const std::string& type, bool instantInit)
{
std::unique_ptr<CComponent> comp = CEngine::GetInstance()->ComponentsFactory.create<std::unique_ptr<CComponent>>(type);
if(!comp) { return; }
Add(std::move(comp));
if(instantInit)
{
GetComponent(type)->Init();
GetComponent(type)->PostInit();
}
}
std::vector<CComponent*> CComponentsManager::getComponentsOrder()
{
std::vector<CComponent*> components;
for (auto& [id, comp] : Items)
{
components.push_back(comp.get());
}
auto comparator = [](CComponent* a, CComponent* b)
{
const auto getPriority = [](CComponent* comp) -> CComponentPriority*
{
return comp ? comp->GetPriority() : nullptr;
};
CComponentPriority* prioA = getPriority(a);
CComponentPriority* prioB = getPriority(b);
if (prioB && prioB->ShouldExecuteAfter(a->GetType()))
{
return true;
}
if (prioA && prioA->ShouldExecuteAfter(b->GetType()))
{
return false;
}
int keyA = prioA ? prioA->GetSortingKey() : 0;
int keyB = prioB ? prioB->GetSortingKey() : 0;
if (keyA != keyB)
{
return keyA > keyB;
}
return false;
};
std::stable_sort(components.begin(), components.end(), comparator);
return components;
}
void CComponentsManager::Trace(const std::function<void(CComponent* nod)>& func)
{
auto components = getComponentsOrder();
for (auto comp : components)
{
func(comp);
}
}
void CComponentsManager::ReverseTrace(const std::function<void(CComponent* nod)>& func)
{
auto components = getComponentsOrder();
for (auto it = components.rbegin(); it != components.rend(); ++it)
{
func(*it);
}
}