Prechádzať zdrojové kódy

Merge branch 'master' of https://github.com/taylor001/crown

mikymod 11 rokov pred
rodič
commit
a2eae51bc7

+ 0 - 2
engine/Android.mk

@@ -125,8 +125,6 @@ LOCAL_SRC_FILES :=\
 	core/settings/StringSetting.cpp\
 \
 	core/strings/Path.cpp\
-\
-	core/Args.cpp\
 \
 	os/android/Android.cpp\
 	os/android/AndroidDevice.cpp\

+ 0 - 1
engine/CMakeLists.txt

@@ -40,7 +40,6 @@ set (HEADERS
 )
 
 set (CORE_SRC
-	core/Args.cpp
 )
 
 set (CORE_HEADERS

+ 1 - 2
engine/Device.cpp

@@ -145,8 +145,7 @@ void Device::init()
 
 	// Create resource manager
 	CE_LOGD("Creating resource manager...");
-	m_resource_manager = CE_NEW(m_allocator, ResourceManager)(*m_resource_bundle, 0);
-	CE_LOGD("Resource seed: %d", m_resource_manager->seed());
+	m_resource_manager = CE_NEW(m_allocator, ResourceManager)(*m_resource_bundle);
 
 	// Create world manager
 	CE_LOGD("Creating world manager...");

+ 3 - 0
engine/Device.h

@@ -133,6 +133,9 @@ public:
 	/// @note See video_modes().
 	virtual void set_display_mode(uint32_t id) = 0;
 
+	/// Sets whether in fullscreen or not.
+	virtual void set_fullscreen(bool full) = 0;
+
 	/// Updates all the subsystems
 	void frame();
 

+ 0 - 211
engine/core/Args.cpp

@@ -1,211 +0,0 @@
-/*
-Copyright (c) 2013 Daniele Bartolini, Michele Rossi
-Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include "Args.h"
-#include "Log.h"
-
-namespace crown
-{
-
-//-----------------------------------------------------------------------------
-Args::Args(int argc, char** argv, const char* shortopts, const ArgsOption* longopts)
-	: m_argc(argc)
-	, m_argv(argv)
-	, m_shortopts(shortopts)
-	, m_longopts(longopts)
-	, m_optind(1)				// Do not consider argv[0]
-	, m_scope(argc)
-	, m_optarg(NULL)
-{
-	CE_ASSERT(argv != NULL, "Argument vector must be != NULL");
-	CE_ASSERT(shortopts != NULL, "Short argument list must be != NULL");
-	// longopts could be NULL
-}
-
-//-----------------------------------------------------------------------------
-Args::~Args()
-{
-}
-
-//-----------------------------------------------------------------------------
-int32_t Args::getopt()
-{
-	// Always reset optarg
-	m_optarg = NULL;
-
-	// End of arguments
-	if (m_optind >= m_scope)
-	{
-		return -1;
-	}
-
-	switch (option_type(m_argv[m_optind]))
-	{
-		case AOT_SHORT:
-		{
-			return short_option(m_argv[m_optind]);
-		}
-		case AOT_LONG:
-		{
-			return long_option(m_argv[m_optind]);
-		}
-		case AOT_NOT_OPTION:
-		{
-			not_option();
-			return getopt();
-		}
-		default:
-		{
-			return '?';
-		}
-	}
-}
-
-//-----------------------------------------------------------------------------
-int32_t Args::optind() const
-{
-	return m_optind;
-}
-
-//-----------------------------------------------------------------------------
-const char* Args::optarg() const
-{
-	return m_optarg;
-}
-
-//-----------------------------------------------------------------------------
-void Args::set_optind(int32_t index)
-{
-	m_optind = index;
-}
-
-//-----------------------------------------------------------------------------
-ArgsOptionType Args::option_type(const char* option)
-{
-	const size_t option_len = string::strlen(option);
-
-	if (option_len == 2 && option[0] == '-' && option[1] != '-')
-	{
-		return AOT_SHORT;
-	}
-	else if (option_len > 2 && option[0] == '-' && option[1] == '-')
-	{
-		return AOT_LONG;
-	}
-
-	return AOT_NOT_OPTION;
-}
-
-//-----------------------------------------------------------------------------
-int32_t Args::long_option(const char* option)
-{
-	const ArgsOption* current_option = m_longopts;
-
-	// Loop through all the long options
-	while (!end_of_longopts(current_option))
-	{
-		if (string::strcmp(current_option->name, &option[2]) == 0)
-		{
-			// If the option requires an argument
-			if (current_option->has_arg == AOA_REQUIRED_ARGUMENT)
-			{
-				// Read the argument if it exists
-				if ((m_optind + 1) < m_scope)
-				{
-					// Read the argument and skip the following parameter
-					m_optarg = m_argv[m_optind + 1];
-					m_optind += 2;
-				}
-				else
-				{
-					// CE_LOGE("%s: option requires an argument -- '%s'", m_argv[0], current_option->name);
-
-					// Missing option
-					m_optind += 1;
-					return '?';
-				}
-			}
-			// If the option does not require an argument
-			else
-			{
-				m_optind++;
-			}
-
-			if (current_option->flag == NULL)
-			{
-				return current_option->val;
-			}
-			else
-			{
-				(*current_option->flag) = current_option->val;
-
-				return 0;
-			}
-		}
-
-		current_option++;
-	}
-
-	// Found a long option but was not included in longopts
-	// CE_LOGE("%s: invalid option -- '%s'", m_argv[0], &option[2]);
-	m_optind++;
-	return '?';
-}
-
-//-----------------------------------------------------------------------------
-int32_t Args::short_option(const char* option)
-{
-	(void)option;
-
-	// CE_LOGE("%s: invalid option -- '%s'", m_argv[0], &option[1]);
-	m_optind++;
-	return '?';
-}
-
-//-----------------------------------------------------------------------------
-void Args::not_option()
-{
-	char* current_option = m_argv[m_optind];
-
-	for (int32_t i = m_optind; i < (m_argc - 1); i++)
-	{
-		m_argv[i] = m_argv[i + 1];
-	}
-
-	m_argv[m_argc - 1] = current_option;
-
-	// Reduce the number of true arguments
-	m_scope--;
-}
-
-//-----------------------------------------------------------------------------
-bool Args::end_of_longopts(const ArgsOption* option) const
-{
-	return (option->name == NULL && option->has_arg == 0 && option->flag == NULL && option->val == 0);
-}
-
-
-} // namespace crown

+ 165 - 24
engine/core/Args.h

@@ -48,19 +48,30 @@ enum ArgsOptionArgument
 
 struct ArgsOption
 {
-	const char*				name;
-	int32_t					has_arg;
-	int32_t*				flag;
-	int32_t					val;
+	const char* name;
+	int32_t has_arg;
+	int32_t* flag;
+	int32_t val;
 };
 
 /// Parses the command line arguments in a way very similar to GNU getopt.
-class CE_EXPORT Args
+class Args
 {
 public:
 
-						Args(int argc, char** argv, const char* shortopts, const ArgsOption* longopts);
-						~Args();
+	Args(int argc, char** argv, const char* shortopts, const ArgsOption* longopts)
+		: m_argc(argc)
+		, m_argv(argv)
+		, m_shortopts(shortopts)
+		, m_longopts(longopts)
+		, m_optind(1)				// Do not consider argv[0]
+		, m_scope(argc)
+		, m_optarg(NULL)
+	{
+		CE_ASSERT(argv != NULL, "Argument vector must be != NULL");
+		CE_ASSERT(shortopts != NULL, "Short argument list must be != NULL");
+		// longopts could be NULL
+	}
 
 	/// Finds the next option character and returns it.
 	/// If there are no more option characters, it returns -1 and optind()
@@ -68,19 +79,59 @@ public:
 	/// an option.
 	/// If it finds an option that was not included in shortopts or longopts,
 	/// or if it finds a missing option argument, it returns '?' character.
-	int32_t				getopt();
+	int32_t getopt()
+	{
+		// Always reset optarg
+		m_optarg = NULL;
+
+		// End of arguments
+		if (m_optind >= m_scope)
+		{
+			return -1;
+		}
+
+		switch (option_type(m_argv[m_optind]))
+		{
+			case AOT_SHORT:
+			{
+				return short_option(m_argv[m_optind]);
+			}
+			case AOT_LONG:
+			{
+				return long_option(m_argv[m_optind]);
+			}
+			case AOT_NOT_OPTION:
+			{
+				not_option();
+				return getopt();
+			}
+			default:
+			{
+				return '?';
+			}
+		}
+	}
 
 	/// Returns the index of the next argument to be processed.
-	int32_t				optind() const;
+	int32_t optind() const
+	{
+		return m_optind;
+	}
 
 	/// Returns the text of the following argv-element in respect
 	/// to the current optind().
-	const char*			optarg() const;
+	const char* optarg() const
+	{
+		return m_optarg;
+	}
 
 
 	/// Sets the @a index into argv[] from where to start option scanning.
 	/// If @a index >= argc nothing will be scanned.
-	void				set_optind(int32_t index);
+	void set_optind(int32_t index)
+	{
+		m_optind = index;
+	}
 
 private:
 
@@ -88,36 +139,126 @@ private:
 	// Returns AOT_SHORT if option is of the form "-x" where 'x' is the option.
 	// Returns AOT_LONG if option is of the form "--option" where "option" is the option.
 	// Returns AOT_NOT_OPTION in all other cases.
-	ArgsOptionType		option_type(const char* option);
+	ArgsOptionType option_type(const char* option)
+	{
+		const size_t option_len = string::strlen(option);
+
+		if (option_len == 2 && option[0] == '-' && option[1] != '-')
+		{
+			return AOT_SHORT;
+		}
+		else if (option_len > 2 && option[0] == '-' && option[1] == '-')
+		{
+			return AOT_LONG;
+		}
+
+		return AOT_NOT_OPTION;
+	}
+
 
 	// Parses a long option
-	int32_t				long_option(const char* option);
+	int32_t long_option(const char* option)
+	{
+		const ArgsOption* current_option = m_longopts;
+
+		// Loop through all the long options
+		while (!end_of_longopts(current_option))
+		{
+			if (string::strcmp(current_option->name, &option[2]) == 0)
+			{
+				// If the option requires an argument
+				if (current_option->has_arg == AOA_REQUIRED_ARGUMENT)
+				{
+					// Read the argument if it exists
+					if ((m_optind + 1) < m_scope)
+					{
+						// Read the argument and skip the following parameter
+						m_optarg = m_argv[m_optind + 1];
+						m_optind += 2;
+					}
+					else
+					{
+						// CE_LOGE("%s: option requires an argument -- '%s'", m_argv[0], current_option->name);
+
+						// Missing option
+						m_optind += 1;
+						return '?';
+					}
+				}
+				// If the option does not require an argument
+				else
+				{
+					m_optind++;
+				}
+
+				if (current_option->flag == NULL)
+				{
+					return current_option->val;
+				}
+				else
+				{
+					(*current_option->flag) = current_option->val;
+
+					return 0;
+				}
+			}
+
+			current_option++;
+		}
+
+		// Found a long option but was not included in longopts
+		// CE_LOGE("%s: invalid option -- '%s'", m_argv[0], &option[2]);
+		m_optind++;
+		return '?';
+	}
 
 	// Parses a short option
-	int32_t				short_option(const char* option);
+	int32_t short_option(const char* option)
+	{
+		(void)option;
+
+		// CE_LOGE("%s: invalid option -- '%s'", m_argv[0], &option[1]);
+		m_optind++;
+		return '?';
+	}
 
-	void				not_option();
+	void not_option()
+	{
+		char* current_option = m_argv[m_optind];
+
+		for (int32_t i = m_optind; i < (m_argc - 1); i++)
+		{
+			m_argv[i] = m_argv[i + 1];
+		}
+
+		m_argv[m_argc - 1] = current_option;
+
+		// Reduce the number of true arguments
+		m_scope--;
+	}
 
 	// Returns whether the given option is the last one
-	bool				end_of_longopts(const ArgsOption* option) const;
+	bool end_of_longopts(const ArgsOption* option) const
+	{
+		return (option->name == NULL && option->has_arg == 0 && option->flag == NULL && option->val == 0);
+	}
 
 private:
 
-	int					m_argc;
-	char**				m_argv;
+	int m_argc;
+	char** m_argv;
 
-	const char*			m_shortopts;
-	const ArgsOption*	m_longopts;
+	const char* m_shortopts;
+	const ArgsOption* m_longopts;
 
 	// Index of the next argument to be processed
-	int32_t				m_optind;
+	int32_t m_optind;
 
 	// Number of "true" arguments
-	int32_t				m_scope;
+	int32_t m_scope;
 
 	// The text of the following argv-element to argv[optind]
-	char*				m_optarg;
+	char* m_optarg;
 };
 
 } // namespace crown
-

+ 1 - 2
engine/core/containers/Hash.h

@@ -27,7 +27,6 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #include "Array.h"
 #include "ContainerTypes.h"
-#include <algorithm>
 
 namespace crown {
 
@@ -103,7 +102,7 @@ namespace crown {
 			uint32_t hash_i;
 			uint32_t data_prev;
 			uint32_t data_i;
-		};	
+		};
 
 		template<typename T> uint32_t add_entry(Hash<T> &h, uint64_t key)
 		{

+ 8 - 0
engine/lua/LuaDevice.cpp

@@ -191,6 +191,13 @@ static int device_set_display_mode(lua_State* L)
 	return 0;
 }
 
+//-----------------------------------------------------------------------------
+static int device_set_fullscreen(lua_State* L)
+{
+	LuaStack stack(L);
+	device()->set_fullscreen(stack.get_bool(1));
+	return 0;
+}
 
 //-----------------------------------------------------------------------------
 void load_device(LuaEnvironment& env)
@@ -208,6 +215,7 @@ void load_device(LuaEnvironment& env)
 	env.load_module_function("Device", "destroy_resource_package", device_destroy_resource_package);
 	env.load_module_function("Device", "display_modes",            device_display_modes);
 	env.load_module_function("Device", "set_display_mode",         device_set_display_mode);
+	env.load_module_function("Device", "set_fullscreen",           device_set_fullscreen);
 }
 
 } // namespace crown

+ 0 - 26
engine/lua/LuaGui.cpp

@@ -71,30 +71,6 @@ static int gui_screen_to_gui(lua_State* L)
 	return 1;
 }
 
-//-----------------------------------------------------------------------------
-static int gui_show(lua_State* L)
-{
-	LuaStack stack(L);
-
-	Gui* gui = stack.get_gui(1);
-
-	gui->show();
-
-	return 0;
-}
-
-//-----------------------------------------------------------------------------
-static int gui_hide(lua_State* L)
-{
-	LuaStack stack(L);
-
-	Gui* gui = stack.get_gui(1);
-
-	gui->hide();
-
-	return 0;
-}
-
 //-----------------------------------------------------------------------------
 static int gui_draw_rectangle(lua_State* L)
 {
@@ -131,8 +107,6 @@ void load_gui(LuaEnvironment& env)
 	env.load_module_function("Gui", "resolution",		gui_resolution);
 	env.load_module_function("Gui", "move",				gui_move);
 	env.load_module_function("Gui", "screen_to_gui",	gui_screen_to_gui);
-	env.load_module_function("Gui", "show",				gui_show);
-	env.load_module_function("Gui", "hide",				gui_hide);
 
 	env.load_module_function("Gui", "draw_rectangle",	gui_draw_rectangle);
 	env.load_module_function("Gui", "draw_image",		gui_draw_image);

+ 6 - 0
engine/os/android/AndroidDevice.cpp

@@ -61,6 +61,12 @@ public:
 		// Do nothing
 	}
 
+	//-----------------------------------------------------------------------------
+	void set_fullscreen(bool /*full*/)
+	{
+		// Do nothing
+	}
+
 	//-----------------------------------------------------------------------------
 	int32_t run(int, char**)
 	{

+ 14 - 0
engine/os/linux/main.cpp

@@ -223,6 +223,20 @@ public:
 							CurrentTime);
 	}
 
