Index: trunk/nv/ecs/ecs.hh
===================================================================
--- trunk/nv/ecs/ecs.hh	(revision 547)
+++ trunk/nv/ecs/ecs.hh	(revision 548)
@@ -55,26 +55,63 @@
 				template<typename>
 				static constexpr nv::false_type check( ... );
-
+			public:
 				typedef decltype( check<C>( 0 ) ) type;
-
-			public:
 				static constexpr bool value = type::value;
 			};
+
+			template < typename S, typename T, typename Cs >
+			struct has_ct_update_helper;
+
+			template < typename S, typename T, typename... Cs >
+			struct has_ct_update_helper< S, T, mpl::list< Cs... > >
+			{
+				using type = detail::has_update<S, void( Cs&..., T ) >;
+			};
+
+			template < typename S, typename E, typename T, typename Cs >
+			struct has_ect_update_helper;
+
+			template < typename S, typename E, typename T, typename... Cs >
+			struct has_ect_update_helper< S, E, T, mpl::list< Cs... > >
+			{
+				using type = detail::has_update<S, void( E&, Cs&..., T ) >;
+			};
+
+			template < typename S, typename E, typename M, typename Cs >
+			struct has_ec_message_helper;
+
+			template < typename S, typename E, typename M, typename... Cs >
+			struct has_ec_message_helper< S, E, M, mpl::list< Cs... > >
+			{
+				using type = detail::has_message<S, void( const M&, E&, Cs&... ) >;
+			};
+
+			template < typename S, typename M, typename Cs >
+			struct has_c_message_helper;
+
+			template < typename S, typename M, typename... Cs >
+			struct has_c_message_helper< S, M, mpl::list< Cs... > >
+			{
+				using type = detail::has_message<S, void( const M&, Cs&... ) >;
+			};
+
 		}
+
+
 
 		template < typename E, typename S, typename T >
 		using has_ecs_update = detail::has_update<S, void( E&, T ) >;
 
-		template < typename S, typename C, typename T >
-		using has_component_update = detail::has_update<S, void( C&, T ) >;
-
-		template < typename E, typename S, typename C, typename T >
-		using has_ecs_component_update = detail::has_update<S, void( E&, C&, T ) >;
-
-		template < typename S, typename C, typename M >
-		using has_component_message = detail::has_message<S, void( const M&, C& ) >;
-
-		template < typename E, typename S, typename C, typename M >
-		using has_ecs_component_message = detail::has_message<S, void( const M&, E&, C& ) >;
+		template < typename S, typename Cs, typename T >
+		using has_component_update = typename detail::has_ct_update_helper<S, T, Cs >::type;
+
+		template < typename E, typename S, typename Cs, typename T >
+		using has_ecs_component_update = typename detail::has_ect_update_helper<S, E, T, Cs >::type;
+
+		template < typename S, typename Cs, typename M >
+		using has_component_message = typename detail::has_c_message_helper<S, M, Cs >::type;
+
+		template < typename E, typename S, typename Cs, typename M >
+		using has_ecs_component_message = typename detail::has_ec_message_helper<S, E, M, Cs >::type;
 
 		template < typename E, typename S, typename M >
@@ -120,5 +157,5 @@
 			};
 
