Index: trunk/src/core/io_event.cc
===================================================================
--- trunk/src/core/io_event.cc	(revision 319)
+++ trunk/src/core/io_event.cc	(revision 319)
@@ -0,0 +1,139 @@
+// Copyright (C) 2012-2014 ChaosForge Ltd
+// http://chaosforge.org/
+//
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
+#include "nv/core/io_event.hh"
+
+using namespace nv;
+
+const char* nv::get_key_name( key_code key )
+{
+	switch ( key )
+	{
+#	define NV_KEY( id, val ) case id : return #id;
+#		include <nv/detail/key_list.inc>
+#	undef NV_KEY
+	NV_RETURN_COVERED_DEFAULT( "KEY_UNKNOWN" );
+	};
+}
+
+const char* nv::get_mouse_name( mouse_code button )
+{
+	switch ( button )
+	{
+#	define NV_MOUSE( id, val ) case id : return #id;
+#		include <nv/detail/mouse_list.inc>
+#	undef NV_MOUSE
+	NV_RETURN_COVERED_DEFAULT( "MOUSE_UNKNOWN" );
+	};
+}
+
+const char* nv::get_io_event_name( io_event_code event )
+{
+	switch ( event )
+	{
+#	define NV_IO_EVENT( id ) case id : return #id;
+#		include <nv/detail/io_event_list.inc>
+#	undef NV_IO_EVENT
+	NV_RETURN_COVERED_DEFAULT( "EV_UNKNOWN" );
+	};
+}
+
+/************************************************************************
+void nv::register_io_types( type_database* db )
+{
+	type_enum key_enums[] = {
+#	define NV_KEY( id, val ) type_enum( #id, id ),
+#		include <nv/detail/key_list.inc>
+#	undef NV_KEY
+	};
+	db->create_type<key_code>("key_code").enums( key_enums );
+
+	type_enum mouse_enums[] = {
+#	define NV_MOUSE( id, val ) type_enum( #id, id ),
+#		include <nv/detail/mouse_list.inc>
+#	undef NV_MOUSE
+	};
+	db->create_type<mouse_code>("mouse_code").enums( mouse_enums );
+
+	type_enum io_event_enums[] = {
+#	define NV_IO_EVENT( id ) type_enum( #id, id ),
+#		include <nv/detail/io_event_list.inc>
+#	undef NV_IO_EVENT
+	};
+	db->create_type<io_event_code>("event_code").enums( io_event_enums );
+
+	type_field key_fields[] = {
+		type_field( "ascii",   &key_event::ascii ),
+		type_field( "code",    &key_event::code ),
+		type_field( "shift",   &key_event::shift ),
+		type_field( "control", &key_event::control ),
+		type_field( "alt",     &key_event::alt ),
+		type_field( "pressed", &key_event::pressed ),
+	};
+	db->create_type<key_event>("key_event").fields( key_fields );
+
+	type_field mouse_button_fields[] = {
+		type_field( "x",       &mouse_button_event::x ),
+		type_field( "y",       &mouse_button_event::y ),
+		type_field( "button",  &mouse_button_event::button ),
+		type_field( "pressed", &mouse_button_event::pressed ),
+		type_field( "code",    &mouse_button_event::code ),
+	};
+	db->create_type<mouse_button_event>("mouse_button_event").fields( mouse_button_fields );
+
+	type_field mouse_move_fields[] = {
+		type_field( "x",       &mouse_move_event::x ),
+		type_field( "y",       &mouse_move_event::y ),
+		type_field( "rx",      &mouse_move_event::rx ),
+		type_field( "ry",      &mouse_move_event::ry ),
+		type_field( "pressed", &mouse_move_event::pressed ),
+		type_field( "code",    &mouse_move_event::code ),
+	};
+	db->create_type<mouse_move_event>("mouse_move_event").fields( mouse_move_fields );
+
+	type_field mouse_wheel_fields[] = {
+		type_field( "x",       &mouse_wheel_event::x ),
+		type_field( "y",       &mouse_wheel_event::y ),
+	};
+	db->create_type<mouse_wheel_event>("mouse_wheel_event").fields( mouse_wheel_fields );
+
+	type_field joy_button_fields[] = {
+		type_field( "id",      &joy_button_event::id ),
+		type_field( "button",  &joy_button_event::button ),
+		type_field( "pressed", &joy_button_event::pressed ),
+	};
+	db->create_type<joy_button_event>("joy_button_event").fields( joy_button_fields );
+
+	type_field joy_axis_fields[] = {
+		type_field( "id",      &joy_axis_event::id ),
+		type_field( "axis",    &joy_axis_event::axis ),
+		type_field( "value",   &joy_axis_event::value ),
+	};
+	db->create_type<joy_axis_event>("joy_axis_event").fields( joy_axis_fields );
+
+	type_field joy_hat_fields[] = {
+		type_field( "id",      &joy_hat_event::id ),
+		type_field( "hat",     &joy_hat_event::hat ),
+		type_field( "value",   &joy_hat_event::value ),
+	};
+	db->create_type<joy_hat_event>("joy_hat_event").fields( joy_hat_fields );
+
+	type_field joy_ball_fields[] = {
+		type_field( "id",      &joy_ball_event::id ),
+		type_field( "ball",    &joy_ball_event::ball ),
+		type_field( "rx",      &joy_ball_event::rx ),
+		type_field( "ry",      &joy_ball_event::ry ),
+	};
+	db->create_type<joy_ball_event>("joy_ball_event").fields( joy_ball_fields );
+
+	type_field system_fields[] = {
+		type_field( "sys_type", &system_event::sys_type ),
+		type_field( "param1",   &system_event::param1 ),
+		type_field( "param2",   &system_event::param2 ),
+	};
+	db->create_type<system_event>("system_event").fields( system_fields );
+}
+************************************************************************/
Index: trunk/src/core/library.cc
===================================================================
--- trunk/src/core/library.cc	(revision 319)
+++ trunk/src/core/library.cc	(revision 319)
@@ -0,0 +1,147 @@
+// Copyright (C) 2012-2014 ChaosForge Ltd
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+#include "nv/core/common.hh"
+#include "nv/core/library.hh"
+
+#if NV_PLATFORM == NV_WINDOWS
+#   define WIN32_LEAN_AND_MEAN
+#   include <windows.h>
+#   define NV_LIB_EXT ".dll"
+#   define NV_LIB_HANDLE HMODULE
+#   define NV_LIB_OPEN( name ) LoadLibraryEx( name, NULL, LOAD_WITH_ALTERED_SEARCH_PATH )
+#   define NV_LIB_GET( handle, name ) GetProcAddress( handle, name )
+#   define NV_LIB_CLOSE( name ) !FreeLibrary( name )
+#elif NV_PLATFORM == NV_LINUX || NV_PLATFORM == NV_APPLE
+#   include <dlfcn.h>
+#   define NV_LIB_EXT ".so"
+#   define NV_LIB_HANDLE void*
+#   define NV_LIB_OPEN( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL)
+#   define NV_LIB_GET( handle, name ) dlsym( handle, name )
+#   define NV_LIB_CLOSE( name ) dlclose( name )
+#elif NV_PLATFORM == NV_APPLE
+#   include "macUtils.h"
+#   include <dlfcn.h>
+#   define NV_LIB_EXT ".dylib"
+#   define NV_LIB_HANDLE CFBundleRef
+#   define NV_LIB_OPEN( name ) mac_loadExeBundle( name )
+#   define NV_LIB_GET( handle, name ) mac_getBundleSym( handle, name )
+#   define NV_LIB_CLOSE( name ) mac_unloadExeBundle( name )
+#endif
+
+#include "nv/core/logging.hh"
+
+using namespace nv;
+
+library::library() 
+    : m_handle( nullptr ), m_name()
+{
+}
+
+void library::open( const string& name )
+{
+	m_name = name;
+	if ( !open() )
+	{
+		m_handle = nullptr;
+		NV_THROW( library_error, "Can't load library!", name );
+	}
+}
+
+bool nv::library::try_open( const string& name )
+{
+	m_name = name;
+	if ( !open() )
+	{
+		m_handle = nullptr;
+		return false;
+	}
+	return true;
+}
+
+const string& library::get_name() const
+{
+    return m_name;
+}
+
+bool library::open( )
+{
+    if ( m_handle != NULL )
+    {
+        return true;
+    }
+    NV_LOG( LOG_NOTICE, "library : loading '" + m_name + "'..." );
+
+    string name = m_name;
+    string ext  = NV_LIB_EXT;
+    size_t ext_len   = ext.length();
+
+    if ( name.length() < ext_len || name.substr( name.length() - ext_len, ext_len ) != ext ) 
+    {
+        name += ext;
+    }
+
+    m_handle = (void*)NV_LIB_OPEN( name.c_str() );
+
+    if ( m_handle == NULL )
+    {
+		NV_LOG( LOG_NOTICE, "library : '" + name + "' failed to open." );
+		return false;
+    }
+    NV_LOG( LOG_NOTICE, "library : '" + name + "' loaded." );
+	return true;
+}
+
+void* library::get( const string& symbol )
+{
+	void* result = (void*) NV_LIB_GET( (NV_LIB_HANDLE) m_handle, symbol.c_str() );
+    if ( !result )
+    {
+        NV_THROW( library_error, "Can't find symbol " + symbol + "!", m_name );
+    }
+	return result;
+}
+
+void* nv::library::try_get( const string& symbol )
+{
+	return (void*) NV_LIB_GET( (NV_LIB_HANDLE) m_handle, symbol.c_str() );
+}
+
+bool library::is_open() const
+{
+	return m_handle != nullptr;
+}
+
+void library::close()
+{
+    if ( NV_LIB_CLOSE( (NV_LIB_HANDLE)m_handle ) )
+    {
+        NV_LOG( LOG_ERROR, "library : can't close library '" + m_name + "'!" );
+    }
+    m_handle = NULL;
+}
+
+library::~library()
+{
+    if ( m_handle != NULL )
+    {
+        close();
+    }
+}
+
+string library::get_error()
+{
+#if NV_PLATFORM == NV_WINDOWS
+    // We do hate WinAPI for code like this, don't we?
+    LPTSTR buffer = NULL;
+    FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+        NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buffer, 0, NULL );
+    string msg( (char*)buffer );
+    LocalFree( buffer );
+    return msg;
+#elif NV_PLATFORM == NV_LINUX || NV_PLATFORM == NV_APPLE
+    return string(dlerror());
+#else
+    return string("");
+#endif
+}
Index: trunk/src/core/logger.cc
===================================================================
--- trunk/src/core/logger.cc	(revision 319)
+++ trunk/src/core/logger.cc	(revision 319)
@@ -0,0 +1,262 @@
+// Copyright (C) 2011-2014 ChaosForge Ltd
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
+#include "nv/core/logger.hh"
+
+#include "nv/core/common.hh"
+#include <iostream>
+#include <utility>
+#include <algorithm>
+#include <fstream>
+#include <ctime>
+#include <cstdio>
+#include "nv/core/exception.hh"
+#if NV_PLATFORM == NV_WINDOWS
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+#endif
+
+using namespace nv;
+
+// log level names
+static const char *log_level_names[] =
+{
+	"NONE",
+	"FATAL",
+	"CRITICAL",
+	"ERROR",
+	"WARNING",
+	"NOTICE",
+	"INFO",
+	"INFO",
+	"DEBUG",
+	"DEBUG2",
+	"TRACE"
+};
+
+// log level names
+static const char *log_level_names_pad[] =
+{
+	"NONE    ",
+	"FATAL   ",
+	"CRITICAL",
+	"ERROR   ",
+	"WARNING ",
+	"NOTICE  ",
+	"INFO    ",
+	"INFO    ",
+	"DEBUG   ",
+	"DEBUG2  ",
+	"TRACE   "
+};
+
+// helper macro to access log_level_names
+#define NV_LOG_LEVEL_NAME(level) (log_level_names[ (level) / 10 ])
+#define NV_LOG_LEVEL_NAME_PAD(level) (log_level_names_pad[ (level) / 10 ])
+
+#if NV_PLATFORM == NV_WINDOWS 
+static unsigned short log_color[] =
+{
+	FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
+	FOREGROUND_RED | FOREGROUND_INTENSITY,
+	FOREGROUND_RED | FOREGROUND_INTENSITY,
+	FOREGROUND_RED,
+	FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
+	FOREGROUND_GREEN | FOREGROUND_INTENSITY,
+	FOREGROUND_GREEN,
+	FOREGROUND_GREEN,
+	FOREGROUND_INTENSITY,
+	FOREGROUND_INTENSITY,
+	FOREGROUND_INTENSITY
+};
+#else
+static const char *log_color[] =
+{
+	"\33[37;1m",
+	"\33[31;1m",
+	"\33[31;1m",
+	"\33[31m",
+	"\33[33;1m",
+	"\33[32;1m",
+	"\33[32m",
+	"\33[32m",
+	"\33[30;1m",
+	"\33[30;1m",
+	"\33[30;1m"
+};
+#endif
+
+// log function
+void logger::log( log_level level, const std::string& message )
+{
+	// get the iterator to the beginning of the log_sink list
+	log_sink_list::reverse_iterator it = m_log_sinks.rbegin();
+
+	// iterate
+	while ( it != m_log_sinks.rend() )
+	{
+		// if we have a log sink with high enough level...
+		if ( it->first >= level )
+		{
+			// log and iterate
+			it->second->log( level, message );
+		}
+		else 
+		{
+			// otherwise return, the list is sorted by log level
+			return;
+		}
+		++it;
+	}
+}
+
+// add a new sink
+void logger::add_sink( log_sink* sink, int level )
+{
+	// add a sink
+	m_log_sinks.push_back( std::make_pair( log_level(level), sink ) );
+	// and sort the list (default sort of pairs is by first element)
+	m_log_sinks.sort();
+}
+
+// remove existing sink
+bool logger::remove_sink( log_sink* sink )
+{
+	// get the iterator to the beginning of the log_sink list
+	log_sink_list::iterator it = m_log_sinks.begin();
+
+	// iterate
+	while ( it != m_log_sinks.end() )
+	{
+		// found?
+		if ( it->second == sink ) 
+		{
+			// erase and return true to report success
+			m_log_sinks.erase(it);
+			return true;
+		}
+		++it;
+	}
+
+	// not found, return false
+	return false;
+}
+
+// destructor
+logger::~logger()
+{
+	// while we have sinks
+	while ( !m_log_sinks.empty() )
+	{
+		// delete the last one
+		delete m_log_sinks.back().second;
+		// and pop it
+		m_log_sinks.pop_back();
+	}
+}
+
+
+// console logging
+void log_console_sink::log( log_level level, const std::string& message )
+{
+	if (m_color) 
+	{
+#if NV_PLATFORM == NV_WINDOWS 
+		SetConsoleTextAttribute( m_handle, FOREGROUND_INTENSITY );
+		std::cout << timestamp() << " [";
+		SetConsoleTextAttribute( m_handle, log_color[ (level) / 10 ] );
+		std::cout << NV_LOG_LEVEL_NAME_PAD(level);
+		SetConsoleTextAttribute( m_handle, FOREGROUND_INTENSITY );
+		std::cout << "] ";
+		SetConsoleTextAttribute( m_handle, FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE );
+		std::cout << message << std::endl;
+#else
+		std::cout << "\33[30;1m" << timestamp() << " [" << log_color[ (level) / 10 ] << NV_LOG_LEVEL_NAME_PAD(level) << "\33[30;1m] \33[37;1m" << message << std::endl;
+#endif
+	}
+	else
+	{
+	std::cout << timestamp() << " [" << NV_LOG_LEVEL_NAME_PAD(level) << "] " << message << std::endl;
+	}
+}
+
+// stream logging
+void log_stream_sink::log( log_level level, const std::string& message )
+{
+	// if flushing is enabled
+	if ( m_flush )
+	{
+		// write and flush using std::endl
+		*m_stream << timestamp() << " [" << NV_LOG_LEVEL_NAME(level) << "] " << message << std::endl;
+	}
+	else
+	{
+		// write and end with "\n" (no flush)
+		*m_stream << timestamp() << " [" << NV_LOG_LEVEL_NAME(level) << "] " << message << "\n";
+	}
+}
+
+// file logging
+log_file_sink::log_file_sink( const std::string file_name, bool flush_always /*= true */ )
+	: log_stream_sink( nullptr, flush_always )
+{
+	// create the stream manually
+	std::ofstream* fstream = new std::ofstream( file_name );
+
+	// check if it's open
+	if ( !fstream->is_open() )
+	{
+		// throw if not open
+		NV_THROW( runtime_error, "Could not open file \""+file_name+"\" for logging!" );
+	}
+
+	m_stream = fstream;
+}
+
+// file logger destructor
+log_file_sink::~log_file_sink()
+{
+	// close the file
+	dynamic_cast< std::ofstream* >(m_stream)->close();
+	// dispose of the stream
+	delete m_stream;
+}
+
+nv::log_console_sink::log_console_sink( bool coloring )
+	: m_color( coloring )
+{
+#if NV_PLATFORM == NV_WINDOWS 
+	m_handle = GetStdHandle( STD_OUTPUT_HANDLE );
+#else
+  NV_UNUSED( m_handle );
+#endif
+}
+
+const char* nv::log_sink::timestamp() const
+{
+	std::clock_t time = std::clock();
+	unsigned int secs = (unsigned int)(time / CLOCKS_PER_SEC);
+	unsigned int mm   = (unsigned int)(time*100 / CLOCKS_PER_SEC) % 100;
+	unsigned int h    = (unsigned int)(secs / (60*60));
+	unsigned int m    = (unsigned int)(secs / 60) % 60;
+	unsigned int s    = secs % 60;
+	static char buffer[128];
+#if NV_PLATFORM == NV_WINDOWS 
+	sprintf_s( buffer, 128, "%02d:%02d:%02d.%02d", h, m, s, mm );
+#else
+	sprintf( buffer, "%02d:%02d:%02d.%02d", h, m, s, mm );
+#endif
+	buffer[11] = '\0';
+	return buffer;
+}
+
+const char* nv::log_sink::level_name( log_level level ) const
+{
+	return NV_LOG_LEVEL_NAME( level );
+}
+
+const char* nv::log_sink::padded_level_name( log_level level ) const
+{
+	return NV_LOG_LEVEL_NAME_PAD( level );
+}
Index: trunk/src/core/profiler.cc
===================================================================
--- trunk/src/core/profiler.cc	(revision 319)
+++ trunk/src/core/profiler.cc	(revision 319)
@@ -0,0 +1,133 @@
+// Copyright (C) 2012-2014 ChaosForge Ltd
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
+#include "nv/core/profiler.hh"
+
+#include <iomanip>
+#include <ios>
+#include "nv/core/time.hh"
+
+using namespace nv;
+
+
+profiler::profiler()
+{
+	m_root = new node( "root", nullptr );
+	m_root->start();
+	m_current = m_root;
+}
+
+profiler::~profiler()
+{
+	delete m_root;
+}
+
+void profiler::start_profile( const char* tag )
+{
+	if ( tag != m_current->m_tag )
+	{
+		m_current = m_current->request_child( tag );
+	}
+	m_current->start();
+}
+
+void profiler::stop_profile()
+{
+	if ( m_current->stop() )
+	{
+		m_current = m_current->get_parent();
+	}
+}
+
+profiler::node::node( const char* tag, node* parent ) 
+	: m_tag( tag )
+	, m_parent( parent )
+	, m_recusion( 0 )
+	, m_calls( 0 )
+	, m_start_time_us( 0 )
+	, m_total_time_us( 0 )
+{
+
+}
+
+profiler::node* profiler::node::request_child( const char* tag )
+{
+	auto it = m_children.find( tag );
+	if ( it != m_children.end() ) 
+		return it->second;
+	else
+	{
+		node* result = new node( tag, this );
+		m_children[ tag ] = result;
+		return result;
+	}
+}
+
+void profiler::node::start()
+{
+	m_calls++;
+	m_recusion++;
+	if ( m_recusion == 1 )
+	{
+		m_start_time_us = get_system_us();
+	}
+}
+
+bool profiler::node::stop()
+{
+	m_recusion--;
+	if ( m_recusion == 0 )
+	{
+		uint64 stop_time_us = get_system_us();
+		uint64 elapsed_us   = stop_time_us - m_start_time_us;
+		m_total_time_us     += elapsed_us;
+		return true;
+	}
+	return false;
+}
+
+
+nv::profiler::node::~node()
+{
+	for ( const auto& pair : m_children )
+	{
+		delete pair.second;
+	}
+}
+
+
+void profiler::log_report()
+{
+	m_root->stop();
+	NV_LOG( LOG_INFO, "-- PROFILER REPORT -----------------------------------------" );
+	NV_LOG( LOG_INFO, std::left << std::setw(24) << "TAG" 
+		<< std::setw(7) << "%PARNT" 
+		<< std::setw(7) << "CALLS" 
+		<< std::setw(10) << "TOTAL(ms)" 
+		<< std::setw(10) << "AVG(ms)" );
+	log_node_children( "", m_root );
+	NV_LOG( LOG_INFO, "-- PROFILER REPORT END -------------------------------------" );
+	m_root->start();
+}
+
+void profiler::log_node_children( const std::string& ind, const node* n )
+{
+	for ( const auto& pair : n->m_children )
+	{
+		const node* c = pair.second;
+		if ( c->m_calls > 0 )
+		{
+			NV_LOG( LOG_INFO, std::left << std::setw(24) << ind + c->m_tag 
+				<< std::setw(7) << std::setprecision(2) << std::fixed << ( (double)c->m_total_time_us / (double)c->m_parent->m_total_time_us ) * 100.0
+				<< std::setw(7) << c->m_calls 
+				<< std::setw(10) << std::setprecision(2) << std::fixed << c->m_total_time_us / 1000.f
+				<< std::setw(10) << std::setprecision(2) << std::fixed << ( (double)c->m_total_time_us / (double)c->m_calls ) / 1000.f
+				);
+			if ( c->m_children.size() > 0 )
+			{
+				log_node_children( ind + "-", c );
+			}
+		}
+	}
+}
Index: trunk/src/core/random.cc
===================================================================
--- trunk/src/core/random.cc	(revision 319)
+++ trunk/src/core/random.cc	(revision 319)
@@ -0,0 +1,276 @@
+// Copyright (C) 2012-2014 ChaosForge Ltd
+// http://chaosforge.org/
+//
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
+#include "nv/core/random.hh"
+#include "nv/core/time.hh"
+
+using namespace nv;
+
+random::random( random::seed_type seed /*= 0 */ )
+	: rng( seed == 0 ? randomized_seed() : seed )
+{
+	
+}
+
+random::seed_type random::randomize()
+{
+	seed_type seed = randomized_seed();
+	rng.seed( seed );
+	return seed;
+}
+
+void random::set_seed( random::seed_type seed /*= 0 */ )
+{
+	rng.seed( seed == 0 ? randomized_seed() : seed );
+}
+
+nv::random& random::get()
+{
+	static random default_rng;
+	return default_rng;
+}
+
+random::result_type random::rand()
+{
+	return rng();
+}
+
+sint32 random::srand( sint32 val )
+{
+	std::uniform_int_distribution<sint32> dist( 0, val - 1 );
+	return dist( rng );
+}
+
+uint32 random::urand( uint32 val )
+{
+	std::uniform_int_distribution<uint32> dist( 0, val - 1 );
+	return dist( rng );
+}
+
+f32 random::frand( f32 val )
+{
+	std::uniform_real_distribution<f32> dist( 0, val );
+	return dist( rng );
+}
+
+sint32 random::srange( sint32 min, sint32 max )
+{
+	std::uniform_int_distribution<sint32> dist( min, max );
+	return dist( rng );
+}
+
+uint32 random::urange( uint32 min, uint32 max )
+{
+	std::uniform_int_distribution<uint32> dist( min, max );
+	return dist( rng );
+}
+
+f32 random::frange( f32 min, f32 max )
+{
+	std::uniform_real_distribution<f32> dist( min, max );
+	return dist( rng );
+}
+
+uint32 random::dice( uint32 count, uint32 sides )
+{
+	std::uniform_int_distribution<uint32> dist( 1, sides );
+	uint32 result = 0;
+	while (count-- > 0)
+	{
+		result += dist( rng );
+	};
+	return result;
+}
+
+random::seed_type random::randomized_seed()
+{
+	return narrow_cast< seed_type >( get_ticks() );
+}
+
+nv::vec2 nv::random::precise_unit_vec2()
+{
+	std::uniform_real_distribution<f32> dist( 0, glm::pi<float>() * 2.f );
+	float angle = dist( rng );
+	return vec2( glm::cos( angle ), glm::sin( angle ) );
+}
+
+nv::vec3 nv::random::precise_unit_vec3()
+{
+	std::uniform_real_distribution<f32> dist11( -1.0f, 1.0f );
+	std::uniform_real_distribution<f32> dist02pi( 0.0f, 2*glm::pi<float>() );
+	float cos_theta = dist11( rng );
+	float sin_theta = glm::sqrt( 1.0f - cos_theta * cos_theta );
+	float phi       = dist02pi( rng );
+	return vec3( 
+		sin_theta * glm::sin(phi),
+		sin_theta * glm::cos(phi),
+		cos_theta
+		);
+}
+
+nv::vec2 nv::random::fast_disk_point()
+{
+	std::uniform_real_distribution<f32> dist( 0.0f, 1.0f );
+	float r1 = dist( rng );
+	float r2 = dist( rng );
+	if ( r1 > r2 ) std::swap( r1, r2 );
+	float rf = 2*glm::pi<float>()*(r1/r2);
+	return vec2( r2*glm::cos( rf ), r2*glm::sin( rf ) );
+}
+
+nv::vec2 nv::random::precise_disk_point()
+{
+	std::uniform_real_distribution<f32> unit( 0.0f, 1.0f );
+	std::uniform_real_distribution<f32> angle( 0.0f, glm::pi<float>() );
+	float r = glm::sqrt( unit( rng ) );
+	float rangle = angle( rng );
+	return vec2( r*glm::cos( rangle ), r*glm::sin( rangle ) );
+}
+
+nv::vec3 nv::random::fast_sphere_point()
+{
+	std::uniform_real_distribution<f32> dist01( 0.0f, 1.0f );
+	std::uniform_real_distribution<f32> dist11( -1.0f, 1.0f );
+	std::uniform_real_distribution<f32> dist02pi( 0.0f, 2*glm::pi<float>() );
+	float rad     = dist01( rng );
+	float pi      = glm::pi<float>();
+	float phi     = glm::asin( dist11( rng ) ) + pi*.5f;
+	float theta   = dist02pi( rng );
+	float sin_phi = glm::sin( phi );
+	return vec3( 
+		rad * glm::cos(theta) * sin_phi,
+		rad * glm::sin(theta) * sin_phi,
+		rad * glm::cos(phi)
+	);
+}
+
+nv::vec3 nv::random::precise_sphere_point()
+{
+	std::uniform_real_distribution<f32> dist01( 0.0f, 1.0f );
+	std::uniform_real_distribution<f32> dist11( -1.0f, 1.0f );
+	std::uniform_real_distribution<f32> dist02pi( 0.0f, 2*glm::pi<float>() );
+	float radius = std::pow( dist01( rng ), 1.f/3.f );
+	float cos_theta = dist11( rng );
+	float sin_theta = glm::sqrt( 1.0f - cos_theta * cos_theta );
+	float phi       = dist02pi( rng );
+	return vec3( 
+		radius * sin_theta * glm::sin(phi),
+		radius * sin_theta * glm::cos(phi),
+		radius * cos_theta
+		);
+}
+
+nv::vec2 nv::random::precise_ellipse_point( const vec2& radii )
+{
+	std::uniform_real_distribution<f32> distx( -radii.x, radii.x );
+	std::uniform_real_distribution<f32> disty( -radii.y, radii.y );
+	vec2 inv_radii  = 1.f / radii;
+	vec2 inv_radii2 = inv_radii * inv_radii;
+	for ( uint32 i = 0; i < 12; ++i )
+	{
+		float x = distx( rng );
+		float y = disty( rng );
+		if ( x * x * inv_radii2.x + y * y * inv_radii2.y <= 1.f )
+		{
+			return vec2( x, y );
+		}
+	}
+	return fast_disk_point() * radii;
+}
+
+nv::vec3 nv::random::precise_ellipsoid_point( const vec3& radii )
+{
+	std::uniform_real_distribution<f32> distx( -radii.x, radii.x );
+	std::uniform_real_distribution<f32> disty( -radii.y, radii.y );
+	std::uniform_real_distribution<f32> distz( -radii.z, radii.z );
+	vec3 inv_radii  = 1.f / radii;
+	vec3 inv_radii2 = inv_radii * inv_radii;
+	for ( uint32 i = 0; i < 12; ++i )
+	{
+		float x = distx( rng );
+		float y = disty( rng );
+		float z = distz( rng );
+		if ( x * x * inv_radii2.x + y * y * inv_radii2.y + z * z * inv_radii2.z <= 1.f )
+		{
+			return vec3( x, y, z );
+		}
+	}
+	return fast_sphere_point() * radii;
+}
+
+nv::vec2 nv::random::fast_hollow_disk_point( float iradius, float oradius )
+{
+	float idist2 = iradius * iradius;
+	float odist2 = oradius * oradius;
+	float rdist  = glm::sqrt( std::uniform_real_distribution<f32>( idist2, odist2 )( rng ) );
+	return rdist * precise_unit_vec2();
+}
+
+nv::vec2 nv::random::precise_hollow_disk_point( float iradius, float oradius )
+{
+	return fast_hollow_disk_point( iradius, oradius );
+}
+
+nv::vec3 nv::random::fast_hollow_sphere_point( float iradius, float oradius )
+{
+	float idist3 = iradius * iradius * iradius;
+	float odist3 = oradius * oradius * oradius;
+	float rdist  = std::pow( std::uniform_real_distribution<f32>( idist3, odist3 )( rng ), 1.f/3.f );
+	return rdist * precise_unit_vec3();
+}
+
+nv::vec3 nv::random::precise_hollow_sphere_point( float iradius, float oradius )
+{
+	return fast_hollow_sphere_point( iradius, oradius );
+}
+
+
+nv::vec2 nv::random::fast_hollow_ellipse_point( const vec2& iradii, const vec2& oradii )
+{
+	vec2 iradii2    = iradii * iradii;
+	vec2 opoint     = ellipse_edge( oradii );
+	vec2 opoint2    = opoint * opoint;
+	vec2 odir       = glm::normalize( opoint );
+	float odist2    = opoint2.x + opoint2.y;
+
+	float low    = iradii2.y * opoint2.x + iradii2.x * opoint2.y;
+	float idist2 = ((iradii2.x * iradii2.y) / low ) * odist2;
+
+	float rdist     = glm::sqrt( std::uniform_real_distribution<f32>( idist2, odist2 )( rng ) );
+	return odir * rdist;	
+}
+
+nv::vec2 nv::random::precise_hollow_ellipse_point( const vec2& iradii, const vec2& oradii )
+{
+	return fast_hollow_ellipse_point( iradii, oradii );
+}
+
+nv::vec3 nv::random::fast_hollow_ellipsoid_point( const vec3& iradii, const vec3& oradii )
+{
+	vec3 iradii2    = iradii * iradii;
+	vec3 opoint     = ellipsoid_edge( oradii );
+	vec3 opoint2    = opoint * opoint;
+	vec3 odir       = glm::normalize( opoint );
+	float odist2    = opoint2.x + opoint2.y + opoint2.z;
+
+	float low    = 
+		iradii2.y * iradii2.z * opoint2.x + 
+		iradii2.x * iradii2.z * opoint2.y +
+		iradii2.x * iradii2.y * opoint2.z;
+	float idist2 = ((iradii2.x * iradii2.y * iradii2.z) / low ) * odist2;
+
+	float odist3 = odist2 * glm::sqrt( odist2 );
+	float idist3 = idist2 * glm::sqrt( idist2 );
+
+	float rdist     = std::pow( std::uniform_real_distribution<f32>( idist3, odist3 )( rng ), 1.f/3.f );
+	return odir * rdist;	
+}
+
+nv::vec3 nv::random::precise_hollow_ellipsoid_point( const vec3& iradii, const vec3& oradii )
+{
+	return fast_hollow_ellipsoid_point( iradii, oradii );
+}
+
Index: trunk/src/core/time.cc
===================================================================
--- trunk/src/core/time.cc	(revision 319)
+++ trunk/src/core/time.cc	(revision 319)
@@ -0,0 +1,100 @@
+// Copyright (C) 2011-2014 ChaosForge Ltd
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
+#include "nv/core/time.hh"
+
+#include "nv/core/logging.hh"
+
+#if NV_COMPILER == NV_MSVC
+#define WIN32_LEAN_AND_MEAN 
+#include <windows.h>
+#include <intrin.h>
+#pragma intrinsic(__rdtsc)
+#else
+#include <unistd.h>
+#include <sys/time.h>
+#endif
+
+#include <ctime>
+
+struct timer_impl
+{
+	timer_impl()
+	{
+		clock_zero = clock();
+#if NV_COMPILER == NV_MSVC
+		QueryPerformanceFrequency(&frequency);
+		QueryPerformanceCounter(&query_zero);
+#else
+		gettimeofday(&timeval_zero, NULL);
+#endif
+	}
+	clock_t clock_zero;
+#if NV_COMPILER == NV_MSVC
+	LARGE_INTEGER query_zero;
+	LARGE_INTEGER frequency;
+#else
+	struct timeval timeval_zero;
+#endif
+};
+
+static timer_impl zero_timer;
+
+nv::uint64 nv::get_ticks()
+{
+#if NV_COMPILER == NV_MSVC
+	return __rdtsc();
+#else
+	register long long ticks asm("eax") = 0;
+	asm volatile (".byte 15, 49" : : : "eax", "edx");
+	return static_cast<nv::uint64>( ticks );
+#endif
+}
+
+void nv::sleep( uint32 ms )
+{
+#if NV_COMPILER == NV_MSVC
+	Sleep( ms );
+#else
+	usleep( ms * 1000 );
+#endif
+}
+
+nv::uint32 nv::get_cpu_ms()
+{
+	return (uint32)( (f32)( clock() - zero_timer.clock_zero ) / ( (f32)CLOCKS_PER_SEC / 1000.0 ) ) ;
+}
+
+nv::uint64 nv::get_cpu_us()
+{
+	return (uint64)( (f32)( clock() - zero_timer.clock_zero ) / ( (f32)CLOCKS_PER_SEC / 1000000.0 ) ) ;
+}
+
+nv::uint32 nv::get_system_ms()
+{
+#if NV_COMPILER == NV_MSVC
+	LARGE_INTEGER now;
+	QueryPerformanceCounter(&now);
+	LONGLONG result = now.QuadPart - zero_timer.query_zero.QuadPart;
+	return (uint32) (1000.0 * result / (double) zero_timer.frequency.QuadPart);
+#else
+	struct timeval now;
+	gettimeofday(&now, NULL);
+	return (uint32)( (now.tv_sec - zero_timer.timeval_zero.tv_sec)*1000+(now.tv_usec-zero_timer.timeval_zero.tv_usec)/1000 );
+#endif
+}
+
+nv::uint64 nv::get_system_us()
+{
+#if NV_COMPILER == NV_MSVC
+	LARGE_INTEGER now;
+	QueryPerformanceCounter(&now);
+	LONGLONG result = now.QuadPart - zero_timer.query_zero.QuadPart;
+	return (uint64) (1000000.0 * result / (double) zero_timer.frequency.QuadPart);
+#else
+	struct timeval now;
+	gettimeofday(&now, NULL);
+	return (uint32)( (now.tv_sec - zero_timer.timeval_zero.tv_sec)*1000000+(now.tv_usec - zero_timer.timeval_zero.tv_usec) );
+#endif
+}
Index: trunk/src/core/uid.cc
===================================================================
--- trunk/src/core/uid.cc	(revision 319)
+++ trunk/src/core/uid.cc	(revision 319)
@@ -0,0 +1,52 @@
+// Copyright (C) 2012-2014 ChaosForge Ltd
+// http://chaosforge.org/
+//
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
+#include "nv/core/uid.hh"
+
+using namespace nv;
+
+uid_store_raw::uid_store_raw()
+	: m_map(), m_current(0)
+{
+	
+}
+
+void* uid_store_raw::get( uid auid ) const
+{
+	map::const_iterator i = m_map.find( auid );
+	if ( i != m_map.end() )
+	{
+		return i->second;
+	}
+	return nullptr;
+}
+
+bool uid_store_raw::remove( uid auid )
+{
+	return m_map.erase( auid ) != 0;
+}
+
+void uid_store_raw::insert( void* o, uid auid )
+{
+	m_map[ auid ] = o;
+}
+
+uid uid_store_raw::insert( void* o )
+{
+	uid u = request_uid();
+	m_map[ u ] = o;
+	return u;
+}
+
+uid uid_store_raw::request_uid()
+{
+	return ++m_current;
+}
+
+uid_store_raw::~uid_store_raw()
+{
+	// no-op
+}
Index: trunk/src/curses/curses_terminal.cc
===================================================================
--- trunk/src/curses/curses_terminal.cc	(revision 318)
+++ trunk/src/curses/curses_terminal.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2013-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -7,5 +7,5 @@
 #include "nv/curses/curses_terminal.hh"
 
