Browse Source

Refactoring

Panagiotis Christopoulos Charitos 11 years ago
parent
commit
aa49f5e952

+ 0 - 97
include/anki/resource/AsyncOperator.h

@@ -1,97 +0,0 @@
-// Copyright (C) 2014, Panagiotis Christopoulos Charitos.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#ifndef ANKI_RESOURCE_ASYNC_LOADER_H
-#define ANKI_RESOURCE_ASYNC_LOADER_H
-
-#include <list>
-#include <string>
-#include <thread>
-#include <mutex>
-
-
-namespace anki {
-
-/*
-
-/// Asynchronous operator
-///
-/// It creates a thread that executes requests on demand. It contains a queue
-/// with requests.
-/// @code async.pushBack(new RequestDerived(...)); @endcode
-/// The AsyncOperator gets the ownership of the request and de-allocates it
-/// when the request is served. Its not meant to be destroyed because of a
-/// deadlock.
-class AsyncOperator
-{
-public:
-	/// XXX
-	class Request
-	{
-	public:
-		bool ok;
-
-		virtual ~Request()
-		{}
-
-		/// Called in the worker thread
-		virtual void exec() = 0;
-
-		/// Called in the main thread after the request is served
-		virtual void postExec(AsyncOperator& al) = 0;
-
-		/// XXX
-		virtual std::string getInfo() const
-		{
-			return "no info";
-		}
-	};
-
-	/// Default constructor starts the thread
-	AsyncOperator()
-	{
-		start();
-	}
-
-	/// Do nothing
-	~AsyncOperator()
-	{}
-
-	/// Add a new request in the queue
-	void putBack(Request* newReq);
-
-	/// Handle the served requests
-	///
-	/// Steps:
-	/// - Gets the served requests
-	/// - Executes the Request::postExec for those requests
-	/// - Deletes them
-	///
-	/// @param[in] availableTime Max time to spend in the Request::postExec
-	/// @return The number of requests served
-	uint execPostLoad(float availableTime);
-
-private:
-	std::list<Request*> requests;
-	std::list<Request*> responses;
-	boost::mutex mutexReq; ///< Protect the requests container
-	boost::mutex mutexRes; ///< Protect the responses container
-	boost::thread thread;
-	boost::condition_variable condVar;
-
-	/// The thread function. It waits for something in the requests
-	/// container
-	void workingFunc();
-
-	void start(); ///< Start thread
-};
-
-*/
-
-
-} // end namespace
-
-
-#endif

+ 0 - 60
include/anki/resource/AsyncTextureResourceManager.h

@@ -1,60 +0,0 @@
-// Copyright (C) 2014, Panagiotis Christopoulos Charitos.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#ifndef ANKI_RESOURCE_ASYNC_TEXTURE_RESOURCE_MANAGER_H
-#define ANKI_RESOURCE_ASYNC_TEXTURE_RESOURCE_MANAGER_H
-
-#include "anki/resource/ResourceManager.h"
-#include "anki/resource/AsyncOperator.h"
-
-
-namespace anki {
-
-
-class Texture;
-
-
-/// @addtogroup resource
-/// @{
-
-/// XXX
-class AsyncTextureResourceManager: public ResourceManager<Texture>
-{
-public:
-
-private:
-	/// XXX
-	class Request: public AsyncOperator::Request
-	{
-		public:
-			std::string filename;
-			Image img;
-			Texture** ppTex;
-
-			Request(const char* fname, Texture**& ppTex_)
-			:	filename(fname),
-				ppTex(ppTex_)
-			{}
-
-			/// Implements AsyncOperator::Request::exec
-			void exec();
-
-			/// Implements AsyncOperator::Request::postExec
-			void postExec(AsyncOperator& al);
-
-			/// Re-implements AsyncOperator::Request::getInfo
-			std::string getInfo() const;
-	};
-
-	boost::scoped_ptr<AsyncOperator> ao;
-
-};
-/// @}
-
-
-} // namespace anki
-
-
-#endif

+ 1 - 1
include/anki/resource/MaterialProgramCreator.h

@@ -26,7 +26,7 @@ class MaterialProgramCreator
 {
 public:
 	using MPString = TempResourceString; 
-	using MPStringList = BasicStringList<TempResourceAllocator<char>>; 
+	using MPStringList = StringListBase<TempResourceAllocator<char>>; 
 
 	class Input
 	{

+ 3 - 3
include/anki/resource/ParticleEmitterResource.h

@@ -6,8 +6,8 @@
 #ifndef ANKI_RESOURCE_PARTICLE_EMITTER_RSRC_H
 #define ANKI_RESOURCE_PARTICLE_EMITTER_RSRC_H
 
+#include "anki/resource/ResourceManager.h"
 #include "anki/Math.h"
-#include "anki/resource/Resource.h"
 
 namespace anki {
 
@@ -110,12 +110,12 @@ public:
 	}
 
 	/// Load it
-	void load(const CString& filename, );
+	void load(const CString& filename, ResourceInitializer& init);
 
 private:
 	MaterialResourcePointer m_material;
 
-	void loadInternal(const XmlElement& el);
+	void loadInternal(const XmlElement& el, ResourceInitializer& init);
 };
 
 } // end namespace anki

