Преглед изворни кода

Simplify resource compilers

Daniele Bartolini пре 12 година
родитељ
комит
c31973d583

+ 16 - 34
engine/CMakeLists.txt

@@ -81,14 +81,6 @@ set (CROWN_INCLUDES
 	${CMAKE_SOURCE_DIR}/engine/lua
 	${CMAKE_SOURCE_DIR}/engine/audio
 	${CMAKE_SOURCE_DIR}/engine/compilers
-	${CMAKE_SOURCE_DIR}/engine/compilers/lua
-	${CMAKE_SOURCE_DIR}/engine/compilers/texture
-	${CMAKE_SOURCE_DIR}/engine/compilers/sound
-	${CMAKE_SOURCE_DIR}/engine/compilers/mesh
-	${CMAKE_SOURCE_DIR}/engine/compilers/package
-	${CMAKE_SOURCE_DIR}/engine/compilers/unit
-	${CMAKE_SOURCE_DIR}/engine/compilers/sprite
-	${CMAKE_SOURCE_DIR}/engine/compilers/physics
 	${CMAKE_SOURCE_DIR}/engine/physics
 )
 
@@ -301,16 +293,16 @@ set (RESOURCE_SRC
 	resource/ResourceLoader.cpp
 	resource/ResourceManager.cpp
 	resource/ResourceRegistry.cpp
+	resource/UnitResource.cpp
+	resource/TextureResource.cpp
+	resource/SpriteResource.cpp
+	resource/SoundResource.cpp
+	resource/PhysicsResource.cpp
+	resource/PackageResource.cpp
+	resource/MeshResource.cpp
+	resource/LuaResource.cpp
 )
 