-#include "nv/time.hh"
+#include "nv/core/time.hh"
 #include "nv/lib/curses.hh"
 
Index: trunk/src/engine/program_manager.cc
===================================================================
--- trunk/src/engine/program_manager.cc	(revision 318)
+++ trunk/src/engine/program_manager.cc	(revision 319)
@@ -6,5 +6,5 @@
 
 #include "nv/engine/program_manager.hh"
-#include "nv/range.hh"
+#include "nv/core/range.hh"
 #include "nv/lua/lua_nova.hh"
 
Index: trunk/src/engine/resource_system.cc
===================================================================
--- trunk/src/engine/resource_system.cc	(revision 318)
+++ trunk/src/engine/resource_system.cc	(revision 319)
@@ -6,5 +6,5 @@
 
 #include "nv/engine/resource_system.hh"
-#include "nv/range.hh"
+#include "nv/core/range.hh"
 #include "nv/lua/lua_nova.hh"
 
@@ -38,15 +38,15 @@
 }
 
-nv::resource_type_id nv::resource_system::register_resource_type( const string& name, resource_manager_base* manager )
+nv::resource_type_id nv::resource_system::register_resource_type( const string& /*name*/, resource_manager_base* /*manager*/ )
 {
 	return 0;
 }
 
-nv::resource_type_id nv::resource_system::get_resource_type_id( const string& name ) const
+nv::resource_type_id nv::resource_system::get_resource_type_id( const string& /*name*/ ) const
 {
 	return 0;
 }
 
