bool EntityManager::RemoveEntitySystem(EntitySystem& s) { ComponentType componentType = s.GetComponentType(); if(!HasEntitySystem(componentType)) { return false; } ComponentType baseType = s.GetBaseType(); s.OnRemoveFromEntityManager(*this); EntitySystemRemovedMessage msg; msg.SetComponentType(componentType); msg.SetComponentTypeString(GetStringFromSID(componentType)); EmitMessage(msg); mEntitySystemStore.erase(mEntitySystemStore.find(componentType)); if(baseType != StringId()) { std::pair<TypeHierarchyMap::iterator, TypeHierarchyMap::iterator> keyRange; keyRange = mTypeHierarchy.equal_range(baseType); TypeHierarchyMap::iterator it = keyRange.first; while(it != keyRange.second) { if(it->second == componentType) { mTypeHierarchy.erase(it); break; } ++it; } } return true; }
void MapSystem::OnSetSystemProperties(const Message& m) { const SetSystemPropertiesMessage& msg = static_cast<const SetSystemPropertiesMessage&>(m); EntitySystem* sys = GetEntityManager().GetEntitySystem(SIDHash(msg.GetComponentType())); if(sys == NULL) { LOG_WARNING("Cannot process SetSystemProperties message. Entity system not found: " << msg.GetComponentType()); return; } const PropertyGroup& props = msg.GetSystemProperties(); for(PropertyGroup::const_iterator i = props.begin(); i != props.end(); ++i) { Property* target = sys->Get(i->first); if(!target) { LOG_ERROR("Cannot process SetSystemProperties message. Entity system " << msg.GetComponentType() << " has no property named " << GetStringFromSID(i->first)); continue; } target->SetFrom(*i->second); #if CALL_ONPROPERTYCHANGED_METHOD sys->OnPropertyChanged(i->first, *target); #endif } sys->Finished(); }
void MessagePump::RegisterForMessages(MessageType msgtype, MessageFunctor ftr, unsigned int options, const std::string& funcname) { MsgRegistryEntry e; e.mOptions = options; e.mFunctor = ftr; e.mFuncName = funcname.empty() ? msgtype : dtEntity::SID(funcname); unsigned int priority = options & 3; std::pair<MessageFunctorRegistry::iterator, MessageFunctorRegistry::iterator> keyRange; keyRange = mMessageFunctors.equal_range(msgtype); MessageFunctorRegistry::iterator it = keyRange.first; while(it != keyRange.second) { unsigned int otherpriority = it->second.mOptions & 3; if(it->second.mFunctor == ftr) { LOG_ERROR("Trying to register a functor twice for same message: " << GetStringFromSID(msgtype)); } if(otherpriority <= priority) { break; } ++it; } mMessageFunctors.insert(it, std::make_pair(msgtype, e)); assert(IsRegistered(msgtype, ftr)); }
bool EntityManager::AddEntitySystem(EntitySystem& s) { if(HasEntitySystem(s.GetComponentType())) { LOG_ERROR("Entity system already added! Type: " << GetStringFromSID(s.GetComponentType())); return false; } mEntitySystemStore[s.GetComponentType()] = &s; if(s.GetBaseType() != StringId()) { mTypeHierarchy.insert(std::make_pair(s.GetBaseType(), s.GetComponentType())); } s.OnAddedToEntityManager(*this); EntitySystemAddedMessage msg; msg.SetComponentType(s.GetComponentType()); msg.SetComponentTypeString(GetStringFromSID(s.GetComponentType())); EmitMessage(msg); return true; }
void MapSystem::OnSetComponentProperties(const Message& m) { const SetComponentPropertiesMessage& msg = static_cast<const SetComponentPropertiesMessage&>(m); ComponentType ctype = dtEntity::SIDHash(msg.GetComponentType()); std::string uniqueid = msg.GetEntityUniqueId(); MapSystem* ms; GetEntityManager().GetEntitySystem(MapComponent::TYPE, ms); EntityId id = ms->GetEntityIdByUniqueId(uniqueid); if(id == 0) { LOG_ERROR("Entity not found for SetComponentPropertiesMessage!"); return; } Component* component; bool found = GetEntityManager().GetComponent(id, ctype, component); if(!found) { LOG_WARNING("Cannot process SetComponentProperties message. Component not found: " + msg.GetComponentType()); return; } const PropertyGroup& props = msg.GetComponentProperties(); for(PropertyGroup::const_iterator i = props.begin(); i != props.end(); ++i) { Property* target = component->Get(i->first); if(!target) { LOG_ERROR( "Cannot process SetComponentProperties message. Component " << msg.GetComponentType() << " has no property named " << GetStringFromSID(i->first) ); continue; } target->SetFrom(*i->second); #if CALL_ONPROPERTYCHANGED_METHOD component->OnPropertyChanged(i->first, *target); #endif } component->Finished(); }
void ComponentPluginManager::UnloadAllPlugins(EntityManager& em) { for(PluginFactoryMap::iterator i = mFactories.begin(); i != mFactories.end(); ++i) { ComponentType ctype = i->first; if(em.HasEntitySystem(ctype)) { dtEntity::EntitySystem* es = em.GetEntitySystem(ctype); if(es == NULL || !em.RemoveEntitySystem(*es)) { LOG_ERROR("Could not cleanly remove entity system " << GetStringFromSID(ctype)); } else { delete es; } } } }
bool EntityManager::CreateComponent(EntityId eid, ComponentType id, Component*& component) { EntitySystem* es = NULL; if(!GetEntitySystem(id, es)) { EntitySystemRequestCallbacks::iterator i; for(i = mEntitySystemRequestCallbacks.begin(); i != mEntitySystemRequestCallbacks.end(); ++i) { if((*i)->CreateEntitySystem(this, id)) { bool success = GetEntitySystem(id, es); assert(success); break; } } if(es == NULL) { LOG_ERROR("Could not add component: no entity system of type " + GetStringFromSID(id)); return false; } } return es->CreateComponent(eid, component); }
bool EntityManager::CloneEntity(EntityId target, EntityId origin) { bool success = true; std::vector<Component*> comps; for(EntitySystemStore::iterator i = mEntitySystemStore.begin(); i != mEntitySystemStore.end(); ++i) { EntitySystem* sys = i->second; if(sys->AllowComponentCreationBySpawner()) { Component* c; if(sys->GetComponent(origin, c)) { comps.push_back(c); } } } // first create all components in target for(std::vector<Component*>::iterator i = comps.begin(); i != comps.end(); ++i) { Component* origincomp = *i; Component* newcomp; if(!CreateComponent(target, origincomp->GetType(), newcomp)) { LOG_ERROR("Could not clone component " << GetStringFromSID(origincomp->GetType())); success = false; } } // then configure them for(std::vector<Component*>::iterator i = comps.begin(); i != comps.end(); ++i) { Component* origincomp = *i; Component* clonecomp; if(!GetComponent(target, origincomp->GetType(), clonecomp)) { LOG_ERROR("Error in clone entity, could not find cloned component?!?"); success = false; continue; } const PropertyGroup& props = origincomp->Get(); for(PropertyGroup::const_iterator i = props.begin(); i != props.end(); ++i) { Property* prp = clonecomp->Get(i->first); if(prp) { prp->SetFrom(*i->second); #if CALL_ONPROPERTYCHANGED_METHOD clonecomp->OnPropertyChanged(i->first, *prp); #endif } else { LOG_ERROR("Error cloning: Property does not exist in target"); success = false; } } } // then configure them for(std::vector<Component*>::iterator i = comps.begin(); i != comps.end(); ++i) { Component* origincomp = *i; Component* clonecomp; if(!GetComponent(target, origincomp->GetType(), clonecomp)) { LOG_ERROR("Error in clone entity, could not find cloned component?!?"); success = false; continue; } clonecomp->Finished(); } return success; }
bool EntityManager::GetDerived(EntityId eid, ComponentType ctype, Component*& comp) const { std::pair<TypeHierarchyMap::const_iterator, TypeHierarchyMap::const_iterator> keyRange; keyRange = mTypeHierarchy.equal_range(ctype); TypeHierarchyMap::const_iterator it = keyRange.first; while(it != keyRange.second) { dtEntity::EntitySystem* es; bool success = this->GetEntitySystem(it->second, es); if(!success) { LOG_ERROR("Error in type hierarchy structure! Cannot find entity system " << GetStringFromSID(it->second)); continue; } if(es->GetComponent(eid, comp)) { return true; } if(GetDerived(eid, es->GetComponentType(), comp)) { return true; } ++it; } return false; }
void PropertyContainer::InitFrom(const PropertyContainer& other) { for(PropertyGroup::const_iterator i = other.mValue.begin(); i != other.mValue.end(); ++i) { Property* own = Get(i->first); if(own == NULL) { LOG_ERROR("Error in InitFrom: PropertyContainer has no property named " << GetStringFromSID(i->first)); } else { own->SetFrom(*i->second); } } }
bool ComponentPluginManager::StartEntitySystem(EntityManager& em, ComponentType ctype) { if(em.HasEntitySystem(ctype)) { return true; } LOG_DEBUG("Starting entity system " << GetStringFromSID(ctype)); ComponentPluginFactory* factory = GetPluginFactory(ctype); if(factory == NULL) { LOG_DEBUG("Cannot start entity system " << dtEntity::GetStringFromSID(ctype) << ": no factory found"); return false; } // start all plugins this plugin depends on std::list<ComponentType> deps; factory->GetDependencies(deps); while(!deps.empty()) { ComponentType dependency = deps.front(); deps.pop_front(); if(em.HasEntitySystem(dependency)) { continue; } // check if dependency can be fulfilled if(!FactoryExists(dependency)) { LOG_ERROR("Cannot start plugin " << dtEntity::GetStringFromSID(ctype) << ": It depends on plugin " << GetStringFromSID(dependency) << " which was not found."); return false; } // only start dependency if it is not running now if(!em.HasEntitySystem(dependency)) { StartEntitySystem(em, dependency); } } // use factory to create the plugin EntitySystem* es; bool success = factory->Create(&em, es); if(success) { // call, although no properties were set yet es->Finished(); LOG_DEBUG("Created entity system of type " << GetStringFromSID(ctype)); em.AddEntitySystem(*es); return true; } else { LOG_ERROR("Error starting entity system " << dtEntity::GetStringFromSID(ctype)); return false; } }