-if (CROWN_DEBUG OR CROWN_DEVELOPMENT)
-	list (APPEND RESOURCE_SRC resource/FileBundle.cpp)
-elseif (CROWN_RELEASE)
-	list (APPEND RESOURCE_SRC resource/ArchiveBundle.cpp)
-else ()
-	message (FATAL_ERROR "Oops, you should not be here")
-endif (CROWN_DEBUG OR CROWN_DEVELOPMENT)
-
 set (RESOURCE_HEADERS
 	resource/Resource.h
 	resource/ResourceLoader.h
@@ -330,6 +322,14 @@ set (RESOURCE_HEADERS
 	resource/PhysicsResource.h
 )
 
+if (CROWN_DEBUG OR CROWN_DEVELOPMENT)
+	list (APPEND RESOURCE_SRC resource/FileBundle.cpp)
+elseif (CROWN_RELEASE)
+	list (APPEND RESOURCE_SRC resource/ArchiveBundle.cpp)
+else ()
+	message (FATAL_ERROR "Oops, you should not be here")
+endif (CROWN_DEBUG OR CROWN_DEVELOPMENT)
+
 set (OS_SRC
 )
 
@@ -395,29 +395,11 @@ set (PHYSICS_HEADERS
 )
 
 set (COMPILER_SRC
-	compilers/Compiler.cpp
 	compilers/BundleCompiler.cpp
-	compilers/mesh/MeshCompiler.cpp
-	compilers/lua/LuaCompiler.cpp
-	compilers/texture/TextureCompiler.cpp
-	compilers/sound/SoundCompiler.cpp
-	compilers/package/PackageCompiler.cpp
-	compilers/unit/UnitCompiler.cpp
-	compilers/sprite/SpriteCompiler.cpp
-	compilers/physics/PhysicsCompiler.cpp
 )
 
 set (COMPILER_HEADER
-	compilers/Compiler.h
 	compilers/BundleCompiler.h
-	compilers/mesh/MeshCompiler.h
-	compilers/lua/LuaCompiler.h
-	compilers/texture/TextureCompiler.h
-	compilers/sound/SoundCompiler.h
-	compilers/package/PackageCompiler.h
-	compilers/unit/UnitCompiler.h
-	compilers/sprite/SpriteCompiler.h
-	compilers/physics/PhysicsCompiler.h
 )
 
 set (CROWN_LIBRARIES)

+ 56 - 42
engine/compilers/BundleCompiler.cpp

@@ -39,6 +39,15 @@ OTHER DEALINGS IN THE SOFTWARE.
 namespace crown
 {
 
+namespace mesh_resource { extern void compile(Filesystem&, const char*, File*); }
+namespace texture_resource { extern void compile(Filesystem&, const char*, File*); }
+namespace package_resource { extern void compile(Filesystem&, const char*, File*); }
+namespace lua_resource { extern void compile(Filesystem&, const char*, File*); }
+namespace physics_resource { extern void compile(Filesystem&, const char*, File*); }
+namespace unit_resource { extern void compile(Filesystem&, const char*, File*); }
+namespace sound_resource { extern void compile(Filesystem&, const char*, File*); }
+namespace sprite_resource { extern void compile(Filesystem&, const char*, File*); }
+
 //-----------------------------------------------------------------------------
 BundleCompiler::BundleCompiler()
 {
@@ -107,48 +116,53 @@ bool BundleCompiler::compile(const char* bundle_dir, const char* source_dir, con
 
 		Log::i("%s <= %s", out_name, filename);
 
-		bool result = false;
-		if (resource_type_hash == MESH_TYPE)
-		{
-			result = m_mesh.compile(source_dir, bundle_dir, filename, out_name);
-		}
-		else if (resource_type_hash == TEXTURE_TYPE)
-		{
-			result = m_texture.compile(source_dir, bundle_dir, filename, out_name);
-		}
-		else if (resource_type_hash == LUA_TYPE)
-		{
-			result = m_lua.compile(source_dir, bundle_dir, filename, out_name);
-		}
-		else if(resource_type_hash == SOUND_TYPE)
-		{
-			result = m_sound.compile(source_dir, bundle_dir, filename, out_name);
-		}
-		else if(resource_type_hash == SPRITE_TYPE)
-		{
-			result = m_sprite.compile(source_dir, bundle_dir, filename, out_name);
-		}
-		else if (resource_type_hash == PACKAGE_TYPE)
-		{
-			result = m_package.compile(source_dir, bundle_dir, filename, out_name);
-		}
-		else if (resource_type_hash == UNIT_TYPE)
-		{
-			result = m_unit.compile(source_dir, bundle_dir, filename, out_name);
-		}
-		else if (resource_type_hash == PHYSICS_TYPE)
-		{
-			result = m_physics.compile(source_dir, bundle_dir, filename, out_name);
-		}
-		else
-		{
-			Log::e("Oops, unknown resource type!");
-			return false;
-		}
-
-		if (!result)
-		{
-			return false;
+		DiskFilesystem root_fs(source_dir);
+		DiskFilesystem dest_fs(bundle_dir);
+
+		// Open destination file
+		File* out_file = dest_fs.open(out_name, FOM_WRITE);
+
+		if (out_file)
+		{
+			if (resource_type_hash == MESH_TYPE)
+			{
+				mesh_resource::compile(root_fs, filename, out_file);
+			}
+			else if (resource_type_hash == TEXTURE_TYPE)
+			{
+				texture_resource::compile(root_fs, filename, out_file);
+			}
+			else if (resource_type_hash == LUA_TYPE)
+			{
+				lua_resource::compile(root_fs, filename, out_file);
+			}
+			else if(resource_type_hash == SOUND_TYPE)
+			{
+				sound_resource::compile(root_fs, filename, out_file);
+			}
+			else if(resource_type_hash == SPRITE_TYPE)
+			{
+				sprite_resource::compile(root_fs, filename, out_file);
+			}
+			else if (resource_type_hash == PACKAGE_TYPE)
+			{
+				package_resource::compile(root_fs, filename, out_file);
+			}
+			else if (resource_type_hash == UNIT_TYPE)
+			{
+				unit_resource::compile(root_fs, filename, out_file);
+			}
+			else if (resource_type_hash == PHYSICS_TYPE)
+			{
+				physics_resource::compile(root_fs, filename, out_file);
+			}
+			else
+			{
+				Log::e("Oops, unknown resource type!");
+				return false;
+			}
+
+			dest_fs.close(out_file);
 		}
 	}
 

+ 1 - 20
engine/compilers/BundleCompiler.h

@@ -26,17 +26,9 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #pragma once
 
-#include "MeshCompiler.h"
-#include "TextureCompiler.h"
-#include "LuaCompiler.h"
-#include "SoundCompiler.h"
-#include "SpriteCompiler.h"
-#include "PackageCompiler.h"
+#include "DiskFilesystem.h"
 #include "DynamicString.h"
 #include "Vector.h"
-#include "DiskFilesystem.h"
-#include "UnitCompiler.h"
-#include "PhysicsCompiler.h"
 
 namespace crown
 {
@@ -55,17 +47,6 @@ public:
 private:
 
 	static void scan(const char* source_dir, const char* cur_dir, Vector<DynamicString>& files);
-
-private:
-
-	MeshCompiler	m_mesh;
-	TextureCompiler	m_texture;
-	LuaCompiler 	m_lua;
-	SoundCompiler	m_sound;
-	SpriteCompiler	m_sprite;
-	PackageCompiler m_package;
-	UnitCompiler	m_unit;
-	PhysicsCompiler m_physics;
 };
 
 } // namespace crown

+ 0 - 72
engine/compilers/Compiler.cpp

@@ -1,72 +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 "Compiler.h"
-#include "Filesystem.h"
-#include "DiskFilesystem.h"
-#include "File.h"
-#include "Log.h"
-
-namespace crown
-{
-
-//-----------------------------------------------------------------------------
-bool Compiler::compile(const char* root_path, const char* dest_path, const char* name_in, const char* name_out)
-{
-	DiskFilesystem root_fs(root_path);
-	DiskFilesystem dest_fs(dest_path);
-
-	// The compilation fails when returned size is zero
-	size_t resource_size = 0;
-	if ((resource_size = compile_impl(root_fs, name_in)) == 0)
-	{
-		Log::e("Compilation failed");
-		return false;
-	}
-
-	// Open destination file
-	File* out_file = dest_fs.open(name_out, FOM_WRITE);
-
-	if (out_file)
-	{
-		// Write data
-		write_impl(out_file);
-		dest_fs.close(out_file);
-		cleanup();
-		return true;
-	}
-
-	Log::e("Unable to write compiled file.");
-	return false;
-}
-
-//-----------------------------------------------------------------------------
-void Compiler::cleanup()
-{
-}
-
-} // namespace crown
-

+ 0 - 66
engine/compilers/Compiler.h

@@ -1,66 +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.
-*/
-
-#pragma once
-
-#include "Types.h"
-
-namespace crown
-{
-
-class Filesystem;
-class File;
-
-/// Resource compiler interface.
-/// Every specific resource compiler must implement this interface.
-class Compiler
-{
-public:
-
-	virtual					~Compiler() {}
-
-	/// Compiles the @name_in resource coming from @a root_path
-	/// in a engine-ready format and puts it into @a dest_path with the @a name_out name.
-	/// Returns true whether the copilation was successfull, false otherwise.
-	bool					compile(const char* root_path, const char* dest_path, const char* name_in, const char* name_out);
-	
-	/// Clears all the temporary stuctures used to compile
-	/// the resource.
-	void					cleanup();
-
-protected:
-
-	/// Compiles the resource found at @a resource path. A Filesystem instance is
-	/// passed along to be able to read resource data. The implementer must care
-	/// of returning the total size in bytes of the compiled resource or 0 if an
-	/// error occurs.
-	virtual size_t			compile_impl(Filesystem& fs, const char* resource_path) = 0;
-
-	/// Writes the compiled resource to @a out_file.
-	virtual void			write_impl(File* out_file) = 0;
-};
-
-} // namespace crown

+ 0 - 50
engine/compilers/lua/LuaCompiler.h

@@ -1,50 +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.
-*/
-
-#pragma once
-
-#include "Compiler.h"
-
-namespace crown
-{
-
-class CE_EXPORT LuaCompiler : public Compiler
-{
-public:
-
-					LuaCompiler();
-					~LuaCompiler();
-
-	size_t			compile_impl(Filesystem& fs, const char* resource_path);
-	void			write_impl(File* out_file);
-
-private:
-
-	size_t			m_luajit_blob_size;
-	char*			m_luajit_blob;
-};
-
-} // namespace crown

+ 0 - 72
engine/compilers/mesh/MeshCompiler.h

@@ -1,72 +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.
-*/
-
-#pragma once
-
-#include "Compiler.h"
-#include "MeshResource.h"
-#include "Vector3.h"
-#include "Vector2.h"
-#include "List.h"
-
-namespace crown
-{
-
-struct MeshVertex
-{
-	Vector3 position;
-	Vector3 normal;
-	Vector2 texcoord;
-
-	bool operator==(const MeshVertex& other)
-	{
-		return position == other.position &&
-				normal == other.normal &&
-				texcoord == other.texcoord;
-	}
-};
-
-class CE_EXPORT MeshCompiler : public Compiler
-{
-public:
-
-						MeshCompiler();
-						~MeshCompiler();
-
-	size_t				compile_impl(Filesystem& fs, const char* resource_path);
-	void				write_impl(File* out_file);
-
-private:
-
-	MeshHeader			m_mesh_header;
-	bool				m_has_normal;
-	bool				m_has_texcoord;
-
-	List<MeshVertex>	m_vertices;
-	List<uint16_t>		m_indices;
-};
-
-} // namespace crown

+ 0 - 56
engine/compilers/package/PackageCompiler.h

@@ -1,56 +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.
-*/
-
-#pragma once
-
-#include "Compiler.h"
-#include "Resource.h"
-#include "List.h"
-
-namespace crown
-{
-
-class CE_EXPORT PackageCompiler : public Compiler
-{
-public:
-
-	PackageCompiler();
-
-	size_t compile_impl(Filesystem& fs, const char* resource_path);
-	void write_impl(File* out_file);
-
-private:
-
-	List<ResourceId> m_texture;
-	List<ResourceId> m_script;
-	List<ResourceId> m_sound;
-	List<ResourceId> m_mesh;
-	List<ResourceId> m_unit;
-	List<ResourceId> m_sprite;
-	List<ResourceId> m_physics;
-};
-
-} // namespace crown

+ 0 - 57
engine/compilers/physics/PhysicsCompiler.h

@@ -1,57 +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.
-*/
-
-#pragma once
-
-#include "Types.h"
-#include "PhysicsResource.h"
-#include "Compiler.h"
-#include "JSONParser.h"
-
-namespace crown
-{
-
-class Filesystem;
-
-//-----------------------------------------------------------------------------
-class PhysicsCompiler : public Compiler
-{
-public:
-							PhysicsCompiler();
-							~PhysicsCompiler();
-
-	size_t					compile_impl(Filesystem& fs, const char* resource_path);
-	void					write_impl(File* out_file);
-
-	void					parse_controller(JSONElement controller);
-
-private:
-
-	bool					m_has_controller;
-	PhysicsController		m_controller;
-};
-
-} // namespace crown

+ 0 - 79
engine/compilers/sound/SoundCompiler.h

@@ -1,79 +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.
-*/
-
-#pragma once
-
-#include <cstdio>
-
-#include "Compiler.h"
-#include "SoundResource.h"
-#include "Types.h"
-
-namespace crown
-{
-
-//-----------------------------------------------------------------------------
-struct WAVHeader
-{
-	char 			riff[4];				// Should contains 'RIFF'
-	int32_t			chunk_size;				// Not Needed
-	char 			wave[4];				// Should contains 'WAVE'
-	char 			fmt[4];					// Should contains 'fmt '
-	int32_t			fmt_size;				// Size of format chunk
-	int16_t			fmt_tag;				// Identifies way data is stored, 1 means no compression
-	int16_t			fmt_channels;			// Channel, 1 means mono, 2 means stereo
-	int32_t			fmt_sample_rate;		// Sample per second
-	int32_t			fmt_avarage;			// Avarage bytes per sample
-	int16_t			fmt_block_align;		// Block alignment
-	int16_t			fmt_bits_ps;			// Number of bits per sample
-	char 			data[4];				// Should contains 'data'
-	int32_t			data_size;				// Data dimension
-};
-
-//-----------------------------------------------------------------------------
-class CE_EXPORT SoundCompiler : public Compiler
-{
-public:
-
-						SoundCompiler();
-						~SoundCompiler();
-
-	size_t				compile_impl(Filesystem& fs, const char* resource_path);
-	void				write_impl(File* out_file);
-
-private:
-
-	size_t				compile_if_wav(Filesystem& fs, const char* resource_path);
-	size_t				compile_if_ogg(Filesystem& fs, const char* resource_path);
-
-private:
-
-	SoundHeader			m_sound_header;
-	size_t				m_sound_data_size;
-	uint8_t*			m_sound_data;
-};
-
-} // namespace crown

+ 0 - 71
engine/compilers/sprite/SpriteCompiler.h

@@ -1,71 +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.
-*/
-
-#pragma once
-
-#include "Types.h"
-#include "List.h"
-#include "SpriteResource.h"
-#include "Compiler.h"
-#include "OS.h"
-#include "Vector2.h"
-#include "JSONParser.h"
-
-namespace crown
-{
-
-class Filesystem;
-
-//-----------------------------------------------------------------------------
-struct FrameData
-{
-	float x0, y0;
-	float x1, y1;
-
-	float scale_x, scale_y;
-	float offset_x, offset_y;
-};
-
-//-----------------------------------------------------------------------------
-class SpriteCompiler : public Compiler
-{
-public:
-							SpriteCompiler();
-							~SpriteCompiler();
-
-	size_t					compile_impl(Filesystem& fs, const char* resource_path);
-	void					write_impl(File* out_file);
-
-	void					parse_frame(JSONElement frame);
-
-private:
-
-	List<StringId32>		m_names;
-	List<FrameData> 		m_regions;
-	List<float>				m_vertices;
-};
-
-} // namespace crown

+ 0 - 78
engine/compilers/texture/TextureCompiler.h

@@ -1,78 +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.
-*/
-
-#pragma once
-
-#include "Compiler.h"
-#include "TextureResource.h"
-
-namespace crown
-{
-
-struct TGAHeader
-{
-
-	char		id_length;			// 00h  Size of Image ID field
-	char		color_map_type;		// 01h  Color map type
-	char		image_type;			// 02h  Image type code
-	char		c_map_spec[5];		// 03h  Color map origin 05h Color map length 07h Depth of color map entries
-	uint16_t	x_offset;			// 08h  X origin of image
-	uint16_t	y_offset;			// 0Ah  Y origin of image
-	uint16_t	width;				// 0Ch  Width of image
-	uint16_t	height;				// 0Eh  Height of image
-	char		pixel_depth;     	// 10h  Image pixel size
-	char		image_descriptor;	// 11h  Image descriptor byte
-};
-
-class CE_EXPORT TextureCompiler : public Compiler
-{
-public:
-
-					TextureCompiler();
-					~TextureCompiler();
-
-	size_t			compile_impl(Filesystem& fs, const char* resource_path);
-	void			write_impl(File* out_file);
-
-private:
-
-	void			load_uncompressed(File* in_file);
-	void			load_compressed(File* in_file);
-	void			swap_red_blue();
-
-private:
-
-	TGAHeader		m_tga_header;
-	uint32_t		m_tga_channels;
-	uint32_t		m_tga_size;
-
-	TextureHeader	m_texture_header;
-	size_t			m_texture_data_size;
-	uint8_t*		m_texture_data;
-};
-
-} // namespace crown
-

+ 0 - 91
engine/compilers/unit/UnitCompiler.h

@@ -1,91 +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.
-*/
-
-#pragma once
-
-#include "Compiler.h"
-#include "Resource.h"
-#include "UnitResource.h"
-#include "List.h"
-#include "Types.h"
-#include "Matrix4x4.h"
-#include "Quaternion.h"
-#include "JSONParser.h"
-
-namespace crown
-{
-
-struct GraphNode
-{
-	StringId32 name;
-	StringId32 parent;
-	Vector3 position;
-	Quaternion rotation;
-};
-
-struct GraphNodeDepth
-{
-	StringId32 name;
-	uint32_t index;
-	uint32_t depth;
-
-	bool operator()(const GraphNodeDepth& a, const GraphNodeDepth& b)
-	{
-		return a.depth < b.depth;
-	}
-};
-
-class CE_EXPORT UnitCompiler : public Compiler
-{
-public:
-
-	UnitCompiler();
-
-	size_t compile_impl(Filesystem& fs, const char* resource_path);
-	void write_impl(File* out_file);
-
-	void parse_node(JSONElement e);
-	void parse_camera(JSONElement e);
-	void parse_renderable(JSONElement e);
-	void parse_actor(JSONElement e);
-
-	uint32_t compute_link_depth(GraphNode& node);
-	uint32_t find_node_index(StringId32 name);
-	int32_t find_node_parent_index(StringId32 name);
-
-private:
-
-	ResourceId				m_physics_resource;
-
-	List<GraphNode>			m_nodes;
-	List<GraphNodeDepth>	m_node_depths;
-
-	List<UnitCamera>		m_cameras;
-	List<UnitRenderable>	m_renderables;
-	List<UnitActor>			m_actors;
-};
-
-} // namespace crown

+ 11 - 25
engine/compilers/lua/LuaCompiler.cpp → engine/resource/LuaResource.cpp

@@ -25,16 +25,12 @@ OTHER DEALINGS IN THE SOFTWARE.
 */
 
 #include "Config.h"
-#include "LuaCompiler.h"
-#include "LuaResource.h"
-#include "TempAllocator.h"
 #include "DynamicString.h"
 #include "Filesystem.h"
-#include "OS.h"
 #include "Log.h"
-
-namespace crown
-{
+#include "LuaResource.h"
+#include "OS.h"
+#include "TempAllocator.h"
 
 #ifdef WINDOWS
 	#define LUAJIT_EXECUTABLE "luajit.exe"
@@ -48,21 +44,16 @@ namespace crown
 	#define LUAJIT_FLAGS "-b"
 #endif
 
-
-
-//-----------------------------------------------------------------------------
-LuaCompiler::LuaCompiler()
-	: m_luajit_blob_size(0), m_luajit_blob(NULL)
+namespace crown
 {
-}
-
-//-----------------------------------------------------------------------------
-LuaCompiler::~LuaCompiler()
+namespace lua_resource
 {
-}
+
+size_t			m_luajit_blob_size = 0;
+char*			m_luajit_blob = NULL;
 
 //-----------------------------------------------------------------------------
-size_t LuaCompiler::compile_impl(Filesystem& fs, const char* resource_path)
+void compile(Filesystem& fs, const char* resource_path, File* out_file)
 {
 	TempAllocator1024 alloc;
 	DynamicString res_abs_path(alloc);
@@ -94,15 +85,9 @@ size_t LuaCompiler::compile_impl(Filesystem& fs, const char* resource_path)
 	else
 	{
 		Log::e("Error while reading luajit bytecode");
-		return 0;
+		return;
 	}
 
-	return 1;
-}
-
-//-----------------------------------------------------------------------------
-void LuaCompiler::write_impl(File* out_file)
-{
 	LuaHeader header;
 	header.version = LUA_RESOURCE_VERSION;
 	header.size = m_luajit_blob_size;
@@ -115,4 +100,5 @@ void LuaCompiler::write_impl(File* out_file)
 	m_luajit_blob = NULL;
 }
 
+} // namespace lua_resource
 } // namespace crown

+ 27 - 19
engine/compilers/mesh/MeshCompiler.cpp → engine/resource/MeshResource.cpp

@@ -24,29 +24,42 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 OTHER DEALINGS IN THE SOFTWARE.
 */
 
-#include "MeshCompiler.h"
 #include "DynamicString.h"
-#include "TempAllocator.h"
 #include "Filesystem.h"
 #include "JSONParser.h"
 #include "Log.h"
+#include "MeshResource.h"
+#include "TempAllocator.h"
+#include "Vector3.h"
 
 namespace crown
 {
-
-//-----------------------------------------------------------------------------
-MeshCompiler::MeshCompiler()
-	: m_vertices(default_allocator()), m_indices(default_allocator())
+namespace mesh_resource
 {
-}
 
-//-----------------------------------------------------------------------------
-MeshCompiler::~MeshCompiler()
+struct MeshVertex
 {
-}
+	Vector3 position;
+	Vector3 normal;
+	Vector2 texcoord;
+
+	bool operator==(const MeshVertex& other)
+	{
+		return position == other.position &&
+				normal == other.normal &&
+				texcoord == other.texcoord;
+	}
+};
+
+MeshHeader			m_mesh_header;
+bool				m_has_normal;
+bool				m_has_texcoord;
+
+List<MeshVertex>	m_vertices(default_allocator());
+List<uint16_t>		m_indices(default_allocator());
 
 //-----------------------------------------------------------------------------
-size_t MeshCompiler::compile_impl(Filesystem& fs, const char* resource_path)
+void compile(Filesystem& fs, const char* resource_path, File* out_file)
 {
 	File* file = fs.open(resource_path, FOM_READ);
 	char* buf = (char*)default_allocator().allocate(file->size());
@@ -66,7 +79,7 @@ size_t MeshCompiler::compile_impl(Filesystem& fs, const char* resource_path)
 	if (position.is_nil())
 	{
 		Log::e("Bad mesh: array 'position' not found.");
-		return 0;
+		return;
 	}
 	List<float> position_array(default_allocator());
 	position.array_value(position_array);
@@ -91,7 +104,7 @@ size_t MeshCompiler::compile_impl(Filesystem& fs, const char* resource_path)
 	if (index.is_nil())
 	{
 		Log::e("Bad mesh: array 'index' not found.");
-		return 0;
+		return;
 	}
 
 	List<uint16_t> position_index(default_allocator());
@@ -163,12 +176,6 @@ size_t MeshCompiler::compile_impl(Filesystem& fs, const char* resource_path)
 	default_allocator().deallocate(buf);
 	fs.close(file);
 
-	return 1;
-}
-
-//-----------------------------------------------------------------------------
-void MeshCompiler::write_impl(File* out_file)
-{
 	MeshData data;
 	data.vertices.num_vertices = m_vertices.size();
 	data.vertices.format = VertexFormat::P3_N3_T2;
@@ -194,4 +201,5 @@ void MeshCompiler::write_impl(File* out_file)
 	m_indices.clear();
 }
 
+} // namespace mesh_resource
 } // namespace crown

