Changeset 548


Ignore:
Timestamp:
02/11/17 00:09:19 (8 years ago)
Author:
epyon
Message:
  • multi-component updates
  • multi-component messaging
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/nv/ecs/ecs.hh

    r547 r548  
    5555                                template<typename>
    5656                                static constexpr nv::false_type check( ... );
    57 
     57                        public:
    5858                                typedef decltype( check<C>( 0 ) ) type;
    59 
    60                         public:
    6159                                static constexpr bool value = type::value;
    6260                        };
     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
    6398                }
     99
     100
    64101
    65102                template < typename E, typename S, typename T >
    66103                using has_ecs_update = detail::has_update<S, void( E&, T ) >;
    67104
    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;
    79116
    80117                template < typename E, typename S, typename M >
     
    120157                        };
    121158
    122                         template< typename Component > 
     159                        template< typename Component >
    123160                        class component_enumerator : public iterator< input_iterator_tag, Component >
    124161                        {
     
    157194                                {
    158195                                        if ( !m_interface ) return;
    159                                         do {
     196                                        do
     197                                        {
    160198                                                m_handle = m_ecs.next( m_handle );
    161199                                                m_component = (Component*)m_interface->get_raw( m_handle );
     
    168206                        };
    169207
     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
    170275                        template< typename System >
    171276                        void register_system( string_view name, System* c )
    172277                        {
    173278                                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{} );
    175281                        }
    176282
     
    183289                                m_component_map_by_name[name] = c;
    184290                                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;
    193300                        }
    194301
     
    217324                        ~ecs()
    218325                        {
    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();
    222329
    223330                        }
     
    249356                                        enumerator( *this, first_child( h ) ),
    250357                                        enumerator( *this )
    251                                 );
     358                                        );
    252359                        }
    253360
     
    325432                        template < typename Component >
    326433                        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 >()] );
    330437                        }
    331438
    332439                        template < typename Component >
    333440                        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                        }
    340445
    341446                        template < typename System, typename Components, template <class...> class List, typename... Messages >
    342447                        void register_component_messages( System* h, List<Messages...>&& )
    343448                        {
    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 )... };
    346451                                int unused_2[] = { ( register_ecs_message<System,Messages>( h ), 0 )... };
    347452                        }
    348453
    349                         template < typename System, typename Components, typename Message >
    350                         typename enable_if< has_component_message< System, Components, Message >::value, void >::type
    351                         register_component_message( System* s )
    352                         {
    353                                 component_interface* ci = get_interface<Components>();
     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>();
    354459                                register_callback( Message::message_id, [=] ( const message& msg )
    355460                                {
    356461                                        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                                        };
    357467                                        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 ) )
    360485                                                {
    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 ) );
    365493                                        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 >::type
    373                         register_ecs_component_message( System* s )
    374                         {
    375                                 component_interface* ci = get_interface<Components>();
    376                                 register_callback( Message::message_id, [=] ( const message& msg )
    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                                {
    378506                                        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                                        };
    379512                                        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 ) )
    382531                                                {
    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 );
    387539                                        else
    388                                         if ( void* c = ci->get_raw( m.entity ) )
    389                                                 s->on( m, *this, *((Components*)(c)) );
    390                                 } );
     540                                                callback( m.entity );
     541                                } );
    391542
    392543                        }
     
    395546                        register_ecs_message( System* s )
    396547                        {
    397                                 register_callback( Message::message_id, [=] ( const message& msg )
    398                                 {
     548                                register_callback( Message::message_id, [=] ( const message& msg )
     549                                {
    399550                                        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 >::type
    406                         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 >::type
    410                         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...>&& ) {}
    411562
    412563                        template < typename System, typename Message >
     
    415566
    416567                        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&& )
    419569                        {
    420570                                register_update( [=] ( time_type dtime )
     
    424574                        }
    425575
    426                         template < typename System, typename Components >
    427                         typename enable_if< has_component_update< System, Components, time_type >::value, void >::type
    428                         register_component_update( System* s )
    429                         {
    430                                 component_interface* ci = get_interface<Components>();
    431                                 component_storage_handler<Components>* 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() );
    432582                                register_update( [=] ( time_type dtime )
    433583                                {
     
    437587                        }
    438588
    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() );
    445613                                register_update( [=] ( time_type dtime )
    446614                                {
     
    451619
    452620
     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
    453641                        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...>&& ) {}
    464651
    465652                        void register_update( update_handler&& handler )
     
    476663                        vector< update_handler >                    m_update_handlers;
    477664
    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;
    481668                };
    482669
Note: See TracChangeset for help on using the changeset viewer.