-			template< typename Component > 
+			template< typename Component >
 			class component_enumerator : public iterator< input_iterator_tag, Component >
 			{
@@ -157,5 +194,6 @@
 				{
 					if ( !m_interface ) return;
-					do {
+					do
+					{
 						m_handle = m_ecs.next( m_handle );
 						m_component = (Component*)m_interface->get_raw( m_handle );
@@ -168,9 +206,77 @@
 			};
 
+			template < typename Component >
+			handle_type handle_cast( const Component& c )
+			{
+				return *reinterpret_cast<const handle_type*>( &c );
+			}
+
+			template < typename... Components >
+			struct gather_components
+			{
+				static constexpr uint32 SIZE = sizeof...( Components );
+				component_interface* cis[SIZE];
+				void* cmps[SIZE];
+
+				gather_components( this_type& ecs )
+				{
+					fill< 0, Components... >( ecs );
+				}
+
+				bool run( handle_type h )
+				{
+					for ( uint32 i = 0; i < SIZE; ++i )
+					{
+						cmps[i] = cis[i]->get_raw( h );
+						if ( !cmps[i] ) return false;
+					}
+					return true;
+				}
+
+				template < typename SC >
+				SC& get()
+				{
+					return run_get< 0, SC, Components...>();
+				}
+
+			private:
+				template < int Index, typename C, typename... Components >
+				void fill( this_type& ecs )
+				{
+					cis[Index] = ecs.get_interface< C >();
+					NV_ASSERT( cis[Index], "What the fuck is this?" );
+					fill< Index + 1, Components... >( ecs );
+				}
+
+				template < int Index >
+				void fill( this_type& ) {}
+
+				template < int Index, typename SC, typename C, typename... Components >
+				C& run_get()
+				{
+					return get_impl< Index, SC, C, Components... >( nv::is_same< SC, C >{} );
+				}
+
+				template < int Index, typename SC, typename C, typename C2, typename... Components >
+				C& get_impl( false_type&& )
+				{
+					return get_impl< Index + 1, SC, C2, Components...>( nv::is_same< SC, C >() );
+				}
+
+				template < int Index, typename SC, typename C, typename... Components >
+				C& get_impl( true_type&& )
+				{
+					return *(C*)cmps[Index];
+				}
+
+			};
+
+
 			template< typename System >
 			void register_system( string_view name, System* c )
 			{
 				register_handler< System >( name, (System*)( c ) );
-				register_ecs_update< System >( (System*)( c ) );
+				register_ecs_update< System >( (System*)( c ),
+					has_ecs_update< this_type, System, time_type >::type{} );
 			}
 
@@ -183,12 +289,13 @@
 				m_component_map_by_name[name] = c;
 				register_handler< Handler >( name, (Handler*)c );
-				register_component_messages< Handler, Component >( (Handler*)( c ), message_list{} );
-				register_ecs_component_update< Handler, Component >( (Handler*)( c ) );
-				register_component_update< Handler, Component >( (Handler*)( c ) );
-				register_ecs_update< Handler >( (Handler*)( c ) );
-//				auto s = c->storage();
-// 				m_cstorage.push_back( s );
-// 				m_cmap[thash64::create<Component>()] = s;
-// 				m_cmap_by_name[name] = s;
+				register_component_messages< Handler, mpl::list< Component > >( (Handler*)( c ), message_list{} );
+				register_ecs_component_update< Handler >( (Handler*)( c ), mpl::list< Component >{} );
+				register_component_update< Handler >( (Handler*)( c ), mpl::list< Component >{} );
+				register_ecs_update< Handler >( (Handler*)( c ), 
+					has_ecs_update< this_type, Handler, time_type >::type{} );
+				//				auto s = c->storage();
+				// 				m_cstorage.push_back( s );
+				// 				m_cmap[thash64::create<Component>()] = s;
+				// 				m_cmap_by_name[name] = s;
 			}
 
@@ -217,7 +324,7 @@
 			~ecs()
 			{
-// 				for ( auto cs : m_component_storage )
-// 					delete cs;
-//				m_cstorage.clear();
+				// 				for ( auto cs : m_component_storage )
+				// 					delete cs;
+				//				m_cstorage.clear();
 
 			}
@@ -249,5 +356,5 @@
 					enumerator( *this, first_child( h ) ),
 					enumerator( *this )
-				);
+					);
 			}
 
@@ -325,68 +432,112 @@
 			template < typename Component >
 			typename component_storage_handler< Component >*
