- Timestamp:
- 02/11/17 00:09:19 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/nv/ecs/ecs.hh
r547 r548 55 55 template<typename> 56 56 static constexpr nv::false_type check( ... ); 57 57 public: 58 58 typedef decltype( check<C>( 0 ) ) type; 59 60 public:61 59 static constexpr bool value = type::value; 62 60 }; 61 62 template < typename S, typename T, typename Cs > 63 struct has_ct_update_helper; 64 65 template < typename S, typename T, typename... Cs > 66 struct has_ct_update_helper< S, T, mpl::list< Cs... > > 67 { 68 using type = detail::has_update<S, void( Cs&..., T ) >; 69 }; 70 71 template < typename S, typename E, typename T, typename Cs > 72 struct has_ect_update_helper; 73 74 template < typename S, typename E, typename T, typename... Cs > 75 struct has_ect_update_helper< S, E, T, mpl::list< Cs... > > 76 { 77 using type = detail::has_update<S, void( E&, Cs&..., T ) >; 78 }; 79 80 template < typename S, typename E, typename M, typename Cs > 81 struct has_ec_message_helper; 82 83 template < typename S, typename E, typename M, typename... Cs > 84 struct has_ec_message_helper< S, E, M, mpl::list< Cs... > > 85 { 86 using type = detail::has_message<S, void( const M&, E&, Cs&... ) >; 87 }; 88 89 template < typename S, typename M, typename Cs > 90 struct has_c_message_helper; 91 92 template < typename S, typename M, typename... Cs > 93 struct has_c_message_helper< S, M, mpl::list< Cs... > > 94 { 95 using type = detail::has_message<S, void( const M&, Cs&... ) >; 96 }; 97 63 98 } 99 100 64 101 65 102 template < typename E, typename S, typename T > 66 103 using has_ecs_update = detail::has_update<S, void( E&, T ) >; 67 104 68 template < typename S, typename C , typename T >69 using has_component_update = detail::has_update<S, void( C&, T ) >;70 71 template < typename E, typename S, typename C , typename T >72 using has_ecs_component_update = detail::has_update<S, void( E&, C&, T ) >;73 74 template < typename S, typename C , typename M >75 using has_component_message = detail::has_message<S, void( const M&, C& ) >;76 77 template < typename E, typename S, typename C , typename M >78 using has_ecs_component_message = detail::has_message<S, void( const M&, E&, C& ) >;105 template < typename S, typename Cs, typename T > 106 using has_component_update = typename detail::has_ct_update_helper<S, T, Cs >::type; 107 108 template < typename E, typename S, typename Cs, typename T > 109 using has_ecs_component_update = typename detail::has_ect_update_helper<S, E, T, Cs >::type; 110 111 template < typename S, typename Cs, typename M > 112 using has_component_message = typename detail::has_c_message_helper<S, M, Cs >::type; 113 114 template < typename E, typename S, typename Cs, typename M > 115 using has_ecs_component_message = typename detail::has_ec_message_helper<S, E, M, Cs >::type; 79 116 80 117 template < typename E, typename S, typename M > … … 120 157 }; 121 158 122 template< typename Component > 159 template< typename Component > 123 160 class component_enumerator : public iterator< input_iterator_tag, Component > 124 161 { … … 157 194 { 158 195 if ( !m_interface ) return; 159 do { 196 do 197 { 160 198 m_handle = m_ecs.next( m_handle ); 161 199 m_component = (Component*)m_interface->get_raw( m_handle ); … … 168 206 }; 169 207 208 template < typename Component > 209 handle_type handle_cast( const Component& c ) 210 { 211 return *reinterpret_cast<const handle_type*>( &c ); 212 } 213 214 template < typename... Components > 215 struct gather_components 216 { 217 static constexpr uint32 SIZE = sizeof...( Components ); 218 component_interface* cis[SIZE]; 219 void* cmps[SIZE]; 220 221 gather_components( this_type& ecs ) 222 { 223 fill< 0, Components... >( ecs ); 224 } 225 226 bool run( handle_type h ) 227 { 228 for ( uint32 i = 0; i < SIZE; ++i ) 229 { 230 cmps[i] = cis[i]->get_raw( h ); 231 if ( !cmps[i] ) return false; 232 } 233 return true; 234 } 235 236 template < typename SC > 237 SC& get() 238 { 239 return run_get< 0, SC, Components...>(); 240 } 241 242 private: 243 template < int Index, typename C, typename... Components > 244 void fill( this_type& ecs ) 245 { 246 cis[Index] = ecs.get_interface< C >(); 247 NV_ASSERT( cis[Index], "What the fuck is this?" ); 248 fill< Index + 1, Components... >( ecs ); 249 } 250 251 template < int Index > 252 void fill( this_type& ) {} 253 254 template < int Index, typename SC, typename C, typename... Components > 255 C& run_get() 256 { 257 return get_impl< Index, SC, C, Components... >( nv::is_same< SC, C >{} ); 258 } 259 260 template < int Index, typename SC, typename C, typename C2, typename... Components > 261 C& get_impl( false_type&& ) 262 { 263 return get_impl< Index + 1, SC, C2, Components...>( nv::is_same< SC, C >() ); 264 } 265 266 template < int Index, typename SC, typename C, typename... Components > 267 C& get_impl( true_type&& ) 268 { 269 return *(C*)cmps[Index]; 270 } 271 272 }; 273 274 170 275 template< typename System > 171 276 void register_system( string_view name, System* c ) 172 277 { 173 278 register_handler< System >( name, (System*)( c ) ); 174 register_ecs_update< System >( (System*)( c ) ); 279 register_ecs_update< System >( (System*)( c ), 280 has_ecs_update< this_type, System, time_type >::type{} ); 175 281 } 176 282 … … 183 289 m_component_map_by_name[name] = c; 184 290 register_handler< Handler >( name, (Handler*)c ); 185 register_component_messages< Handler, Component >( (Handler*)( c ), message_list{} ); 186 register_ecs_component_update< Handler, Component >( (Handler*)( c ) ); 187 register_component_update< Handler, Component >( (Handler*)( c ) ); 188 register_ecs_update< Handler >( (Handler*)( c ) ); 189 // auto s = c->storage(); 190 // m_cstorage.push_back( s ); 191 // m_cmap[thash64::create<Component>()] = s; 192 // m_cmap_by_name[name] = s; 291 register_component_messages< Handler, mpl::list< Component > >( (Handler*)( c ), message_list{} ); 292 register_ecs_component_update< Handler >( (Handler*)( c ), mpl::list< Component >{} ); 293 register_component_update< Handler >( (Handler*)( c ), mpl::list< Component >{} ); 294 register_ecs_update< Handler >( (Handler*)( c ), 295 has_ecs_update< this_type, Handler, time_type >::type{} ); 296 // auto s = c->storage(); 297 // m_cstorage.push_back( s ); 298 // m_cmap[thash64::create<Component>()] = s; 299 // m_cmap_by_name[name] = s; 193 300 } 194 301 … … 217 324 ~ecs() 218 325 { 219 // for ( auto cs : m_component_storage )220 // delete cs;221 // m_cstorage.clear();326 // for ( auto cs : m_component_storage ) 327 // delete cs; 328 // m_cstorage.clear(); 222 329 223 330 } … … 249 356 enumerator( *this, first_child( h ) ), 250 357 enumerator( *this ) 251 );358 ); 252 359 } 253 360 … … 325 432 template < typename Component > 326 433 typename component_storage_handler< Component >* 327 get_storage()328 { 329 return storage_cast< Component>( m_cmap[thash64::create< Component >()] );434 get_storage() 435 { 436 return storage_cast<Component>( m_cmap[thash64::create< Component >()] ); 330 437 } 331 438 332 439 template < typename Component > 333 440 const typename component_storage_handler< Component >* 334 get_storage() const 335 { 336 return storage_cast< Component >( m_cmap[thash64::create< Component >()] ); 337 } 338 339 // protected: 441 get_storage() const 442 { 443 return storage_cast<Component>( m_cmap[thash64::create< Component >()] ); 444 } 340 445 341 446 template < typename System, typename Components, template <class...> class List, typename... Messages > 342 447 void register_component_messages( System* h, List<Messages...>&& ) 343 448 { 344 int unused_0[] = { ( register_ecs_component_message<System, Components,Messages>( h), 0 )... };345 int unused_1[] = { ( register_component_message<System, Components,Messages>( h), 0 )... };449 int unused_0[] = { ( register_ecs_component_message<System,Messages>( h, Components{} ), 0 )... }; 450 int unused_1[] = { ( register_component_message<System,Messages>( h, Components{} ), 0 )... }; 346 451 int unused_2[] = { ( register_ecs_message<System,Messages>( h ), 0 )... }; 347 452 } 348 453 349 template < typename System, typename Components, typename Message>350 typename enable_if< has_component_message< System, Components, Message >::value, void >::type351 register_component_message( System* s)352 { 353 component_interface* ci = get_interface<C omponents>();454 template < typename System, typename Message, typename C > 455 typename enable_if< has_component_message< System, mpl::list< C >, Message >::value, void >::type 456 register_component_message( System* s, mpl::list< C >&& ) 457 { 458 component_interface* ci = get_interface<C>(); 354 459 register_callback( Message::message_id, [=] ( const message& msg ) 355 460 { 356 461 const Message& m = message_cast<Message>( msg ); 462 auto callback = [=] ( handle_type h ) 463 { 464 if ( void* c = ci->get_raw( h ) ) 465 s->on( m, *( (C*)( c ) ) ); 466 }; 357 467 if ( msg.recursive ) 358 { 359 this->recursive_call( m.entity, [=] ( handle_type h ) 468 this->recursive_call( m.entity, nv::move( callback ) ); 469 else 470 callback( m.entity ); 471 } ); 472 } 473 474 template < typename System, typename Message, typename C, typename... Cs > 475 typename enable_if< has_component_message< System, mpl::list< C, Cs...>, Message >::value, void >::type 476 register_component_message( System* s, mpl::list< C, Cs...>&& ) 477 { 478 component_interface* ci = get_interface<C>(); 479 register_callback( Message::message_id, [=] ( const message& msg ) 480 { 481 const Message& m = message_cast<Message>( msg ); 482 auto callback = [=] ( handle_type h ) 483 { 484 if ( void* c = ci->get_raw( h ) ) 360 485 { 361 if ( void* c = ci->get_raw( h ) ) 362 s->on( m, *( (Components*)( c ) ) ); 363 } ); 364 } 486 gather_components< Cs... > gather( *this ); 487 if ( gather.run( h ) ) 488 s->on( m, *( (C*)( c ) ), gather.get<Cs>()... ); 489 } 490 }; 491 if ( msg.recursive ) 492 this->recursive_call( m.entity, nv::move( callback ) ); 365 493 else 366 if ( void* c = ci->get_raw( m.entity ) )367 s->on( m, *( (Components*)( c ) ) );368 } ); 369 } 370 371 template < typename System, typename Components, typename Message>372 typename enable_if< has_ecs_component_message< this_type, System, Components, Message >::value, void >::type373 register_ecs_component_message( System* s)374 { 375 component_interface* ci = get_interface<C omponents>();376 377 494 callback( m.entity ); 495 496 } ); 497 } 498 499 template < typename System, typename Message, typename C > 500 typename enable_if< has_ecs_component_message< this_type, System, mpl::list< C >, Message >::value, void >::type 501 register_ecs_component_message( System* s, mpl::list< C >&& ) 502 { 503 component_interface* ci = get_interface<C>(); 504 register_callback( Message::message_id, [=] ( const message& msg ) 505 { 378 506 const Message& m = message_cast<Message>( msg ); 507 auto callback = [=] ( handle_type h ) 508 { 509 if ( void* c = ci->get_raw( h ) ) 510 s->on( m, *this, *( (C*)( c ) ) ); 511 }; 379 512 if ( msg.recursive ) 380 { 381 this->recursive_call( m.entity, [=] ( handle_type h ) 513 this->recursive_call( m.entity, nv::move( callback ) ); 514 else 515 callback( m.entity ); 516 } ); 517 518 } 519 520 template < typename System, typename Message, typename C, typename... Cs > 521 typename enable_if< has_ecs_component_message< this_type, System, mpl::list< C, Cs...>, Message >::value, void >::type 522 register_ecs_component_message( System* s, mpl::list< C, Cs...>&& ) 523 { 524 component_interface* ci = get_interface<C>(); 525 register_callback( Message::message_id, [=] ( const message& msg ) 526 { 527 const Message& m = message_cast<Message>( msg ); 528 auto callback = [=] ( handle_type h ) 529 { 530 if ( void* c = ci->get_raw( h ) ) 382 531 { 383 if ( void* c = ci->get_raw( h ) ) 384 s->on( m, *this, *( (Components*)( c ) ) ); 385 } ); 386 } 532 gather_components< Cs... > gather( *this ); 533 if ( gather.run( h ) ) 534 s->on( m, *this, *( (C*)( c ) ), gather.get<Cs>()... ); 535 } 536 }; 537 if ( msg.recursive ) 538 this->recursive_call( m.entity, callback ); 387 539 else 388 if ( void* c = ci->get_raw( m.entity ) ) 389 s->on( m, *this, *((Components*)(c)) ); 390 } ); 540 callback( m.entity ); 541 } ); 391 542 392 543 } … … 395 546 register_ecs_message( System* s ) 396 547 { 397 398 548 register_callback( Message::message_id, [=] ( const message& msg ) 549 { 399 550 s->on( message_cast<Message>( msg ), *this ); 400 401 402 } 403 404 template < typename System, typename Components, typename Message>405 typename enable_if< !has_component_message< System, Components, Message >::value, void >::type406 register_component_message( System* ) {}407 408 template < typename System, typename Components, typename Message>409 typename enable_if< !has_ecs_component_message< this_type, System, Components, Message >::value, void >::type410 register_ecs_component_message( System* ) {}551 } ); 552 553 } 554 555 template < typename System, typename Message, typename... Cs > 556 typename enable_if< !has_component_message< System, mpl::list< Cs...>, Message >::value, void >::type 557 register_component_message( System*, mpl::list< Cs...>&& ) {} 558 559 template < typename System, typename Message, typename... Cs > 560 typename enable_if< !has_ecs_component_message< this_type, System, mpl::list< Cs...>, Message >::value, void >::type 561 register_ecs_component_message( System*, mpl::list< Cs...>&& ) {} 411 562 412 563 template < typename System, typename Message > … … 415 566 416 567 template < typename System > 417 typename enable_if< has_ecs_update< this_type, System, time_type >::value, void >::type 418 register_ecs_update( System* s ) 568 void register_ecs_update( System* s, true_type&& ) 419 569 { 420 570 register_update( [=] ( time_type dtime ) … … 424 574 } 425 575 426 template < typename System, typename C omponents>427 typename enable_if< has_component_update< System, Components, time_type >::value, void >::type428 register_component_update( System* s )429 { 430 component_interface* ci = get_interface<C omponents>();431 component_storage_handler<C omponents>* storage = storage_cast<Components>( ci->storage() );576 template < typename System, typename C > 577 typename enable_if< has_component_update< System, mpl::list< C >, time_type >::value, void >::type 578 register_component_update( System* s, mpl::list< C >&& ) 579 { 580 component_interface* ci = get_interface<C>(); 581 component_storage_handler<C>* storage = storage_cast<C>( ci->storage() ); 432 582 register_update( [=] ( time_type dtime ) 433 583 { … … 437 587 } 438 588 439 template < typename System, typename Components > 440 typename enable_if< has_ecs_component_update< this_type, System, Components, time_type >::value, void >::type 441 register_ecs_component_update( System* s ) 442 { 443 component_interface* ci = get_interface<Components>(); 444 component_storage_handler<Components>* storage = storage_cast<Components>( ci->storage() ); 589 template < typename System, typename C, typename... Cs > 590 typename enable_if< has_component_update< System, mpl::list< C, Cs...>, time_type >::value, void >::type 591 register_component_update( System* s, mpl::list< C, Cs...>&& ) 592 { 593 component_interface* ci = get_interface<C>(); 594 component_storage_handler<C>* storage = storage_cast<C>( ci->storage() ); 595 register_update( [=] ( time_type dtime ) 596 { 597 gather_components< Cs... > gather( *this ); 598 for ( auto& c : *storage ) 599 { 600 handle_type h = handle_cast( c ); 601 if ( gather.run( h ) ) 602 s->update( c, gather.get<Cs>()..., dtime ); 603 } 604 } ); 605 } 606 607 template < typename System, typename C > 608 typename enable_if< has_ecs_component_update< this_type, System, mpl::list< C >, time_type >::value, void >::type 609 register_ecs_component_update( System* s, mpl::list< C >&& ) 610 { 611 component_interface* ci = get_interface<C>(); 612 component_storage_handler<C>* storage = storage_cast<C>( ci->storage() ); 445 613 register_update( [=] ( time_type dtime ) 446 614 { … … 451 619 452 620 621 622 template < typename System, typename C, typename... Cs > 623 typename enable_if< has_ecs_component_update< this_type, System, mpl::list< C, Cs...>, time_type >::value, void >::type 624 register_ecs_component_update( System* s, mpl::list< C, Cs...>&& ) 625 { 626 component_interface* ci = get_interface<C>(); 627 component_storage_handler<C>* storage = storage_cast<C>( ci->storage() ); 628 register_update( [=] ( time_type dtime ) 629 { 630 gather_components< Cs... > gather(*this); 631 for ( auto& c : *storage ) 632 { 633 handle_type h = handle_cast( c ); 634 if ( gather.run( h ) ) 635 s->update( *this, c, gather.get<Cs>()..., dtime ); 636 } 637 } ); 638 } 639 640 453 641 template < typename System > 454 typename enable_if< !has_ecs_update< this_type, System, time_type >::value, void >::type 455 register_ecs_update( System* ) {} 456 457 template < typename System, typename Components > 458 typename enable_if< !has_component_message< System, Components, time_type >::value, void >::type 459 register_component_update( System* ) {} 460 461 template < typename System, typename Components > 462 typename enable_if< !has_ecs_component_update< this_type, System, Components, time_type >::value, void >::type 463 register_ecs_component_update( System* ) {} 642 void register_ecs_update( System*, false_type&& ) {} 643 644 template < typename System, typename... Cs > 645 typename enable_if< !has_component_update< System, mpl::list< Cs...>, time_type >::value, void >::type 646 register_component_update( System*, mpl::list< Cs...>&& ) {} 647 648 template < typename System, typename... Cs > 649 typename enable_if< !has_ecs_component_update< this_type, System, mpl::list< Cs...>, time_type >::value, void >::type 650 register_ecs_component_update( System*, mpl::list< Cs...>&& ) {} 464 651 465 652 void register_update( update_handler&& handler ) … … 476 663 vector< update_handler > m_update_handlers; 477 664 478 // vector< component_storage* > m_cstorage;479 // hash_store< thash64, component_storage* > m_cmap;480 // hash_store< shash64, component_storage* > m_cmap_by_name;665 // vector< component_storage* > m_cstorage; 666 // hash_store< thash64, component_storage* > m_cmap; 667 // hash_store< shash64, component_storage* > m_cmap_by_name; 481 668 }; 482 669
Note: See TracChangeset
for help on using the changeset viewer.