Index: /trunk/nv/ecs/ecs.hh
===================================================================
--- /trunk/nv/ecs/ecs.hh	(revision 540)
+++ /trunk/nv/ecs/ecs.hh	(revision 541)
@@ -1,3 +1,3 @@
-// Copyright (C) 2016-2016 ChaosForge Ltd
+// Copyright (C) 2016-2017 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -22,4 +22,5 @@
 #include <nv/stl/range.hh>
 #include <nv/core/types.hh>
+#include <nv/ecs/message_queue.hh>
 
 namespace nv
@@ -35,35 +36,13 @@
 
 		template < typename Handle, typename Time = f32 >
-		class ecs
+		class ecs : public message_queue< Handle, Time >
 		{
 		public:
-			typedef Time   time_type;
-			typedef Handle handle_type;
-
-			typedef uint32 message_type;
-
-			struct message
-			{
-				message_type type;
-				handle_type  entity;
-				time_type    time;
-				uint8        payload[128 - sizeof( uint32 ) - sizeof( handle_type ) - sizeof( time_type )];
-			};
-
-			struct message_compare_type
-			{
-				bool operator()( const message& l, const message& r )
-				{
-					return l.time > r.time;
-				}
-			};
-
-			class receiver_interface
-			{
-			public:
-				virtual void update( time_type dtime ) = 0;
-				virtual bool handle_message( const message& ) = 0;
-				virtual void clear() = 0;
-			};
+			typedef message_queue< Handle, Time > base_class;
+			using base_class::time_type;
+			using base_class::handle_type;
+			using base_class::message_type;
+			using base_class::message;
+			using base_class::receiver_interface;
 
 			class component_interface : public receiver_interface
@@ -96,17 +75,4 @@
 			};
 
-			template < typename Payload >
-			static const Payload& message_cast( const message& m )
-			{
-				static_assert( sizeof( Payload ) < sizeof( message::payload ), "Payload size over limit!" );
-				NV_ASSERT( Payload::message_id == m.type, "Payload cast fail!" );
-				return *reinterpret_cast<const Payload*>( &( m.payload ) );
-			}
-
-			void register_receiver( string_view /*name*/, receiver_interface* c )
-			{
-				m_receivers.push_back( c );
-			}
-
 			template < typename Component >
 			void register_component( string_view name, component_interface* c )
@@ -118,85 +84,7 @@
 			}
 
-			bool dispatch( const message& m )
-			{
-				for ( auto c : m_receivers )
-					c->handle_message( m );
-				return true;
-			}
-
-			template < typename Payload, typename ...Args >
-			bool dispatch( handle_type h, Args&&... args )
-			{
-				message m{ Payload::message_id, h, time_type(0) };
-				new( &m.payload ) Payload{ nv::forward<Args>( args )... };
-				return dispatch( m );
-			}
-
-			bool queue( const message& m )
-			{
-				m_pqueue.push( m );
-				return true;
-			}
-
-			template < typename Payload, typename ...Args >
-			bool queue( handle_type h, time_type delay, Args&&... args )
-			{
-				message m{ Payload::message_id, h, m_time + delay };
-				new( &m.payload ) Payload{ nv::forward<Args>( args )... };
-				return queue( m );
-			}
-
 			handle_type create()
 			{
 				return m_handles.create_handle();
-			}
-
-			void update( time_type dtime )
-			{
-				if ( dtime == time_type(0) ) return;
-				m_time += dtime;
-				while ( !m_pqueue.empty() && m_pqueue.top().time <= m_time )
-				{
-					message msg = m_pqueue.top();
-					m_pqueue.pop();
-					dispatch( msg );
-				}
-
-				for ( auto c : m_receivers )
-					c->update( dtime );
-			}
-
-			time_type update_step()
-			{
-				time_type before = m_time;
-				if ( !m_pqueue.empty() )
-				{
-					message msg = m_pqueue.top();
-					m_time = msg.time;
-					m_pqueue.pop();
-					dispatch( msg );
-					if ( before != m_time )
-						for ( auto c : m_receivers )
-							c->update( m_time - before );
-				}
-				return m_time;
-			}
-
-			time_type get_time() const { return m_time; }
-
-			bool events_pending() const
-			{
-				return !m_pqueue.empty();
-			}
-
-			const message& top_event() const
-			{
-				return m_pqueue.top();
-			}
-
-			void reset_events()
-			{
-				m_pqueue.clear();
-				m_time = time_type(0);
 			}
 