-			get_storage()
-			{
-				return storage_cast< Component >( m_cmap[thash64::create< Component >()] );
+				get_storage()
+			{
+				return storage_cast<Component>( m_cmap[thash64::create< Component >()] );
 			}
 
 			template < typename Component >
 			const typename component_storage_handler< Component >*
-			get_storage() const
-			{
-				return storage_cast< Component >( m_cmap[thash64::create< Component >()] );
-			}
-
-//		protected:
+				get_storage() const
+			{
+				return storage_cast<Component>( m_cmap[thash64::create< Component >()] );
+			}
 
 			template < typename System, typename Components, template <class...> class List, typename... Messages >
 			void register_component_messages( System* h, List<Messages...>&& )
 			{
-				int unused_0[] = { ( register_ecs_component_message<System,Components,Messages>( h ), 0 )... };
-				int unused_1[] = { ( register_component_message<System,Components,Messages>( h ), 0 )... };
+				int unused_0[] = { ( register_ecs_component_message<System,Messages>( h, Components{} ), 0 )... };
+				int unused_1[] = { ( register_component_message<System,Messages>( h, Components{} ), 0 )... };
 				int unused_2[] = { ( register_ecs_message<System,Messages>( h ), 0 )... };
 			}
 
-			template < typename System, typename Components, typename Message >
-			typename enable_if< has_component_message< System, Components, Message >::value, void >::type
-			register_component_message( System* s )
-			{
-				component_interface* ci = get_interface<Components>();
+			template < typename System, typename Message, typename C >
+			typename enable_if< has_component_message< System, mpl::list< C >, Message >::value, void >::type
+				register_component_message( System* s, mpl::list< C >&& )
+			{
+				component_interface* ci = get_interface<C>();
 				register_callback( Message::message_id, [=] ( const message& msg )
 				{
 					const Message& m = message_cast<Message>( msg );
+					auto callback = [=] ( handle_type h )
+					{
+						if ( void* c = ci->get_raw( h ) )
+							s->on( m, *( (C*)( c ) ) );
+					};
 					if ( msg.recursive )
-					{
-						this->recursive_call( m.entity, [=] ( handle_type h )
+						this->recursive_call( m.entity, nv::move( callback ) );
+					else
+						callback( m.entity );
+				} );
+			}
+
+			template < typename System, typename Message, typename C, typename... Cs >
+			typename enable_if< has_component_message< System, mpl::list< C, Cs...>, Message >::value, void >::type
+			register_component_message( System* s, mpl::list< C, Cs...>&& )
+			{
+				component_interface* ci = get_interface<C>();
+				register_callback( Message::message_id, [=] ( const message& msg )
+				{
+					const Message& m = message_cast<Message>( msg );
+					auto callback = [=] ( handle_type h )
+					{
+						if ( void* c = ci->get_raw( h ) )
 						{
-							if ( void* c = ci->get_raw( h ) )
-								s->on( m, *( (Components*)( c ) ) );
-						} );
-					}
+							gather_components< Cs... > gather( *this );
+							if ( gather.run( h ) )
+								s->on( m, *( (C*)( c ) ), gather.get<Cs>()... );
+						}
+					};
+					if ( msg.recursive )
+						this->recursive_call( m.entity, nv::move( callback ) );
 					else
-						if ( void* c = ci->get_raw( m.entity ) )
-							s->on( m, *( (Components*)( c ) ) );
-				} );
-			}
-
-			template < typename System, typename Components, typename Message >
-			typename enable_if< has_ecs_component_message< this_type, System, Components, Message >::value, void >::type
-			register_ecs_component_message( System* s )
-			{
-				component_interface* ci = get_interface<Components>();
- 				register_callback( Message::message_id, [=] ( const message& msg )
- 				{
+						callback( m.entity );
+	
+				} );
+			}
+
+			template < typename System, typename Message, typename C >
+			typename enable_if< has_ecs_component_message< this_type, System, mpl::list< C >, Message >::value, void >::type
+				register_ecs_component_message( System* s, mpl::list< C >&& )
+			{
+				component_interface* ci = get_interface<C>();
+				register_callback( Message::message_id, [=] ( const message& msg )
+				{
 					const Message& m = message_cast<Message>( msg );
+					auto callback = [=] ( handle_type h )
+					{
+						if ( void* c = ci->get_raw( h ) )
+							s->on( m, *this, *( (C*)( c ) ) );
+					};
 					if ( msg.recursive )
-					{
-						this->recursive_call( m.entity, [=] ( handle_type h )
+						this->recursive_call( m.entity, nv::move( callback ) );
+					else
+						callback( m.entity );
+				} );
+
+			}
+
+			template < typename System, typename Message, typename C, typename... Cs >
+			typename enable_if< has_ecs_component_message< this_type, System, mpl::list< C, Cs...>, Message >::value, void >::type
+			register_ecs_component_message( System* s, mpl::list< C, Cs...>&& )
+			{
+				component_interface* ci = get_interface<C>();
+				register_callback( Message::message_id, [=] ( const message& msg )
+				{
+					const Message& m = message_cast<Message>( msg );
+					auto callback = [=] ( handle_type h )
+					{
+						if ( void* c = ci->get_raw( h ) )
 						{
-							if ( void* c = ci->get_raw( h ) )
-								s->on( m, *this, *( (Components*)( c ) ) );
-						} );
-					}
+							gather_components< Cs... > gather( *this );
+							if ( gather.run( h ) )
+								s->on( m, *this, *( (C*)( c ) ), gather.get<Cs>()... );
+						}
+					};
+					if ( msg.recursive )
+						this->recursive_call( m.entity, callback );
 					else
-					if ( void* c = ci->get_raw( m.entity ) )
-						s->on( m, *this, *((Components*)(c)) );
- 				} );
+						callback( m.entity );
+				} );
 
 			}