+	//-----------------------------------------------------------------------------
+	void set_fullscreen(bool full)
+	{
+		XEvent e;
+		e.xclient.type = ClientMessage;
+		e.xclient.window = m_x11_window;
+		e.xclient.message_type = XInternAtom(m_x11_display, "_NET_WM_STATE", False );
+		e.xclient.format = 32;
+		e.xclient.data.l[0] = full ? 1 : 0;
+		e.xclient.data.l[1] = XInternAtom(m_x11_display, "_NET_WM_STATE_FULLSCREEN", False);
+
+		XSendEvent(m_x11_display, DefaultRootWindow(m_x11_display), False, SubstructureNotifyMask, &e);
+	}
+
 	//-----------------------------------------------------------------------------
 	int32_t run(int argc, char** argv)
 	{

+ 6 - 0
engine/os/win/main.cpp

@@ -197,6 +197,12 @@ public:
 		#error "Implement me"
 	}
 
+	//-----------------------------------------------------------------------------
+	void set_fullscreen(bool full)
+	{
+		#error "Implement me"
+	}
+
 	//-----------------------------------------------------------------------------
 	int32_t	run(int argc, char** argv)
 	{

+ 3 - 16
engine/renderers/Gui.cpp

@@ -106,7 +106,6 @@ Gui::Gui(RenderWorld& render_world, uint16_t width, uint16_t height)
 	, m_width(width)
 	, m_height(height)
 	, m_pose(matrix4x4::IDENTITY)
-	, m_visible(true)
 {
 	set_orthographic_rh(m_projection, 0, width, 0, height, -0.01f, 100.0f);
 }
@@ -142,18 +141,6 @@ Vector2 Gui::screen_to_gui(const Vector2& pos)
 	return Vector2(pos.x, m_height - pos.y);
 }
 
