Cogs.Core
DeferredNameResolution.cpp
1#include "DeferredNameResolution.h"
2
3#include "EntityStore.h"
4#include "Context.h"
5#include "Services.h"
6#include "Types.h"
7
8#include "Foundation/Logging/Logger.h"
9#include "Foundation/Reflection/TypeDatabase.h"
10
11using namespace Cogs::Core;
12
13namespace
14{
15 Cogs::Logging::Log logger = Cogs::Logging::getLogger("DeferredNameResolution");
16}
17
18DeferredNameResolution::DeferredNameResolution(Context* context)
19 : context(context)
20{
21 context->services->addFrameCallback([&] { update(); });
22}
23
24void DeferredNameResolution::update()
25{
26 if (!rescan) return;
27 rescan = false;
28
29 for (auto it = scheduled.begin(); it != scheduled.end();) {
30 auto comp = it->component.resolve();
31 if (!comp) {
32 LOG_DEBUG(logger, "Component of entity reference '%s' is dead.", it->name.c_str());
33 it = scheduled.erase(it);
34 } else if (comp->getGeneration() != it->component.generation) {
35 LOG_DEBUG(logger, "Component handle from entity reference '%s' no longer valid.", it->name.c_str());
36 it = scheduled.erase(it);
37 } else {
38 //auto entityPtr = context->store->findEntity(it->name, comp->getContainer());
39 auto entityPtr = context->store->findEntity(it->name);
40 if (entityPtr) {
41 LOG_DEBUG(logger, "Found entity '%s', updating reference.", it->name.c_str());
42
43 if (it->index < 0) {
44 if (it->field->getTypeId() == Reflection::TypeDatabase::getType<EntityPtr>().getTypeId()) {
45 *(it->field->getPtr<EntityPtr>(comp)) = std::move(entityPtr);
46 } else if (it->field->getTypeId() == Reflection::TypeDatabase::getType<WeakEntityPtr>().getTypeId()) {
47 *(it->field->getPtr<WeakEntityPtr>(comp)) = std::move(entityPtr);
48 } else {
49 LOG_ERROR(logger, "Entity reference to '%s' has unhandled type %d.", it->name.c_str(), (int)it->field->getTypeId());
50 }
51 comp->setChanged();
52 } else {
53 if (it->field->getTypeId() == Reflection::TypeDatabase::getType<std::vector<EntityPtr>>().getTypeId()) {
54 auto * ptr = it->field->getPtr<std::vector<EntityPtr>>(comp);
55
56 if (static_cast<int64_t>(ptr->size()) <= it->index) ptr->resize(it->index + 1);
57
58 (*ptr)[it->index] = std::move(entityPtr);
59 } else if (it->field->getTypeId() == Reflection::TypeDatabase::getType<std::vector<WeakEntityPtr>>().getTypeId()) {
60 auto * ptr = it->field->getPtr<std::vector<WeakEntityPtr>>(comp);
61
62 if (static_cast<int64_t>(ptr->size()) <= it->index) ptr->resize(it->index + 1);
63
64 (*ptr)[it->index] = std::move(entityPtr);
65 } else {
66 LOG_ERROR(logger, "Entity reference to '%s' has unhandled type %d.", it->name.c_str(), (int)it->field->getTypeId());
67 }
68 comp->setChanged();
69 }
70 it = scheduled.erase(it);
71 } else {
72 it++;
73 }
74 }
75 }
76}
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
std::unique_ptr< class Services > services
Services.
Definition: Context.h:174
class EntityStore * store
Entity store.
Definition: Context.h:231
EntityPtr findEntity(const StringView &name, const ComponentModel::Entity *root=nullptr, EntityFind findOptions=EntityFind::Default) const
Finds an entity with the given name.
Log implementation class.
Definition: LogManager.h:139
static const Type & getType()
Get the Type of the given template argument.
Definition: TypeDatabase.h:168
constexpr TypeId getTypeId() const
Get the unique Reflection::TypeId of this instance.
Definition: Type.h:325
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
std::shared_ptr< ComponentModel::Entity > EntityPtr
Smart pointer for Entity access.
Definition: EntityPtr.h:12
std::weak_ptr< ComponentModel::Entity > WeakEntityPtr
Weak Smart pointer for Entity access.
Definition: EntityPtr.h:18
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:180