-void nv::resource_system::initialize( lua::state* a_lua_state )
+void nv::resource_system::initialize( lua::state* /*a_lua_state*/ )
 {
 
Index: trunk/src/fmod/fmod_audio.cc
===================================================================
--- trunk/src/fmod/fmod_audio.cc	(revision 318)
+++ trunk/src/fmod/fmod_audio.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -8,5 +8,5 @@
 
 #include "nv/lib/fmod.hh"
-#include "nv/logging.hh"
+#include "nv/core/logging.hh"
 
 using namespace nv;
Index: trunk/src/formats/md2_loader.cc
===================================================================
--- trunk/src/formats/md2_loader.cc	(revision 318)
+++ trunk/src/formats/md2_loader.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -8,5 +8,5 @@
 
 #include <glm/gtc/constants.hpp>
-#include "nv/logging.hh"
+#include "nv/core/logging.hh"
 #include <cstring>
 
Index: trunk/src/formats/md3_loader.cc
===================================================================
--- trunk/src/formats/md3_loader.cc	(revision 318)
+++ trunk/src/formats/md3_loader.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -8,5 +8,5 @@
 
 #include <glm/gtc/constants.hpp>
-#include "nv/logging.hh"
+#include "nv/core/logging.hh"
 #include <cstring>
 
Index: trunk/src/formats/md5_loader.cc
===================================================================
--- trunk/src/formats/md5_loader.cc	(revision 318)
+++ trunk/src/formats/md5_loader.cc	(revision 319)
@@ -1,5 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
-// http://chaosforge.org/
-//
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // This file is part of NV Libraries.
 // For conditions of distribution and use, see copyright notice in nv.hh
@@ -8,5 +6,5 @@
 
 #include <glm/gtc/constants.hpp>
-#include "nv/logging.hh"
+#include "nv/core/logging.hh"
 #include "nv/io/std_stream.hh"
 #include <cstring>
Index: trunk/src/formats/nmd_loader.cc
===================================================================
--- trunk/src/formats/nmd_loader.cc	(revision 318)
+++ trunk/src/formats/nmd_loader.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2014 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -7,5 +7,5 @@
 #include "nv/formats/nmd_loader.hh"
 #include "nv/io/std_stream.hh"
-#include "nv/string.hh"
+#include "nv/core/string.hh"
 
 using namespace nv;
Index: trunk/src/formats/obj_loader.cc
===================================================================
--- trunk/src/formats/obj_loader.cc	(revision 318)
+++ trunk/src/formats/obj_loader.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
Index: trunk/src/gfx/debug_draw.cc
===================================================================
--- trunk/src/gfx/debug_draw.cc	(revision 318)
+++ trunk/src/gfx/debug_draw.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2014 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
Index: trunk/src/gfx/image.cc
===================================================================
--- trunk/src/gfx/image.cc	(revision 318)
+++ trunk/src/gfx/image.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2011 Kornel Kisielewicz
+// Copyright (C) 2011-2014 ChaosForge Ltd
 // This file is part of NV Libraries.
 // For conditions of distribution and use, see copyright notice in nv.hh
Index: trunk/src/gfx/keyframed_mesh.cc
===================================================================
--- trunk/src/gfx/keyframed_mesh.cc	(revision 318)
+++ trunk/src/gfx/keyframed_mesh.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2011 Kornel Kisielewicz
+// Copyright (C) 2011-2014 ChaosForge Ltd
 // This file is part of NV Libraries.
 // For conditions of distribution and use, see copyright notice in nv.hh
@@ -11,5 +11,5 @@
 
 
-#include "nv/logging.hh"
+#include "nv/core/logging.hh"
 
 using namespace nv;
Index: trunk/src/gfx/particle_engine.cc
===================================================================
--- trunk/src/gfx/particle_engine.cc	(revision 318)
+++ trunk/src/gfx/particle_engine.cc	(revision 319)
@@ -1,8 +1,12 @@
+// Copyright (C) 2014 ChaosForge Ltd
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
 #include "nv/gfx/particle_engine.hh"
 
 #include <nv/interface/device.hh>
-#include <nv/random.hh>
+#include <nv/core/random.hh>
 #include <nv/lua/lua_glm.hh>
-#include <nv/logging.hh>
+#include <nv/core/logging.hh>
 #include <cmath>
 
Index: trunk/src/gfx/skeletal_mesh.cc
===================================================================
--- trunk/src/gfx/skeletal_mesh.cc	(revision 318)
+++ trunk/src/gfx/skeletal_mesh.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2011 Kornel Kisielewicz
+// Copyright (C) 2011-2014 ChaosForge Ltd
 // This file is part of NV Libraries.
 // For conditions of distribution and use, see copyright notice in nv.hh
Index: trunk/src/gfx/texture_atlas.cc
===================================================================
--- trunk/src/gfx/texture_atlas.cc	(revision 318)
+++ trunk/src/gfx/texture_atlas.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -7,5 +7,5 @@
 #include "nv/gfx/texture_atlas.hh"
 
-#include "nv/logging.hh"
+#include "nv/core/logging.hh"
 #include <iostream>
 
Index: trunk/src/gfx/texture_font.cc
===================================================================
--- trunk/src/gfx/texture_font.cc	(revision 318)
+++ trunk/src/gfx/texture_font.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
Index: trunk/src/gl/gl_context.cc
===================================================================
--- trunk/src/gl/gl_context.cc	(revision 318)
+++ trunk/src/gl/gl_context.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // This file is part of NV Libraries.
 // For conditions of distribution and use, see copyright notice in nv.hh
Index: trunk/src/gl/gl_device.cc
===================================================================
--- trunk/src/gl/gl_device.cc	(revision 318)
+++ trunk/src/gl/gl_device.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // This file is part of NV Libraries.
 // For conditions of distribution and use, see copyright notice in nv.hh
@@ -6,5 +6,5 @@
 
 #include "nv/gl/gl_window.hh"
-#include "nv/logging.hh"
+#include "nv/core/logging.hh"
 #include "nv/lib/sdl.hh"
 #include "nv/lib/sdl_image.hh"
Index: trunk/src/gl/gl_enum.cc
===================================================================
--- trunk/src/gl/gl_enum.cc	(revision 318)
+++ trunk/src/gl/gl_enum.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // This file is part of NV Libraries.
 // For conditions of distribution and use, see copyright notice in nv.hh
Index: trunk/src/gl/gl_window.cc
===================================================================
--- trunk/src/gl/gl_window.cc	(revision 318)
+++ trunk/src/gl/gl_window.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // This file is part of NV Libraries.
 // For conditions of distribution and use, see copyright notice in nv.hh
@@ -5,5 +5,5 @@
 #include "nv/gl/gl_window.hh"
 
-#include "nv/logging.hh"
+#include "nv/core/logging.hh"
 #include "nv/lib/gl.hh"
 #include "nv/lib/sdl.hh"
Index: trunk/src/gui/gui_environment.cc
===================================================================
--- trunk/src/gui/gui_environment.cc	(revision 318)
+++ trunk/src/gui/gui_environment.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
Index: trunk/src/gui/gui_renderer.cc
===================================================================
--- trunk/src/gui/gui_renderer.cc	(revision 318)
+++ trunk/src/gui/gui_renderer.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
Index: trunk/src/gui/gui_style.cc
===================================================================
--- trunk/src/gui/gui_style.cc	(revision 318)
+++ trunk/src/gui/gui_style.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
Index: trunk/src/io/c_file_system.cc
===================================================================
--- trunk/src/io/c_file_system.cc	(revision 318)
+++ trunk/src/io/c_file_system.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // This file is part of NV Libraries.
 // For conditions of distribution and use, see copyright notice in nv.hh
Index: trunk/src/io/c_stream.cc
===================================================================
--- trunk/src/io/c_stream.cc	(revision 318)
+++ trunk/src/io/c_stream.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // This file is part of NV Libraries.
 // For conditions of distribution and use, see copyright notice in nv.hh
Index: trunk/src/io/std_stream.cc
===================================================================
--- trunk/src/io/std_stream.cc	(revision 318)
+++ trunk/src/io/std_stream.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
Index: trunk/src/io_event.cc
===================================================================
--- trunk/src/io_event.cc	(revision 318)
+++ 	(revision )
@@ -1,139 +1,0 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
-// http://chaosforge.org/
-//
-// This file is part of NV Libraries.
-// For conditions of distribution and use, see copyright notice in nv.hh
-
-#include "nv/io_event.hh"
-
-#include <nv/types.hh>
-
-using namespace nv;
-
-const char* nv::get_key_name( key_code key )
-{
-	switch ( key )
-	{
-#	define NV_KEY( id, val ) case id : return #id;
-#		include <nv/detail/key_list.inc>
-#	undef NV_KEY
-	NV_RETURN_COVERED_DEFAULT( "KEY_UNKNOWN" );
-	};
-}
-
-const char* nv::get_mouse_name( mouse_code button )
-{
-	switch ( button )
-	{
-#	define NV_MOUSE( id, val ) case id : return #id;
-#		include <nv/detail/mouse_list.inc>
-#	undef NV_MOUSE
-	NV_RETURN_COVERED_DEFAULT( "MOUSE_UNKNOWN" );
-	};
-}
-
-const char* nv::get_io_event_name( io_event_code event )
-{
-	switch ( event )
-	{
-#	define NV_IO_EVENT( id ) case id : return #id;
-#		include <nv/detail/io_event_list.inc>
-#	undef NV_IO_EVENT
-	NV_RETURN_COVERED_DEFAULT( "EV_UNKNOWN" );
-	};
-}
-
-void nv::register_io_types( type_database* db )
-{
-	type_enum key_enums[] = {
-#	define NV_KEY( id, val ) type_enum( #id, id ),
-#		include <nv/detail/key_list.inc>
-#	undef NV_KEY
-	};
-	db->create_type<key_code>("key_code").enums( key_enums );
-
-	type_enum mouse_enums[] = {
-#	define NV_MOUSE( id, val ) type_enum( #id, id ),
-#		include <nv/detail/mouse_list.inc>
-#	undef NV_MOUSE
-	};
-	db->create_type<mouse_code>("mouse_code").enums( mouse_enums );
-
-	type_enum io_event_enums[] = {
-#	define NV_IO_EVENT( id ) type_enum( #id, id ),
-#		include <nv/detail/io_event_list.inc>
-#	undef NV_IO_EVENT
-	};
-	db->create_type<io_event_code>("event_code").enums( io_event_enums );
-
-	type_field key_fields[] = {
-		type_field( "ascii",   &key_event::ascii ),
-		type_field( "code",    &key_event::code ),
-		type_field( "shift",   &key_event::shift ),
-		type_field( "control", &key_event::control ),
-		type_field( "alt",     &key_event::alt ),
-		type_field( "pressed", &key_event::pressed ),
-	};
-	db->create_type<key_event>("key_event").fields( key_fields );
-
-	type_field mouse_button_fields[] = {
-		type_field( "x",       &mouse_button_event::x ),
-		type_field( "y",       &mouse_button_event::y ),
-		type_field( "button",  &mouse_button_event::button ),
-		type_field( "pressed", &mouse_button_event::pressed ),
-		type_field( "code",    &mouse_button_event::code ),
-	};
-	db->create_type<mouse_button_event>("mouse_button_event").fields( mouse_button_fields );
-
-	type_field mouse_move_fields[] = {
-		type_field( "x",       &mouse_move_event::x ),
-		type_field( "y",       &mouse_move_event::y ),
-		type_field( "rx",      &mouse_move_event::rx ),
-		type_field( "ry",      &mouse_move_event::ry ),
-		type_field( "pressed", &mouse_move_event::pressed ),
-		type_field( "code",    &mouse_move_event::code ),
-	};
-	db->create_type<mouse_move_event>("mouse_move_event").fields( mouse_move_fields );
-
-	type_field mouse_wheel_fields[] = {
-		type_field( "x",       &mouse_wheel_event::x ),
-		type_field( "y",       &mouse_wheel_event::y ),
-	};
-	db->create_type<mouse_wheel_event>("mouse_wheel_event").fields( mouse_wheel_fields );
-
-	type_field joy_button_fields[] = {
-		type_field( "id",      &joy_button_event::id ),
-		type_field( "button",  &joy_button_event::button ),
-		type_field( "pressed", &joy_button_event::pressed ),
-	};
-	db->create_type<joy_button_event>("joy_button_event").fields( joy_button_fields );
-
-	type_field joy_axis_fields[] = {
-		type_field( "id",      &joy_axis_event::id ),
-		type_field( "axis",    &joy_axis_event::axis ),
-		type_field( "value",   &joy_axis_event::value ),
-	};
-	db->create_type<joy_axis_event>("joy_axis_event").fields( joy_axis_fields );
-
-	type_field joy_hat_fields[] = {
-		type_field( "id",      &joy_hat_event::id ),
-		type_field( "hat",     &joy_hat_event::hat ),
-		type_field( "value",   &joy_hat_event::value ),
-	};
-	db->create_type<joy_hat_event>("joy_hat_event").fields( joy_hat_fields );
-
-	type_field joy_ball_fields[] = {
-		type_field( "id",      &joy_ball_event::id ),
-		type_field( "ball",    &joy_ball_event::ball ),
-		type_field( "rx",      &joy_ball_event::rx ),
-		type_field( "ry",      &joy_ball_event::ry ),
-	};
-	db->create_type<joy_ball_event>("joy_ball_event").fields( joy_ball_fields );
-
-	type_field system_fields[] = {
-		type_field( "sys_type", &system_event::sys_type ),
-		type_field( "param1",   &system_event::param1 ),
-		type_field( "param2",   &system_event::param2 ),
-	};
-	db->create_type<system_event>("system_event").fields( system_fields );
-}
Index: trunk/src/lib/assimp.cc
===================================================================
--- trunk/src/lib/assimp.cc	(revision 318)
+++ trunk/src/lib/assimp.cc	(revision 319)
@@ -23,5 +23,5 @@
 #if defined( NV_ASSIMP_DYNAMIC )
 
-#include "nv/library.hh"
+#include "nv/core/library.hh"
 
 #define NV_ASSIMP_FUN( rtype, fname, fparams ) rtype (NV_ASSIMP_APIENTRY *fname) fparams = nullptr;
Index: trunk/src/lib/curses.cc
===================================================================
--- trunk/src/lib/curses.cc	(revision 318)
+++ trunk/src/lib/curses.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2013-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -9,5 +9,5 @@
 #if defined( NV_CURSES_DYNAMIC )
 
-#include "nv/library.hh"
+#include "nv/core/library.hh"
 
 #define NV_CURSES_FUN( rtype, fname, fparams ) rtype (*fname) fparams = nullptr;
Index: trunk/src/lib/fmod.cc
===================================================================
--- trunk/src/lib/fmod.cc	(revision 318)
+++ trunk/src/lib/fmod.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -9,5 +9,5 @@
 #if defined( NV_FMOD_DYNAMIC )
 
-#include "nv/library.hh"
+#include "nv/core/library.hh"
 
 #define NV_FMOD_FUN( rtype, fname, fparams ) rtype (NV_FMOD_APIENTRY *fname) fparams = nullptr;
Index: trunk/src/lib/freetype2.cc
===================================================================
--- trunk/src/lib/freetype2.cc	(revision 318)
+++ trunk/src/lib/freetype2.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -9,5 +9,5 @@
 #if defined( NV_FREETYPE_DYNAMIC )
 
-#include "nv/library.hh"
+#include "nv/core/library.hh"
 
 #define NV_FREETYPE_FUN( rtype, fname, fparams ) rtype (*fname) fparams = nullptr;
Index: trunk/src/lib/gl.cc
===================================================================
--- trunk/src/lib/gl.cc	(revision 318)
+++ trunk/src/lib/gl.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -5,11 +5,11 @@
 // For conditions of distribution and use, see copyright notice in nv.hh
 
-#include "nv/common.hh"
-#include "nv/range.hh"
+#include "nv/core/common.hh"
+#include "nv/core/range.hh"
 #include "nv/lib/gl.hh"
 
 #if defined( NV_GL_DYNAMIC )
 
-#include "nv/library.hh"
+#include "nv/core/library.hh"
 
 #if defined( NV_SDL_GL )
Index: trunk/src/lib/lua.cc
===================================================================
--- trunk/src/lib/lua.cc	(revision 318)
+++ trunk/src/lib/lua.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -9,5 +9,5 @@
 #if defined( NV_LUA_DYNAMIC )
 
-#include "nv/library.hh"
+#include "nv/core/library.hh"
 
 #if NV_LUA_VERSION == NV_LUA_52
Index: trunk/src/lib/sdl.cc
===================================================================
--- trunk/src/lib/sdl.cc	(revision 318)
+++ trunk/src/lib/sdl.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -9,5 +9,5 @@
 #if defined( NV_SDL_DYNAMIC )
 
-#include "nv/library.hh"
+#include "nv/core/library.hh"
 
 #define NV_SDL_FUN( rtype, fname, fparams ) rtype (NV_SDL_APIENTRY *fname) fparams = nullptr;
Index: trunk/src/lib/sdl_image.cc
===================================================================
--- trunk/src/lib/sdl_image.cc	(revision 318)
+++ trunk/src/lib/sdl_image.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -9,5 +9,5 @@
 #if defined( NV_SDL_DYNAMIC )
 
-#include "nv/library.hh"
+#include "nv/core/library.hh"
 
 #define NV_SDL_FUN( rtype, fname, fparams ) rtype (NV_SDL_APIENTRY *fname) fparams = nullptr;
Index: trunk/src/lib/sdl_mixer.cc
===================================================================
--- trunk/src/lib/sdl_mixer.cc	(revision 318)
+++ trunk/src/lib/sdl_mixer.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -9,5 +9,5 @@
 #if defined( NV_SDL_DYNAMIC )
 
-#include "nv/library.hh"
+#include "nv/core/library.hh"
 
 #define NV_SDL_FUN( rtype, fname, fparams ) rtype (NV_SDL_APIENTRY *fname) fparams = nullptr;
Index: trunk/src/library.cc
===================================================================
--- trunk/src/library.cc	(revision 318)
+++ 	(revision )
@@ -1,147 +1,0 @@
-// Copyright (C) 2012 Kornel Kisielewicz
-// This file is part of NV Libraries.
-// For conditions of distribution and use, see copyright notice in nv.hh
-#include "nv/common.hh"
-#include "nv/library.hh"
-
-#if NV_PLATFORM == NV_WINDOWS
-#   define WIN32_LEAN_AND_MEAN
-#   include <windows.h>
-#   define NV_LIB_EXT ".dll"
-#   define NV_LIB_HANDLE HMODULE
-#   define NV_LIB_OPEN( name ) LoadLibraryEx( name, NULL, LOAD_WITH_ALTERED_SEARCH_PATH )
-#   define NV_LIB_GET( handle, name ) GetProcAddress( handle, name )
-#   define NV_LIB_CLOSE( name ) !FreeLibrary( name )
-#elif NV_PLATFORM == NV_LINUX || NV_PLATFORM == NV_APPLE
-#   include <dlfcn.h>
-#   define NV_LIB_EXT ".so"
-#   define NV_LIB_HANDLE void*
-#   define NV_LIB_OPEN( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL)
-#   define NV_LIB_GET( handle, name ) dlsym( handle, name )
-#   define NV_LIB_CLOSE( name ) dlclose( name )
-#elif NV_PLATFORM == NV_APPLE
-#   include "macUtils.h"
-#   include <dlfcn.h>
-#   define NV_LIB_EXT ".dylib"
-#   define NV_LIB_HANDLE CFBundleRef
-#   define NV_LIB_OPEN( name ) mac_loadExeBundle( name )
-#   define NV_LIB_GET( handle, name ) mac_getBundleSym( handle, name )
-#   define NV_LIB_CLOSE( name ) mac_unloadExeBundle( name )
-#endif
-
-#include "nv/logging.hh"
-
-using namespace nv;
-
-library::library() 
-    : m_handle( nullptr ), m_name()
-{
-}
-
-void library::open( const string& name )
-{
-	m_name = name;
-	if ( !open() )
-	{
-		m_handle = nullptr;
-		NV_THROW( library_error, "Can't load library!", name );
-	}
-}
-
-bool nv::library::try_open( const string& name )
-{
-	m_name = name;
-	if ( !open() )
-	{
-		m_handle = nullptr;
-		return false;
-	}
-	return true;
-}
-
-const string& library::get_name() const
-{
-    return m_name;
-}
-
-bool library::open( )
-{
-    if ( m_handle != NULL )
-    {
-        return true;
-    }
-    NV_LOG( LOG_NOTICE, "library : loading '" + m_name + "'..." );
-
-    string name = m_name;
-    string ext  = NV_LIB_EXT;
-    size_t ext_len   = ext.length();
-
-    if ( name.length() < ext_len || name.substr( name.length() - ext_len, ext_len ) != ext ) 
-    {
-        name += ext;
-    }
-
-    m_handle = (void*)NV_LIB_OPEN( name.c_str() );
-
-    if ( m_handle == NULL )
-    {
-		NV_LOG( LOG_NOTICE, "library : '" + name + "' failed to open." );
-		return false;
-    }
-    NV_LOG( LOG_NOTICE, "library : '" + name + "' loaded." );
-	return true;
-}
-
-void* library::get( const string& symbol )
-{
-	void* result = (void*) NV_LIB_GET( (NV_LIB_HANDLE) m_handle, symbol.c_str() );
-    if ( !result )
-    {
-        NV_THROW( library_error, "Can't find symbol " + symbol + "!", m_name );
-    }
-	return result;
-}
-
-void* nv::library::try_get( const string& symbol )
-{
-	return (void*) NV_LIB_GET( (NV_LIB_HANDLE) m_handle, symbol.c_str() );
-}
-
-bool library::is_open() const
-{
-	return m_handle != nullptr;
-}
-
-void library::close()
-{
-    if ( NV_LIB_CLOSE( (NV_LIB_HANDLE)m_handle ) )
-    {
-        NV_LOG( LOG_ERROR, "library : can't close library '" + m_name + "'!" );
-    }
-    m_handle = NULL;
-}
-
-library::~library()
-{
-    if ( m_handle != NULL )
-    {
-        close();
-    }
-}
-
-string library::get_error()
-{
-#if NV_PLATFORM == NV_WINDOWS
-    // We do hate WinAPI for code like this, don't we?
-    LPTSTR buffer = NULL;
-    FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
-        NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buffer, 0, NULL );
-    string msg( (char*)buffer );
-    LocalFree( buffer );
-    return msg;
-#elif NV_PLATFORM == NV_LINUX || NV_PLATFORM == NV_APPLE
-    return string(dlerror());
-#else
-    return string("");
-#endif
-}
Index: trunk/src/logger.cc
===================================================================
--- trunk/src/logger.cc	(revision 318)
+++ 	(revision )
@@ -1,262 +1,0 @@
-// Copyright (C) 2011 Kornel Kisielewicz
-// This file is part of NV Libraries.
-// For conditions of distribution and use, see copyright notice in nv.hh
-
-#include "nv/logger.hh"
-
-#include "nv/common.hh"
-#include <iostream>
-#include <utility>
-#include <algorithm>
-#include <fstream>
-#include <ctime>
-#include <cstdio>
-#include <nv/exception.hh>
-#if NV_PLATFORM == NV_WINDOWS
-#define WIN32_LEAN_AND_MEAN
-#include <Windows.h>
-#endif
-
-using namespace nv;
-
-// log level names
-static const char *log_level_names[] =
-{
-	"NONE",
-	"FATAL",
-	"CRITICAL",
-	"ERROR",
-	"WARNING",
-	"NOTICE",
-	"INFO",
-	"INFO",
-	"DEBUG",
-	"DEBUG2",
-	"TRACE"
-};
-
-// log level names
-static const char *log_level_names_pad[] =
-{
-	"NONE    ",
-	"FATAL   ",
-	"CRITICAL",
-	"ERROR   ",
-	"WARNING ",
-	"NOTICE  ",
-	"INFO    ",
-	"INFO    ",
-	"DEBUG   ",
-	"DEBUG2  ",
-	"TRACE   "
-};
-
-// helper macro to access log_level_names
-#define NV_LOG_LEVEL_NAME(level) (log_level_names[ (level) / 10 ])
-#define NV_LOG_LEVEL_NAME_PAD(level) (log_level_names_pad[ (level) / 10 ])
-
-#if NV_PLATFORM == NV_WINDOWS 
-static unsigned short log_color[] =
-{
-	FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
-	FOREGROUND_RED | FOREGROUND_INTENSITY,
-	FOREGROUND_RED | FOREGROUND_INTENSITY,
-	FOREGROUND_RED,
-	FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
-	FOREGROUND_GREEN | FOREGROUND_INTENSITY,
-	FOREGROUND_GREEN,
-	FOREGROUND_GREEN,
-	FOREGROUND_INTENSITY,
-	FOREGROUND_INTENSITY,
-	FOREGROUND_INTENSITY
-};
-#else
-static const char *log_color[] =
-{
-	"\33[37;1m",
-	"\33[31;1m",
-	"\33[31;1m",
-	"\33[31m",
-	"\33[33;1m",
-	"\33[32;1m",
-	"\33[32m",
-	"\33[32m",
-	"\33[30;1m",
-	"\33[30;1m",
-	"\33[30;1m"
-};
-#endif
-
-// log function
-void logger::log( log_level level, const std::string& message )
-{
-	// get the iterator to the beginning of the log_sink list
-	log_sink_list::reverse_iterator it = m_log_sinks.rbegin();
-
-	// iterate
-	while ( it != m_log_sinks.rend() )
-	{
-		// if we have a log sink with high enough level...
-		if ( it->first >= level )
-		{
-			// log and iterate
-			it->second->log( level, message );
-		}
-		else 
-		{
-			// otherwise return, the list is sorted by log level
-			return;
-		}
-		++it;
-	}
-}
-
-// add a new sink
-void logger::add_sink( log_sink* sink, int level )
-{
-	// add a sink
-	m_log_sinks.push_back( std::make_pair( log_level(level), sink ) );
-	// and sort the list (default sort of pairs is by first element)
-	m_log_sinks.sort();
-}
-
-// remove existing sink
-bool logger::remove_sink( log_sink* sink )
-{
-	// get the iterator to the beginning of the log_sink list
-	log_sink_list::iterator it = m_log_sinks.begin();
-
-	// iterate
-	while ( it != m_log_sinks.end() )
-	{
-		// found?
-		if ( it->second == sink ) 
-		{
-			// erase and return true to report success
-			m_log_sinks.erase(it);
-			return true;
-		}
-		++it;
-	}
-
-	// not found, return false
-	return false;
-}
-
-// destructor
-logger::~logger()
-{
-	// while we have sinks
-	while ( !m_log_sinks.empty() )
-	{
-		// delete the last one
-		delete m_log_sinks.back().second;
-		// and pop it
-		m_log_sinks.pop_back();
-	}
-}
-
-
-// console logging
-void log_console_sink::log( log_level level, const std::string& message )
-{
-	if (m_color) 
-	{
-#if NV_PLATFORM == NV_WINDOWS 
-		SetConsoleTextAttribute( m_handle, FOREGROUND_INTENSITY );
-		std::cout << timestamp() << " [";
-		SetConsoleTextAttribute( m_handle, log_color[ (level) / 10 ] );
-		std::cout << NV_LOG_LEVEL_NAME_PAD(level);
-		SetConsoleTextAttribute( m_handle, FOREGROUND_INTENSITY );
-		std::cout << "] ";
-		SetConsoleTextAttribute( m_handle, FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE );
-		std::cout << message << std::endl;
-#else
-		std::cout << "\33[30;1m" << timestamp() << " [" << log_color[ (level) / 10 ] << NV_LOG_LEVEL_NAME_PAD(level) << "\33[30;1m] \33[37;1m" << message << std::endl;
-#endif
-	}
-	else
-	{
-	std::cout << timestamp() << " [" << NV_LOG_LEVEL_NAME_PAD(level) << "] " << message << std::endl;
-	}
-}
-
-// stream logging
-void log_stream_sink::log( log_level level, const std::string& message )
-{
-	// if flushing is enabled
-	if ( m_flush )
-	{
-		// write and flush using std::endl
-		*m_stream << timestamp() << " [" << NV_LOG_LEVEL_NAME(level) << "] " << message << std::endl;
-	}
-	else
-	{
-		// write and end with "\n" (no flush)
-		*m_stream << timestamp() << " [" << NV_LOG_LEVEL_NAME(level) << "] " << message << "\n";
-	}
-}
-
-// file logging
-log_file_sink::log_file_sink( const std::string file_name, bool flush_always /*= true */ )
-	: log_stream_sink( nullptr, flush_always )
-{
-	// create the stream manually
-	std::ofstream* fstream = new std::ofstream( file_name );
-
-	// check if it's open
-	if ( !fstream->is_open() )
-	{
-		// throw if not open
-		NV_THROW( runtime_error, "Could not open file \""+file_name+"\" for logging!" );
-	}
-
-	m_stream = fstream;
-}
-
-// file logger destructor
-log_file_sink::~log_file_sink()
-{
-	// close the file
-	dynamic_cast< std::ofstream* >(m_stream)->close();
-	// dispose of the stream
-	delete m_stream;
-}
-
-nv::log_console_sink::log_console_sink( bool coloring )
-	: m_color( coloring )
-{
-#if NV_PLATFORM == NV_WINDOWS 
-	m_handle = GetStdHandle( STD_OUTPUT_HANDLE );
-#else
-  NV_UNUSED( m_handle );
-#endif
-}
-
-const char* nv::log_sink::timestamp() const
-{
-	std::clock_t time = std::clock();
-	unsigned int secs = (unsigned int)(time / CLOCKS_PER_SEC);
-	unsigned int mm   = (unsigned int)(time*100 / CLOCKS_PER_SEC) % 100;
-	unsigned int h    = (unsigned int)(secs / (60*60));
-	unsigned int m    = (unsigned int)(secs / 60) % 60;
-	unsigned int s    = secs % 60;
-	static char buffer[128];
-#if NV_PLATFORM == NV_WINDOWS 
-	sprintf_s( buffer, 128, "%02d:%02d:%02d.%02d", h, m, s, mm );
-#else
-	sprintf( buffer, "%02d:%02d:%02d.%02d", h, m, s, mm );
-#endif
-	buffer[11] = '\0';
-	return buffer;
-}
-
-const char* nv::log_sink::level_name( log_level level ) const
-{
-	return NV_LOG_LEVEL_NAME( level );
-}
-
-const char* nv::log_sink::padded_level_name( log_level level ) const
-{
-	return NV_LOG_LEVEL_NAME_PAD( level );
-}
Index: trunk/src/lua/lua_area.cc
===================================================================
--- trunk/src/lua/lua_area.cc	(revision 318)
+++ trunk/src/lua/lua_area.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -8,6 +8,6 @@
 
 #include "nv/lua/lua_raw.hh"
