Ticket #4046: EntityMapForComponents.patch

File EntityMapForComponents.patch, 14.0 KB (added by wraitii, 8 years ago)

Fix bit operation

  • ComponentManager.cpp

     
    305305    {
    306306        // For every script component with this cid, we need to switch its
    307307        // prototype from the old constructor's prototype property to the new one's
    308         const std::map<entity_id_t, IComponent*>& comps = componentManager->m_ComponentsByTypeId[cid];
    309         std::map<entity_id_t, IComponent*>::const_iterator eit = comps.begin();
     308        const EntityMap<IComponent*>& comps = componentManager->m_ComponentsByTypeId[cid];
     309        EntityMap<IComponent*>::const_iterator eit = comps.begin();
    310310        for (; eit != comps.end(); ++eit)
    311311        {
    312312            JS::RootedValue instance(cx, eit->second->GetJSInstance());
     
    315315                componentManager->m_ScriptInterface.SetPrototype(instance, protoVal);
    316316            }
    317317        }
     318        const EntityMap<IComponent*>& localComps = componentManager->m_LocalComponentsByTypeId[cid];
     319        eit = localComps.begin();
     320        for (; eit != localComps.end(); ++eit)
     321        {
     322            JS::RootedValue instance(cx, eit->second->GetJSInstance());
     323            if (!instance.isNull())
     324            {
     325                componentManager->m_ScriptInterface.SetPrototype(instance, protoVal);
     326            }
     327        }
    318328    }
    319329}
    320330
     
    509519    m_DynamicMessageSubscriptionsNonsyncByComponent.clear();
    510520
    511521    // Delete all IComponents
    512     std::map<ComponentTypeId, std::map<entity_id_t, IComponent*> >::iterator iit = m_ComponentsByTypeId.begin();
     522    std::map<ComponentTypeId, EntityMap<IComponent*> >::iterator iit = m_ComponentsByTypeId.begin();
    513523    for (; iit != m_ComponentsByTypeId.end(); ++iit)
    514524    {
    515         std::map<entity_id_t, IComponent*>::iterator eit = iit->second.begin();
     525        EntityMap<IComponent*>::iterator eit = iit->second.begin();
    516526        for (; eit != iit->second.end(); ++eit)
    517527        {
    518528            eit->second->Deinit();
     
    519529            m_ComponentTypesById[iit->first].dealloc(eit->second);
    520530        }
    521531    }
     532    std::map<ComponentTypeId, EntityMap<IComponent*> >::iterator localiit = m_LocalComponentsByTypeId.begin();
     533    for (; localiit != m_LocalComponentsByTypeId.end(); ++localiit)
     534    {
    522535
     536        EntityMap<IComponent*>::iterator eit = localiit->second.begin();
     537        for (; eit != localiit->second.end(); ++eit)
     538        {
     539            eit->second->Deinit();
     540            m_ComponentTypesById[localiit->first].dealloc(eit->second);
     541        }
     542    }
    523543    std::vector<boost::unordered_map<entity_id_t, IComponent*> >::iterator ifcit = m_ComponentsByInterface.begin();
    524544    for (; ifcit != m_ComponentsByInterface.end(); ++ifcit)
    525545        ifcit->clear();
    526546
    527547    m_ComponentsByTypeId.clear();
     548    m_LocalComponentsByTypeId.clear();
    528549
    529550    // Delete all SEntityComponentCaches
    530551    std::map<entity_id_t, SEntityComponentCache*>::iterator ccit = m_ComponentCaches.begin();
     
    757778        return NULL;
    758779    }
    759780
    760     std::map<entity_id_t, IComponent*>& emap2 = m_ComponentsByTypeId[cid];
    761 
    762781    // If this is a scripted component, construct the appropriate JS object first
    763782    JS::RootedValue obj(cx);
    764783    if (ct.type == CT_Script)
     
    780799
    781800    // Store a reference to the new component
    782801    emap1.insert(std::make_pair(ent.GetId(), component));
    783     emap2.insert(std::make_pair(ent.GetId(), component));
     802
     803    if (ENTITY_IS_LOCAL(ent.GetId()))
     804        m_LocalComponentsByTypeId[cid].insert(ent.GetId() & ~ENTITY_TAGMASK, component);
     805    else
     806        m_ComponentsByTypeId[cid].insert(ent.GetId(), component);
    784807    // TODO: We need to more careful about this - if an entity is constructed by a component
    785808    // while we're iterating over all components, this will invalidate the iterators and everything
    786809    // will break.
     
    917940            CMessageDestroy msg(ent);
    918941            PostMessage(ent, msg);
    919942
    920             // Destroy the components, and remove from m_ComponentsByTypeId:
    921             std::map<ComponentTypeId, std::map<entity_id_t, IComponent*> >::iterator iit = m_ComponentsByTypeId.begin();
     943            // Destroy the components, and remove from m_ComponentsByTypeId and m_LocalComponentsByTypeId:
     944            std::map<ComponentTypeId, EntityMap<IComponent*> >::iterator iit = m_ComponentsByTypeId.begin();
    922945            for (; iit != m_ComponentsByTypeId.end(); ++iit)
    923946            {
    924                 std::map<entity_id_t, IComponent*>::iterator eit = iit->second.find(ent);
     947                EntityMap<IComponent*>::iterator eit = iit->second.find(ent);
    925948                if (eit != iit->second.end())
    926949                {
    927950                    eit->second->Deinit();
     
    931954                    handle.GetComponentCache()->interfaces[m_ComponentTypesById[iit->first].iid] = NULL;
    932955                }
    933956            }
     957            iit = m_LocalComponentsByTypeId.begin();
     958            for (; iit != m_LocalComponentsByTypeId.end(); ++iit)
     959            {
     960                EntityMap<IComponent*>::iterator eit = iit->second.find(ent);
     961                if (eit != iit->second.end())
     962                {
     963                    eit->second->Deinit();
     964                    RemoveComponentDynamicSubscriptions(eit->second);
     965                    m_ComponentTypesById[iit->first].dealloc(eit->second);
     966                    iit->second.erase(ent);
     967                    handle.GetComponentCache()->interfaces[m_ComponentTypesById[iit->first].iid] = NULL;
     968                }
     969            }
    934970
    935971            free(handle.GetComponentCache());
    936972            m_ComponentCaches.erase(ent);
     
    10061042        std::vector<ComponentTypeId>::const_iterator ctit = it->second.begin();
    10071043        for (; ctit != it->second.end(); ++ctit)
    10081044        {
     1045            std::map<ComponentTypeId, EntityMap<IComponent*> >::const_iterator emap;
    10091046            // Find the component instances of this type (if any)
    1010             std::map<ComponentTypeId, std::map<entity_id_t, IComponent*> >::const_iterator emap = m_ComponentsByTypeId.find(*ctit);
    1011             if (emap == m_ComponentsByTypeId.end())
    1012                 continue;
    1013 
     1047            if (ENTITY_IS_LOCAL(ent))
     1048            {
     1049                emap = m_LocalComponentsByTypeId.find(*ctit);
     1050                if (emap == m_LocalComponentsByTypeId.end())
     1051                    continue;
     1052            }
     1053            else
     1054            {
     1055                emap = m_ComponentsByTypeId.find(*ctit);
     1056                if (emap == m_ComponentsByTypeId.end())
     1057                    continue;
     1058            }
    10141059            // Send the message to all of them
    1015             std::map<entity_id_t, IComponent*>::const_iterator eit = emap->second.find(ent);
     1060            EntityMap<IComponent*>::const_iterator eit = emap->second.find(ent);
    10161061            if (eit != emap->second.end())
    10171062                eit->second->HandleMessage(msg, false);
    10181063        }
     
    10321077        for (; ctit != it->second.end(); ++ctit)
    10331078        {
    10341079            // Find the component instances of this type (if any)
    1035             std::map<ComponentTypeId, std::map<entity_id_t, IComponent*> >::const_iterator emap = m_ComponentsByTypeId.find(*ctit);
    1036             if (emap == m_ComponentsByTypeId.end())
    1037                 continue;
    1038 
    1039             // Send the message to all of them
    1040             std::map<entity_id_t, IComponent*>::const_iterator eit = emap->second.begin();
    1041             for (; eit != emap->second.end(); ++eit)
    1042                 eit->second->HandleMessage(msg, false);
     1080            std::map<ComponentTypeId, EntityMap<IComponent*> >::const_iterator emap = m_ComponentsByTypeId.find(*ctit);
     1081            if (emap != m_ComponentsByTypeId.end())
     1082            {
     1083                // Send the message to all of them
     1084                EntityMap<IComponent*>::const_iterator eit = emap->second.begin();
     1085                for (; eit != emap->second.end(); ++eit)
     1086                    eit->second->HandleMessage(msg, false);
     1087            }
     1088            emap = m_LocalComponentsByTypeId.find((*ctit) & !ENTITY_TAGMASK);
     1089            if (emap != m_LocalComponentsByTypeId.end())
     1090            {
     1091                // Send the message to all of them
     1092                EntityMap<IComponent*>::const_iterator eit = emap->second.begin();
     1093                for (; eit != emap->second.end(); ++eit)
     1094                    eit->second->HandleMessage(msg, false);
     1095            }
    10431096        }
    10441097    }
    10451098
     
    10691122            }
    10701123
    10711124            // Find the component instances of this type (if any)
    1072             std::map<ComponentTypeId, std::map<entity_id_t, IComponent*> >::const_iterator emap = m_ComponentsByTypeId.find(*ctit);
    1073             if (emap == m_ComponentsByTypeId.end())
    1074                 continue;
    1075 
    1076             // Send the message to all of them
    1077             std::map<entity_id_t, IComponent*>::const_iterator eit = emap->second.begin();
    1078             for (; eit != emap->second.end(); ++eit)
    1079                 eit->second->HandleMessage(msg, true);
     1125            std::map<ComponentTypeId, EntityMap<IComponent*> >::const_iterator emap = m_ComponentsByTypeId.find(*ctit);
     1126            if (emap != m_ComponentsByTypeId.end())
     1127            {
     1128                // Send the message to all of them
     1129                EntityMap<IComponent*>::const_iterator eit = emap->second.begin();
     1130                for (; eit != emap->second.end(); ++eit)
     1131                    eit->second->HandleMessage(msg, true);
     1132            }
     1133            emap = m_LocalComponentsByTypeId.find((*ctit) & !ENTITY_TAGMASK);
     1134            if (emap != m_LocalComponentsByTypeId.end())
     1135            {
     1136                // Send the message to all of them
     1137                EntityMap<IComponent*>::const_iterator eit = emap->second.begin();
     1138                for (; eit != emap->second.end(); ++eit)
     1139                    eit->second->HandleMessage(msg, true);
     1140            }
    10801141        }
    10811142    }
    10821143
  • ComponentManager.h

     
    2727#include <boost/random/linear_congruential.hpp>
    2828#include <boost/unordered_map.hpp>
    2929
     30#include "EntityMap.h"
    3031#include <map>
    3132
    3233class IComponent;
     
    355356    std::map<ComponentTypeId, ComponentType> m_ComponentTypesById;
    356357    std::vector<CComponentManager::ComponentTypeId> m_ScriptedSystemComponents;
    357358    std::vector<boost::unordered_map<entity_id_t, IComponent*> > m_ComponentsByInterface; // indexed by InterfaceId
    358     std::map<ComponentTypeId, std::map<entity_id_t, IComponent*> > m_ComponentsByTypeId;
     359    std::map<ComponentTypeId, EntityMap<IComponent*> > m_ComponentsByTypeId;
     360    std::map<ComponentTypeId, EntityMap<IComponent*> > m_LocalComponentsByTypeId;
    359361    std::map<MessageTypeId, std::vector<ComponentTypeId> > m_LocalMessageSubscriptions;
    360362    std::map<MessageTypeId, std::vector<ComponentTypeId> > m_GlobalMessageSubscriptions;
    361363    std::map<std::string, ComponentTypeId> m_ComponentTypeIdsByName;
  • ComponentManagerSerialization.cpp

     
    5858    std::map<entity_id_t, std::map<ComponentTypeId, IComponent*> > components;
    5959    //std::map<ComponentTypeId, std::string> names;
    6060
    61     std::map<ComponentTypeId, std::map<entity_id_t, IComponent*> >::const_iterator ctit = m_ComponentsByTypeId.begin();
     61    std::map<ComponentTypeId, EntityMap<IComponent*> >::const_iterator ctit = m_ComponentsByTypeId.begin();
    6262    for (; ctit != m_ComponentsByTypeId.end(); ++ctit)
    6363    {
    64         std::map<entity_id_t, IComponent*>::const_iterator eit = ctit->second.begin();
     64        EntityMap<IComponent*>::const_iterator eit = ctit->second.begin();
    6565        for (; eit != ctit->second.end(); ++eit)
    6666        {
    6767            components[eit->first][ctit->first] = eit->second;
     
    109109    serializer.StringASCII("rng", SerializeRNG(m_RNG), 0, 32);
    110110    serializer.NumberU32_Unbounded("next entity id", m_NextEntityId);
    111111
    112     std::map<ComponentTypeId, std::map<entity_id_t, IComponent*> >::const_iterator cit = m_ComponentsByTypeId.begin();
     112    std::map<ComponentTypeId, EntityMap<IComponent*> >::const_iterator cit = m_ComponentsByTypeId.begin();
    113113    for (; cit != m_ComponentsByTypeId.end(); ++cit)
    114114    {
    115115        // In quick mode, only check unit positions
     
    118118
    119119        // Only emit component types if they have a component that will be serialized
    120120        bool needsSerialization = false;
    121         for (std::map<entity_id_t, IComponent*>::const_iterator eit = cit->second.begin(); eit != cit->second.end(); ++eit)
     121        for (EntityMap<IComponent*>::const_iterator eit = cit->second.begin(); eit != cit->second.end(); ++eit)
    122122        {
    123123            // Don't serialize local entities
    124124            if (ENTITY_IS_LOCAL(eit->first))
     
    133133
    134134        serializer.NumberI32_Unbounded("component type id", cit->first);
    135135
    136         for (std::map<entity_id_t, IComponent*>::const_iterator eit = cit->second.begin(); eit != cit->second.end(); ++eit)
     136        for (EntityMap<IComponent*>::const_iterator eit = cit->second.begin(); eit != cit->second.end(); ++eit)
    137137        {
    138138            // Don't serialize local entities
    139139            if (ENTITY_IS_LOCAL(eit->first))
     
    188188    serializer.StringASCII("rng", SerializeRNG(m_RNG), 0, 32);
    189189    serializer.NumberU32_Unbounded("next entity id", m_NextEntityId);
    190190
    191     std::map<ComponentTypeId, std::map<entity_id_t, IComponent*> >::const_iterator cit;
     191    std::map<ComponentTypeId, EntityMap<IComponent*> >::const_iterator cit;
    192192   
    193193    uint32_t numSystemComponentTypes = 0;
    194194    uint32_t numComponentTypes = 0;
     
    199199    {
    200200        // Only emit component types if they have a component that will be serialized
    201201        bool needsSerialization = false;
    202         for (std::map<entity_id_t, IComponent*>::const_iterator eit = cit->second.begin(); eit != cit->second.end(); ++eit)
     202        for (EntityMap<IComponent*>::const_iterator eit = cit->second.begin(); eit != cit->second.end(); ++eit)
    203203        {
    204204            // Don't serialize local entities, and handle SYSTEM_ENTITY separately
    205205            if (ENTITY_IS_LOCAL(eit->first) || eit->first == SYSTEM_ENTITY)
     
    238238
    239239        serializer.StringASCII("name", ctit->second.name, 0, 255);
    240240
    241         std::map<entity_id_t, IComponent*>::const_iterator eit = cit->second.find(SYSTEM_ENTITY);
     241        EntityMap<IComponent*>::const_iterator eit = cit->second.find(SYSTEM_ENTITY);
    242242        if (eit == cit->second.end())
    243243        {
    244244            debug_warn(L"Invalid eit"); // this should never happen
     
    265265
    266266        // Count the components before serializing any of them
    267267        uint32_t numComponents = 0;
    268         for (std::map<entity_id_t, IComponent*>::const_iterator eit = cit->second.begin(); eit != cit->second.end(); ++eit)
     268        for (EntityMap<IComponent*>::const_iterator eit = cit->second.begin(); eit != cit->second.end(); ++eit)
    269269        {
    270270            // Don't serialize local entities or SYSTEM_ENTITY
    271271            if (ENTITY_IS_LOCAL(eit->first) || eit->first == SYSTEM_ENTITY)
     
    278278        serializer.NumberU32_Unbounded("num components", numComponents);
    279279
    280280        // Serialize the components now
    281         for (std::map<entity_id_t, IComponent*>::const_iterator eit = cit->second.begin(); eit != cit->second.end(); ++eit)
     281        for (EntityMap<IComponent*>::const_iterator eit = cit->second.begin(); eit != cit->second.end(); ++eit)
    282282        {
    283283            // Don't serialize local entities or SYSTEM_ENTITY
    284284            if (ENTITY_IS_LOCAL(eit->first) || eit->first == SYSTEM_ENTITY)
  • EntityMap.h

     
    1818#define INCLUDED_ENTITYMAP
    1919
    2020#include "Entity.h"
     21#include "simulation2/serialization/ISerializer.h"
     22#include "simulation2/serialization/IDeserializer.h"
    2123
    2224/**
    2325 * A fast replacement for map<entity_id_t, T>.