-//-----------------------------------------------------------------------------
-void Gui::show()
-{
-	m_visible = true;
-}
-
-//-----------------------------------------------------------------------------
-void Gui::hide()
-{
-	m_visible = false;
-}
-
 //-----------------------------------------------------------------------------
 void Gui::draw_rectangle(const Vector3& pos, const Vector2& size, const Color4& color)
 {
@@ -197,7 +184,7 @@ void Gui::draw_rectangle(const Vector3& pos, const Vector2& size, const Color4&
 	r->set_uniform(render_world_globals::default_color_uniform(), UniformType::FLOAT_4, color4::to_float_ptr(color), 1);
 	r->set_vertex_buffer(tvb);
 	r->set_index_buffer(tib);
-	r->commit(1);
+	r->commit(1, (int32_t) pos.z);
 }
 
 //-----------------------------------------------------------------------------
@@ -256,7 +243,7 @@ void Gui::draw_image(const char* material, const Vector3& pos, const Vector2& si
 	r->set_uniform(render_world_globals::default_color_uniform(), UniformType::FLOAT_4, color4::to_float_ptr(color), 1);
 	r->set_vertex_buffer(tvb);
 	r->set_index_buffer(tib);
-	r->commit(1);
+	r->commit(1, (int32_t) pos.z);
 }
 
 //-----------------------------------------------------------------------------
@@ -383,7 +370,7 @@ void Gui::draw_text(const char* str, const char* font, uint32_t font_size, const
 	r->set_uniform(render_world_globals::default_color_uniform(), UniformType::FLOAT_4, color4::to_float_ptr(color), 1);
 	r->set_vertex_buffer(vb);
 	r->set_index_buffer(ib);
-	r->commit(1);
+	r->commit(1, (int32_t) pos.z);
 }
 
 } // namespace crown