-#include "nv/string.hh"
-#include "nv/random.hh"
+#include "nv/core/string.hh"
+#include "nv/core/random.hh"
 
 const char* nv::lua::detail::AREA_METATABLE = "area";
Index: trunk/src/lua/lua_aux.cc
===================================================================
--- trunk/src/lua/lua_aux.cc	(revision 318)
+++ trunk/src/lua/lua_aux.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -9,5 +9,5 @@
 #include <utility>
 #include "nv/lua/lua_raw.hh"
-#include "nv/random.hh"
+#include "nv/core/random.hh"
 
 static int nluaaux_table_copy( lua_State* L )
Index: trunk/src/lua/lua_flags.cc
===================================================================
--- trunk/src/lua/lua_flags.cc	(revision 318)
+++ trunk/src/lua/lua_flags.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -8,5 +8,5 @@
 
 #include "nv/lua/lua_raw.hh"
-#include "nv/string.hh"
+#include "nv/core/string.hh"
 
 
Index: trunk/src/lua/lua_function.cc
===================================================================
--- trunk/src/lua/lua_function.cc	(revision 318)
+++ trunk/src/lua/lua_function.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
Index: trunk/src/lua/lua_glm.cc
===================================================================
--- trunk/src/lua/lua_glm.cc	(revision 318)
+++ trunk/src/lua/lua_glm.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -8,6 +8,6 @@
 
 #include "nv/lua/lua_raw.hh"
