- Timestamp:
- 02/03/17 20:28:45 (8 years ago)
- Location:
- trunk/nv
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/nv/ecs/component.hh
r540 r542 36 36 typename Ecs, 37 37 typename Component, 38 typename Handler, 38 39 template < typename, typename > class IndexTable = index_table 39 40 > … … 41 42 { 42 43 public: 43 typedef Ecs ecs_type; 44 typedef typename ecs_type::message message_type; 45 typedef typename ecs_type::handle_type handle_type; 46 typedef typename ecs_type::time_type time_type; 47 typedef IndexTable< handle_type, sint32 > index_table_type; 48 typedef Component value_type; 49 typedef Component component_type; 50 typedef vector< value_type > storage_type; 51 typedef typename index_table_type::index_type index_type; 44 typedef Ecs ecs_type; 45 typedef typename ecs_type::message message_type; 46 typedef typename ecs_type::handle_type handle_type; 47 typedef typename ecs_type::time_type time_type; 48 typedef IndexTable< handle_type, sint32 > index_table_type; 49 typedef Component value_type; 50 typedef Component component_type; 51 typedef component_storage_handler< value_type > storage_type; 52 // typedef vector< value_type > storage_type; 53 typedef typename index_table_type::index_type index_type; 52 54 53 typedef typename storage_type::iterator iterator;54 typedef typename storage_type::const_iterator const_iterator;55 typedef typename storage_type::reference reference;56 typedef typename storage_type::const_reference const_reference;55 typedef typename storage_type::iterator iterator; 56 typedef typename storage_type::const_iterator const_iterator; 57 typedef typename storage_type::reference reference; 58 typedef typename storage_type::const_reference const_reference; 57 59 58 60 component( ecs_type& a_ecs, string_view a_name, uint32 reserve = 0 ) 59 61 : m_ecs( a_ecs ) 60 62 { 61 m_ecs.register_component<component_type>( a_name, this ); 63 m_ecs.register_component<component_type, Handler>( a_name, this ); 64 62 65 if ( reserve != 0 ) 63 66 { … … 99 102 virtual void clear() 100 103 { 101 for ( uint32 i = 0; i < m_data.size(); ++i )102 destroy( &m_data[i] );104 for ( uint32 i = 0; i < m_data.size(); ++i ) 105 destroy( &m_data[i] ); 103 106 m_index.clear(); 104 m_data.clear();107 m_data.clear(); 105 108 } 106 109 … … 119 122 const void* get_raw( handle_type h ) const { return get( h ); } 120 123 121 virtual void remove( handle_type h ) 124 virtual void remove( handle_type h ) override 122 125 { 123 126 value_type* v = get( h ); … … 138 141 } 139 142 140 virtual bool handle_message( const message_type& )141 {142 return true;143 }144 145 143 ~component() 146 144 { … … 148 146 } 149 147 150 inline handle_type get_handle( index_type i ) const { return m_index.get_handle( i ); }148 inline handle_type _get_handle( index_type i ) const { return m_index.get_handle( i ); } 151 149 152 150 inline const value_type& operator[] ( index_type i ) const { return m_data[i]; } … … 157 155 inline iterator begin() { return m_data.begin(); } 158 156 inline const_iterator begin() const { return m_data.begin(); } 159 inline const_iterator cbegin() const { return m_data.begin(); }160 157 161 158 inline iterator end() { return m_data.end(); } 162 159 inline const_iterator end() const { return m_data.end(); } 163 inline const_iterator cend() const { return m_data.end(); } 160 161 //inline virtual component_storage* storage() { return &m_data; } 164 162 protected: 165 163 ecs_type& m_ecs; 164 storage_type m_data; 165 private: 166 166 index_table_type m_index; 167 storage_type m_data;168 167 }; 169 168 -
trunk/nv/ecs/component_storage.hh
r538 r542 25 25 namespace ecs 26 26 { 27 28 class component_storage 29 { 30 protected: 31 component_storage() {} 32 template < typename T > 33 void initialize() 34 { 35 m_data = nullptr; 36 m_size = 0; 37 m_allocated = 0; 38 // TODO: detect trivially destructible objects 39 m_destructor = raw_destroy_object < T >; 40 m_csize = sizeof( T ); 41 } 42 public: 43 void reserve( uint32 count ) 44 { 45 reallocate( count ); 46 } 47 uint32 size() const { return m_size; } 48 uint32 raw_size() const { return m_size * m_csize; } 49 void reset() 50 { 51 clear(); 52 nvfree( m_data ); 53 m_data = nullptr; 54 m_allocated = 0; 55 } 56 void clear() 57 { 58 uint32 count = m_size; 59 uint8* d = m_data; 60 for ( ; count > 0; --count, d += m_csize ) 61 m_destructor(d); 62 m_size = 0; 63 } 64 void* raw() { return m_data; } 65 const void* raw() const { return m_data; } 66 // TODO: Debug-time type checking 67 template < typename T > 68 T* as() { return (T*)m_data; } 69 template < typename T > 70 const T* as() const { return m_data; } 71 72 void pop_back() 73 { 74 NV_ASSERT( m_size > 0, "BAD OP!" ); 75 m_size--; 76 m_destructor( m_data + m_size * m_csize ); 77 } 78 79 ~component_storage() 80 { 81 reset(); 82 } 83 protected: 84 void grow() 85 { 86 uint32 new_size = m_size + 1; 87 if ( new_size > m_allocated ) 88 { 89 reallocate( m_allocated > 3 ? m_allocated * 2 : 8 ); 90 } 91 m_size = new_size; 92 } 93 94 void reallocate( uint32 new_size ) 95 { 96 m_data = static_cast<uint8*>( nvrealloc( m_data, new_size * m_csize ) ); 97 m_allocated = new_size; 98 NV_ASSERT( m_data, "OMG" ); 99 } 100 101 //thash64 m_type; 102 uint32 m_csize; 103 uint32 m_allocated; 104 uint32 m_size; 105 destructor_t m_destructor; 106 uint8* m_data; 107 }; 108 109 template < typename Component > 110 class component_storage_handler : public component_storage 111 { 112 public: 113 typedef Component value_type; 114 typedef Component* iterator; 115 typedef const Component* const_iterator; 116 typedef Component& reference; 117 typedef const Component& const_reference; 118 119 component_storage_handler() 120 { 121 initialize<Component>(); 122 } 123 Component* data() { return (Component*)m_data; } 124 const Component* data() const { return (Component*)m_data; } 125 inline const Component& operator[] ( uint32 i ) const { return ((Component*)m_data)[i]; } 126 inline Component& operator[] ( uint32 i ) { return ( (Component*)m_data )[i]; } 127 128 inline iterator begin() { return (Component*)m_data; } 129 inline const_iterator begin() const { return (const Component*)m_data; } 130 inline void* raw_begin() { return m_data; } 131 inline const void* raw_begin() const { return m_data; } 132 133 inline iterator end() { return ((Component*)m_data)+m_size; } 134 inline const_iterator end() const { return ( (Component*)m_data ) + m_size; } 135 inline void* raw_end() { return ( (Component*)m_data ) + m_size; } 136 inline const void* raw_end() const { return ( (Component*)m_data ) + m_size; } 137 138 template < typename... Args > 139 void emplace_back( Args&&... args ) 140 { 141 grow(); 142 construct_object( data() + sint32( m_size ) - 1, forward<Args>( args )... ); 143 } 144 145 Component& back() 146 { 147 NV_ASSERT( m_size > 0, "EMPTY COMPONENT STORAGE" ); 148 return *( data() + sint32( m_size ) - 1 ); 149 } 150 }; 151 152 template < typename Component > 153 component_storage_handler< Component >* storage_cast( component_storage* storage ) 154 { 155 // TODO: error checking 156 return ( component_storage_handler< Component >* )storage; 157 } 27 158 28 159 template < typename Handle, typename Component > -
trunk/nv/ecs/ecs.hh
r541 r542 23 23 #include <nv/core/types.hh> 24 24 #include <nv/ecs/message_queue.hh> 25 #include <nv/ecs/component_storage.hh> 26 25 27 26 28 namespace nv … … 34 36 namespace ecs 35 37 { 36 37 template < typename Handle, typename Time = f32 > 38 class ecs : public message_queue< Handle, Time > 38 template < typename S, typename C, typename M > 39 using has_component_message = detail::has_message<S, void( const M&, C& ) >; 40 41 template < typename E, typename S, typename C, typename M > 42 using has_ecs_component_message = detail::has_message<S, void( const M&, E&, C& ) >; 43 44 template < typename E, typename S, typename M > 45 using has_ecs_message = detail::has_message<S, void( const M&, E& ) >; 46 47 48 template < typename Handle, typename MessageList, typename Time = f32 > 49 class ecs : public message_queue< MessageList, Time > 39 50 { 40 51 public: 41 typedef message_queue< Handle, Time > base_class; 42 using base_class::time_type; 43 using base_class::handle_type; 44 using base_class::message_type; 45 using base_class::message; 46 using base_class::receiver_interface; 47 48 class component_interface : public receiver_interface 52 typedef message_queue< MessageList, Time > base_type; 53 typedef ecs< Handle, MessageList, Time > this_type; 54 typedef Handle handle_type; 55 using base_type::time_type; 56 using base_type::message_type; 57 using base_type::message; 58 59 60 61 class component_interface 49 62 { 50 63 public: 64 virtual void update( time_type dtime ) = 0; 65 virtual void clear() = 0; 51 66 virtual void initialize( handle_type, lua::stack_proxy& ) = 0; 52 67 virtual void remove( handle_type h ) = 0; 53 68 virtual void* get_raw( handle_type h ) = 0; 54 69 virtual const void* get_raw( handle_type h ) const = 0; 70 // virtual component_storage* storage() = 0; 55 71 }; 56 72 … … 65 81 return *this; 66 82 } 67 value_enumerator_baseoperator++ ( int )68 {69 auto result = *this;70 base_class::m_value = m_ecs.next( base_class::m_value );71 return result;72 }83 // enumerator operator++ ( int ) 84 // { 85 // auto result = *this; 86 // base_class::m_value = m_ecs.next( base_class::m_value ); 87 // return result; 88 // } 73 89 private: 74 90 const ecs& m_ecs; 75 91 }; 76 92 77 template < typename Component > 93 template< typename Component > 94 class component_enumerator : public iterator< input_iterator_tag, Component > 95 { 96 public: 97 typedef value_enumerator_base < handle_type > base_class; 98 explicit component_enumerator( ecs& aecs, handle_type current = handle_type() ) 99 : m_ecs( aecs ), m_handle( current ), m_component( nullptr ) 100 { 101 m_interface = m_ecs.get_interface< Component >(); 102 if ( m_interface && m_handle ) 103 { 104 m_component = (Component*)m_interface->get_raw( current ); 105 if ( !m_component ) 106 find_next(); 107 } 108 else 109 m_handle = handle_type(); 110 } 111 component_enumerator& operator++ () 112 { 113 find_next(); 114 return *this; 115 } 116 Component& operator* () { return *m_component; } 117 Component* operator-> () { return &m_component; } 118 const Component& operator* () const { return *m_component; } 119 const Component* operator-> () const { return &m_component; } 120 bool operator== ( const component_enumerator& rhs ) const 121 { 122 return m_handle == rhs.m_handle; 123 } 124 bool operator!= ( const component_enumerator& rhs ) const 125 { 126 return !( *this == rhs ); 127 } 128 private: 129 void find_next() 130 { 131 if ( !m_interface ) return; 132 do { 133 m_handle = m_ecs.next( m_handle ); 134 m_component = (Component*)m_interface->get_raw( m_handle ); 135 } while ( m_handle && !m_component ); 136 } 137 component_interface* m_interface; 138 handle_type m_handle; 139 Component* m_component; 140 ecs& m_ecs; 141 }; 142 143 template < typename Component, typename Handler > 78 144 void register_component( string_view name, component_interface* c ) 79 145 { 80 146 m_components.push_back( c ); 81 register_receiver( name, c );82 147 m_component_map[thash64::create<Component>()] = c; 83 148 m_component_map_by_name[name] = c; 149 register_handler< Handler >( name, (Handler*)c ); 150 register_component_messages< Handler, Component >( (Handler*)( c ), message_list{} ); 151 // auto s = c->storage(); 152 // m_cstorage.push_back( s ); 153 // m_cmap[thash64::create<Component>()] = s; 154 // m_cmap_by_name[name] = s; 84 155 } 85 156 … … 89 160 } 90 161 162 void update( time_type dtime ) 163 { 164 update_time( dtime ); 165 for ( auto c : m_components ) 166 c->update( dtime ); 167 } 168 91 169 void clear() 92 170 { 93 171 reset_events(); 94 for ( auto c : m_ receivers )172 for ( auto c : m_components ) 95 173 c->clear(); 96 174 m_handles.clear(); 175 } 176 177 ~ecs() 178 { 179 // for ( auto cs : m_component_storage ) 180 // delete cs; 181 // m_cstorage.clear(); 182 97 183 } 98 184 … … 126 212 } 127 213 214 template< typename Component > 215 enumerator_provider< component_enumerator< Component > > child_components( handle_type h ) 216 { 217 return enumerator_provider< component_enumerator< Component > >( 218 component_enumerator< Component >( *this, first_child( h ) ), 219 component_enumerator< Component >( *this ) 220 ); 221 } 222 128 223 void remove( handle_type h ) 129 224 { … … 157 252 158 253 template < typename Component > 254 component_interface* get_interface() 255 { 256 return m_component_map[thash64::create< Component >()]; 257 } 258 259 template < typename Component > 260 const component_interface* get_interface() const 261 { 262 return m_component_map[thash64::create< Component >()]; 263 } 264 265 template < typename Component > 159 266 Component* get( handle_type h ) 160 267 { 161 return static_cast< Component*>( m_component_map[thash64::create< Component >()]->get_raw( h ) );268 return static_cast<Component*>( m_component_map[thash64::create< Component >()]->get_raw( h ) ); 162 269 } 163 270 … … 168 275 } 169 276 277 template < typename Component > 278 typename component_storage_handler< Component >* 279 get_storage() 280 { 281 return storage_cast< Component >( m_cmap[thash64::create< Component >()] ); 282 } 283 284 template < typename Component > 285 const typename component_storage_handler< Component >* 286 get_storage() const 287 { 288 return storage_cast< Component >( m_cmap[thash64::create< Component >()] ); 289 } 290 170 291 protected: 292 293 template < typename System, typename Components, template <class...> class List, typename... Messages > 294 void register_component_messages( System* h, List<Messages...>&& ) 295 { 296 int unused_0[] = { ( register_component_message<System,Components,Messages>( h ), 0 )... }; 297 int unused_1[] = { ( register_ecs_component_message<System,Components,Messages>( h ), 0 )... }; 298 int unused_2[] = { ( register_ecs_message<System,Messages>( h ), 0 )... }; 299 } 300 301 template < typename System, typename Components, typename Message > 302 typename enable_if< has_component_message< System, Components, Message >::value, void >::type 303 register_component_message( System* s ) 304 { 305 component_interface* ci = get_interface<Components>(); 306 register_callback( Message::message_id, [=] ( const message& msg ) 307 { 308 const Message& m = message_cast<Message>( msg ); 309 if ( void* c = ci->get_raw( m.entity ) ) 310 s->on( m, *((Components*)(c)) ); 311 } ); 312 313 } 314 315 template < typename System, typename Components, typename Message > 316 typename enable_if< has_ecs_component_message< this_type, System, Components, Message >::value, void >::type 317 register_ecs_component_message( System* s ) 318 { 319 component_interface* ci = get_interface<Components>(); 320 register_callback( Message::message_id, [=] ( const message& msg ) 321 { 322 const Message& m = message_cast<Message>( msg ); 323 if ( void* c = ci->get_raw( m.entity ) ) 324 s->on( m, *this, *((Components*)(c)) ); 325 } ); 326 327 } 328 template < typename System, typename Message > 329 typename enable_if< has_ecs_message< this_type, System, Message >::value, void >::type 330 register_ecs_message( System* s ) 331 { 332 register_callback( Message::message_id, [=] ( const message& msg ) 333 { 334 s->on( message_cast<Message>( msg ), *this ); 335 } ); 336 337 } 338 339 template < typename System, typename Components, typename Message > 340 typename enable_if< !has_component_message< System, Components, Message >::value, void >::type 341 register_component_message( System* ) {} 342 343 template < typename System, typename Components, typename Message > 344 typename enable_if< !has_ecs_component_message< this_type, System, Components, Message >::value, void >::type 345 register_ecs_component_message( System* ) {} 346 347 template < typename System, typename Message > 348 typename enable_if< !has_ecs_message< this_type, System, Message >::value, void >::type 349 register_ecs_message( System* ) {} 350 351 171 352 172 353 handle_tree_manager< handle_type > m_handles; … … 174 355 hash_store< thash64, component_interface* > m_component_map; 175 356 hash_store< shash64, component_interface* > m_component_map_by_name; 357 // vector< component_storage* > m_cstorage; 358 // hash_store< thash64, component_storage* > m_cmap; 359 // hash_store< shash64, component_storage* > m_cmap_by_name; 176 360 }; 177 361 -
trunk/nv/ecs/message_queue.hh
r541 r542 18 18 #include <nv/stl/handle.hh> 19 19 #include <nv/stl/priority_queue.hh> 20 #include <nv/stl/mpl/list.hh> 21 #include <nv/stl/functional/function.hh> 20 22 #include <nv/core/types.hh> 21 23 … … 25 27 namespace ecs 26 28 { 29 30 namespace detail 31 { 32 template<typename, typename T> 33 struct has_message 34 { 35 static_assert( nv::integral_constant<T, false>::value, "Second template parameter needs to be of function type." ); 36 }; 37 38 template< typename C, typename Ret, typename... Args > 39 struct has_message<C, Ret( Args... )> 40 { 41 private: 42 template<typename T> 43 static constexpr auto check( T* ) 44 -> typename nv::is_same< decltype( nv::declval<T>().on( nv::declval<Args>()... ) ), Ret >::type; 45 46 template<typename> 47 static constexpr nv::false_type check( ... ); 48 49 typedef decltype( check<C>( 0 ) ) type; 50 51 public: 52 static constexpr bool value = type::value; 53 }; 54 } 55 56 template < typename S, typename M > 57 using has_message = detail::has_message<S, void( const M& ) >; 27 58 28 59 template < typename Payload, typename Message > … … 35 66 36 67 37 template < typename Handle, typename Time = f32 >68 template < typename MessageList, typename Time = f32 > 38 69 class message_queue 39 70 { 40 71 public: 41 typedef Time time_type; 42 typedef Handle handle_type; 43 typedef uint32 message_type; 44 45 struct message 72 typedef Time time_type; 73 typedef MessageList message_list; 74 typedef uint32 message_type; 75 76 constexpr static const uint32 message_list_size = mpl::list_size< message_list >::value; 77 78 message_queue() 79 { 80 m_handlers.resize( message_list_size ); 81 } 82 83 struct message 46 84 { 47 85 message_type type; 48 handle_type entity;49 86 time_type time; 50 uint8 payload[128 - sizeof( uint32 ) - sizeof( handle_type ) - sizeof( time_type )];87 uint8 payload[128 - sizeof( message_type ) - sizeof( time_type ) ]; 51 88 }; 52 89 … … 59 96 }; 60 97 98 using message_handler = function< void( const message& ) >; 99 100 struct message_handlers 101 { 102 vector< message_handler > list; 103 }; 104 61 105 typedef priority_queue< message, vector< message >, message_compare_type > queue_type; 62 106 63 class receiver_interface 64 { 65 public: 66 virtual void update( time_type dtime ) = 0; 67 virtual bool handle_message( const message& ) = 0; 68 virtual void clear() = 0; 69 }; 70 71 void register_receiver( string_view /*name*/, receiver_interface* c ) 72 { 73 m_receivers.push_back( c ); 107 template< typename Handler > 108 void register_handler( string_view /*name*/, Handler* c ) 109 { 110 register_messages< Handler > ( (Handler*)( c ), message_list{} ); 111 } 112 113 template<> 114 void register_handler<void>( string_view /*name*/, void* ) 115 { 74 116 } 75 117 76 118 bool dispatch( const message& m ) 77 119 { 78 for ( auto c : m_receivers)79 c->handle_message( m );120 for ( auto& h : m_handlers[m.type].list ) 121 h( m ); 80 122 return true; 81 123 } 82 124 83 125 template < typename Payload, typename ...Args > 84 bool dispatch( handle_type h,Args&&... args )85 { 86 message m{ Payload::message_id, h,time_type( 0 ) };126 bool dispatch( Args&&... args ) 127 { 128 message m{ Payload::message_id, time_type( 0 ) }; 87 129 new( &m.payload ) Payload{ nv::forward<Args>( args )... }; 88 130 return dispatch( m ); … … 96 138 97 139 template < typename Payload, typename ...Args > 98 bool queue( handle_type h,time_type delay, Args&&... args )99 { 100 message m{ Payload::message_id, h,m_time + delay };140 bool queue( time_type delay, Args&&... args ) 141 { 142 message m{ Payload::message_id, m_time + delay }; 101 143 new( &m.payload ) Payload{ nv::forward<Args>( args )... }; 102 144 return queue( m ); … … 121 163 } 122 164 123 void update ( time_type dtime )165 void update_time( time_type dtime ) 124 166 { 125 167 if ( dtime == time_type( 0 ) ) return; … … 131 173 dispatch( msg ); 132 174 } 133 134 for ( auto c : m_receivers )135 c->update( dtime );136 175 } 137 176 138 177 time_type update_step() 139 178 { 140 time_type before = m_time;141 179 if ( !m_pqueue.empty() ) 142 180 { … … 145 183 m_pqueue.pop(); 146 184 dispatch( msg ); 147 if ( before != m_time )148 for ( auto c : m_receivers )149 c->update( m_time - before );150 185 } 151 186 return m_time; 152 187 } 153 188 189 void register_callback( message_type msg, message_handler&& handler ) 190 { 191 m_handlers[msg].list.push_back( handler ); 192 } 193 154 194 protected: 195 196 template < typename System, template <class...> class List, typename... Messages > 197 void register_messages( System* h, List<Messages...>&& ) 198 { 199 int unused[] = { ( register_message<System,Messages>( h ), 0 )... }; 200 } 201 202 203 template < typename System, typename Message > 204 typename enable_if< has_message< System, Message >::value, void >::type 205 register_message( System* s ) 206 { 207 register_callback( Message::message_id, [=] ( const message& msg ) 208 { 209 s->on( message_cast<Message>( msg ) ); 210 } ); 211 } 212 213 template < typename System, typename Message > 214 typename enable_if< !has_message< System, Message >::value, void >::type 215 register_message( System* ) {} 216 155 217 time_type m_time = time_type( 0 ); 156 218 queue_type m_pqueue; 157 vector< receiver_interface* > m_receivers;219 vector< message_handlers > m_handlers; 158 220 }; 159 221 160 template < typename Ecs >161 class receiver : public Ecs::receiver_interface162 {163 public:164 typedef Ecs ecs_type;165 typedef typename ecs_type::message message_type;166 typedef typename ecs_type::handle_type handle_type;167 typedef typename ecs_type::time_type time_type;168 169 receiver( ecs_type& a_ecs, string_view a_name ) : m_ecs( a_ecs )170 {171 m_ecs.register_receiver( a_name, this );172 }173 virtual void update( time_type /*dtime*/ )174 {175 // no-op176 }177 178 virtual void clear()179 {180 // no-op181 }182 virtual bool handle_message( const message_type& )183 {184 return false;185 }186 protected:187 ecs_type& m_ecs;188 };189 190 222 } 191 223 -
trunk/nv/stl/algorithm/copy.hh
r401 r542 41 41 inline OutputIterator copy_n_impl( InputIterator first, size_t n, OutputIterator out, AnyType, input_iterator_tag, forward_iterator_tag ) 42 42 { 43 for ( ; n-- > 0; ++first, ++out ) * first = *out;43 for ( ; n-- > 0; ++first, ++out ) *out = *first++; 44 44 return out; 45 45 } -
trunk/nv/stl/index_table.hh
r538 r542 75 75 } 76 76 77 index_type remove_swap( index_type dead_eindex )78 {79 if ( uint32( dead_eindex ) >= m_handles.size() ) return -1;80 handle_type h = m_handles[dead_eindex];81 handle_type swap_handle = m_handles.back();82 if ( dead_eindex != static_cast<index_type>( m_handles.size() - 1 ) )83 {84 m_handles[unsigned( dead_eindex )] = swap_handle;85 m_indexes[swap_handle.index()] = dead_eindex;86 }87 m_handles.pop_back();88 m_indexes[h.index()] = -1;89 return dead_eindex;90 }77 // index_type remove_swap( index_type dead_eindex ) 78 // { 79 // if ( uint32( dead_eindex ) >= m_handles.size() ) return -1; 80 // handle_type h = m_handles[dead_eindex]; 81 // handle_type swap_handle = m_handles.back(); 82 // if ( dead_eindex != static_cast<index_type>( m_handles.size() - 1 ) ) 83 // { 84 // m_handles[unsigned( dead_eindex )] = swap_handle; 85 // m_indexes[swap_handle.index()] = dead_eindex; 86 // } 87 // m_handles.pop_back(); 88 // m_indexes[h.index()] = -1; 89 // return dead_eindex; 90 // } 91 91 92 92 … … 159 159 if ( h.is_nil() ) return -1; 160 160 auto ih = m_indexes.find( h ); 161 if ( ih == m_indexes.end() ) return -1;161 if ( ih == m_indexes.end() || ih->second == index_type(-1) ) return -1; 162 162 handle_type swap_handle = m_handles.back(); 163 163 index_type dead_eindex = ih->second;
Note: See TracChangeset
for help on using the changeset viewer.