+ 11 - 5
engine/renderers/Gui.h

@@ -35,6 +35,9 @@ namespace crown
 
 class RenderWorld;
 
+/// Manages the rendering of GUI objects.
+///
+/// @ingroup Graphics
 struct Gui
 {
 	Gui(RenderWorld& render_world, uint16_t width, uint16_t height);
@@ -47,11 +50,16 @@ struct Gui
 
 	Vector2 screen_to_gui(const Vector2& pos);
 
-	void show();
-	void hide();
-
+	/// Draws a rectangle of size @a size at @a pos.
+	/// @note Higher values of pos.z make the object appear in front of other objects.
 	void draw_rectangle(const Vector3& pos, const Vector2& size, const Color4& color = Color4::WHITE);
+
+	/// Draws an image with the given @a material.
+	/// @note Higher values of pos.z make the object appear in front of other objects.
 	void draw_image(const char* material, const Vector3& pos, const Vector2& size, const Color4& color = Color4::WHITE);
+
+	/// Draws the text @a str with the given @a font and @a font_size.
+	/// @note Higher values of pos.z make the object appear in front of other objects.
 	void draw_text(const char* str, const char* font, uint32_t font_size, const Vector3& pos, const Color4& color = Color4::WHITE);
 
 public:
@@ -64,8 +72,6 @@ public:
 
 	Matrix4x4 m_projection;
 	Matrix4x4 m_pose;
-
-	bool m_visible;
 };
 
 } // namespace crown

