Ticket #1707: entitymap.patch
File entitymap.patch, 10.7 KB (added by , 11 years ago) |
---|
-
components/CCmpRangeManager.cpp
26 26 #include "simulation2/components/ICmpVision.h" 27 27 #include "simulation2/helpers/Render.h" 28 28 #include "simulation2/helpers/Spatial.h" 29 #include "simulation2/helpers/EntityMap.h" 29 30 30 31 #include "graphics/Overlay.h" 31 32 #include "graphics/Terrain.h" … … 149 150 */ 150 151 struct EntityDistanceOrdering 151 152 { 152 EntityDistanceOrdering(const std::map<entity_id_t,EntityData>& entities, const CFixedVector2D& source) :153 EntityDistanceOrdering(const EntityMap<EntityData>& entities, const CFixedVector2D& source) : 153 154 m_EntityData(entities), m_Source(source) 154 155 { 155 156 } … … 163 164 return (vecA.CompareLength(vecB) < 0); 164 165 } 165 166 166 const std::map<entity_id_t,EntityData>& m_EntityData;167 const EntityMap<EntityData>& m_EntityData; 167 168 CFixedVector2D m_Source; 168 169 169 170 private: … … 210 211 // Range query state: 211 212 tag_t m_QueryNext; // next allocated id 212 213 std::map<tag_t, Query> m_Queries; 213 std::map<entity_id_t,EntityData> m_EntityData;214 EntityMap<EntityData> m_EntityData; 214 215 SpatialSubdivision<entity_id_t> m_Subdivision; // spatial index of m_EntityData 215 216 216 217 // LOS state: … … 284 285 285 286 serialize.NumberU32_Unbounded("query next", m_QueryNext); 286 287 SerializeMap<SerializeU32_Unbounded, SerializeQuery>()(serialize, "queries", m_Queries); 287 Serialize Map<SerializeU32_Unbounded,SerializeEntityData>()(serialize, "entity data", m_EntityData);288 SerializeEntityMap<SerializeEntityData>()(serialize, "entity data", m_EntityData); 288 289 289 290 SerializeMap<SerializeI32_Unbounded, SerializeBool>()(serialize, "los reveal all", m_LosRevealAll); 290 291 serialize.Bool("los circular", m_LosCircular); … … 355 356 const CMessagePositionChanged& msgData = static_cast<const CMessagePositionChanged&> (msg); 356 357 entity_id_t ent = msgData.entity; 357 358 358 std::map<entity_id_t,EntityData>::iterator it = m_EntityData.find(ent);359 EntityMap<EntityData>::iterator it = m_EntityData.find(ent); 359 360 360 361 // Ignore if we're not already tracking this entity 361 362 if (it == m_EntityData.end()) … … 402 403 const CMessageOwnershipChanged& msgData = static_cast<const CMessageOwnershipChanged&> (msg); 403 404 entity_id_t ent = msgData.entity; 404 405 405 std::map<entity_id_t,EntityData>::iterator it = m_EntityData.find(ent);406 EntityMap<EntityData>::iterator it = m_EntityData.find(ent); 406 407 407 408 // Ignore if we're not already tracking this entity 408 409 if (it == m_EntityData.end()) … … 425 426 const CMessageDestroy& msgData = static_cast<const CMessageDestroy&> (msg); 426 427 entity_id_t ent = msgData.entity; 427 428 428 std::map<entity_id_t,EntityData>::iterator it = m_EntityData.find(ent);429 EntityMap<EntityData>::iterator it = m_EntityData.find(ent); 429 430 430 431 // Ignore if we're not already tracking this entity 431 432 if (it == m_EntityData.end()) … … 447 448 const CMessageVisionRangeChanged& msgData = static_cast<const CMessageVisionRangeChanged&> (msg); 448 449 entity_id_t ent = msgData.entity; 449 450 450 std::map<entity_id_t,EntityData>::iterator it = m_EntityData.find(ent);451 EntityMap<EntityData>::iterator it = m_EntityData.find(ent); 451 452 452 453 // Ignore if we're not already tracking this entity 453 454 if (it == m_EntityData.end()) … … 555 556 m_LosStateRevealed.clear(); 556 557 m_LosStateRevealed.resize(m_TerrainVerticesPerSide*m_TerrainVerticesPerSide); 557 558 558 for ( std::map<entity_id_t,EntityData>::const_iterator it = m_EntityData.begin(); it != m_EntityData.end(); ++it)559 for (EntityMap<EntityData>::const_iterator it = m_EntityData.begin(); it != m_EntityData.end(); ++it) 559 560 { 560 561 if (it->second.inWorld) 561 562 LosAdd(it->second.owner, it->second.visionRange, CFixedVector2D(it->second.x, it->second.z)); … … 572 573 // (TODO: find the optimal number instead of blindly guessing) 573 574 m_Subdivision.Reset(x1, z1, entity_pos_t::FromInt(8*TERRAIN_TILE_SIZE)); 574 575 575 for ( std::map<entity_id_t,EntityData>::const_iterator it = m_EntityData.begin(); it != m_EntityData.end(); ++it)576 for (EntityMap<EntityData>::const_iterator it = m_EntityData.begin(); it != m_EntityData.end(); ++it) 576 577 { 577 578 if (it->second.inWorld) 578 579 m_Subdivision.Add(it->first, CFixedVector2D(it->second.x, it->second.z)); … … 693 694 694 695 u32 ownerMask = CalcOwnerMask(player); 695 696 696 for ( std::map<entity_id_t,EntityData>::const_iterator it = m_EntityData.begin(); it != m_EntityData.end(); ++it)697 for (EntityMap<EntityData>::const_iterator it = m_EntityData.begin(); it != m_EntityData.end(); ++it) 697 698 { 698 699 // Check owner and add to list if it matches 699 700 if (CalcOwnerMask(it->second.owner) & ownerMask) … … 804 805 // Special case: range -1.0 means check all entities ignoring distance 805 806 if (q.maxRange == entity_pos_t::FromInt(-1)) 806 807 { 807 for ( std::map<entity_id_t,EntityData>::const_iterator it = m_EntityData.begin(); it != m_EntityData.end(); ++it)808 for (EntityMap<EntityData>::const_iterator it = m_EntityData.begin(); it != m_EntityData.end(); ++it) 808 809 { 809 810 if (!TestEntityQuery(q, it->first, it->second)) 810 811 continue; … … 819 820 820 821 for (size_t i = 0; i < ents.size(); ++i) 821 822 { 822 std::map<entity_id_t,EntityData>::const_iterator it = m_EntityData.find(ents[i]);823 EntityMap<EntityData>::const_iterator it = m_EntityData.find(ents[i]); 823 824 ENSURE(it != m_EntityData.end()); 824 825 825 826 if (!TestEntityQuery(q, it->first, it->second)) … … 945 946 946 947 virtual void SetEntityFlag(entity_id_t ent, std::string identifier, bool value) 947 948 { 948 std::map<entity_id_t,EntityData>::iterator it = m_EntityData.find(ent);949 EntityMap<EntityData>::iterator it = m_EntityData.find(ent); 949 950 950 951 // We don't have this entity 951 952 if (it == m_EntityData.end()) -
helpers/EntityMap.h
1 #ifndef INCLUDED_ENTITYMAP 2 #define INCLUDED_ENTITYMAP 3 4 #ifndef NDEBUG 5 #define ENTITYMAP_INSERTION_CHECK 6 #endif 7 8 /** 9 * A fast replacement for map<entity_id_t, T>. 10 * We make the following assumptions: 11 * - entity id's (keys) are unique and are inserted in increasing order 12 * - an entity id that was removed is never added again 13 * - modifications (add / delete) are far less frequent then look-ups 14 * - preformance for iteration is important 15 */ 16 template<typename T> 17 class EntityMap 18 { 19 20 public: 21 EntityMap() : m_Data(), m_Lookup() 22 { 23 } 24 25 EntityMap(const EntityMap& m) : m_Data(m.m_Data), m_Lookup(m.m_Lookup) 26 { 27 } 28 29 // Map interface: 30 // Member types 31 typedef entity_id_t key_type; 32 typedef T mapped_type; 33 typedef std::pair<entity_id_t, T> value_type; 34 35 typedef typename std::vector<value_type>::difference_type difference_type; 36 typedef typename std::vector<value_type>::size_type size_type; 37 38 typedef typename std::vector<value_type>::iterator iterator; 39 typedef typename std::vector<value_type>::const_iterator const_iterator; 40 typedef typename std::vector<value_type>::reverse_iterator reverse_iterator; 41 typedef typename std::vector<value_type>::const_reverse_iterator const_reverse_iterator; 42 43 // Iterators 44 iterator begin() 45 { return m_Data.begin(); } 46 47 const_iterator begin() const 48 { return m_Data.begin(); } 49 50 iterator end() 51 { return m_Data.end(); } 52 53 const_iterator end() const 54 { return m_Data.end(); } 55 56 reverse_iterator rbegin() 57 { return m_Data.rbegin(); } 58 59 const_reverse_iterator rbegin() const 60 { return m_Data.rbegin(); } 61 62 reverse_iterator rend() 63 { return m_Data.rend(); } 64 65 const_reverse_iterator rend() const 66 { return m_Data.rend(); } 67 68 // Capacity 69 bool empty() const 70 { return m_Data.empty(); } 71 72 size_type size() const 73 { return m_Data.size(); } 74 75 size_type max_size() const 76 { return m_Data.max_size(); } 77 78 // Modification 79 std::pair<iterator, bool> insert(const value_type& val) 80 { 81 #ifdef ENTITYMAP_INSERTION_CHECK 82 ENSURE(val.first >= size()); 83 #endif 84 m_Data.push_back(val); 85 difference_type pos = m_Data.size() - 1; 86 m_Lookup.resize(val.first + 1, -1); 87 m_Lookup[val.first] = pos; 88 return std::make_pair(m_Data.begin() + pos, true); 89 } 90 91 void erase(iterator it) 92 { 93 // update all lookup indices 94 m_Lookup[it->first] = -1; 95 for(difference_type pos = it->first + 1; pos < m_Lookup.size(); pos++) 96 { 97 if (m_Lookup[pos]) m_Lookup[pos]--; 98 } 99 m_Data.erase(it); 100 } 101 102 size_type erase(const key_type& key) 103 { 104 size_type count = 0; 105 iterator it = find(key); 106 if (it != end()) 107 { 108 erase(it); 109 count = 1; 110 } 111 return count; 112 } 113 114 void swap(EntityMap &map) 115 { 116 m_Data.swap(map.m_Data); 117 m_Lookup.swap(map.m_Lookup); 118 } 119 120 void clear() 121 { 122 m_Data.clear(); 123 m_Lookup.clear(); 124 } 125 126 // Operations 127 iterator find(const key_type& key) 128 { 129 if (key >= 0 && key < m_Lookup.size()) 130 { 131 difference_type pos = m_Lookup[key]; 132 if (pos >= 0) 133 { 134 return m_Data.begin() + pos; 135 } 136 } 137 return m_Data.end(); 138 } 139 140 const_iterator find(const key_type& key) const 141 { 142 if (key >= 0 && key < m_Lookup.size()) 143 { 144 difference_type pos = m_Lookup[key]; 145 if (pos >= 0) 146 { 147 return m_Data.begin() + pos; 148 } 149 } 150 return m_Data.end(); 151 } 152 153 size_type count(const key_type& key) const 154 { 155 return find(key) == end() ? 0 : 1; 156 } 157 158 private: 159 std::vector<value_type> m_Data; 160 std::vector<difference_type> m_Lookup; 161 }; 162 #endif -
serialization/SerializeTemplates.h
24 24 */ 25 25 26 26 #include "simulation2/components/ICmpPathfinder.h" 27 #include "simulation2/helpers/EntityMap.h" 27 28 28 29 template<typename ELEM> 29 30 struct SerializeVector … … 87 88 } 88 89 }; 89 90 91 template<typename VS> 92 struct SerializeEntityMap 93 { 94 template<typename V> 95 void operator()(ISerializer& serialize, const char* UNUSED(name), EntityMap<V>& value) 96 { 97 size_t len = value.size(); 98 serialize.NumberU32_Unbounded("length", (u32)len); 99 for (typename EntityMap<V>::iterator it = value.begin(); it != value.end(); ++it) 100 { 101 serialize.NumberU32_Unbounded("key", it->first); 102 VS()(serialize, "value", it->second); 103 } 104 } 105 106 template<typename V> 107 void operator()(IDeserializer& deserialize, const char* UNUSED(name), EntityMap<V>& value) 108 { 109 value.clear(); 110 u32 len; 111 deserialize.NumberU32_Unbounded("length", len); 112 for (size_t i = 0; i < len; ++i) 113 { 114 entity_id_t k; 115 deserialize.NumberU32_Unbounded("key", k); 116 V v; 117 VS()(deserialize, "value", v); 118 value.insert(std::make_pair(k, v)); 119 } 120 } 121 }; 122 90 123 // We have to order the map before serializing to make things consistent 91 124 template<typename KS, typename VS> 92 125 struct SerializeUnorderedMap