-#include "nv/string.hh"
-#include "nv/random.hh"
+#include "nv/core/string.hh"
+#include "nv/core/random.hh"
 
 static size_t nlua_swizzel_lookup[256];
Index: trunk/src/lua/lua_map_area.cc
===================================================================
--- trunk/src/lua/lua_map_area.cc	(revision 318)
+++ trunk/src/lua/lua_map_area.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -6,5 +6,5 @@
 
 #include "nv/lua/lua_map_area.hh"
-#include "nv/flags.hh"
+#include "nv/core/flags.hh"
 #include "nv/lua/lua_area.hh"
 #include "nv/lua/lua_glm.hh"
Index: trunk/src/lua/lua_map_tile.cc
===================================================================
--- trunk/src/lua/lua_map_tile.cc	(revision 318)
+++ trunk/src/lua/lua_map_tile.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -9,6 +9,6 @@
 #include <numeric>
 #include "nv/lua/lua_map_area.hh"
-#include "nv/flags.hh"
-#include "nv/random.hh"
+#include "nv/core/flags.hh"
+#include "nv/core/random.hh"
 #include "nv/lua/lua_area.hh"
 #include "nv/lua/lua_glm.hh"
Index: trunk/src/lua/lua_nova.cc
===================================================================
--- trunk/src/lua/lua_nova.cc	(revision 318)
+++ trunk/src/lua/lua_nova.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
Index: trunk/src/lua/lua_path.cc
===================================================================
--- trunk/src/lua/lua_path.cc	(revision 318)
+++ trunk/src/lua/lua_path.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
Index: trunk/src/lua/lua_raw.cc
===================================================================
--- trunk/src/lua/lua_raw.cc	(revision 318)
+++ trunk/src/lua/lua_raw.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -7,5 +7,5 @@
 #include "nv/lua/lua_raw.hh"
 