+ 7 - 2
engine/renderers/backend/RenderContext.h

@@ -226,17 +226,21 @@ struct RenderKey
 
 	uint64_t encode()
 	{
-		return uint64_t(m_layer) << RENDER_LAYER_SHIFT;
+		const uint64_t a = uint64_t(m_layer) << RENDER_LAYER_SHIFT;
+		const uint64_t b = m_depth;
+		return a | b;
 	}
 
 	void decode(uint64_t key)
 	{
 		m_layer = (key & RENDER_LAYER_MASK) >> RENDER_LAYER_SHIFT;
+		m_depth = (key & 0xFFFFFFFF);
 	}
 
 public:
 
 	uint8_t m_layer;
+	int32_t m_depth;
 };
 
 struct SortKey
@@ -417,10 +421,11 @@ struct RenderContext
 		m_scissors[layer].m_height = height;
 	}
 
-	void commit(uint8_t layer)
+	void commit(uint8_t layer, int32_t depth)
 	{
 		CE_ASSERT(layer < MAX_RENDER_LAYERS, "Layer out of bounds");
 		m_render_key.m_layer = layer;
+		m_render_key.m_depth = depth;
 
 		m_state.begin_uniform = m_last_uniform_offset;
 		m_state.end_uniform = m_constants.position();

+ 2 - 2
engine/renderers/backend/Renderer.h

@@ -845,9 +845,9 @@ public:
 		m_submit->set_layer_scissor(layer, x, y, width, height);
 	}
 