+ 18 - 35
engine/compilers/package/PackageCompiler.cpp → engine/resource/PackageResource.cpp

@@ -29,28 +29,17 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Filesystem.h"
 #include "Hash.h"
 #include "JSONParser.h"
-#include "PackageCompiler.h"
+#include "Log.h"
 #include "PackageResource.h"
 #include "TempAllocator.h"
-#include "Log.h"
 
 namespace crown
 {
-
-//-----------------------------------------------------------------------------
-PackageCompiler::PackageCompiler()
-	: m_texture(default_allocator())
-	, m_script(default_allocator())
-	, m_sound(default_allocator())
-	, m_mesh(default_allocator())
-	, m_unit(default_allocator())
-	, m_sprite(default_allocator())
-	, m_physics(default_allocator())
+namespace package_resource
 {
-}
 
 //-----------------------------------------------------------------------------
-size_t PackageCompiler::compile_impl(Filesystem& fs, const char* resource_path)
+void compile(Filesystem& fs, const char* resource_path, File* out_file)
 {
 	File* file = fs.open(resource_path, FOM_READ);
 
@@ -61,6 +50,14 @@ size_t PackageCompiler::compile_impl(Filesystem& fs, const char* resource_path)
 	JSONParser json(file_buf);
 	JSONElement root = json.root();
 
+	List<ResourceId> m_texture(default_allocator());
+	List<ResourceId> m_script(default_allocator());
+	List<ResourceId> m_sound(default_allocator());
+	List<ResourceId> m_mesh(default_allocator());
+	List<ResourceId> m_unit(default_allocator());
+	List<ResourceId> m_sprite(default_allocator());
+	List<ResourceId> m_physics(default_allocator());
+
 	// Check for resource types
 	if (root.has_key("texture"))
 	{
@@ -77,7 +74,7 @@ size_t PackageCompiler::compile_impl(Filesystem& fs, const char* resource_path)
 			if (!fs.is_file(texture_name.c_str()))
 			{
 				Log::e("Texture '%s' does not exist.", texture_name.c_str());
-				return 0;
+				return;
 			}
 
 			ResourceId id;
@@ -103,7 +100,7 @@ size_t PackageCompiler::compile_impl(Filesystem& fs, const char* resource_path)
 			if (!fs.is_file(lua_name.c_str()))
 			{
 				Log::e("Lua script '%s' does not exist.", lua_name.c_str());
-				return 0;
+				return;
 			}
 
 			ResourceId id;
@@ -128,7 +125,7 @@ size_t PackageCompiler::compile_impl(Filesystem& fs, const char* resource_path)
 			if (!fs.is_file(sound_name.c_str()))
 			{
 				Log::e("Sound '%s' does not exist.", sound_name.c_str());
-				return 0;
+				return;
 			}
 
 			ResourceId id;
@@ -153,7 +150,7 @@ size_t PackageCompiler::compile_impl(Filesystem& fs, const char* resource_path)
 			if (!fs.is_file(mesh_name.c_str()))
 			{
 				Log::e("Mesh '%s' does not exist.", mesh_name.c_str());
-				return 0;
+				return;
 			}
 
 			ResourceId id;
@@ -202,7 +199,7 @@ size_t PackageCompiler::compile_impl(Filesystem& fs, const char* resource_path)
 			if (!fs.is_file(sprite_name.c_str()))
 			{
 				Log::e("Sprite '%s' does not exist.", sprite_name.c_str());
-				return 0;
+				return;
 			}
 
 			ResourceId id;
@@ -227,7 +224,7 @@ size_t PackageCompiler::compile_impl(Filesystem& fs, const char* resource_path)
 			if (!fs.is_file(physics_name.c_str()))
 			{
 				Log::e("Physics '%s' does not exist.", physics_name.c_str());
-				return 0;
+				return;
 			}
 
 			ResourceId id;
@@ -236,12 +233,6 @@ size_t PackageCompiler::compile_impl(Filesystem& fs, const char* resource_path)
 		}	
 	}
 
-	return 1;
-}
-
-//-----------------------------------------------------------------------------
-void PackageCompiler::write_impl(File* out_file)
-{
 	PackageHeader header;
 	header.num_textures = m_texture.size();
 	header.num_scripts = m_script.size();
@@ -289,15 +280,7 @@ void PackageCompiler::write_impl(File* out_file)
 	{
 		out_file->write((char*) m_physics.begin(), sizeof(ResourceId) * header.num_physics);
 	}
-
-	// Cleanup
-	m_texture.clear();
-	m_script.clear();
-	m_sound.clear();
-	m_mesh.clear();
-	m_unit.clear();
-	m_sprite.clear();
-	m_physics.clear();
 }
 