-#include "nv/string.hh"
+#include "nv/core/string.hh"
 
 std::string nlua_typecontent( lua_State* L, int idx )
Index: trunk/src/lua/lua_state.cc
===================================================================
--- trunk/src/lua/lua_state.cc	(revision 318)
+++ trunk/src/lua/lua_state.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -9,6 +9,6 @@
 #include "nv/lua/lua_raw.hh"
 #include "nv/lua/lua_nova.hh"
-#include "nv/logging.hh"
-#include "nv/string.hh"
+#include "nv/core/logging.hh"
+#include "nv/core/string.hh"
 
 using namespace nv;
Index: trunk/src/lua/lua_values.cc
===================================================================
--- trunk/src/lua/lua_values.cc	(revision 318)
+++ trunk/src/lua/lua_values.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
Index: trunk/src/object.cc
===================================================================
--- trunk/src/object.cc	(revision 318)
+++ 	(revision )
@@ -1,133 +1,0 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
-// http://chaosforge.org/
-//
-// This file is part of NV Libraries.
-// For conditions of distribution and use, see copyright notice in nv.hh
-
-#include "nv/object.hh"
-
-#include <algorithm>
-
-using namespace nv;
-
-object::object( const string& aid )
-	: m_id( aid )
-	, m_name()
-	, m_uid(0)
-	, m_parent( nullptr )
-	, m_children()
-	, m_child_count(0)
-{
-}
-
-void object::add_child( object* child )
-{
-	if (child)
-	{
-		if (child->m_parent)
-		{
-			child->detach();
-		}
-		child->m_parent = this;
-		m_children.push_back( child );
-		m_child_count++;
-	}
-}
-
-void object::remove_child( object* child )
-{
-	if ( child->m_parent != this )
-	{
-		return; // signal error?
-	}
-	list::iterator it = std::find( m_children.begin(), m_children.end(), child );
-	if ( it != m_children.end() )
-	{
-		(*it)->m_parent = nullptr;
-		m_children.erase(it);
-	}	
-}
-
-void object::detach()
-{
-	if (m_parent)
-	{
-		m_parent->remove_child( this );
-	}
-}
-
-void object::change_parent( object* new_parent )
-{
-	if (m_parent) detach();
-	if (new_parent) new_parent->add_child( this );
-}
-
-object::~object()
-{
-}
-
-object* object::find( object* child, bool recursive /*= false */ )
-{
-	list::iterator it = std::find( m_children.begin(), m_children.end(), child );
-	if ( it != m_children.end() )
-	{
-		return *it;
-	}
-	if ( recursive )
-	{
-		for ( object* i : m_children )
-		{
-			object* r = i->find( child, recursive );
-			if (r) return r;
-		}
-	}
-	return nullptr;
-}
-
-object* object::find( uid child, bool recursive /*= false */ )
-{
-	for ( object* i : m_children )
-	{
-		if (i->m_uid == child) return i;
-	}
-	if ( recursive )
-	{
-		for ( object* i : m_children )
-		{
-			object* r = i->find( child, recursive );
-			if (r) return r;
-		}
-	}
-	return nullptr;
-}
-
-object* object::find( string child, bool recursive /*= false */ )
-{
-	for ( object* i : m_children )
-	{
-		if (i->m_id == child) return i;
-	}
-	if ( recursive )
-	{
-		for ( object* i : m_children )
-		{
-			object* r = i->find( child, recursive );
-			if (r) return r;
-		}
-	}
-	return nullptr;
-}
-
-
-// void object::register_type( type_database* db )
-// {
-// 	type_field fields[] = {
-// 		type_field("id",          &object::m_id),
-// 		type_field("uid",         &object::m_uid).flag( TF_READONLY ), 
-// 		type_field("lua_index",   &object::m_lua_index).flag( TF_READONLY | TF_NOSERIALIZE ),
-// 		type_field("parent",      &object::m_parent).flag( TF_READONLY | TF_NOSERIALIZE ),
-// 		type_field("child_count", &object::m_child_count).flag( TF_READONLY ),
-// 		type_field("children"   , &object::m_children).flag( TF_READONLY ),
-// 	};
-// 	db->create_type<object>("object").fields(fields);
-// }
Index: trunk/src/profiler.cc
===================================================================
--- trunk/src/profiler.cc	(revision 318)
+++ 	(revision )
@@ -1,133 +1,0 @@
-// Copyright (C) 2012-2013 Kornel Kisielewicz
-// This file is part of NV Libraries.
-// For conditions of distribution and use, see copyright notice in nv.hh
-
-#include "nv/profiler.hh"
-
-#include <iomanip>
-#include <ios>
-#include "nv/time.hh"
-
-using namespace nv;
-
-
-profiler::profiler()
-{
-	m_root = new node( "root", nullptr );
-	m_root->start();
-	m_current = m_root;
-}
-
-profiler::~profiler()
-{
-	delete m_root;
-}
-
-void profiler::start_profile( const char* tag )
-{
-	if ( tag != m_current->m_tag )
-	{
-		m_current = m_current->request_child( tag );
-	}
-	m_current->start();
-}
-
-void profiler::stop_profile()
-{
-	if ( m_current->stop() )
-	{
-		m_current = m_current->get_parent();
-	}
-}
-
-profiler::node::node( const char* tag, node* parent ) 
-	: m_tag( tag )
-	, m_parent( parent )
-	, m_recusion( 0 )
-	, m_calls( 0 )
-	, m_start_time_us( 0 )
-	, m_total_time_us( 0 )
-{
-
-}
-
-profiler::node* profiler::node::request_child( const char* tag )
-{
-	auto it = m_children.find( tag );
-	if ( it != m_children.end() ) 
-		return it->second;
-	else
-	{
-		node* result = new node( tag, this );
-		m_children[ tag ] = result;
-		return result;
-	}
-}
-
-void profiler::node::start()
-{
-	m_calls++;
-	m_recusion++;
-	if ( m_recusion == 1 )
-	{
-		m_start_time_us = get_system_us();
-	}
-}
-
-bool profiler::node::stop()
-{
-	m_recusion--;
-	if ( m_recusion == 0 )
-	{
-		uint64 stop_time_us = get_system_us();
-		uint64 elapsed_us   = stop_time_us - m_start_time_us;
-		m_total_time_us     += elapsed_us;
-		return true;
-	}
-	return false;
-}
-
-
-nv::profiler::node::~node()
-{
-	for ( const auto& pair : m_children )
-	{
-		delete pair.second;
-	}
-}
-
-
-void profiler::log_report()
-{
-	m_root->stop();
-	NV_LOG( LOG_INFO, "-- PROFILER REPORT -----------------------------------------" );
-	NV_LOG( LOG_INFO, std::left << std::setw(24) << "TAG" 
-		<< std::setw(7) << "%PARNT" 
-		<< std::setw(7) << "CALLS" 
-		<< std::setw(10) << "TOTAL(ms)" 
-		<< std::setw(10) << "AVG(ms)" );
-	log_node_children( "", m_root );
-	NV_LOG( LOG_INFO, "-- PROFILER REPORT END -------------------------------------" );
-	m_root->start();
-}
-
-void profiler::log_node_children( const std::string& ind, const node* n )
-{
-	for ( const auto& pair : n->m_children )
-	{
-		const node* c = pair.second;
-		if ( c->m_calls > 0 )
-		{
-			NV_LOG( LOG_INFO, std::left << std::setw(24) << ind + c->m_tag 
-				<< std::setw(7) << std::setprecision(2) << std::fixed << ( (double)c->m_total_time_us / (double)c->m_parent->m_total_time_us ) * 100.0
-				<< std::setw(7) << c->m_calls 
-				<< std::setw(10) << std::setprecision(2) << std::fixed << c->m_total_time_us / 1000.f
-				<< std::setw(10) << std::setprecision(2) << std::fixed << ( (double)c->m_total_time_us / (double)c->m_calls ) / 1000.f
-				);
-			if ( c->m_children.size() > 0 )
-			{
-				log_node_children( ind + "-", c );
-			}
-		}
-	}
-}
Index: trunk/src/random.cc
===================================================================
--- trunk/src/random.cc	(revision 318)
+++ 	(revision )
@@ -1,276 +1,0 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
-// http://chaosforge.org/
-//
-// This file is part of NV Libraries.
-// For conditions of distribution and use, see copyright notice in nv.hh
-
-#include "nv/random.hh"
-#include "nv/time.hh"
-
-using namespace nv;
-
-random::random( random::seed_type seed /*= 0 */ )
-	: rng( seed == 0 ? randomized_seed() : seed )
-{
-	
-}
-
-random::seed_type random::randomize()
-{
-	seed_type seed = randomized_seed();
-	rng.seed( seed );
-	return seed;
-}
-
-void random::set_seed( random::seed_type seed /*= 0 */ )
-{
-	rng.seed( seed == 0 ? randomized_seed() : seed );
-}
-
-nv::random& random::get()
-{
-	static random default_rng;
-	return default_rng;
-}
-
-random::result_type random::rand()
-{
-	return rng();
-}
-
-sint32 random::srand( sint32 val )
-{
-	std::uniform_int_distribution<sint32> dist( 0, val - 1 );
-	return dist( rng );
-}
-
-uint32 random::urand( uint32 val )
-{
-	std::uniform_int_distribution<uint32> dist( 0, val - 1 );
-	return dist( rng );
-}
-
-f32 random::frand( f32 val )
-{
-	std::uniform_real_distribution<f32> dist( 0, val );
-	return dist( rng );
-}
-
-sint32 random::srange( sint32 min, sint32 max )
-{
-	std::uniform_int_distribution<sint32> dist( min, max );
-	return dist( rng );
-}
-
-uint32 random::urange( uint32 min, uint32 max )
-{
-	std::uniform_int_distribution<uint32> dist( min, max );
-	return dist( rng );
-}
-
-f32 random::frange( f32 min, f32 max )
-{
-	std::uniform_real_distribution<f32> dist( min, max );
-	return dist( rng );
-}
-
-uint32 random::dice( uint32 count, uint32 sides )
-{
-	std::uniform_int_distribution<uint32> dist( 1, sides );
-	uint32 result = 0;
-	while (count-- > 0)
-	{
-		result += dist( rng );
-	};
-	return result;
-}
-
-random::seed_type random::randomized_seed()
-{
-	return narrow_cast< seed_type >( get_ticks() );
-}
-
-nv::vec2 nv::random::precise_unit_vec2()
-{
-	std::uniform_real_distribution<f32> dist( 0, glm::pi<float>() * 2.f );
-	float angle = dist( rng );
-	return vec2( glm::cos( angle ), glm::sin( angle ) );
-}
-
-nv::vec3 nv::random::precise_unit_vec3()
-{
-	std::uniform_real_distribution<f32> dist11( -1.0f, 1.0f );
-	std::uniform_real_distribution<f32> dist02pi( 0.0f, 2*glm::pi<float>() );
-	float cos_theta = dist11( rng );
-	float sin_theta = glm::sqrt( 1.0f - cos_theta * cos_theta );
-	float phi       = dist02pi( rng );
-	return vec3( 
-		sin_theta * glm::sin(phi),
-		sin_theta * glm::cos(phi),
-		cos_theta
-		);
-}
-
-nv::vec2 nv::random::fast_disk_point()
-{
-	std::uniform_real_distribution<f32> dist( 0.0f, 1.0f );
-	float r1 = dist( rng );
-	float r2 = dist( rng );
-	if ( r1 > r2 ) std::swap( r1, r2 );
-	float rf = 2*glm::pi<float>()*(r1/r2);
-	return vec2( r2*glm::cos( rf ), r2*glm::sin( rf ) );
-}
-
-nv::vec2 nv::random::precise_disk_point()
-{
-	std::uniform_real_distribution<f32> unit( 0.0f, 1.0f );
-	std::uniform_real_distribution<f32> angle( 0.0f, glm::pi<float>() );
-	float r = glm::sqrt( unit( rng ) );
-	float rangle = angle( rng );
-	return vec2( r*glm::cos( rangle ), r*glm::sin( rangle ) );
-}
-
-nv::vec3 nv::random::fast_sphere_point()
-{
-	std::uniform_real_distribution<f32> dist01( 0.0f, 1.0f );
-	std::uniform_real_distribution<f32> dist11( -1.0f, 1.0f );
-	std::uniform_real_distribution<f32> dist02pi( 0.0f, 2*glm::pi<float>() );
-	float rad     = dist01( rng );
-	float pi      = glm::pi<float>();
-	float phi     = glm::asin( dist11( rng ) ) + pi*.5f;
-	float theta   = dist02pi( rng );
-	float sin_phi = glm::sin( phi );
-	return vec3( 
-		rad * glm::cos(theta) * sin_phi,
-		rad * glm::sin(theta) * sin_phi,
-		rad * glm::cos(phi)
-	);
-}
-
-nv::vec3 nv::random::precise_sphere_point()
-{
-	std::uniform_real_distribution<f32> dist01( 0.0f, 1.0f );
-	std::uniform_real_distribution<f32> dist11( -1.0f, 1.0f );
-	std::uniform_real_distribution<f32> dist02pi( 0.0f, 2*glm::pi<float>() );
-	float radius = std::pow( dist01( rng ), 1.f/3.f );
-	float cos_theta = dist11( rng );
-	float sin_theta = glm::sqrt( 1.0f - cos_theta * cos_theta );
-	float phi       = dist02pi( rng );
-	return vec3( 
-		radius * sin_theta * glm::sin(phi),
-		radius * sin_theta * glm::cos(phi),
-		radius * cos_theta
-		);
-}
-
-nv::vec2 nv::random::precise_ellipse_point( const vec2& radii )
-{
-	std::uniform_real_distribution<f32> distx( -radii.x, radii.x );
-	std::uniform_real_distribution<f32> disty( -radii.y, radii.y );
-	vec2 inv_radii  = 1.f / radii;
-	vec2 inv_radii2 = inv_radii * inv_radii;
-	for ( uint32 i = 0; i < 12; ++i )
-	{
-		float x = distx( rng );
-		float y = disty( rng );
-		if ( x * x * inv_radii2.x + y * y * inv_radii2.y <= 1.f )
-		{
-			return vec2( x, y );
-		}
-	}
-	return fast_disk_point() * radii;
-}
-
-nv::vec3 nv::random::precise_ellipsoid_point( const vec3& radii )
-{
-	std::uniform_real_distribution<f32> distx( -radii.x, radii.x );
-	std::uniform_real_distribution<f32> disty( -radii.y, radii.y );
-	std::uniform_real_distribution<f32> distz( -radii.z, radii.z );
-	vec3 inv_radii  = 1.f / radii;
-	vec3 inv_radii2 = inv_radii * inv_radii;
-	for ( uint32 i = 0; i < 12; ++i )
-	{
-		float x = distx( rng );
-		float y = disty( rng );
-		float z = distz( rng );
-		if ( x * x * inv_radii2.x + y * y * inv_radii2.y + z * z * inv_radii2.z <= 1.f )
-		{
-			return vec3( x, y, z );
-		}
-	}
-	return fast_sphere_point() * radii;
-}
-
-nv::vec2 nv::random::fast_hollow_disk_point( float iradius, float oradius )
-{
-	float idist2 = iradius * iradius;
-	float odist2 = oradius * oradius;
-	float rdist  = glm::sqrt( std::uniform_real_distribution<f32>( idist2, odist2 )( rng ) );
-	return rdist * precise_unit_vec2();
-}
-
-nv::vec2 nv::random::precise_hollow_disk_point( float iradius, float oradius )
-{
-	return fast_hollow_disk_point( iradius, oradius );
-}
-
-nv::vec3 nv::random::fast_hollow_sphere_point( float iradius, float oradius )
-{
-	float idist3 = iradius * iradius * iradius;
-	float odist3 = oradius * oradius * oradius;
-	float rdist  = std::pow( std::uniform_real_distribution<f32>( idist3, odist3 )( rng ), 1.f/3.f );
-	return rdist * precise_unit_vec3();
-}
-
-nv::vec3 nv::random::precise_hollow_sphere_point( float iradius, float oradius )
-{
-	return fast_hollow_sphere_point( iradius, oradius );
-}
-
-
-nv::vec2 nv::random::fast_hollow_ellipse_point( const vec2& iradii, const vec2& oradii )
-{
-	vec2 iradii2    = iradii * iradii;
-	vec2 opoint     = ellipse_edge( oradii );
-	vec2 opoint2    = opoint * opoint;
-	vec2 odir       = glm::normalize( opoint );
-	float odist2    = opoint2.x + opoint2.y;
-
-	float low    = iradii2.y * opoint2.x + iradii2.x * opoint2.y;
-	float idist2 = ((iradii2.x * iradii2.y) / low ) * odist2;
-
-	float rdist     = glm::sqrt( std::uniform_real_distribution<f32>( idist2, odist2 )( rng ) );
-	return odir * rdist;	
-}
-
-nv::vec2 nv::random::precise_hollow_ellipse_point( const vec2& iradii, const vec2& oradii )
-{
-	return fast_hollow_ellipse_point( iradii, oradii );
-}
-
-nv::vec3 nv::random::fast_hollow_ellipsoid_point( const vec3& iradii, const vec3& oradii )
-{
-	vec3 iradii2    = iradii * iradii;
-	vec3 opoint     = ellipsoid_edge( oradii );
-	vec3 opoint2    = opoint * opoint;
-	vec3 odir       = glm::normalize( opoint );
-	float odist2    = opoint2.x + opoint2.y + opoint2.z;
-
-	float low    = 
-		iradii2.y * iradii2.z * opoint2.x + 
-		iradii2.x * iradii2.z * opoint2.y +
-		iradii2.x * iradii2.y * opoint2.z;
-	float idist2 = ((iradii2.x * iradii2.y * iradii2.z) / low ) * odist2;
-
-	float odist3 = odist2 * glm::sqrt( odist2 );
-	float idist3 = idist2 * glm::sqrt( idist2 );
-
-	float rdist     = std::pow( std::uniform_real_distribution<f32>( idist3, odist3 )( rng ), 1.f/3.f );
-	return odir * rdist;	
-}
-
-nv::vec3 nv::random::precise_hollow_ellipsoid_point( const vec3& iradii, const vec3& oradii )
-{
-	return fast_hollow_ellipsoid_point( iradii, oradii );
-}
-
Index: trunk/src/rogue/fov_recursive_shadowcasting.cc
===================================================================
--- trunk/src/rogue/fov_recursive_shadowcasting.cc	(revision 318)
+++ trunk/src/rogue/fov_recursive_shadowcasting.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -7,5 +7,5 @@
 #include "nv/rogue/fov_recursive_shadowcasting.hh"
 
