Index: trunk/nv/core/resource.hh
===================================================================
--- trunk/nv/core/resource.hh	(revision 474)
+++ trunk/nv/core/resource.hh	(revision 474)
@@ -0,0 +1,210 @@
+// Copyright (C) 2015-2015 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 terminal.hh
+* @author Kornel Kisielewicz epyon@chaosforge.org
+* @brief resource interface
+*/
+
+#ifndef NV_CORE_RESOURCE_HH
+#define NV_CORE_RESOURCE_HH
+
+#include <nv/common.hh>
+#include <nv/stl/string.hh>
+#include <nv/stl/hash_store.hh>
+
+
+namespace nv
+{
+
+	template < typename T > class resource;
+	template < typename T > class resource_handle;
+	template < typename T > class resource_lock;
+	using resource_id = shash64;
+	using resource_type_id = shash64;
+
+	class resource_handler
+	{
+
+	protected:
+		virtual const void* lock( resource_id id, resource_type_id type_hash ) = 0;
+//		virtual const void* create( resource_id id, resource_type_id type_hash ) = 0;
+		virtual void unlock( resource_id id, resource_type_id type_hash ) = 0;
+		virtual void release( resource_id id, resource_type_id type_hash ) = 0;
+
+		template< typename T >
+		const T* lock( resource_id id )
+		{
+			return reinterpret_cast< const T* >( lock( id, shash64( rtti_type_hash<T>::hash() ) ) );
+		}
+		template< typename T >
+		resource< T > create( resource_id id )
+		{
+			resource< T > result;
+			result.m_id = id;
+			result.m_handler = this;
+			return result;
+		}
+
+// 		template< typename T >
+// 		resource< T > create( resource_id id )
+// 		{
+// 			return reinterpret_cast<const T*>( create( id, rtti_type_hash<T>::hash() ) );
+// 		}
+
+		template < typename T >
+		friend class resource;
+		template < typename T >
+		friend class resource_handle;
+		template < typename T >
+		friend class resource_lock;
+		//		friend class resource_manager;
+	};
+
+
+	template < typename T >
+	class resource 
+	{
+	public:
+		resource() : m_id(0), m_handler( nullptr ) {}
+		bool is_valid() const { return m_id.valid() && m_handler != nullptr;  }
+		~resource()
+		{
+			if ( m_handler ) m_handler->release( m_id, shash64( rtti_type_hash<T>::hash() ) );
+		}
+	protected:
+		resource_id       m_id;
+		resource_handler* m_handler;
+
+		template < typename U >
+		friend constexpr bool operator==( const resource< U >&, const resource< U >& );
+		template < typename U >
+		friend constexpr bool operator<( const resource< U >&, const resource< U >& );
+		template < typename U >
+		friend constexpr bool operator>( const resource< U >&, const resource< U >& );
+
+		friend class resource_lock< T >;
+		friend class resource_handler;
+	};
+
+	template < typename T >
+	constexpr bool operator== ( const resource< T >& lhs, const resource< T >& rhs )
+	{
+		return lhs.m_id == lhs.m_id && rhs.m_handler == rhs.m_handler;
+	}
+
+	template < typename T >
+	constexpr bool operator< ( const resource< T >& lhs, const resource< T >& rhs )
+	{
+		return lhs.m_id.value() < lhs.m_id.value();
+	}
+
+	template < typename T >
+	constexpr bool operator> ( const resource< T >& lhs, const resource< T >& rhs )
+	{
+		return lhs.m_id.value() > lhs.m_id.value();
+	}
+
+	template < typename T >
+	class resource_handle
+	{
+	public:
+
+		void release( resource_handler* r )
+		{
+			r->release( m_id );
+			m_id = 0;
+		}
+		~resource_handle()
+		{
+			NV_ASSERT( m_id == 0, "Resource not released!" );
+		}
+	protected:
+		resource_id       m_id;
+
+		friend class resource_lock< T >;
+		friend class resource_handler;
+	};
+
+	template < typename T >
+	class resource_lock
+	{
+		static const uint64 hash_value = rtti_type_hash<T>::value;
+	public:
+		explicit resource_lock( const resource< T >& r ) : m_id( r.m_id ), m_handler( r.m_handler ), m_resource( r.m_handler->lock<T>( r.m_id ) ) {}
+		explicit resource_lock( const resource_handle< T >& r, resource_handler* handler ) : m_id( r.m_id ), m_handler( handler ), m_resource( handler->lock( r.m_id, shash64( hash_value ) ) ) {}
+		const T& operator*() const { return *m_resource; }
+		const T* operator->() const { return m_resource; }
+		~resource_lock()
+		{
+			m_handler->unlock( m_id, shash64( hash_value ) );
+		}
+	private:
+		resource_id       m_id;
+		resource_handler* m_handler;
+		const T*          m_resource;
+	};
+
+
+// 	class resource_manager : public resource_handler
+// 	{
+// 	public:
+// 		template < typename T >
+// 		shash64 register_resource_handler( resource_handler* handler )
+// 		{
+// 			return register_resource_handler( handler, rtti_type_hash<T>::hash() );
+// 		}
+// 
+// 		~resource_manager()
+// 		{
+// 			for ( auto p : m_handlers )
+// 			{
+// 				delete p.second;
+// 			}
+// 		}
+// 	protected:
+// 		virtual const void* lock( resource_id id, resource_type_id type_hash )
+// 		{
+// 			auto handler = m_handlers.find( type_hash );
+// 			NV_ASSERT( handler != m_handlers.end(), "Handler not registered!" );
+// 			return handler->second->lock( id, type_hash );
+// 		}
+// 
+// 		virtual const void* create( resource_id id, resource_type_id type_hash )
+// 		{
+// 			auto handler = m_handlers.find( type_hash );
+// 			NV_ASSERT( handler != m_handlers.end(), "Handler not registered!" );
+// 			return handler->second->create( id, type_hash );
+// 		}
+// 
+// 		virtual void unlock( resource_id id, resource_type_id type_hash )
+// 		{
+// 			auto handler = m_handlers.find( type_hash );
+// 			NV_ASSERT( handler != m_handlers.end(), "Handler not registered!" );
+// 			handler->second->unlock( id, type_hash );
+// 		}
+// 
+// 		virtual void release( resource_id id, resource_type_id type_hash )
+// 		{
+// 			auto handler = m_handlers.find( type_hash );
+// 			NV_ASSERT( handler != m_handlers.end(), "Handler not registered!" );
+// 			handler->second->release( id, type_hash );
+// 		}
+// 
+// 		resource_type_id register_resource_handler( resource_handler* handler, resource_type_id type_hash )
+// 		{
+// 			NV_ASSERT( m_handlers.find( type_hash ) == m_handlers.end(), "Handler already registered!" );
+// 			m_handlers[type_hash] = handler;
+// 		}
+// 
+// 	protected:
+// 		hash_store< resource_type_id, resource_handler* > m_handlers;
+// 	};
+}
+
+#endif // NV_CORE_RESOURCE_HH
+
Index: trunk/nv/engine/program_manager.hh
===================================================================
--- trunk/nv/engine/program_manager.hh	(revision 473)
+++ trunk/nv/engine/program_manager.hh	(revision 474)
@@ -27,7 +27,7 @@
 		virtual string_view get_resource_name() const { return "program"; }
 	protected:
-		virtual resource_id load_resource( lua::table_guard& table );
+		virtual res_id load_resource( lua::table_guard& table );
 		string_buffer load_source( lua::table_guard& table, const string_view& append );
-		virtual void release( program p );
+		virtual void release( program* p );
 	private:
 		context* m_context;
Index: trunk/nv/engine/resource_system.hh
===================================================================
--- trunk/nv/engine/resource_system.hh	(revision 473)
+++ trunk/nv/engine/resource_system.hh	(revision 474)
@@ -16,4 +16,5 @@
 #include <nv/common.hh>
 #include <nv/interface/context.hh>
+#include <nv/core/resource.hh>
 #include <nv/lua/lua_state.hh>
 #include <nv/stl/hash_store.hh>
@@ -23,10 +24,10 @@
 {
 
-	typedef uint32 resource_id;
-	typedef uint32 resource_type_id;
+	typedef uint32 res_id;
+	typedef uint32 res_type_id;
 
 	class resource_system;
 
-	class resource_manager_base
+	class resource_manager_base : public resource_handler
 	{
 	public:	
@@ -37,11 +38,15 @@
 		virtual void clear() { m_names.clear(); }
 		void load_all();
-		resource_id load_resource( const string_view& id );
+		res_id load_resource( const string_view& id );
 		virtual ~resource_manager_base() {}
 	protected:
-		virtual resource_id load_resource( lua::table_guard& table ) = 0;
+		virtual res_id load_resource( lua::table_guard& table ) = 0;
+
+//		virtual const void* lock( resource_id id, resource_type_id );
+		virtual void unlock( resource_id, resource_type_id ) {};
+		virtual void release( resource_id, resource_type_id ) {};
 
 		lua::state* m_lua;
-		hash_store< shash64, resource_id > m_names;
+		hash_store< shash64, res_id > m_names;
 	};
 
@@ -50,10 +55,10 @@
 	{
 	public:
-		resource_manager() { m_data.push_back(T()); }
-		T get_resource( resource_id id )
+		resource_manager() { m_data.push_back(nullptr); }
+		T* get_resource( res_id id )
 		{
-			return ( id < m_data.size() ? m_data[ id ] : T() );
+			return ( id < m_data.size() ? m_data[ id ] : nullptr );
 		}
-		T get_resource( const string_view& id )
+		T* get_resource( const string_view& id )
 		{
 			auto m = m_names.find( id );
@@ -64,4 +69,21 @@
 			return get_resource( load_resource( id ) );
 		}
+		resource< T > get( const string_view& id )
+		{
+			auto m = m_names.find( id );
+			if ( m != m_names.end() )
+			{
+				return create< T >( id );
+			}
+			else
+			{
+				if ( get_resource( id ) != nullptr )
+				{
+					return create< T >( id );
+				}
+			}
+//			NV_ASSERT( false, "resource_manager.get failed!" );
+			return resource<T>();
+		}
 		virtual void clear()
 		{
@@ -70,6 +92,7 @@
 				release( m_data[i] );
 			m_data.clear();
-			m_data.push_back( T() );
+			m_data.push_back( nullptr );
 		}
+
 		virtual ~resource_manager() 
 		{
@@ -77,7 +100,17 @@
 		}
 	protected:
-		virtual void release( T ) {}
+		virtual const void* lock( resource_id id, resource_type_id )
+		{
+			auto m = m_names.find( id );
+			if ( m != m_names.end() )
+			{
+				return m_data[m->second];
+			}
+			return nullptr;
+		}
 
-		resource_id add( T resource )
+		virtual void release( T* ) {}
+
+		res_id add( T* resource )
 		{
 			m_data.push_back( resource );
@@ -85,22 +118,7 @@
 		}
 
-		vector< T > m_data;
+		vector< T* > m_data;
 	};
-
-
-	class resource_system
-	{
-	public:
-		explicit resource_system() : m_lua_state( nullptr ) { m_managers.push_back(nullptr); }
-		resource_type_id register_resource_type( const string_view& name, resource_manager_base* manager );
-		resource_type_id get_resource_type_id( const string_view& name ) const;
-		void initialize( lua::state* a_lua_state );
-		virtual ~resource_system();
-	protected:
-		vector< resource_manager_base* >     m_managers;
-		hash_store< shash64, resource_id > m_manager_names;
-		lua::state* m_lua_state; 
-	};
-
+	
 }
 