+} // namespace package_resource
 } // namespace crown

+ 23 - 32
engine/compilers/physics/PhysicsCompiler.cpp → engine/resource/PhysicsResource.cpp

@@ -26,26 +26,39 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #include "Allocator.h"
 #include "Filesystem.h"
-#include "StringUtils.h"
-#include "PhysicsCompiler.h"
 #include "Hash.h"
 #include "JSONParser.h"
+#include "PhysicsResource.h"
+#include "StringUtils.h"
 
 namespace crown
 {
-
-//-----------------------------------------------------------------------------
-PhysicsCompiler::PhysicsCompiler()
+namespace physics_resource
 {
-}
+
+bool					m_has_controller = false;
+PhysicsController		m_controller;
 
 //-----------------------------------------------------------------------------
-PhysicsCompiler::~PhysicsCompiler()
+void parse_controller(JSONElement controller)
 {
+	JSONElement name = controller.key("name");
+	JSONElement height = controller.key("height");
+	JSONElement radius = controller.key("radius");
+	JSONElement slope_limit = controller.key("slope_limit");
+	JSONElement step_offset = controller.key("step_offset");
+	JSONElement contact_offset = controller.key("contact_offset");
+
+	m_controller.name = hash::murmur2_32(name.string_value(), name.size(), 0);
+	m_controller.height = height.float_value();
+	m_controller.radius = radius.float_value();
+	m_controller.slope_limit = slope_limit.float_value();
+	m_controller.step_offset = step_offset.float_value();
+	m_controller.contact_offset = contact_offset.float_value();
 }
 
 //-----------------------------------------------------------------------------
-size_t PhysicsCompiler::compile_impl(Filesystem& fs, const char* resource_path)
+void compile(Filesystem& fs, const char* resource_path, File* out_file)
 {
 	File* file = fs.open(resource_path, FOM_READ);
 	char* buf = (char*)default_allocator().allocate(file->size());
@@ -68,30 +81,7 @@ size_t PhysicsCompiler::compile_impl(Filesystem& fs, const char* resource_path)
 
 	fs.close(file);
 	default_allocator().deallocate(buf);
-	return 1;
-}
 
-//-----------------------------------------------------------------------------
-void PhysicsCompiler::parse_controller(JSONElement controller)
-{
-	JSONElement name = controller.key("name");
-	JSONElement height = controller.key("height");
-	JSONElement radius = controller.key("radius");
-	JSONElement slope_limit = controller.key("slope_limit");
-	JSONElement step_offset = controller.key("step_offset");
-	JSONElement contact_offset = controller.key("contact_offset");
-
-	m_controller.name = hash::murmur2_32(name.string_value(), name.size(), 0);
-	m_controller.height = height.float_value();
-	m_controller.radius = radius.float_value();
-	m_controller.slope_limit = slope_limit.float_value();
-	m_controller.step_offset = step_offset.float_value();
-	m_controller.contact_offset = contact_offset.float_value();
-}
-
-//-----------------------------------------------------------------------------
-void PhysicsCompiler::write_impl(File* out_file)
-{
 	PhysicsHeader h;
 	h.version = 1;
 	h.num_controllers = m_has_controller ? 1 : 0;
@@ -107,4 +97,5 @@ void PhysicsCompiler::write_impl(File* out_file)
 	}
 }
 