-	void commit(uint8_t layer)
+	void commit(uint8_t layer, int32_t depth = 0)
 	{
-		m_submit->commit(layer);
+		m_submit->commit(layer, depth);
 	}
 
 	static int32_t render_thread(void* thiz)

+ 1 - 0
engine/resource/MaterialResource.h

@@ -90,6 +90,7 @@ public:
 	//-----------------------------------------------------------------------------
 	ResourceId get_texture_layer(uint32_t i) const
 	{
+		CE_ASSERT(i < num_texture_layers(), "Index out of bounds");
 		MaterialHeader* h = (MaterialHeader*) this;
 		ResourceId* begin = (ResourceId*) (((char*) this) + h->texture_layers_offset);
 		return begin[i];

+ 2 - 0
engine/resource/Resource.h

@@ -72,6 +72,8 @@ struct ResourceId
 	ResourceId(const char* type, const char* name);
 	ResourceId(const char* name);
 
+	bool operator==(const ResourceId& a) const { return id == a.id; }
+
 	uint64_t id;
 };
 

+ 20 - 29
engine/resource/ResourceManager.cpp

@@ -46,7 +46,7 @@ ResourceId::ResourceId(const char* type, const char* name)
 	res_name += '.';
 	res_name += type;
 
-	id = string::murmur2_64(res_name.c_str(), string::strlen(res_name.c_str()), 0);
+	id = string::murmur2_64(res_name.c_str(), res_name.length(), 0);
 }
 
 ResourceId::ResourceId(const char* name)
@@ -55,12 +55,11 @@ ResourceId::ResourceId(const char* name)
 }
 
 //-----------------------------------------------------------------------------
-ResourceManager::ResourceManager(Bundle& bundle, uint32_t seed) :
-	m_resource_heap("resource", default_allocator()),
-	m_loader(bundle, m_resource_heap),
-	m_seed(seed),
-	m_pendings(default_allocator()),
-	m_resources(default_allocator())
+ResourceManager::ResourceManager(Bundle& bundle)
+	: m_resource_heap("resource", default_allocator())
+	, m_loader(bundle, m_resource_heap)
+	, m_pendings(default_allocator())
+	, m_resources(default_allocator())
 {
 	m_loader.start();
 }
@@ -85,13 +84,16 @@ void ResourceManager::unload(ResourceId name, bool force)
 	ResourceEntry* entry = find(name);
 
 	entry->references--;
-	
+
 	if (entry->references == 0 || force)
 	{
 		resource_on_offline(entry->type, entry->resource);
 		resource_on_unload(entry->type, m_resource_heap, entry->resource);
 
-		hash::remove(m_resources, name.id);
+		// Swap with last
+		ResourceEntry temp = m_resources[array::size(m_resources) - 1];
+		(*entry) = temp;
+		array::pop_back(m_resources);
 	}
 }
 
@@ -106,7 +108,6 @@ bool ResourceManager::has(ResourceId name) const
 //-----------------------------------------------------------------------------
 const void* ResourceManager::get(const char* type, const char* name) const
 {
-
 	ResourceEntry* entry = find(ResourceId(type, name));
 
 	CE_ASSERT(entry != NULL, "Resource not loaded: type = '%s', name = '%s'", type, name);
@@ -148,23 +149,12 @@ void ResourceManager::flush()
 	}
 }
 