Index: trunk/src/engine/program_manager.cc
===================================================================
--- trunk/src/engine/program_manager.cc	(revision 473)
+++ trunk/src/engine/program_manager.cc	(revision 474)
@@ -16,5 +16,5 @@
 }
 
-nv::resource_id nv::program_manager::load_resource( lua::table_guard& table )
+nv::res_id nv::program_manager::load_resource( lua::table_guard& table )
 {
 	NV_LOG_DEBUG( table.get_string("id") );
@@ -36,11 +36,12 @@
 	}
 
-	nv::program program = m_context->get_device()->create_program( vsource, fsource );
+	nv::program* program = new nv::program( m_context->get_device()->create_program( vsource, fsource ) );
 	return add( program );
 }
 
-void nv::program_manager::release( program p )
+void nv::program_manager::release( program* p )
 {
-	m_context->get_device()->release( p );
+	m_context->get_device()->release( *p );
+	delete p;
 }
 
Index: trunk/src/engine/resource_system.cc
===================================================================
--- trunk/src/engine/resource_system.cc	(revision 473)
+++ trunk/src/engine/resource_system.cc	(revision 474)
@@ -16,8 +16,8 @@
 }
 
-nv::resource_id nv::resource_manager_base::load_resource( const string_view& id )
+nv::res_id nv::resource_manager_base::load_resource( const string_view& id )
 {
 	lua::table_guard table( m_lua, lua::path( get_storage_name(), id ) );
-	resource_id rid = load_resource( table );
+	res_id rid = load_resource( table );
 	if ( rid != 0 ) m_names[ id ] = rid;
 	return rid;
@@ -32,26 +32,6 @@
 	{
 		lua::table_guard sub_table( table, i+1 );
-		resource_id rid = load_resource( sub_table );
+		res_id rid = load_resource( sub_table );
 		if ( rid != 0 ) m_names[ sub_table.get_string_hash_64("id") ] = rid;
 	}
 }
-
-nv::resource_type_id nv::resource_system::register_resource_type( const string_view& /*name*/, resource_manager_base* /*manager*/ )
-{
-	return 0;
-}
-
-nv::resource_type_id nv::resource_system::get_resource_type_id( const string_view& /*name*/ ) const
-{
-	return 0;
-}
-
-void nv::resource_system::initialize( lua::state* /*a_lua_state*/ )
-{
-
-}
-
-nv::resource_system::~resource_system()
-{
-
-}