-} // namespace crown
+} // namespace physics_resource
+} // namespace crown

+ 52 - 44
engine/compilers/sound/SoundCompiler.cpp → engine/resource/SoundResource.cpp

@@ -29,61 +29,44 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include <errno.h>
 #include <vorbis/vorbisfile.h>
 
-#include "Config.h"
-#include "SoundCompiler.h"
 #include "Allocator.h"
-#include "Filesystem.h"
-#include "StringUtils.h"
+#include "Config.h"
 #include "DynamicString.h"
+#include "Filesystem.h"
 #include "OS.h"
+#include "SoundResource.h"
+#include "StringUtils.h"
 
 namespace crown
 {
-
-//-----------------------------------------------------------------------------
-SoundCompiler::SoundCompiler() 
-	: m_sound_data_size(0)
-	, m_sound_data(NULL)
+namespace sound_resource
 {
-}
 
 //-----------------------------------------------------------------------------
-SoundCompiler::~SoundCompiler()
+struct WAVHeader
 {
-}
-
-//-----------------------------------------------------------------------------
-size_t SoundCompiler::compile_impl(Filesystem& fs, const char* resource_path)
-{
-	size_t size = 0;
-	
-	size = compile_if_wav(fs, resource_path);
+	char 			riff[4];				// Should contains 'RIFF'
+	int32_t			chunk_size;				// Not Needed
+	char 			wave[4];				// Should contains 'WAVE'
+	char 			fmt[4];					// Should contains 'fmt '
+	int32_t			fmt_size;				// Size of format chunk
+	int16_t			fmt_tag;				// Identifies way data is stored, 1 means no compression
+	int16_t			fmt_channels;			// Channel, 1 means mono, 2 means stereo
+	int32_t			fmt_sample_rate;		// Sample per second
+	int32_t			fmt_avarage;			// Avarage bytes per sample
+	int16_t			fmt_block_align;		// Block alignment
+	int16_t			fmt_bits_ps;			// Number of bits per sample
+	char 			data[4];				// Should contains 'data'
+	int32_t			data_size;				// Data dimension
+};
+
+SoundHeader			m_sound_header;
+size_t				m_sound_data_size = 0;
+uint8_t*			m_sound_data = NULL;
 
-	if (size == 0)
-	{
-		size = compile_if_ogg(fs, resource_path);
-	}
-	
-	return 1;
-}
 
 //-----------------------------------------------------------------------------
-void SoundCompiler::write_impl(File* out_file)
-{
-	out_file->write((char*)&m_sound_header, sizeof(SoundHeader));
-	out_file->write((char*)m_sound_data, m_sound_data_size);
-
-	if (m_sound_data)
-	{
-
-		default_allocator().deallocate(m_sound_data);
-		m_sound_data_size = 0;
-		m_sound_data = NULL;
-	}
-}
-
-//-----------------------------------------------------------------------------
-size_t SoundCompiler::compile_if_wav(Filesystem& fs, const char* resource_path)
+size_t compile_if_wav(Filesystem& fs, const char* resource_path)
 {
 	File* in_file = fs.open(resource_path, FOM_READ);
 
@@ -123,7 +106,7 @@ size_t SoundCompiler::compile_if_wav(Filesystem& fs, const char* resource_path)
 }
 
 //-----------------------------------------------------------------------------
-size_t SoundCompiler::compile_if_ogg(Filesystem& fs, const char* resource_path)
+size_t compile_if_ogg(Filesystem& fs, const char* resource_path)
 {
 	// Retrieves resource absolute path
 	DynamicString s(default_allocator());
@@ -168,4 +151,29 @@ size_t SoundCompiler::compile_if_ogg(Filesystem& fs, const char* resource_path)
 	return sizeof(SoundHeader) + m_sound_data_size;
 }
 
-} // namespace crown
+//-----------------------------------------------------------------------------
+void compile(Filesystem& fs, const char* resource_path, File* out_file)
+{
+	size_t size = 0;
+	
+	size = compile_if_wav(fs, resource_path);
+
+	if (size == 0)
+	{
+		size = compile_if_ogg(fs, resource_path);
+	}
+
+	out_file->write((char*)&m_sound_header, sizeof(SoundHeader));
+	out_file->write((char*)m_sound_data, m_sound_data_size);
+
+	if (m_sound_data)
+	{
+
+		default_allocator().deallocate(m_sound_data);
+		m_sound_data_size = 0;
+		m_sound_data = NULL;
+	}
+}
+
+} // namespace sound_resource
+} // namespace crown

+ 37 - 44
engine/compilers/sprite/SpriteCompiler.cpp → engine/resource/SpriteResource.cpp

@@ -29,29 +29,51 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #include "Allocator.h"
 #include "Filesystem.h"
-#include "StringUtils.h"
-#include "SpriteCompiler.h"
 #include "Hash.h"
 #include "JSONParser.h"