@@ -395,18 +546,18 @@
 			register_ecs_message( System* s )
 			{
- 				register_callback( Message::message_id, [=] ( const message& msg )
- 				{
+				register_callback( Message::message_id, [=] ( const message& msg )
+				{
 					s->on( message_cast<Message>( msg ), *this );
- 				} );
-
-			}
-
-			template < typename System, typename Components, typename Message >
-			typename enable_if< !has_component_message< System, Components, Message >::value, void >::type
-			register_component_message( System* ) {}
-
-			template < typename System, typename Components, typename Message >
-			typename enable_if< !has_ecs_component_message< this_type, System, Components, Message >::value, void >::type
-			register_ecs_component_message( System* ) {}
+				} );
+
+			}
+
+			template < typename System, typename Message, typename... Cs >
+			typename enable_if< !has_component_message< System, mpl::list< Cs...>, Message >::value, void >::type
+			register_component_message( System*, mpl::list< Cs...>&& ) {}
+
+			template < typename System, typename Message, typename... Cs >
+			typename enable_if< !has_ecs_component_message< this_type, System, mpl::list< Cs...>, Message >::value, void >::type
+			register_ecs_component_message( System*, mpl::list< Cs...>&& ) {}
 
 			template < typename System, typename Message >
@@ -415,6 +566,5 @@
 
 			template < typename System >