-#include <nv/math.hh>
+#include "nv/core/math.hh"
 
 static int nv_rogue_rs_mult[4][8] = {
Index: trunk/src/root.cc
===================================================================
--- trunk/src/root.cc	(revision 318)
+++ 	(revision )
@@ -1,25 +1,0 @@
-// Copyright (C) 2012-2014 ChaosForge Ltd
-// http://chaosforge.org/
-//
-// This file is part of NV Libraries.
-// For conditions of distribution and use, see copyright notice in nv.hh
-
-#include "nv/root.hh"
-
-#include "nv/uid.hh"
-#include "nv/lua/lua_state.hh"
-
-void nv::root::destroy_object( object* o )
-{
-	destroy_children( o );
-	o->detach();
-	delete o;
-}
-
-void nv::root::destroy_children( object* o )
-{
-	while ( !o->m_children.empty() )
-	{
-		destroy_object( o->m_children.front() );
-	}
-}
Index: trunk/src/sdl/sdl_audio.cc
===================================================================
--- trunk/src/sdl/sdl_audio.cc	(revision 318)
+++ trunk/src/sdl/sdl_audio.cc	(revision 319)
@@ -1,3 +1,3 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
+// Copyright (C) 2012-2014 ChaosForge Ltd
 // http://chaosforge.org/
 //
@@ -9,5 +9,5 @@
 #include "nv/lib/sdl.hh"
 #include "nv/lib/sdl_mixer.hh"
-#include "nv/logging.hh"
+#include "nv/core/logging.hh"
 
 using namespace nv;
Index: trunk/src/time.cc
===================================================================
--- trunk/src/time.cc	(revision 318)
+++ 	(revision )
@@ -1,100 +1,0 @@
-// Copyright (C) 2011 Kornel Kisielewicz
-// This file is part of NV Libraries.
-// For conditions of distribution and use, see copyright notice in nv.hh
-
-#include "nv/time.hh"
-
-#include "nv/logging.hh"
-
-#if NV_COMPILER == NV_MSVC
-#define WIN32_LEAN_AND_MEAN 
-#include <windows.h>
-#include <intrin.h>
-#pragma intrinsic(__rdtsc)
-#else
-#include <unistd.h>
-#include <sys/time.h>
-#endif
-
-#include <ctime>
-
-struct timer_impl
-{
-	timer_impl()
-	{
-		clock_zero = clock();
-#if NV_COMPILER == NV_MSVC
-		QueryPerformanceFrequency(&frequency);
-		QueryPerformanceCounter(&query_zero);
-#else
-		gettimeofday(&timeval_zero, NULL);
-#endif
-	}
-	clock_t clock_zero;
-#if NV_COMPILER == NV_MSVC
-	LARGE_INTEGER query_zero;
-	LARGE_INTEGER frequency;
-#else
-	struct timeval timeval_zero;
-#endif
-};
-
-static timer_impl zero_timer;
-
-nv::uint64 nv::get_ticks()
-{
-#if NV_COMPILER == NV_MSVC
-	return __rdtsc();
-#else
-	register long long ticks asm("eax") = 0;
-	asm volatile (".byte 15, 49" : : : "eax", "edx");
-	return static_cast<nv::uint64>( ticks );
-#endif
-}
-
-void nv::sleep( uint32 ms )
-{
-#if NV_COMPILER == NV_MSVC
-	Sleep( ms );
-#else
-	usleep( ms * 1000 );
-#endif
-}
-
-nv::uint32 nv::get_cpu_ms()
-{
-	return (uint32)( (f32)( clock() - zero_timer.clock_zero ) / ( (f32)CLOCKS_PER_SEC / 1000.0 ) ) ;
-}
-
-nv::uint64 nv::get_cpu_us()
-{
-	return (uint64)( (f32)( clock() - zero_timer.clock_zero ) / ( (f32)CLOCKS_PER_SEC / 1000000.0 ) ) ;
-}
-
-nv::uint32 nv::get_system_ms()
-{
-#if NV_COMPILER == NV_MSVC
-	LARGE_INTEGER now;
-	QueryPerformanceCounter(&now);
-	LONGLONG result = now.QuadPart - zero_timer.query_zero.QuadPart;
-	return (uint32) (1000.0 * result / (double) zero_timer.frequency.QuadPart);
-#else
-	struct timeval now;
-	gettimeofday(&now, NULL);
-	return (uint32)( (now.tv_sec - zero_timer.timeval_zero.tv_sec)*1000+(now.tv_usec-zero_timer.timeval_zero.tv_usec)/1000 );
-#endif
-}
-
-nv::uint64 nv::get_system_us()
-{
-#if NV_COMPILER == NV_MSVC
-	LARGE_INTEGER now;
-	QueryPerformanceCounter(&now);
-	LONGLONG result = now.QuadPart - zero_timer.query_zero.QuadPart;
-	return (uint64) (1000000.0 * result / (double) zero_timer.frequency.QuadPart);
-#else
-	struct timeval now;
-	gettimeofday(&now, NULL);
-	return (uint32)( (now.tv_sec - zero_timer.timeval_zero.tv_sec)*1000000+(now.tv_usec - zero_timer.timeval_zero.tv_usec) );
-#endif
-}
Index: trunk/src/uid.cc
===================================================================
--- trunk/src/uid.cc	(revision 318)
+++ 	(revision )
@@ -1,52 +1,0 @@
-// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
-// http://chaosforge.org/
-//
-// This file is part of NV Libraries.
-// For conditions of distribution and use, see copyright notice in nv.hh
-
-#include "nv/uid.hh"
-
-using namespace nv;
-
-uid_store_raw::uid_store_raw()
-	: m_map(), m_current(0)
-{
-	
-}
-
-void* uid_store_raw::get( uid auid ) const
-{
-	map::const_iterator i = m_map.find( auid );
-	if ( i != m_map.end() )
-	{
-		return i->second;
-	}
-	return nullptr;
-}
-
-bool uid_store_raw::remove( uid auid )
-{
-	return m_map.erase( auid ) != 0;
-}
-
-void uid_store_raw::insert( void* o, uid auid )
-{
-	m_map[ auid ] = o;
-}
-
-uid uid_store_raw::insert( void* o )
-{
-	uid u = request_uid();
-	m_map[ u ] = o;
-	return u;
-}
-
-uid uid_store_raw::request_uid()
-{
-	return ++m_current;
-}
-
-uid_store_raw::~uid_store_raw()
-{
-	// no-op
-}