+#include "SpriteResource.h"
+#include "StringUtils.h"
 
 namespace crown
 {
+namespace sprite_resource
+{
 
 //-----------------------------------------------------------------------------
-SpriteCompiler::SpriteCompiler()
-	: m_names(default_allocator())
-	, m_regions(default_allocator())
-	, m_vertices(default_allocator())
+struct FrameData
 {
-}
+	float x0, y0;
+	float x1, y1;
+
+	float scale_x, scale_y;
+	float offset_x, offset_y;
+};
 
 //-----------------------------------------------------------------------------
-SpriteCompiler::~SpriteCompiler()
+void parse_frame(JSONElement frame, List<StringId32>& names, List<FrameData>& regions)
 {
+	JSONElement name = frame.key("name");
+	JSONElement region = frame.key("region");
+	JSONElement offset = frame.key("offset");
+	JSONElement scale = frame.key("scale");
+
+	StringId32 name_hash = hash::murmur2_32(name.string_value(), name.size(), 0);
+	FrameData fd;
+	fd.x0 = region[0].float_value();
+	fd.y0 = region[1].float_value();
+	fd.x1 = region[2].float_value();
+	fd.y1 = region[3].float_value();
+	fd.offset_x = offset[0].float_value();
+	fd.offset_y = offset[1].float_value();
+	fd.scale_x = scale[0].float_value();
+	fd.scale_y = scale[1].float_value();
+
+	names.push_back(name_hash);
+	regions.push_back(fd);
 }
 
 //-----------------------------------------------------------------------------
-size_t SpriteCompiler::compile_impl(Filesystem& fs, const char* resource_path)
+void compile(Filesystem& fs, const char* resource_path, File* out_file)
 {
 	File* file = fs.open(resource_path, FOM_READ);
 	char* buf = (char*)default_allocator().allocate(file->size());
@@ -60,12 +82,16 @@ size_t SpriteCompiler::compile_impl(Filesystem& fs, const char* resource_path)
 	JSONParser json(buf);
 	JSONElement root = json.root();
 
+	List<StringId32>		m_names(default_allocator());
+	List<FrameData> 		m_regions(default_allocator());
+	List<float>				m_vertices(default_allocator());
+
 	// Read frames
 	JSONElement frames = root.key("frames");
 	uint32_t num_frames = frames.size();
 	for (uint32_t i = 0; i < num_frames; i++)
 	{
-		parse_frame(frames[i]);
+		parse_frame(frames[i], m_names, m_regions);
 	}
 
 	for (uint32_t i = 0; i < num_frames; i++)
@@ -103,35 +129,6 @@ size_t SpriteCompiler::compile_impl(Filesystem& fs, const char* resource_path)
 	fs.close(file);
 	default_allocator().deallocate(buf);
 
-	return 1;
-}
-
-//-----------------------------------------------------------------------------
-void SpriteCompiler::parse_frame(JSONElement frame)
-{
-	JSONElement name = frame.key("name");
-	JSONElement region = frame.key("region");
-	JSONElement offset = frame.key("offset");
-	JSONElement scale = frame.key("scale");
-
-	StringId32 name_hash = hash::murmur2_32(name.string_value(), name.size(), 0);
-	FrameData fd;
-	fd.x0 = region[0].float_value();
-	fd.y0 = region[1].float_value();
-	fd.x1 = region[2].float_value();
-	fd.y1 = region[3].float_value();
-	fd.offset_x = offset[0].float_value();
-	fd.offset_y = offset[1].float_value();
-	fd.scale_x = scale[0].float_value();
-	fd.scale_y = scale[1].float_value();
-
-	m_names.push_back(name_hash);
-	m_regions.push_back(fd);
-}
-
-//-----------------------------------------------------------------------------
-void SpriteCompiler::write_impl(File* out_file)
-{
 	SpriteHeader h;
 	h.texture.id = hash::murmur2_64("textures/circle.texture", string::strlen("textures/circle.texture"), 0);
 	h.num_frames = m_names.size();
@@ -143,11 +140,7 @@ void SpriteCompiler::write_impl(File* out_file)
 	out_file->write((char*) &h, sizeof(SpriteHeader));
 	out_file->write((char*) m_names.begin(), sizeof(StringId32) * m_names.size());
 	out_file->write((char*) m_vertices.begin(), sizeof(float) * 16 * m_vertices.size());
-
-	m_names.clear();
-	m_regions.clear();
-	m_vertices.clear();
 }
 
-
+} // namespace sprite_resource
 } // namespace crown

+ 121 - 114
engine/compilers/texture/TextureCompiler.cpp → engine/resource/TextureResource.cpp

@@ -24,130 +24,52 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 OTHER DEALINGS IN THE SOFTWARE.
 */
 
-#include "TextureCompiler.h"
-#include "PixelFormat.h"
 #include "Allocator.h"
 #include "Filesystem.h"
+#include "PixelFormat.h"
+#include "TextureResource.h"
 
 namespace crown
 {
-
-//-----------------------------------------------------------------------------
-TextureCompiler::TextureCompiler() :
-	m_texture_data_size(0),
-	m_texture_data(NULL)
-{
-}
-
-//-----------------------------------------------------------------------------
-TextureCompiler::~TextureCompiler()
+namespace texture_resource
 {
-}
 
-//-----------------------------------------------------------------------------
-size_t TextureCompiler::compile_impl(Filesystem& fs, const char* resource_path)
+struct TGAHeader
 {
-	File* in_file = fs.open(resource_path, FOM_READ);
-
-	if (!in_file)
-	{
-		Log::e("Unable to open file: %s", resource_path);
-		return 0;
-	}
-
-	// Read the header
-	in_file->read((char*)(char*)&m_tga_header, sizeof(TGAHeader));
-
-	// Skip TGA ID
-	in_file->skip(m_tga_header.id_length);
 
-	// Compute color channels
-	m_tga_channels = m_tga_header.pixel_depth / 8;
-	m_tga_size = m_tga_header.width * m_tga_header.height;
-
-	m_texture_header.version = TEXTURE_VERSION;
-	m_texture_header.width = m_tga_header.width;
-	m_texture_header.height = m_tga_header.height;
-
-	// Select the appropriate pixel format and allocate
-	// resource data based on tga size and channels
-	switch (m_tga_channels)
-	{
-		case 2:
-		case 3:
-		{
-			m_texture_header.format = PixelFormat::RGB_8;
-
-			m_texture_data_size = m_tga_size * 3;
-			m_texture_data = (uint8_t*)default_allocator().allocate(m_texture_data_size);
-
-			break;
-		}
-		case 4:
-		{
-			m_texture_header.format = PixelFormat::RGBA_8;
-
-			m_texture_data_size = m_tga_size * m_tga_channels;
-			m_texture_data = (uint8_t*)default_allocator().allocate(m_texture_data_size);
-			
-			break;
-		}
-		default:
-		{
-			Log::e("Unable to determine TGA channels.");
-			return 0;
-		}
-	}
-
-	// Determine image type (compressed/uncompressed) and call proper function to load TGA
-	switch (m_tga_header.image_type)
-	{
-		case 0:
-		{
-			Log::e("The file does not contain image data: %s", resource_path);
-			return 0;
-		}
-		case 2:
-		{
-			load_uncompressed(in_file);
-			break;
-		}
-
-		case 10:
-		{
-			load_compressed(in_file);
-			break;
-		}
-
-		default:
-		{
-			Log::e("Image type not supported.");
-			return 0;
-		}
-	}
-
-	fs.close(in_file);
-
-	// Return the total resource size
-	return 1;
-}
+	char		id_length;			// 00h  Size of Image ID field
+	char		color_map_type;		// 01h  Color map type
+	char		image_type;			// 02h  Image type code
+	char		c_map_spec[5];		// 03h  Color map origin 05h Color map length 07h Depth of color map entries
+	uint16_t	x_offset;			// 08h  X origin of image
+	uint16_t	y_offset;			// 0Ah  Y origin of image
+	uint16_t	width;				// 0Ch  Width of image
+	uint16_t	height;				// 0Eh  Height of image
+	char		pixel_depth;     	// 10h  Image pixel size
+	char		image_descriptor;	// 11h  Image descriptor byte
+};
+
+TGAHeader		m_tga_header;
+uint32_t		m_tga_channels;
+uint32_t		m_tga_size;
+
+TextureHeader	m_texture_header;
+size_t			m_texture_data_size = 0;
+uint8_t*		m_texture_data = NULL;
 
 //-----------------------------------------------------------------------------
-void TextureCompiler::write_impl(File* out_file)
+void swap_red_blue()
 {
-	out_file->write((char*)&m_texture_header, sizeof(TextureHeader));
-	out_file->write((char*)m_texture_data, m_texture_data_size);
-
-	if (m_texture_data)
+	for (uint64_t i = 0; i < m_tga_size * m_tga_channels; i += m_tga_channels)
 	{
-		default_allocator().deallocate(m_texture_data);
-		m_texture_data_size = 0;
-		m_texture_data = NULL;
+		m_texture_data[i + 0] ^= m_texture_data[i + 2];
+		m_texture_data[i + 2] ^= m_texture_data[i + 0];
+		m_texture_data[i + 0] ^= m_texture_data[i + 2];
 	}
 }
 
 //-----------------------------------------------------------------------------
-void TextureCompiler::load_uncompressed(File* in_file)
+void load_uncompressed(File* in_file)
 {
 	uint64_t size = m_tga_header.width * m_tga_header.height;
 
@@ -177,7 +99,7 @@ void TextureCompiler::load_uncompressed(File* in_file)
 }
 
 //-----------------------------------------------------------------------------
-void TextureCompiler::load_compressed(File* in_file)
+void load_compressed(File* in_file)
 {
 	uint8_t rle_id = 0;
 	uint32_t i = 0;
@@ -240,14 +162,99 @@ void TextureCompiler::load_compressed(File* in_file)
 }
 
 //-----------------------------------------------------------------------------