-			typename enable_if< has_ecs_update< this_type, System, time_type >::value, void >::type
-			register_ecs_update( System* s )
+			void register_ecs_update( System* s, true_type&& )
 			{
 				register_update( [=] ( time_type dtime )
@@ -424,10 +574,10 @@
 			}
 
-			template < typename System, typename Components >
-			typename enable_if< has_component_update< System, Components, time_type >::value, void >::type
-			register_component_update( System* s )
-			{
-				component_interface* ci = get_interface<Components>();
-				component_storage_handler<Components>* storage = storage_cast<Components>( ci->storage() );
+			template < typename System, typename C >
+			typename enable_if< has_component_update< System, mpl::list< C >, time_type >::value, void >::type
+			register_component_update( System* s, mpl::list< C >&& )
+			{
+				component_interface* ci = get_interface<C>();
+				component_storage_handler<C>* storage = storage_cast<C>( ci->storage() );
 				register_update( [=] ( time_type dtime )
 				{
@@ -437,10 +587,28 @@
 			}
 
-			template < typename System, typename Components >
-			typename enable_if< has_ecs_component_update< this_type, System, Components, time_type >::value, void >::type
-			register_ecs_component_update( System* s )
-			{
-				component_interface* ci = get_interface<Components>();
-				component_storage_handler<Components>* storage = storage_cast<Components>( ci->storage() );
+			template < typename System, typename C, typename... Cs >
+			typename enable_if< has_component_update< System, mpl::list< C, Cs...>, time_type >::value, void >::type
+			register_component_update( System* s, mpl::list< C, Cs...>&& )
+			{
+				component_interface* ci = get_interface<C>();
+				component_storage_handler<C>* storage = storage_cast<C>( ci->storage() );
+				register_update( [=] ( time_type dtime )
+				{
+					gather_components< Cs... > gather( *this );
+					for ( auto& c : *storage )
+					{
+						handle_type h = handle_cast( c );
+						if ( gather.run( h ) )
+							s->update( c, gather.get<Cs>()..., dtime );
+					}
+				} );
+			}
+
+			template < typename System, typename C >
+			typename enable_if< has_ecs_component_update< this_type, System, mpl::list< C >, time_type >::value, void >::type
+			register_ecs_component_update( System* s, mpl::list< C >&& )
+			{
+				component_interface* ci = get_interface<C>();
+				component_storage_handler<C>* storage = storage_cast<C>( ci->storage() );
 				register_update( [=] ( time_type dtime )
 				{
@@ -451,15 +619,34 @@
 
 
+
+			template < typename System, typename C, typename... Cs >
+			typename enable_if< has_ecs_component_update< this_type, System, mpl::list< C, Cs...>, time_type >::value, void >::type
+				register_ecs_component_update( System* s, mpl::list< C, Cs...>&& )
+			{
+				component_interface* ci = get_interface<C>();
+				component_storage_handler<C>* storage = storage_cast<C>( ci->storage() );
+				register_update( [=] ( time_type dtime )
+				{
+					gather_components< Cs... > gather(*this);
+					for ( auto& c : *storage )
+					{
+						handle_type h = handle_cast( c );
+						if ( gather.run( h ) )
+							s->update( *this, c, gather.get<Cs>()..., dtime );
+					}
+				} );
+			}
+
+
 			template < typename System >
-			typename enable_if< !has_ecs_update< this_type, System, time_type >::value, void >::type
-			register_ecs_update( System* ) {}
-
-			template < typename System, typename Components >
-			typename enable_if< !has_component_message< System, Components, time_type >::value, void >::type
-			register_component_update( System* ) {}
-
-			template < typename System, typename Components >
-			typename enable_if< !has_ecs_component_update< this_type, System, Components, time_type >::value, void >::type
-			register_ecs_component_update( System* ) {}
+			void register_ecs_update( System*, false_type&& ) {}
+
+			template < typename System, typename... Cs >
+			typename enable_if< !has_component_update< System, mpl::list< Cs...>, time_type >::value, void >::type
+				register_component_update( System*, mpl::list< Cs...>&& ) {}
+
+			template < typename System, typename... Cs >
+			typename enable_if< !has_ecs_component_update< this_type, System, mpl::list< Cs...>, time_type >::value, void >::type
+				register_ecs_component_update( System*, mpl::list< Cs...>&& ) {}
 
 			void register_update( update_handler&& handler )
@@ -476,7 +663,7 @@
 			vector< update_handler >                    m_update_handlers;
 
-// 			vector< component_storage* >                m_cstorage;
-// 			hash_store< thash64, component_storage* >   m_cmap;
-// 			hash_store< shash64, component_storage* >   m_cmap_by_name;
+			// 			vector< component_storage* >                m_cstorage;
+			// 			hash_store< thash64, component_storage* >   m_cmap;
+			// 			hash_store< shash64, component_storage* >   m_cmap_by_name;
 		};
 
