Index: trunk/nv/ecs/ecs.hh
===================================================================
--- trunk/nv/ecs/ecs.hh	(revision 497)
+++ trunk/nv/ecs/ecs.hh	(revision 497)
@@ -0,0 +1,238 @@
+// Copyright (C) 2016-2016 ChaosForge Ltd
+// http://chaosforge.org/
+//
+// This file is part of Nova libraries. 
+// For conditions of distribution and use, see copying.txt file in root folder.
+
+/**
+* @file ecs.hh
+* @author Kornel Kisielewicz epyon@chaosforge.org
+* @brief Data-driven Entity Component System
+*/
+
+#ifndef NV_ECS_HH
+#define NV_ECS_HH
+
+#include <nv/common.hh>
+#include <nv/stl/string.hh>
+#include <nv/stl/handle.hh>
+
+namespace nv
+{
+
+	namespace ecs
+	{
+
+		template <
+			typename Handle = handle<>,
+			typename Index = sint32
+		>
+		class index_table
+		{
+		public:
+			typedef Handle              handle_type;
+			typedef Index               index_type;
+
+			index_table() {}
+			index_table( uint32 reserve )
+			{
+				m_indexes.reserve( reserve );
+			}
+
+			index_type insert( handle_type h )
+			{
+				NV_ASSERT( !exists( h ), "Reinserting handle!" );
+				resize_indexes_to( index_type( h.index() ) );
+				index_type lindex = m_handles.size();
+				m_indexes[h.index()] = index_type( lindex );
+				m_handles.push_back( h );
+				return lindex;
+			}
+
+			bool exists( handle_type h ) const
+			{
+				if ( h.is_nil() || h.index() >= m_indexes.size() ) return false;
+				return m_indexes[h.index()] >= 0;
+			}
+
+			index_type get( handle_type h ) const
+			{
+				if ( h.is_nil() || h.index() >= m_indexes.size() ) return -1;
+				return m_indexes[h.index()];
+			}
+
+			index_type remove_swap( handle_type h )
+			{
+				if ( h.is_nil() || h.index() >= m_indexes.size() || m_indexes[h.index()] == -1 )
+					return -1;
+				handle_type swap_handle = m_handles.back();
+				index_type  dead_eindex = m_indexes[h.index()];
+				if ( dead_eindex != static_cast<index_type>( m_handles.size() - 1 ) )
+				{
+					m_handles[unsigned( dead_eindex )] = swap_handle;
+					m_indexes[swap_handle.index()] = dead_eindex;
+				}
+				m_handles.pop_back();
+				m_indexes[h.index()] = -1;
+				return dead_eindex;
+			}
+
+			void clear()
+			{
+				m_handles.clear();
+				m_indexes.clear();
+			}
+
+			handle_type get_handle( index_type i ) const { return m_handles[unsigned( i )]; }
+
+			size_t size() const { return m_handles.size(); }
+
+		private:
+			void resize_indexes_to( index_type i )
+			{
+				index_type size = index_type( m_indexes.size() );
+				if ( i >= size )
+				{
+					if ( size == 0 ) size = 1;
+					while ( i >= size ) size = size * 2;
+					m_indexes.resize( static_cast<size_t>( size ), -1 );
+				}
+			}
+
+			vector< handle_type > m_handles;
+			vector< index_type >  m_indexes;
+		};
+	
+		template < typename HANDLE = handle<> >
+		class ecs
+		{
+		public:
+			typedef HANDLE handle_type;
+
+			template < typename COMPONENT, typename MANAGER >
+			void register_component( string_view /*name*/, MANAGER* /*manager*/ )
+			{
+
+			}
+
+			handle_type create_handle()
+			{
+				return m_handles.create_handle();
+			}
+
+			void free_handle( handle_type h )
+			{
+				m_handles.free_handle( h );
+			}
+
+			bool exists( handle_type h ) const
+			{
+				return m_handles.is_valid( h );
+			}
+
+		protected:
+			handle_manager< handle_type > m_handles;
+		};
+
+		template < typename ECS, typename COMPONENT >
+		class component
+		{
+		public:
+			typedef ECS                                    ecs_type;
+			typedef typename ecs_type::handle_type         handle_type;
+			typedef index_table< handle_type >             index_table_type;
+			typedef COMPONENT                              value_type;
+			typedef COMPONENT                              component_type;
+			typedef vector< value_type >                   storage_type;
+			typedef typename index_table_type::index_type  index_type;
+
+			typedef typename storage_type::iterator        iterator;
+			typedef typename storage_type::const_iterator  const_iterator;
+			typedef typename storage_type::reference       reference;
+			typedef typename storage_type::const_reference const_reference;
+
+			component( ecs_type& a_ecs, string_view a_name, uint32 reserve = 0 ) : m_ecs( a_ecs )
+			{
+				m_ecs.register_component<component_type>( a_name, this );
+				if ( reserve != 0 )
+				{
+					m_data.reserve( reserve );
+				}
+			}
+
+			value_type& insert( handle_type h )
+			{
+				/*index_type i = */m_index.insert( h );
+				//NV_ASSERT( i == m_data.size(), "Fail!" );
+				m_data.emplace_back();
+				return m_data.back();
+			}
+
+			bool exists( handle_type h )
+			{
+				return m_index.exists( h );
+			}
+
+			void clear()
+			{
+				m_index.clear();
+				m_data.clear();
+			}
+			
+			value_type* get( handle_type h )
+			{
+				index_type i = m_index.get( h );
+				return i >= 0 ? &( m_data[unsigned( i )] ) : nullptr;
+			}
+
+			const value_type* get( handle_type h ) const
+			{
+				index_type i = m_index.get( h );
+				return i >= 0 ? &( m_data[unsigned( i )] ) : nullptr;
+			}
+
+			void remove( handle_type h )
+			{
+				index_type dead_eindex = m_index.remove_swap( h );
+				if ( dead_eindex == -1 ) return;
+				if ( dead_eindex != static_cast<index_type>( m_data.size() - 1 ) )
+				{
+					m_data[unsigned( dead_eindex )] = move( m_data.back() );
+				}
+				m_data.pop_back();
+			}
+
+			handle_type get_handle( index_type i ) const { return m_index.get_handle( i ); }
+
+			const value_type& operator[] ( index_type i ) const { return m_data[i]; }
+			value_type& operator[] ( index_type i ) { return m_data[i]; }
+
+			size_t size() const { return m_data.size(); }
+
+			iterator        begin() { return m_data.begin(); }
+			const_iterator  begin()  const { return m_data.cbegin(); }
+			const_iterator  cbegin() const { return m_data.cbegin(); }
+
+			iterator        end() { return m_data.end(); }
+			const_iterator  end()  const { return m_data.cend(); }
+			const_iterator  cend() const { return m_data.cend(); }
+		protected:
+			ecs_type&        m_ecs;
+			index_table_type m_index;
+			storage_type     m_data;
+		};
+
+		template < typename COMPONENTS >
+		class system
+		{
+
+		};
+
+	}
+
+
+
+
+}
+
+#endif // NV_ECS_HH
Index: trunk/nv/stl/handle.hh
===================================================================
--- trunk/nv/stl/handle.hh	(revision 496)
+++ trunk/nv/stl/handle.hh	(revision 497)
@@ -327,5 +327,4 @@
 		{
 			m_data.reserve( reserve );
-			m_indexes.reserve( reserve );
 		}
 