-//-----------------------------------------------------------------------------
-uint32_t ResourceManager::seed() const
-{
-	return m_seed;
-}
-
 //-----------------------------------------------------------------------------
 ResourceEntry* ResourceManager::find(ResourceId id) const
 {
-	ResourceEntry deff;
-	deff.type = 0xFFFFFFFFu;
-	deff.references = 0xFFFFFFFFu;
-	deff.resource = NULL;
-
-	const ResourceEntry& entry = hash::get(m_resources, id.id, deff);
+	const ResourceEntry* entry = std::find(array::begin(m_resources), array::end(m_resources), id);
 
-	return memcmp(&deff, &entry, sizeof(ResourceEntry)) == 0 ? NULL : const_cast<ResourceEntry*>(&entry);
+	return entry != array::end(m_resources) ? const_cast<ResourceEntry*>(entry) : NULL;
 }
 
 //-----------------------------------------------------------------------------
@@ -193,13 +183,14 @@ ResourceId ResourceManager::load(uint32_t type, ResourceId name)
 	// If resource not found, create a new one
 	if (entry == NULL)
 	{
-		ResourceEntry new_entry;
+		ResourceEntry entry;
 
-		new_entry.type = type;
-		new_entry.references = 1;
-		new_entry.resource = NULL;
+		entry.id = name;
+		entry.type = type;
+		entry.references = 1;
+		entry.resource = NULL;
 
-		hash::set(m_resources, name.id, new_entry);
+		array::push_back(m_resources, entry);
 
 		// Issue request to resource loader
 		PendingRequest pr;
@@ -214,7 +205,7 @@ ResourceId ResourceManager::load(uint32_t type, ResourceId name)
 	// Else, increment its reference count
 	entry->references++;
 
-	return name;
+	return entry->id;
 }
 
 //-----------------------------------------------------------------------------

+ 11 - 13
engine/resource/ResourceManager.h

@@ -31,16 +31,19 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Resource.h"
 #include "ProxyAllocator.h"
 #include "ResourceLoader.h"
-#include "Hash.h"
 
 namespace crown
 {
 
 struct ResourceEntry
 {
-	uint32_t type;
-	uint32_t references;
-	void* resource;
+	bool operator==(const ResourceId& resource) const { return id == resource; }
+	bool operator==(const ResourceEntry& b) const { return id == b.id; }
+
+	ResourceId		id;
+	uint32_t		type;
+	uint32_t		references;
+	void*			resource;
 };
 
 struct PendingRequest
@@ -52,17 +55,13 @@ struct PendingRequest
 
 class Bundle;
 
-/// @defgroup Resource Resource.
-
 /// Keeps track and manages resources loaded by ResourceLoader.
-///
-/// @ingroup Resource
 class ResourceManager
 {
 public:
 
 	/// The resources will be loaded from @a bundle.
-	ResourceManager(Bundle& bundle, uint32_t seed);
+	ResourceManager(Bundle& bundle);
 	~ResourceManager();
 
 	/// Loads the resource by @a type and @a name and returns its ResourceId.
@@ -102,11 +101,10 @@ public:
 	/// Forces all of the loading requests to complete before preceeding.
 	void flush();
 
-	/// Returns the seed used to generate resource name hashes.
-	uint32_t seed() const;
-
 private:
 
+
+	// Returns the entry of the given id.
 	ResourceEntry* find(ResourceId id) const;
 
 	// Polls the resource loader for loaded resources.
@@ -123,7 +121,7 @@ private:
 	uint32_t m_seed;
 
 	Queue<PendingRequest> m_pendings;
-	Hash<ResourceEntry> m_resources;
+	Array<ResourceEntry> m_resources;
 
 private:
 

+ 4 - 1
engine/resource/ResourcePackage.h

@@ -42,7 +42,10 @@ public:
 
 	//-----------------------------------------------------------------------------
 	ResourcePackage(ResourceManager& resman, const ResourceId id, const PackageResource* package)
-		: m_resource_manager(&resman), m_package_id(id), m_package(package), m_has_loaded(false)
+		: m_resource_manager(&resman)
+		, m_package_id(id)
+		, m_package(package)
+		, m_has_loaded(false)
 	{
 		CE_ASSERT_NOT_NULL(package);
 	}