-void TextureCompiler::swap_red_blue()
+void compile(Filesystem& fs, const char* resource_path, File* out_file)
 {
-	for (uint64_t i = 0; i < m_tga_size * m_tga_channels; i += m_tga_channels)
+	File* in_file = fs.open(resource_path, FOM_READ);
+
+	if (!in_file)
 	{
-		m_texture_data[i + 0] ^= m_texture_data[i + 2];
-		m_texture_data[i + 2] ^= m_texture_data[i + 0];
-		m_texture_data[i + 0] ^= m_texture_data[i + 2];
+		Log::e("Unable to open file: %s", resource_path);
+		return;
+	}
+
+	// Read the header
+	in_file->read((char*)(char*)&m_tga_header, sizeof(TGAHeader));
+
+	// Skip TGA ID
+	in_file->skip(m_tga_header.id_length);
+
+	// Compute color channels
+	m_tga_channels = m_tga_header.pixel_depth / 8;
+	m_tga_size = m_tga_header.width * m_tga_header.height;
+
+	m_texture_header.version = TEXTURE_VERSION;
+	m_texture_header.width = m_tga_header.width;
+	m_texture_header.height = m_tga_header.height;
+
+	// Select the appropriate pixel format and allocate
+	// resource data based on tga size and channels
+	switch (m_tga_channels)
+	{
+		case 2:
+		case 3:
+		{
+			m_texture_header.format = PixelFormat::RGB_8;
+
+			m_texture_data_size = m_tga_size * 3;
+			m_texture_data = (uint8_t*)default_allocator().allocate(m_texture_data_size);
+
+			break;
+		}
+		case 4:
+		{
+			m_texture_header.format = PixelFormat::RGBA_8;
+
+			m_texture_data_size = m_tga_size * m_tga_channels;
+			m_texture_data = (uint8_t*)default_allocator().allocate(m_texture_data_size);
+			
+			break;
+		}
+		default:
+		{
+			Log::e("Unable to determine TGA channels.");
+			return;
+		}
+	}
+
+	// Determine image type (compressed/uncompressed) and call proper function to load TGA
+	switch (m_tga_header.image_type)
+	{
+		case 0:
+		{
+			Log::e("The file does not contain image data: %s", resource_path);
+			return;
+		}
+		case 2:
+		{
+			load_uncompressed(in_file);
+			break;
+		}
+
+		case 10:
+		{
+			load_compressed(in_file);
+			break;
+		}
+
+		default:
+		{
+			Log::e("Image type not supported.");
+			return;
+		}
+	}
+
+	fs.close(in_file);
+
+	out_file->write((char*)&m_texture_header, sizeof(TextureHeader));
+	out_file->write((char*)m_texture_data, m_texture_data_size);
+
+	if (m_texture_data)
+	{
+		default_allocator().deallocate(m_texture_data);
+		m_texture_data_size = 0;
+		m_texture_data = NULL;
 	}
 }
 
-} // namespace crown
+} // namespace texture_resource
+} // namespace crown

+ 133 - 125
engine/compilers/unit/UnitCompiler.cpp → engine/resource/UnitResource.cpp

@@ -29,116 +29,95 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Filesystem.h"
 #include "Hash.h"
 #include "JSONParser.h"
-#include "UnitCompiler.h"
-#include "TempAllocator.h"
+#include "List.h"
 #include "Log.h"
+#include "Matrix4x4.h"
 #include "PhysicsTypes.h"
 #include "Quaternion.h"
+#include "Resource.h"
+#include "TempAllocator.h"
+#include "Types.h"
+#include "UnitResource.h"
 #include "Vector3.h"
-#include "Matrix4x4.h"
 
 namespace crown
 {
+namespace unit_resource
+{
 
 const StringId32 NO_PARENT = 0xFFFFFFFF;
 
-//-----------------------------------------------------------------------------
-UnitCompiler::UnitCompiler()
-	: m_nodes(default_allocator())
-	, m_node_depths(default_allocator())
-	, m_cameras(default_allocator())
-	, m_renderables(default_allocator())
-	, m_actors(default_allocator())
+struct GraphNode
 {
-}
+	StringId32 name;
+	StringId32 parent;
+	Vector3 position;
+	Quaternion rotation;
+};
 
-//-----------------------------------------------------------------------------
-size_t UnitCompiler::compile_impl(Filesystem& fs, const char* resource_path)
+struct GraphNodeDepth
 {
-	File* file = fs.open(resource_path, FOM_READ);
-
-	char file_buf[4096];
-	file->read(file_buf, file->size());
-	fs.close(file);
-
-	JSONParser json(file_buf);
-	JSONElement root = json.root();
+	StringId32 name;
+	uint32_t index;
+	uint32_t depth;
 
-	// Check for nodes
-	if (root.has_key("nodes"))
+	bool operator()(const GraphNodeDepth& a, const GraphNodeDepth& b)
 	{
-		JSONElement nodes = root.key("nodes");
-		const uint32_t num_nodes = nodes.size();
-
-		for (uint32_t i = 0; i < num_nodes; i++)
-		{
-			parse_node(nodes[i]);
-		}
+		return a.depth < b.depth;
 	}
+};
 
-	for (uint32_t i = 0; i < m_nodes.size(); i++)
+//-----------------------------------------------------------------------------
+uint32_t compute_link_depth(const GraphNode& node, const List<GraphNode>& nodes)
+{
+	if (node.parent == NO_PARENT) return 0;
+	else
 	{
-		m_node_depths[i].depth = compute_link_depth(m_nodes[i]);
+		for (uint32_t i = 0; i < nodes.size(); i++)
+		{
+			if (nodes[i].name == node.parent)
+			{
+				return 1 + compute_link_depth(nodes[i], nodes);
+			}
+		}
 	}
 
-	std::sort(m_node_depths.begin(), m_node_depths.end(), GraphNodeDepth());
+	CE_FATAL("Node not found");
+}
 
-	// Check for renderable
-	if (root.has_key("renderables"))
+//-----------------------------------------------------------------------------
+uint32_t find_node_index(StringId32 name, const List<GraphNodeDepth>& node_depths)
+{
+	for (uint32_t i = 0; i < node_depths.size(); i++)
 	{
-		JSONElement renderables = root.key("renderables");
-		uint32_t renderables_size = renderables.size();
-
-		for (uint32_t i = 0; i < renderables_size; i++)
+		if (node_depths[i].name == name)
 		{
-			parse_renderable(renderables[i]);
+			return i;
 		}
 	}
 
-	// Check for cameras
-	if (root.has_key("cameras"))
-	{
-		JSONElement cameras = root.key("cameras");
-		uint32_t num_cameras = cameras.size();
+	CE_FATAL("Node not found");
+}
 
-		for (uint32_t i = 0; i < num_cameras; i++)
-		{
-			parse_camera(cameras[i]);
-		}
-	}
+//-----------------------------------------------------------------------------
+int32_t find_node_parent_index(uint32_t node, const List<GraphNode>& nodes, const List<GraphNodeDepth>& node_depths)
+{
+	StringId32 parent_name = nodes[node_depths[node].index].parent;
 
-	// check for actors
-	if (root.has_key("actors"))
+	if (parent_name == NO_PARENT) return -1;
+	for (uint32_t i = 0; i < node_depths.size(); i++)
 	{
-		JSONElement actors = root.key("actors");
-		uint32_t num_actors = actors.size();
-
-		for (uint32_t i = 0; i < num_actors; i++)
+		if (parent_name == node_depths[i].name)
 		{
-			parse_actor(actors[i]);
+			return i;
 		}
 	}
 
-	// Check if the unit has a .physics resource
-	DynamicString unit_name(resource_path);
-	unit_name.strip_trailing("unit");
-	unit_name += "physics";
-	Log::d("Checking %s", unit_name.c_str());
-	if (fs.is_file(unit_name.c_str()))
-	{
-		Log::d("YES");
-		m_physics_resource.id = hash::murmur2_64(unit_name.c_str(), string::strlen(unit_name.c_str()), 0);
-	}
-	else
-	{
-		m_physics_resource.id = 0;
-	}
-
-	return 1;
+	CE_FATAL("Node not found");
 }
 
 //-----------------------------------------------------------------------------
-void UnitCompiler::parse_node(JSONElement e)
+void parse_node(JSONElement e, List<GraphNode>& nodes, List<GraphNodeDepth>& node_depths)
 {
 	JSONElement name = e.key("name");
 	JSONElement parent = e.key("parent");
@@ -153,15 +132,15 @@ void UnitCompiler::parse_node(JSONElement e)
 
 	GraphNodeDepth gnd;
 	gnd.name = gn.name;
-	gnd.index = m_nodes.size();
+	gnd.index = nodes.size();
 	gnd.depth = 0;
 
-	m_nodes.push_back(gn);
-	m_node_depths.push_back(gnd);
+	nodes.push_back(gn);
+	node_depths.push_back(gnd);
 }
 
 //-----------------------------------------------------------------------------
-void UnitCompiler::parse_camera(JSONElement e)
+void parse_camera(JSONElement e, List<UnitCamera>& cameras, const List<GraphNodeDepth>& node_depths)
 {
 	JSONElement name = e.key("name");
 	JSONElement node = e.key("node");
@@ -170,13 +149,13 @@ void UnitCompiler::parse_camera(JSONElement e)
 
 	UnitCamera cn;
 	cn.name = hash::murmur2_32(name.string_value(), name.size(), 0);
-	cn.node = find_node_index(node_name);
+	cn.node = find_node_index(node_name, node_depths);
 
-	m_cameras.push_back(cn);
+	cameras.push_back(cn);
 }
 
 //-----------------------------------------------------------------------------
-void UnitCompiler::parse_renderable(JSONElement e)
+void parse_renderable(JSONElement e, List<UnitRenderable>& renderables, const List<GraphNodeDepth>& node_depths)
 {
 	JSONElement name = e.key("name");
 	JSONElement node = e.key("node");
@@ -188,7 +167,7 @@ void UnitCompiler::parse_renderable(JSONElement e)
 
 	UnitRenderable rn;
 	rn.name = hash::murmur2_32(name.string_value(), name.size(), 0);
-	rn.node = find_node_index(node_name);
+	rn.node = find_node_index(node_name, node_depths);
 	rn.visible = vis.bool_value();
 
 	const char* res_type = type.string_value();
@@ -212,11 +191,11 @@ void UnitCompiler::parse_renderable(JSONElement e)
 	}
 	rn.resource.id = hash::murmur2_64(res_name.c_str(), string::strlen(res_name.c_str()), 0);
 
-	m_renderables.push_back(rn);
+	renderables.push_back(rn);
 }
 
 //-----------------------------------------------------------------------------