+ 1 - 1
include/anki/resource/ProgramPrePreprocessor.h

@@ -38,7 +38,7 @@ enum class ShaderType
 class ProgramPrePreprocessor
 {
 private:
-	using PPPStringList = BasicStringList<TempResourceAllocator<char>>;
+	using PPPStringList = StringListBase<TempResourceAllocator<char>>;
 	using PPPString = TempResourceString;
 
 public:

+ 27 - 23
include/anki/resource/ResourceManager.h

@@ -16,10 +16,10 @@ namespace anki {
 
 // Forward
 class ConfigSet;
-class App;
 class GlDevice;
 class ResourceManager;
 
+// NOTE: Add resources in 3 places
 #define ANKI_RESOURCE(rsrc_, name_) \
 	class rsrc_; \
 	using name_ = ResourcePointer<rsrc_, ResourceManager>;
@@ -31,10 +31,7 @@ ANKI_RESOURCE(Material, MaterialResourcePointer)
 ANKI_RESOURCE(Mesh, MeshResourcePointer)
 ANKI_RESOURCE(BucketMesh, BucketMeshResourcePointer)
 ANKI_RESOURCE(Skeleton, SkeletonResourcePointer)
-ANKI_RESOURCE(SkelAnim, SkelAnimResourcePointer)
-ANKI_RESOURCE(LightRsrc, LightRsrcResourcePointer)
 ANKI_RESOURCE(ParticleEmitterResource, ParticleEmitterResourcePointer)
-ANKI_RESOURCE(Script, ScriptResourcePointer)
 ANKI_RESOURCE(Model, ModelResourcePointer)
 
 #undef ANKI_RESOURCE
@@ -62,13 +59,6 @@ public:
 
 	/// @privatesection
 	/// @{
-	void init(HeapAllocator<U8>& alloc)
-	{
-		HeapAllocator<ResourcePointerType> alloc2 = alloc;
-		Container ptrs(alloc2);
-		m_ptrs = std::move(ptrs);
-	}
-
 	Bool _findLoadedResource(const CString& filename, ResourcePointerType& ptr)
 	{
 		auto it = find(filename);
@@ -101,6 +91,14 @@ public:
 	}
 	/// @}
 
+protected:
+	void init(HeapAllocator<U8>& alloc)
+	{
+		HeapAllocator<ResourcePointerType> alloc2 = alloc;
+		Container ptrs(alloc2);
+		m_ptrs = std::move(ptrs);
+	}
+
 private:
 	Container m_ptrs;
 
@@ -132,14 +130,22 @@ class ResourceManager:
 	ANKI_RESOURCE(Mesh),
 	ANKI_RESOURCE(BucketMesh),
 	ANKI_RESOURCE(Skeleton),
-	ANKI_RESOURCE(SkelAnim),
-	ANKI_RESOURCE(LightRsrc),
 	ANKI_RESOURCE(ParticleEmitterResource),
-	ANKI_RESOURCE(Script),
 	ANKI_RESOURCE(Model)
 {
 public:
-	ResourceManager(App* app, const ConfigSet& config);
+	class Initializer
+	{
+	public:
+		GlDevice* m_gl = nullptr;
+		const ConfigSet* m_config = nullptr;
+		CString m_cacheDir;
+		AllocAlignedCallback m_allocCallback = 0;
+		void* m_allocCallbackData = nullptr;
+		U32 m_tempAllocatorMemorySize = 1024 * 1024;
+	};
+
+	ResourceManager(Initializer& init);
 
 	const ResourceString& getDataDirectory() const
 	{
@@ -170,15 +176,12 @@ public:
 		return m_tmpAlloc;
 	}
 
-	App& _getApp()
-	{
-		return *m_app;
-	}
-
 	GlDevice& _getGlDevice();
 
-	/// For materials
-	CString _getShaderPostProcessorString() const;
+	const ResourceString& _getCacheDirectory() const
+	{
+		return m_cacheDir;
+	}
 
 	template<typename T>
 	Bool _findLoadedResource(const CString& filename, 
@@ -202,9 +205,10 @@ public:
 	/// @}
 
 private:
-	App* m_app;
+	GlDevice* m_gl = nullptr;
 	ResourceAllocator<U8> m_alloc;
 	TempResourceAllocator<U8> m_tmpAlloc;
+	ResourceString m_cacheDir;
 	ResourceString m_dataDir;
 	U32 m_maxTextureSize;
 	U32 m_textureAnisotropy;

+ 0 - 128
include/anki/resource/ResourceManager.inl.h

@@ -1,128 +0,0 @@
-// Copyright (C) 2014, Panagiotis Christopoulos Charitos.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include "anki/resource/ResourceManager.h"
-#include "anki/util/Assert.h"
-#include "anki/util/Exception.h"
-
-namespace anki {
-
-//==============================================================================
-template<typename Type>
-void TypeResourceManager<Type>::
-	allocAndLoadRsrc(const char* filename, Type*& newInstance)
-{
-	newInstance = nullptr;
-
-	// Alloc
-	try
-	{
-		newInstance = new Type();
-	}
-	catch(const std::exception& e)
-	{
-		throw ANKI_EXCEPTION("Constructor failed") << e;
-	}
-
-	// Load
-	try
-	{
-		newInstance->load(filename);
-	}
-	catch(std::exception& e)
-	{
-		throw ANKI_EXCEPTION("load() failed") << e;
-	}
-}
-
-//==============================================================================
-template<typename Type>
-typename TypeResourceManager<Type>::Hook& TypeResourceManager<Type>::
-	load(const char* filename)
-{
-	Iterator it = find(filename);
-
-	// If already loaded
-	if(it != hooks.end())
-	{
-		++(*it)->referenceCounter;
-		return *(*it);
-	}
-	// else create new, load it and update the container
-	else
-	{
-		Hook* hook = nullptr;
-		hook = new Hook;
-		hook->uuid = filename;
-		hook->referenceCounter = 1;
-		std::string newFname =
-			ResourceManagerSingleton::get().fixResourcePath(filename);
-
-		try
-		{
-			allocAndLoadRsrc(newFname.c_str(), hook->resource);
-		}
-		catch(std::exception& e)
-		{
-			delete hook;
-			throw ANKI_EXCEPTION("Cannot load: %s", newFname.c_str()) << e;
-		}
-
-		hooks.push_back(hook);
-		return *hook;
-	}
-}
-
-//==============================================================================
-template<typename Type>
-void TypeResourceManager<Type>::deallocRsrc(Type* rsrc)
-{
-	propperDelete(rsrc);
-}
-
-//==============================================================================
-template<typename Type>
-void TypeResourceManager<Type>::unload(const Hook& hook)
-{
-	// Find
-	Iterator it = find(hook.uuid.c_str());
-
-	// If not found
-	if(it == hooks.end())
-	{
-		throw ANKI_EXCEPTION("Resource hook not found: %s", hook.uuid.c_str());
-	}
-
-	ANKI_ASSERT(*(*it) == hook);
-	ANKI_ASSERT((*it)->referenceCounter > 0);
-
-	--(*it)->referenceCounter;
-
-	// Delete the resource
-	if((*it)->referenceCounter == 0)
-	{
-		deallocRsrc((*it)->resource);
-		hooks.erase(it);
-	}
-}
-
-//==============================================================================
-template<typename Type>
-typename TypeResourceManager<Type>::Iterator TypeResourceManager<Type>::
-	find(const char* filename)
-{
-	Iterator it = hooks.begin();
-	for(; it != hooks.end(); it++)
-	{
-		if((*it)->uuid == filename)
-		{
-			break;
-		}
-	}
-
-	return it;
-}
-
-} // end namespace anki

+ 14 - 15
include/anki/resource/Skeleton.h

@@ -6,8 +6,8 @@
 #ifndef ANKI_RESOURCE_SKELETON_H
 #define ANKI_RESOURCE_SKELETON_H
 
+#include "anki/resource/Common.h"
 #include "anki/Math.h"
-#include "anki/util/Vector.h"
 
 namespace anki {
 
@@ -17,28 +17,28 @@ struct Bone
 	friend class Skeleton; ///< For loading
 
 public:
-	/// @name Accessors
-	/// @{
-	const std::string& getName() const
+	Bone(ResourceAllocator<U8>& alloc)
+	:	m_name(alloc)
+	{}
+
+	const ResourceString& getName() const
 	{
-		return name;
+		return m_name;
 	}
 
 	const Mat4& getTransform() const
 	{
-		return transform;
+		return m_transform;
 	}
-	/// @}
 
 private:
-	std::string name; ///< The name of the bone
+	ResourceString m_name; ///< The name of the bone
 	static const U32 MAX_CHILDS_PER_BONE = 4; ///< Please dont change this
 
 	// see the class notes
-	Mat4 transform;
+	Mat4 m_transform;
 };
 
-
 /// It contains the bones with their position and hierarchy
 ///
 /// XML file format:
@@ -58,21 +58,20 @@ class Skeleton
 {
 public:
 	/// Load file
-	void load(const char* filename);
+	void load(const CString& filename, ResourceInitializer& init);
 
 	/// @name Accessors
 	/// @{
-	const Vector<Bone>& getBones() const
+	const ResourceVector<Bone>& getBones() const
 	{
-		return bones;
+		return m_bones;
 	}
 	/// @}
 
 private:
-	Vector<Bone> bones;
+	ResourceVector<Bone> m_bones;
 };
 
-
 } // end namespace
 
 

+ 3 - 4
include/anki/resource/Skin.h

@@ -6,14 +6,12 @@
 #ifndef ANKI_RESOURCE_SKIN_H
 #define ANKI_RESOURCE_SKIN_H
 
-#include "anki/resource/Resource.h"
+#include "anki/resource/ResourceManager.h"
 #include "anki/resource/Model.h"
 
+#if 0
 namespace anki {
 
-class Skeleton;
-class SkelAnim;
-
 /// Skin resource
 /// 
 /// XML file format:
@@ -66,5 +64,6 @@ private:
 };
 
 } // end namespace anki
+#endif
 
 #endif

+ 9 - 19
include/anki/util/String.h

@@ -12,6 +12,7 @@
 #include <cstring>
 #include <cmath> // For HUGE_VAL
 #include <climits> // For LLONG_MAX
+#include <cstdarg> // For var args
 
 namespace anki {
 
@@ -128,10 +129,6 @@ public:
 		return m_ptr == nullptr;
 	}
 
-	/// Add with a BasicString.
-	template<typename TAlloc>
-	BasicString<TAlloc> operator+(const BasicString<TAlloc>& str) const;
-
 	Bool operator==(const CString& b) const noexcept
 	{
 		checkInit();
@@ -593,7 +590,7 @@ public:
 	PtrSize find(const CStringType& cstr, PtrSize position = 0) const noexcept
 	{
 		checkInit();
-		return toString().find(cstr, position);
+		return toCString().find(cstr, position);
 	}
 
 	/// Find a substring of this string.
@@ -683,27 +680,20 @@ private:
 };
 
 template<typename TAlloc>
-inline BasicString<TAlloc> CString::operator+(
-	const BasicString<TAlloc>& str) const
+inline BasicString<TAlloc> operator+(
+	const CString& left, const BasicString<TAlloc>& right)
 {
-	BasicString<TAlloc> out(str.getAllocator());
+	BasicString<TAlloc> out(right.getAllocator());
 
-	auto thisLength = getLength();
-	out.resize(thisLength + str.getLength());
+	auto leftLength = left.getLength();
+	out.resize(leftLength + right.getLength());
 
-	std::memcpy(&out[0], &m_ptr[0], thisLength);
-	std::memcpy(&out[thisLength], &str[0], str.getLength() + 1);
+	std::memcpy(&out[0], &left[0], leftLength);
+	std::memcpy(&out[leftLength], &right[0], right.getLength() + 1);
 
 	return out;
 }
 
-template<typename TAlloc>
-inline BasicString<TAlloc> operator+(
-	const CString& left, const BasicString<TAlloc>& right)
-{
-	return left.operator+(right);
-}
-
 /// A common string type that uses heap allocator.
 using String = BasicString<HeapAllocator<char>>;
 

+ 3 - 3
include/anki/util/StringList.h

@@ -16,10 +16,10 @@ namespace anki {
 
 /// A simple convenience class for string lists
 template<typename TAlloc>
-class BasicStringList: public Vector<BasicString<TAlloc>, TAlloc>
+class StringListBase: public Vector<BasicString<TAlloc>, TAlloc>
 {
 public:
-	using Self = BasicStringList; ///< Self type
+	using Self = StringListBase; ///< Self type
 	using Char = char; ///< Char type
 	using Allocator = TAlloc;
 	using String = BasicString<TAlloc>; ///< String type
@@ -76,7 +76,7 @@ private:
 };
 
 /// A common string list allocated in heap.
-using StringList = BasicStringList<HeapAllocator<char>>;
+using StringList = StringListBase<HeapAllocator<char>>;
 
 /// @}
 

+ 5 - 5
include/anki/util/StringList.inl.h

@@ -10,8 +10,8 @@ namespace anki {
 
 //==============================================================================
 template<typename TAlloc>
-typename BasicStringList<TAlloc>::String 
-	BasicStringList<TAlloc>::join(const CString& separator) const
+typename StringListBase<TAlloc>::String 
+	StringListBase<TAlloc>::join(const CString& separator) const
 {
 	// Count the characters
 	I sepLen = separator.getLength();
@@ -43,7 +43,7 @@ typename BasicStringList<TAlloc>::String
 
 //==============================================================================
 template<typename TAlloc>
-I BasicStringList<TAlloc>::getIndexOf(const CString& value) const
+I StringListBase<TAlloc>::getIndexOf(const CString& value) const
 {
 	U pos = 0;
 
@@ -61,8 +61,8 @@ I BasicStringList<TAlloc>::getIndexOf(const CString& value) const
 
 //==============================================================================
 template<typename TAlloc>
-BasicStringList<TAlloc> 
-	BasicStringList<TAlloc>::splitString(
+StringListBase<TAlloc> 
+	StringListBase<TAlloc>::splitString(
 	const CString& s, 
 	const Char separator,
 	Allocator alloc)

+ 8 - 8
src/misc/Xml.cpp

@@ -50,8 +50,8 @@ Vector<F64, StackAllocator<F64>> XmlElement::getFloats() const
 			m_el->Value());
 	}
 
-	BasicStringList<StackAllocator<char>> list(
-		BasicStringList<StackAllocator<char>>::splitString(
+	StringListBase<StackAllocator<char>> list(
+		StringListBase<StackAllocator<char>>::splitString(
 		CString(txt), ' ', m_alloc));
 
 	Vector<F64, StackAllocator<F64>> out;
@@ -83,8 +83,8 @@ Mat4 XmlElement::getMat4() const
 		throw ANKI_EXCEPTION("Failed to return Mat4");
 	}
 
-	BasicStringList<StackAllocator<char>> list = 
-		BasicStringList<StackAllocator<char>>::splitString(
+	StringListBase<StackAllocator<char>> list = 
+		StringListBase<StackAllocator<char>>::splitString(
 		CString(txt), ' ', m_alloc);
 
 	if(list.size() != 16)
@@ -120,8 +120,8 @@ Vec3 XmlElement::getVec3() const
 		throw ANKI_EXCEPTION("Failed to return Vec3");
 	}
 
-	BasicStringList<StackAllocator<char>> list = 
-		BasicStringList<StackAllocator<char>>::splitString(
+	StringListBase<StackAllocator<char>> list = 
+		StringListBase<StackAllocator<char>>::splitString(
 		CString(txt), ' ', m_alloc);
 
 	if(list.size() != 3)
@@ -156,8 +156,8 @@ Vec4 XmlElement::getVec4() const
 		throw ANKI_EXCEPTION("Failed to return Vec4");
 	}
 
-	BasicStringList<StackAllocator<char>> list = 
-		BasicStringList<StackAllocator<char>>::splitString(
+	StringListBase<StackAllocator<char>> list = 
+		StringListBase<StackAllocator<char>>::splitString(
 		CString(txt), ' ', m_alloc);
 
 	if(list.size() != 4)

+ 0 - 118
src/resource/AsyncOperator.cpp

@@ -1,118 +0,0 @@
-// Copyright (C) 2014, Panagiotis Christopoulos Charitos.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include "anki/resource/AsyncOperator.h"
-#include "anki/core/Logger.h"
-#include "anki/util/HighRezTimer.h"
-
-
-namespace anki {
-/*
-
-//==============================================================================
-void AsyncOperator::start()
-{
-	ANKI_LOGI("Starting async operator thread...");
-	thread = boost::thread(&AsyncOperator::workingFunc, this);
-}
-
-
-//==============================================================================
-void AsyncOperator::putBack(Request* newReq)
-{
-	ANKI_LOGI("New request (" << newReq->getInfo() << ")");
-	boost::mutex::scoped_lock lock(mutexReq);
-	requests.push_back(newReq);
-	lock.unlock();
-
-	condVar.notify_one();
-}
-
-
-//==============================================================================
-void AsyncOperator::workingFunc()
-{
-	while(1)
-	{
-		Request* req;
-
-		// Wait for something
-		{
-			boost::mutex::scoped_lock lock(mutexReq);
-			while(requests.empty())
-			{
-				ANKI_LOGI("Waiting...");
-				condVar.wait(lock);
-			}
-
-			req = requests.front();
-			requests.pop_front();
-		}
-
-		if(req == NULL)
-		{
-			return;
-		}
-
-		// Exec the loader
-		bool ok = true;
-		try
-		{
-			req->exec();
-			ANKI_LOGI("Request served (" << req->getInfo() << ")");
-		}
-		catch(const std::exception& e)
-		{
-			ANKI_LOGE("Request failed (" << req->getInfo() << "): " <<
-				e.what());
-			ok = false;
-		}
-
-		req->ok = ok;
-
-		// Put back the response
-		{
-			boost::mutex::scoped_lock lock(mutexRes);
-			responses.push_back(req);
-		}
-	} // end thread loop
-}
-
-
-//==============================================================================
-uint AsyncOperator::execPostLoad(float maxTime)
-{
-	uint count = 0;
-	HighRezTimer t;
-	t.start();
-
-	while(true)
-	{
-		boost::mutex::scoped_lock lock(mutexRes);
-		if(responses.empty())
-		{
-			break;
-		}
-
-		Request* resp = responses.front();
-		responses.pop_front();
-		lock.unlock();
-
-		resp->postExec(*this);
-		delete resp;
-		++count;
-
-		// Leave if you passed the max time
-		if(t.getElapsedTime() >= maxTime)
-		{
-			break;
-		}
-	}
-
-	return count;
-}
-*/
-
-} // end namespace

+ 5 - 4
src/resource/Material.cpp

@@ -396,9 +396,10 @@ void Material::parseMaterialTag(const XmlElement& materialEl,
 				{
 					TempResourceString src(rinit.m_tempAlloc);
 
-					src.sprintf("#define LOD %u\n#define PASS %u\n"
-						"#define TESSELLATION %u\n%s\n", level, pid, tess,
-						&rinit.m_resources._getShaderPostProcessorString()[0]);
+					src.sprintf("#define LOD %u\n"
+						"#define PASS %u\n"
+						"#define TESSELLATION %u\n", 
+						level, pid, tess);
 
 					TempResourceString filename =
 						createProgramSourceToChache(src);
@@ -434,7 +435,7 @@ TempResourceString Material::createProgramSourceToChache(
 	// Create path
 	TempResourceString newfPathName(source.getAllocator());
 	newfPathName.sprintf("%s/mtl_%s.glsl", 
-		&m_resources->_getApp().getCacheDirectory()[0],
+		&m_resources->_getCacheDirectory()[0],
 		&prefix[0]);
 
 	// If file not exists write it

+ 23 - 33
src/resource/ParticleEmitterResource.cpp

@@ -17,11 +17,7 @@ namespace anki {
 //==============================================================================
 
 //==============================================================================
-#define PE_EXCEPTION(x) ANKI_EXCEPTION("Particle emmiter: " \
-	"Incorrect or missing value %s", x)
-
-//==============================================================================
-static void xmlReadVec3(const XmlElement& el_, const char* str, Vec3& out)
+static void xmlReadVec3(const XmlElement& el_, const CString& str, Vec3& out)
 {
 	XmlElement el = el_.getChildElementOptional(str);
 
@@ -30,22 +26,11 @@ static void xmlReadVec3(const XmlElement& el_, const char* str, Vec3& out)
 		return;
 	}
 
-	StringList list;
-
-	list = StringList::splitString(el.getText(), ' ');
-	if(list.size() != 3)
-	{
-		throw ANKI_EXCEPTION("Expecting 3 floats for Vec3");
-	}
-
-	for(U i = 0; i < 3; i++)
-	{
-		out[i] = std::stof(list[i]);
-	}
+	out = el.getVec3();
 }
 
 //==============================================================================
-static void xmlReadFloat(const XmlElement& el_, const char* str, F32& out)
+static void xmlReadFloat(const XmlElement& el_, const CString& str, F32& out)
 {
 	XmlElement el = el_.getChildElementOptional(str);
 
@@ -54,11 +39,11 @@ static void xmlReadFloat(const XmlElement& el_, const char* str, F32& out)
 		return;
 	}
 
-	out = std::stof(el.getText());
+	out = el.getFloat();
 }
 
 //==============================================================================
-static void xmlReadU(const XmlElement& el_, const char* str, U32& out)
+static void xmlReadU(const XmlElement& el_, const CString& str, U32& out)
 {
 	XmlElement el = el_.getChildElementOptional(str);
 
@@ -67,7 +52,7 @@ static void xmlReadU(const XmlElement& el_, const char* str, U32& out)
 		return;
 	}
 
-	out = (U32)std::stoi(el.getText());
+	out = static_cast<U32>(el.getInt());
 }
 
 //==============================================================================
@@ -78,7 +63,7 @@ static void xmlReadU(const XmlElement& el_, const char* str, U32& out)
 ParticleEmitterProperties& ParticleEmitterProperties::operator=(
 	const ParticleEmitterProperties& b)
 {
-	memcpy(this, &b, sizeof(ParticleEmitterProperties));
+	std::memcpy(this, &b, sizeof(ParticleEmitterProperties));
 	return *this;
 }
 
@@ -108,13 +93,14 @@ ParticleEmitterResource::~ParticleEmitterResource()
 {}
 
 //==============================================================================
-void ParticleEmitterResource::load(const char* filename)
+void ParticleEmitterResource::load(const CString& filename, 
+	ResourceInitializer& init)
 {
 	try
 	{
 		XmlDocument doc;
-		doc.loadFile(filename);
-		loadInternal(doc.getChildElement("particleEmitter"));
+		doc.loadFile(filename, init.m_tempAlloc);
+		loadInternal(doc.getChildElement("particleEmitter"), init);
 	}
 	catch(std::exception& e)
 	{
@@ -123,7 +109,8 @@ void ParticleEmitterResource::load(const char* filename)
 }
 
 //==============================================================================
-void ParticleEmitterResource::loadInternal(const XmlElement& rootel)
+void ParticleEmitterResource::loadInternal(const XmlElement& rootel,
+	ResourceInitializer& init)
 {
 	// XML load
 	//
@@ -166,39 +153,42 @@ void ParticleEmitterResource::loadInternal(const XmlElement& rootel)
 	m_usePhysicsEngine = tmp;
 
 	XmlElement el = rootel.getChildElement("material");
-	m_material.load(el.getText());
+	m_material.load(el.getText(), &init.m_resources);
 
 	// sanity checks
 	//
 
+	static const char* ERROR = "Particle emmiter: "
+		"Incorrect or missing value %s";
+
 	if(m_particle.m_life <= 0.0)
 	{
-		throw PE_EXCEPTION("life");
+		throw ANKI_EXCEPTION(ERROR, "life");
 	}
 
 	if(m_particle.m_life - m_particle.m_lifeDeviation <= 0.0)
 	{
-		throw PE_EXCEPTION("lifeDeviation");
+		throw ANKI_EXCEPTION(ERROR, "lifeDeviation");
 	}
 
 	if(m_particle.m_size <= 0.0)
 	{
-		throw PE_EXCEPTION("size");
+		throw ANKI_EXCEPTION(ERROR, "size");
 	}
 
 	if(m_maxNumOfParticles < 1)
 	{
-		throw PE_EXCEPTION("maxNumOfParticles");
+		throw ANKI_EXCEPTION(ERROR, "maxNumOfParticles");
 	}
 
 	if(m_emissionPeriod <= 0.0)
 	{
-		throw PE_EXCEPTION("emissionPeriod");
+		throw ANKI_EXCEPTION(ERROR, "emissionPeriod");
 	}
 
 	if(m_particlesPerEmittion < 1)
 	{
-		throw PE_EXCEPTION("particlesPerEmission");
+		throw ANKI_EXCEPTION(ERROR, "particlesPerEmission");
 	}
 
 	// Calc some stuff

+ 3 - 3
src/resource/ProgramResource.cpp

@@ -17,7 +17,7 @@ namespace anki {
 //==============================================================================
 void ProgramResource::load(const CString& filename, ResourceInitializer& init)
 {
-	load(filename, " ", init.m_resourceManager);
+	load(filename, " ", init.m_resources);
 }
 
 //==============================================================================
@@ -58,8 +58,8 @@ String ProgramResource::createSourceToCache(
 	String suffix(String::toString(h, alloc));
 
 	// Compose cached filename
-	String newFilename(manager._getApp().getCachePath()
-		+ CString("/") + filenamePrefix + suffix + CString(".glsl"));
+	String newFilename(manager._getCacheDirectory()
+		+ "/" + filenamePrefix + suffix + ".glsl");
 
 	if(fileExists(newFilename.toCString()))
 	{

+ 32 - 28
src/resource/ResourceManager.cpp

@@ -13,71 +13,75 @@
 #include "anki/resource/TextureResource.h"
 #include "anki/core/Logger.h"
 #include "anki/misc/ConfigSet.h"
-#include <cstring>
 
 namespace anki {
 
 //==============================================================================
-ResourceManager::ResourceManager(App* app, const ConfigSet& config)
-:	m_app(app),
-	m_alloc(HeapMemoryPool(
-		m_app->getAllocationCallback(), m_app->getAllocationCallbackData())),
-	m_tmpAlloc(StackMemoryPool(m_app->getAllocationCallback(), 
-		m_app->getAllocationCallbackData(), 1024 * 1024))
+ResourceManager::ResourceManager(Initializer& init)
+:	m_gl(init.m_gl),
+	m_alloc(HeapMemoryPool(init.m_allocCallback, init.m_allocCallbackData)),
+	m_tmpAlloc(StackMemoryPool(
+		init.m_allocCallback, init.m_allocCallbackData, 
+		init.m_tempAllocatorMemorySize)),
+	m_cacheDir(m_alloc),
+	m_dataDir(init.m_cacheDir, m_alloc)
 {
 	// Init the data path
 	//
 	if(getenv("ANKI_DATA_PATH"))
 	{
-		m_dataDir = ResourceString(getenv("ANKI_DATA_PATH"), m_alloc);
+		m_dataDir = getenv("ANKI_DATA_PATH");
 		m_dataDir += "/";
-		ANKI_LOGI("Data path: %s", m_dataDir.c_str());
+		ANKI_LOGI("Data path: %s", &m_dataDir[0]);
 	}
 	else
 	{
 		// Assume working directory
 #if ANKI_OS == ANKI_OS_ANDROID
-		m_dataDir = ResourceString("$", m_alloc);
+		m_dataDir = "$";
 #else
-		m_dataDir = ResourceString("./", m_alloc);
+		m_dataDir = "./";
 #endif
 	}
 
-	// Init cache dir
-	//
-	m_cacheDir = ResourceString(cacheDir, m_alloc);
-
 	// Init some constants
 	//
-	m_maxTextureSize = config.get("maxTextureSize");
-	m_textureAnisotropy = config.get("textureAnisotropy");
+	m_maxTextureSize = init.m_config->get("maxTextureSize");
+	m_textureAnisotropy = init.m_config->get("textureAnisotropy");
 
 	// Init type resource managers
 	//
-	TypeResourceManager<Animation, ResourceManager>::init(m_alloc);
-	TypeResourceManager<Material, ResourceManager>::init(m_alloc);
-	TypeResourceManager<Mesh, ResourceManager>::init(m_alloc);
-	TypeResourceManager<Model, ResourceManager>::init(m_alloc);
-	TypeResourceManager<BucketMesh, ResourceManager>::init(m_alloc);
-	TypeResourceManager<ProgramResource, ResourceManager>::init(m_alloc);
-	TypeResourceManager<ParticleEmitterResource, ResourceManager>::init(
-		m_alloc);
+#define ANKI_RESOURCE(type_) \
+	TypeResourceManager<type_, ResourceManager>::init(m_alloc);
+
+	ANKI_RESOURCE(Animation)
+	ANKI_RESOURCE(TextureResource)
+	ANKI_RESOURCE(ProgramResource)
+	ANKI_RESOURCE(Material)
+	ANKI_RESOURCE(Mesh)
+	ANKI_RESOURCE(BucketMesh)
+	ANKI_RESOURCE(Skeleton)
+	ANKI_RESOURCE(ParticleEmitterResource)
+	ANKI_RESOURCE(Model)
+
+#undef ANKI_RESOURCE
 }
 
 //==============================================================================
 TempResourceString ResourceManager::fixResourceFilename(
-	const char* filename) const
+	const CString& filename) const
 {
 	TempResourceString newFname(m_tmpAlloc);
 
 	// If the filename is in cache then dont append the data path
-	if(std::strstr(filename, m_cacheDir.c_str()) != nullptr)
+	if(filename.find(m_cacheDir.toCString()) != TempResourceString::NPOS)
 	{
 		newFname = filename;
 	}
 	else
 	{
-		newFname = TempResourceString(m_dataDir.c_str(), m_tmpAlloc) + filename;
+		newFname = TempResourceString(m_dataDir.toCString(), m_tmpAlloc) 
+			+ filename;
 	}
 
 	return newFname;

+ 7 - 16
src/resource/Skeleton.cpp

@@ -10,10 +10,10 @@
 namespace anki {
 
 //==============================================================================
-void Skeleton::load(const char* filename)
+void Skeleton::load(const CString& filename, ResourceInitializer& init)
 {
 	XmlDocument doc;
-	doc.loadFile(filename);
+	doc.loadFile(filename, init.m_tempAlloc);
 
 	XmlElement rootEl = doc.getChildElement("skeleton");
 	XmlElement bonesEl = rootEl.getChildElement("bones");
@@ -30,32 +30,23 @@ void Skeleton::load(const char* filename)
 	} while(boneEl);
 
 	// Alloc the vector
-	bones.resize(bonesCount);
+	m_bones = std::move(ResourceVector<Bone>(init.m_alloc));
+	m_bones.resize(bonesCount, Bone(init.m_alloc));
 
 	// Load every bone
 	boneEl = bonesEl.getChildElement("bone");
 	bonesCount = 0;
 	do
 	{
-		Bone& bone = bones[bonesCount++];
+		Bone& bone = m_bones[bonesCount++];
 
 		// <name>
 		XmlElement nameEl = boneEl.getChildElement("name");
-		bone.name = nameEl.getText();
+		bone.m_name = nameEl.getText();
 
 		// <transform>
 		XmlElement trfEl = boneEl.getChildElement("transform");
-		StringList list = StringList::splitString(trfEl.getText(), ' ');
-
-		if(list.size() != 16)
-		{
-			throw ANKI_EXCEPTION("Expecting 16 floats for <transform>");
-		}
-
-		for(U i = 0; i < 16; i++)
-		{
-			bone.transform[i] = std::stof(list[i]);
-		}
+		bone.m_transform = trfEl.getMat4();
 
 		// Advance 
 		boneEl = boneEl.getNextSiblingElement("bone");

+ 2 - 0
src/resource/Skin.cpp

@@ -13,6 +13,7 @@
 #include "anki/resource/Material.h"
 #include "anki/misc/Xml.h"
 
+#if 0
 namespace anki {
 
 //==============================================================================
@@ -96,3 +97,4 @@ void Skin::load(const char* filename)
 }
 
 } // end namespace anki
+#endif