@@ -284,39 +172,6 @@
 			handle_tree_manager< handle_type >          m_handles;
 			vector< component_interface* >              m_components;
-			vector< receiver_interface* >               m_receivers;
 			hash_store< thash64, component_interface* > m_component_map;
 			hash_store< shash64, component_interface* > m_component_map_by_name;
-			time_type                                   m_time = time_type(0);
-			priority_queue< message, vector< message >, message_compare_type > m_pqueue;
-		};
-
-		template < typename Ecs >
-		class receiver : public Ecs::receiver_interface
-		{
-		public:
-			typedef Ecs                                    ecs_type;
-			typedef typename ecs_type::message             message_type;
-			typedef typename ecs_type::handle_type         handle_type;
-			typedef typename ecs_type::time_type           time_type;
-
-			receiver( ecs_type& a_ecs, string_view a_name ) : m_ecs( a_ecs )
-			{
-				m_ecs.register_receiver( a_name, this );
-			}
-			virtual void update( time_type /*dtime*/ )
-			{
-				// no-op
-			}
-
-			virtual void clear()
-			{
-				// no-op
-			}
-			virtual bool handle_message( const message_type& )
-			{
-				return false;
-			}
-		protected:
-			ecs_type&        m_ecs;
 		};
 
Index: /trunk/nv/ecs/message_queue.hh
===================================================================
--- /trunk/nv/ecs/message_queue.hh	(revision 541)
+++ /trunk/nv/ecs/message_queue.hh	(revision 541)
@@ -0,0 +1,194 @@
+// Copyright (C) 2016-2017 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 message_queue.hh
+* @author Kornel Kisielewicz epyon@chaosforge.org
+* @brief Data-driven Entity Component System
+*/
+
+#ifndef NV_ECS_MESSAGE_QUEUE_HH
+#define NV_ECS_MESSAGE_QUEUE_HH
+
+#include <nv/common.hh>
+#include <nv/stl/string.hh>
+#include <nv/stl/handle.hh>
+#include <nv/stl/priority_queue.hh>
+#include <nv/core/types.hh>
+
+namespace nv
+{
+
+	namespace ecs
+	{
+
+		template < typename Payload, typename Message >
+		static const Payload& message_cast( const Message& m )
+		{
+			static_assert( sizeof( Payload ) < sizeof( Message::payload ), "Payload size over limit!" );
+			NV_ASSERT( Payload::message_id == m.type, "Payload cast fail!" );
+			return *reinterpret_cast<const Payload*>( &( m.payload ) );
+		}
+
+
+		template < typename Handle, typename Time = f32 >
+		class message_queue
+		{
+		public:
+			typedef Time   time_type;
+			typedef Handle handle_type;
+			typedef uint32 message_type;
+
+			struct message
+			{
+				message_type type;
+				handle_type  entity;
+				time_type    time;
+				uint8        payload[128 - sizeof( uint32 ) - sizeof( handle_type ) - sizeof( time_type )];
+			};
+
+			struct message_compare_type
+			{
+				bool operator()( const message& l, const message& r )
+				{
+					return l.time > r.time;
+				}
+			};
+
+			typedef priority_queue< message, vector< message >, message_compare_type > queue_type;
+
+			class receiver_interface
+			{
+			public:
+				virtual void update( time_type dtime ) = 0;
+				virtual bool handle_message( const message& ) = 0;
+				virtual void clear() = 0;
+			};
+
+			void register_receiver( string_view /*name*/, receiver_interface* c )
+			{
+				m_receivers.push_back( c );
+			}
+
+			bool dispatch( const message& m )
+			{
+				for ( auto c : m_receivers )
+					c->handle_message( m );
+				return true;
+			}
+
+			template < typename Payload, typename ...Args >
+			bool dispatch( handle_type h, Args&&... args )
+			{
+				message m{ Payload::message_id, h, time_type( 0 ) };
+				new( &m.payload ) Payload{ nv::forward<Args>( args )... };
+				return dispatch( m );
+			}
+
+			bool queue( const message& m )
+			{
+				m_pqueue.push( m );
+				return true;
+			}
+
+			template < typename Payload, typename ...Args >
+			bool queue( handle_type h, time_type delay, Args&&... args )
+			{
+				message m{ Payload::message_id, h, m_time + delay };
+				new( &m.payload ) Payload{ nv::forward<Args>( args )... };
+				return queue( m );
+			}
+
+			time_type get_time() const { return m_time; }
+
+			bool events_pending() const
+			{
+				return !m_pqueue.empty();
+			}
+
+			const message& top_event() const
+			{
+				return m_pqueue.top();
+			}
+
+			void reset_events()
+			{
+				m_pqueue.clear();
+				m_time = time_type( 0 );
+			}
+
+			void update( time_type dtime )
+			{
+				if ( dtime == time_type( 0 ) ) return;
+				m_time += dtime;
+				while ( !m_pqueue.empty() && m_pqueue.top().time <= m_time )
+				{
+					message msg = m_pqueue.top();
+					m_pqueue.pop();
+					dispatch( msg );
+				}
+
+				for ( auto c : m_receivers )
+					c->update( dtime );
+			}
+
+			time_type update_step()
+			{
+				time_type before = m_time;
+				if ( !m_pqueue.empty() )
+				{
+					message msg = m_pqueue.top();
+					m_time = msg.time;
+					m_pqueue.pop();
+					dispatch( msg );
+					if ( before != m_time )
+						for ( auto c : m_receivers )
+							c->update( m_time - before );
+				}
+				return m_time;
+			}
+
+		protected:
+			time_type                     m_time = time_type( 0 );
+			queue_type                    m_pqueue;
+			vector< receiver_interface* > m_receivers;
+		};
+
+		template < typename Ecs >
+		class receiver : public Ecs::receiver_interface
+		{
+		public:
+			typedef Ecs                                    ecs_type;
+			typedef typename ecs_type::message             message_type;
+			typedef typename ecs_type::handle_type         handle_type;
+			typedef typename ecs_type::time_type           time_type;
+
+			receiver( ecs_type& a_ecs, string_view a_name ) : m_ecs( a_ecs )
+			{
+				m_ecs.register_receiver( a_name, this );
+			}
+			virtual void update( time_type /*dtime*/ )
+			{
+				// no-op
+			}
+
+			virtual void clear()
+			{
+				// no-op
+			}
+			virtual bool handle_message( const message_type& )
+			{
+				return false;
+			}
+		protected:
+			ecs_type&        m_ecs;
+		};
+
+	}
+
+}
+
+#endif // NV_ECS_MESSAGE_QUEUE_HH
Index: /trunk/src/lua/lua_proxy.cc
===================================================================
--- /trunk/src/lua/lua_proxy.cc	(revision 540)
+++ /trunk/src/lua/lua_proxy.cc	(revision 541)
@@ -96,5 +96,5 @@
 
 nv::lua::temporary_proxy::temporary_proxy( state* state )
-	: stack_proxy( state, -1 )
+	: stack_proxy( state, lua_gettop( *state ) )
 {
 
Index: /trunk/src/lua/lua_state.cc
===================================================================
--- /trunk/src/lua/lua_state.cc	(revision 540)
+++ /trunk/src/lua/lua_state.cc	(revision 541)
@@ -153,5 +153,5 @@
 		// TODO : error handling
 	}
-	m_index = -1;
+	m_index = nlua_absindex( m_state, -1 );
 }
 
@@ -166,10 +166,10 @@
 		// TODO : error handling
 	}
-	m_index = -1;
+	m_index = nlua_absindex( m_state, -1 );
 }
 
 lua::table_guard::~table_guard()
 {
-	if ( m_index == -1 )
+	if ( m_level != lua_gettop( m_state ) )
 		lua_settop( m_state, m_level );
 }
@@ -184,5 +184,5 @@
 {
 	m_level = lua_gettop( m_state );
-	m_index = proxy.m_index;
+	m_index = nlua_absindex( m_state, proxy.m_index );
 }
 