-void UnitCompiler::parse_actor(JSONElement e)
+void parse_actor(JSONElement e, List<UnitActor>& actors, const List<GraphNodeDepth>& node_depths)
 {
 	JSONElement name = e.key("name");
 	JSONElement node = e.key("node");
@@ -228,67 +207,102 @@ void UnitCompiler::parse_actor(JSONElement e)
 
 	UnitActor an;
 	an.name = hash::murmur2_32(name.string_value(), name.size(), 0);
-	an.node = find_node_index(node_name);
+	an.node = find_node_index(node_name, node_depths);
 	an.type = string::strcmp(type.string_value(), "STATIC") == 0 ? UnitActor::STATIC : UnitActor::DYNAMIC;
 	an.shape = string::strcmp(shape.string_value(), "SPHERE") == 0 ? UnitActor::SPHERE :
 	 			string::strcmp(shape.string_value(), "BOX") == 0 ? UnitActor::BOX : UnitActor::PLANE;
 	an.active = active.bool_value();
 
-	m_actors.push_back(an);
+	actors.push_back(an);
 }
 
 //-----------------------------------------------------------------------------
-uint32_t UnitCompiler::compute_link_depth(GraphNode& node)
+void compile(Filesystem& fs, const char* resource_path, File* out_file)
 {
-	if (node.parent == NO_PARENT) return 0;
-	else
+	File* file = fs.open(resource_path, FOM_READ);
+
+	char file_buf[4096];
+	file->read(file_buf, file->size());
+	fs.close(file);
+
+	JSONParser json(file_buf);
+	JSONElement root = json.root();
+
+	ResourceId				m_physics_resource;
+	List<GraphNode>			m_nodes(default_allocator());
+	List<GraphNodeDepth>	m_node_depths(default_allocator());
+	List<UnitCamera>		m_cameras(default_allocator());
+	List<UnitRenderable>	m_renderables(default_allocator());
+	List<UnitActor>			m_actors(default_allocator());
+
+	// Check for nodes
+	if (root.has_key("nodes"))
 	{
-		for (uint32_t i = 0; i < m_nodes.size(); i++)
+		JSONElement nodes = root.key("nodes");
+		const uint32_t num_nodes = nodes.size();
+
+		for (uint32_t i = 0; i < num_nodes; i++)
 		{
-			if (m_nodes[i].name == node.parent)
-			{
-				return 1 + compute_link_depth(m_nodes[i]);
-			}
+			parse_node(nodes[i], m_nodes, m_node_depths);
 		}
 	}
 
-	CE_FATAL("Node not found");
-}
+	for (uint32_t i = 0; i < m_nodes.size(); i++)
+	{
+		m_node_depths[i].depth = compute_link_depth(m_nodes[i], m_nodes);
+	}
 
-//-----------------------------------------------------------------------------
-uint32_t UnitCompiler::find_node_index(StringId32 name)
-{
-	for (uint32_t i = 0; i < m_node_depths.size(); i++)
+	std::sort(m_node_depths.begin(), m_node_depths.end(), GraphNodeDepth());
+
+	// Check for renderable
+	if (root.has_key("renderables"))
 	{
-		if (m_node_depths[i].name == name)
+		JSONElement renderables = root.key("renderables");
+		uint32_t renderables_size = renderables.size();
+
+		for (uint32_t i = 0; i < renderables_size; i++)
 		{
-			return i;
+			parse_renderable(renderables[i], m_renderables, m_node_depths);
 		}
 	}
 
-	CE_FATAL("Node not found");
-}
+	// Check for cameras
+	if (root.has_key("cameras"))
+	{
+		JSONElement cameras = root.key("cameras");
+		uint32_t num_cameras = cameras.size();
 
-//-----------------------------------------------------------------------------
-int32_t UnitCompiler::find_node_parent_index(uint32_t node)
-{
-	StringId32 parent_name = m_nodes[m_node_depths[node].index].parent;
+		for (uint32_t i = 0; i < num_cameras; i++)
+		{
+			parse_camera(cameras[i], m_cameras, m_node_depths);
+		}
+	}
 
-	if (parent_name == NO_PARENT) return -1;
-	for (uint32_t i = 0; i < m_node_depths.size(); i++)
+	// check for actors
+	if (root.has_key("actors"))
 	{
-		if (parent_name == m_node_depths[i].name)
+		JSONElement actors = root.key("actors");
+		uint32_t num_actors = actors.size();
+
+		for (uint32_t i = 0; i < num_actors; i++)
 		{
-			return i;
+			parse_actor(actors[i], m_actors, m_node_depths);
 		}
 	}
 
-	CE_FATAL("Node not found");
-}
+	// Check if the unit has a .physics resource
+	DynamicString unit_name(resource_path);
+	unit_name.strip_trailing("unit");
+	unit_name += "physics";
+	if (fs.is_file(unit_name.c_str()))
+	{
+		m_physics_resource.id = hash::murmur2_64(unit_name.c_str(), string::strlen(unit_name.c_str()), 0);
+	}
+	else
+	{
+		m_physics_resource.id = 0;
+	}
 
-//-----------------------------------------------------------------------------
-void UnitCompiler::write_impl(File* out_file)
-{
 	UnitHeader h;
 	h.physics_resource = m_physics_resource;
 	h.num_renderables = m_renderables.size();
@@ -338,16 +352,10 @@ void UnitCompiler::write_impl(File* out_file)
 	// Write parent hierarchy
 	for (uint32_t i = 0; i < h.num_scene_graph_nodes; i++)
 	{
-		int32_t parent = find_node_parent_index(i);
+		int32_t parent = find_node_parent_index(i, m_nodes, m_node_depths);
 		out_file->write((char*) &parent, sizeof(int32_t));
 	}
-
-	m_nodes.clear();
-	m_node_depths.clear();
-	m_renderables.clear();
-	m_cameras.clear();
-	m_actors.clear();
-	(void)out_file;
 }
 
+} // namespace unit_resource
 } // namespace crown