Browse Source

Removing exceptions

Panagiotis Christopoulos Charitos 11 years ago
parent
commit
b9271ae35b

+ 5 - 6
include/anki/resource/MaterialProgramCreator.h

@@ -51,11 +51,14 @@ public:
 		Bool8 m_inBlock = true;
 		Bool8 m_inBlock = true;
 	};
 	};
 
 
-	explicit MaterialProgramCreator(const XmlElement& pt, 
-		TempResourceAllocator<U8>& alloc);
+	explicit MaterialProgramCreator(TempResourceAllocator<U8>& alloc);
 
 
 	~MaterialProgramCreator();
 	~MaterialProgramCreator();
 
 
+	/// Parse what is within the
+	/// @code <programs></programs> @endcode
+	ANKI_USE_RESULT Error parseProgramsTag(const XmlElement& el);
+
 	/// Get the shader program source code
 	/// Get the shader program source code
 	MPString getProgramSource(ShaderType shaderType_) const
 	MPString getProgramSource(ShaderType shaderType_) const
 	{
 	{
@@ -85,10 +88,6 @@ private:
 	GLbitfield m_instanceIdMask = 0;
 	GLbitfield m_instanceIdMask = 0;
 	Bool8 m_tessellation = false;
 	Bool8 m_tessellation = false;
 
 
-	/// Parse what is within the
-	/// @code <programs></programs> @endcode
-	ANKI_USE_RESULT Error parseProgramsTag(const XmlElement& el);
-
 	/// Parse what is within the
 	/// Parse what is within the
 	/// @code <program></program> @endcode
 	/// @code <program></program> @endcode
 	ANKI_USE_RESULT Error parseProgramTag(const XmlElement& el);
 	ANKI_USE_RESULT Error parseProgramTag(const XmlElement& el);

+ 33 - 28
include/anki/resource/MeshLoader.h

@@ -48,7 +48,7 @@ class MeshLoader
 {
 {
 public:
 public:
 	template<typename T>
 	template<typename T>
-	using MLVector = TempResourceVector<T>;
+	using MLDArray = TempResourceDArray<T>;
 
 
 	/// If two vertices have the same position and normals under the angle 
 	/// If two vertices have the same position and normals under the angle 
 	/// specified by this constant then combine those normals
 	/// specified by this constant then combine those normals
@@ -78,27 +78,26 @@ public:
 
 
 	MeshLoader(TempResourceAllocator<U8>& alloc);
 	MeshLoader(TempResourceAllocator<U8>& alloc);
 
 
-	~MeshLoader()
-	{}
+	~MeshLoader();
 
 
 	/// @name Accessors
 	/// @name Accessors
 	/// @{
 	/// @{
-	const MLVector<Vec3>& getPositions() const
+	const MLDArray<Vec3>& getPositions() const
 	{
 	{
 		return m_positions;
 		return m_positions;
 	}
 	}
 
 
-	const MLVector<HVec3>& getNormals() const
+	const MLDArray<HVec3>& getNormals() const
 	{
 	{
 		return m_normalsF16;
 		return m_normalsF16;
 	}
 	}
 
 
-	const MLVector<HVec4>& getTangents() const
+	const MLDArray<HVec4>& getTangents() const
 	{
 	{
 		return m_tangentsF16;
 		return m_tangentsF16;
 	}
 	}
 
 
-	const MLVector<HVec2>& getTextureCoordinates(const U32 channel) const
+	const MLDArray<HVec2>& getTextureCoordinates(const U32 channel) const
 	{
 	{
 		return m_texCoordsF16;
 		return m_texCoordsF16;
 	}
 	}
@@ -107,53 +106,59 @@ public:
 		return 1;
 		return 1;
 	}
 	}
 
 
-	const MLVector<VertexWeight>& getWeights() const
+	const MLDArray<VertexWeight>& getWeights() const
 	{
 	{
 		return m_weights;
 		return m_weights;
 	}
 	}
 
 
-	const MLVector<U16>& getIndices() const
+	const MLDArray<U16>& getIndices() const
 	{
 	{
 		return m_vertIndices;
 		return m_vertIndices;
 	}
 	}
 	/// @}
 	/// @}
 
 
 	/// Append data from another mesh loader. BucketMesh method
 	/// Append data from another mesh loader. BucketMesh method
-	void append(const MeshLoader& other);
+	ANKI_USE_RESULT Error append(const MeshLoader& other);
 
 
 	/// Load the mesh data from a binary file
 	/// Load the mesh data from a binary file
 	/// @exception Exception
 	/// @exception Exception
 	ANKI_USE_RESULT Error load(const CString& filename);
 	ANKI_USE_RESULT Error load(const CString& filename);
 
 
 private:
 private:
-	MLVector<Vec3> m_positions; ///< Loaded from file
+	TempResourceAllocator<U8> m_alloc;
 
 
-	MLVector<Vec3> m_normals; ///< Generated
-	MLVector<HVec3> m_normalsF16;
+	MLDArray<Vec3> m_positions; ///< Loaded from file
 
 
-	MLVector<Vec4> m_tangents; ///< Generated
-	MLVector<HVec4> m_tangentsF16;
+	MLDArray<Vec3> m_normals; ///< Generated
+	MLDArray<HVec3> m_normalsF16;
+
+	MLDArray<Vec4> m_tangents; ///< Generated
+	MLDArray<HVec4> m_tangentsF16;
 
 
 	/// Optional. One for every vert so we can use vertex arrays & VBOs
 	/// Optional. One for every vert so we can use vertex arrays & VBOs
-	MLVector<Vec2> m_texCoords;
-	MLVector<HVec2> m_texCoordsF16;
+	MLDArray<Vec2> m_texCoords;
+	MLDArray<HVec2> m_texCoordsF16;
 
 
-	MLVector<VertexWeight> m_weights; ///< Optional
+	MLDArray<VertexWeight> m_weights; ///< Optional
 
 
-	MLVector<Triangle> m_tris; ///< Required
+	MLDArray<Triangle> m_tris; ///< Required
 
 
 	/// Generated. Used for vertex arrays & VBOs
 	/// Generated. Used for vertex arrays & VBOs
-	MLVector<U16> m_vertIndices;
+	MLDArray<U16> m_vertIndices;
 
 
-	void createFaceNormals();
-	void createVertNormals();
-	void createAllNormals()
+	ANKI_USE_RESULT Error createFaceNormals();
+	ANKI_USE_RESULT Error createVertNormals();
+	ANKI_USE_RESULT Error createAllNormals()
 	{
 	{
-		createFaceNormals();
-		createVertNormals();
+		Error err = createFaceNormals();
+		if(!err)
+		{
+			err = createVertNormals();
+		}
+		return err;
 	}
 	}
-	void createVertTangents();
-	void createVertIndeces();
+	ANKI_USE_RESULT Error createVertTangents();
+	ANKI_USE_RESULT Error createVertIndeces();
 
 
 	/// This method does some sanity checks and creates normals,
 	/// This method does some sanity checks and creates normals,
 	/// tangents, VBOs etc
 	/// tangents, VBOs etc
@@ -164,7 +169,7 @@ private:
 	void fixNormals();
 	void fixNormals();
 
 
 	/// Compress some buffers for increased BW performance
 	/// Compress some buffers for increased BW performance
-	void compressBuffers();
+	ANKI_USE_RESULT Error compressBuffers();
 };
 };
 
 
 } // end namespace anki
 } // end namespace anki

+ 11 - 16
include/anki/resource/ProgramPrePreprocessor.h

@@ -33,20 +33,21 @@ private:
 public:
 public:
 	/// It loads a file and parses it
 	/// It loads a file and parses it
 	/// @param[in] filename The file to load
 	/// @param[in] filename The file to load
-	ProgramPrePreprocessor(
-		const CString& filename, ResourceManager* manager)
+	ProgramPrePreprocessor(ResourceManager* manager)
 	:	m_shaderSource(manager->_getTempAllocator()),
 	:	m_shaderSource(manager->_getTempAllocator()),
 		m_sourceLines(manager->_getTempAllocator()),
 		m_sourceLines(manager->_getTempAllocator()),
 		m_manager(manager)
 		m_manager(manager)
-	{
-		parseFile(filename);
-	}
+	{}
 
 
 	~ProgramPrePreprocessor()
 	~ProgramPrePreprocessor()
 	{}
 	{}
 
 
-	/// @name Accessors
-	/// @{
+	/// Parse a PrePreprocessor formated GLSL file. Use the accessors to get 
+	/// the output
+	///
+	/// @param filename The file to parse
+	ANKI_USE_RESULT Error parseFile(const CString& filename);
+
 	const PPPString& getShaderSource() const
 	const PPPString& getShaderSource() const
 	{
 	{
 		ANKI_ASSERT(!m_shaderSource.isEmpty());
 		ANKI_ASSERT(!m_shaderSource.isEmpty());
@@ -58,7 +59,6 @@ public:
 		ANKI_ASSERT(m_type != ShaderType::COUNT);
 		ANKI_ASSERT(m_type != ShaderType::COUNT);
 		return m_type;
 		return m_type;
 	}
 	}
-	/// @}
 
 
 protected:
 protected:
 	/// The final program source
 	/// The final program source
@@ -73,22 +73,17 @@ protected:
 	/// Keep the manager for some path conversions.
 	/// Keep the manager for some path conversions.
 	ResourceManager* m_manager;
 	ResourceManager* m_manager;
 
 
-	/// Parse a PrePreprocessor formated GLSL file. Use the accessors to get 
-	/// the output
-	///
-	/// @param filename The file to parse
-	void parseFile(const CString& filename);
-
 	/// A recursive function that parses a file for pragmas and updates the 
 	/// A recursive function that parses a file for pragmas and updates the 
 	/// output
 	/// output
 	///
 	///
 	/// @param filename The file to parse
 	/// @param filename The file to parse
 	/// @param depth The #line in GLSL does not support filename so an
 	/// @param depth The #line in GLSL does not support filename so an
 	///              depth it being used. It also tracks the includance depth
 	///              depth it being used. It also tracks the includance depth
-	void parseFileForPragmas(const PPPString& filename, U32 depth);
+	ANKI_USE_RESULT Error parseFileForPragmas(
+		const PPPString& filename, U32 depth);
 
 
 	/// Parse the type
 	/// Parse the type
-	Bool parseType(const PPPString& line);
+	ANKI_USE_RESULT Error parseType(const PPPString& line, Bool& found);
 
 
 	void printSourceLines() const;  ///< For debugging
 	void printSourceLines() const;  ///< For debugging
 };
 };

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

@@ -145,7 +145,7 @@ public:
 		CString m_cacheDir;
 		CString m_cacheDir;
 		AllocAlignedCallback m_allocCallback = 0;
 		AllocAlignedCallback m_allocCallback = 0;
 		void* m_allocCallbackData = nullptr;
 		void* m_allocCallbackData = nullptr;
-		U32 m_tempAllocatorMemorySize = 1024 * 1024;
+		U32 m_tempAllocatorMemorySize = 2 * 1024 * 1024;
 	};
 	};
 
 
 	ResourceManager(Initializer& init);
 	ResourceManager(Initializer& init);

+ 0 - 6
include/anki/resource/ResourcePointer.h

@@ -39,12 +39,6 @@ public:
 		copy(b);
 		copy(b);
 	}
 	}
 
 
-	/// Construct and load
-	ResourcePointer(const CString& filename, TResourceManager* resources)
-	{
-		load(filename, resources);
-	}
-
 	~ResourcePointer()
 	~ResourcePointer()
 	{
 	{
 		reset();
 		reset();

+ 28 - 21
include/anki/resource/ResourcePointer.inl.h

@@ -43,33 +43,38 @@ Error ResourcePointer<T, TResourceManager>::load(
 		// Populate the m_cb. Use a block ton cleanup temp_pool allocations
 		// Populate the m_cb. Use a block ton cleanup temp_pool allocations
 		auto& pool = resources->_getTempAllocator().getMemoryPool();
 		auto& pool = resources->_getTempAllocator().getMemoryPool();
 
 
-		TempResourceString newFname(
-			resources->fixResourceFilename(filename));
-
-		ResourceInitializer init(
-			alloc,
-			resources->_getTempAllocator(),
-			*resources);
-
-		U allocsCountBefore = pool.getAllocationsCount();
-		(void)allocsCountBefore;
-
-		err = m_cb->m_resource.load(newFname.toCString(), init);
-		if(err)
+		// WARNING: Keep the brackets to force deallocation of newFname before
+		// reseting the mempool
 		{
 		{
-			ANKI_LOGE("Failed to load resource: %s", &newFname[0]);
-			alloc.deleteInstance(m_cb);
-			m_cb = nullptr;
-			return err;
+			TempResourceString newFname(
+				resources->fixResourceFilename(filename));
+
+			ResourceInitializer init(
+				alloc,
+				resources->_getTempAllocator(),
+				*resources);
+
+			U allocsCountBefore = pool.getAllocationsCount();
+			(void)allocsCountBefore;
+
+			err = m_cb->m_resource.load(newFname.toCString(), init);
+			if(err)
+			{
+				ANKI_LOGE("Failed to load resource: %s", &newFname[0]);
+				alloc.deleteInstance(m_cb);
+				m_cb = nullptr;
+				return err;
+			}
+
+			ANKI_ASSERT(pool.getAllocationsCount() == allocsCountBefore
+				&& "Forgot to deallocate");
 		}
 		}
 
 
-		ANKI_ASSERT(pool.getAllocationsCount() == allocsCountBefore
-			&& "Forgot to deallocate");
-
 		m_cb->m_resources = resources;
 		m_cb->m_resources = resources;
 		std::memcpy(&m_cb->m_uuid[0], &filename[0], len + 1);
 		std::memcpy(&m_cb->m_uuid[0], &filename[0], len + 1);
 
 
-		// Reset the memory pool if no-one is using it
+		// Reset the memory pool if no-one is using it.
+		// NOTE: Check because resources load other resources
 		if(pool.getAllocationsCount() == 0)
 		if(pool.getAllocationsCount() == 0)
 		{
 		{
 			pool.reset();
 			pool.reset();
@@ -82,6 +87,8 @@ Error ResourcePointer<T, TResourceManager>::load(
 	{
 	{
 		*this = other;
 		*this = other;
 	}
 	}
+
+	return err;
 }
 }
 
 
 //==============================================================================
 //==============================================================================

+ 15 - 8
include/anki/util/DArray.h

@@ -120,24 +120,31 @@ public:
 		return m_size;
 		return m_size;
 	}
 	}
 
 
+	PtrSize getSizeInBytes() const
+	{
+		return m_size * sizeof(Value);
+	}
+
 	/// Create the array.
 	/// Create the array.
 	template<typename... TArgs>
 	template<typename... TArgs>
 	ANKI_USE_RESULT Error create(Allocator alloc, PtrSize size, TArgs... args)
 	ANKI_USE_RESULT Error create(Allocator alloc, PtrSize size, TArgs... args)
 	{
 	{
 		ANKI_ASSERT(m_data == nullptr && m_size == 0);
 		ANKI_ASSERT(m_data == nullptr && m_size == 0);
-		ANKI_ASSERT(size);
 		Error err = ErrorCode::NONE;
 		Error err = ErrorCode::NONE;
 
 
 		destroy(alloc);
 		destroy(alloc);
 
 
-		m_data = alloc.template newArray<Value>(size, args...);
-		if(m_data)
-		{
-			m_size = size;
-		}
-		else
+		if(size > 0)
 		{
 		{
-			err = ErrorCode::OUT_OF_MEMORY;
+			m_data = alloc.template newArray<Value>(size, args...);
+			if(m_data)
+			{
+				m_size = size;
+			}
+			else
+			{
+				err = ErrorCode::OUT_OF_MEMORY;
+			}
 		}
 		}
 
 
 		return err;
 		return err;

+ 5 - 5
src/resource/Material.cpp

@@ -427,7 +427,8 @@ Error Material::parseMaterialTag(const XmlElement& materialEl,
 	// shaderProgram
 	// shaderProgram
 	//
 	//
 	ANKI_CHECK(materialEl.getChildElement("programs", el));
 	ANKI_CHECK(materialEl.getChildElement("programs", el));
-	MaterialProgramCreator loader(el, rinit.m_tempAlloc);
+	MaterialProgramCreator loader(rinit.m_tempAlloc);
+	ANKI_CHECK(loader.parseProgramsTag(el));
 
 
 	m_tessellation = loader.hasTessellation();
 	m_tessellation = loader.hasTessellation();
 	U tessCount = m_tessellation ? 2 : 1;
 	U tessCount = m_tessellation ? 2 : 1;
@@ -500,7 +501,8 @@ Error Material::parseMaterialTag(const XmlElement& materialEl,
 
 
 					RenderingKey key((Pass)pid, level, tess);
 					RenderingKey key((Pass)pid, level, tess);
 					ProgramResourcePointer& progr = getProgram(key, shader);
 					ProgramResourcePointer& progr = getProgram(key, shader);
-					progr.load(filename.toCString(), &rinit.m_resources);
+					ANKI_CHECK(
+						progr.load(filename.toCString(), &rinit.m_resources));
 
 
 					// Update the hash
 					// Update the hash
 					m_hash ^= computeHash(&src[0], src.getLength());
 					m_hash ^= computeHash(&src[0], src.getLength());
@@ -615,9 +617,7 @@ Error Material::populateVariables(const MaterialProgramCreator& loader)
 				
 				
 				if(in.m_value.size() > 0)
 				if(in.m_value.size() > 0)
 				{
 				{
-					tp = TextureResourcePointer(
-						in.m_value[0].toCString(),
-						m_resources);
+					ANKI_CHECK(tp.load(in.m_value[0].toCString(), m_resources));
 				}
 				}
 
 
 				auto alloc = m_resources->_getAllocator();
 				auto alloc = m_resources->_getAllocator();

+ 2 - 4
src/resource/MaterialProgramCreator.cpp

@@ -88,13 +88,11 @@ static ANKI_USE_RESULT Error getShaderInfo(
 
 
 //==============================================================================
 //==============================================================================
 MaterialProgramCreator::MaterialProgramCreator(
 MaterialProgramCreator::MaterialProgramCreator(
-	const XmlElement& el, TempResourceAllocator<U8>& alloc)
+	TempResourceAllocator<U8>& alloc)
 :	m_alloc(alloc),
 :	m_alloc(alloc),
 	m_inputs(alloc),
 	m_inputs(alloc),
 	m_uniformBlock(m_alloc)
 	m_uniformBlock(m_alloc)
-{
-	parseProgramsTag(el);
-}
+{}
 
 
 //==============================================================================
 //==============================================================================
 MaterialProgramCreator::~MaterialProgramCreator()
 MaterialProgramCreator::~MaterialProgramCreator()

+ 16 - 16
src/resource/Mesh.cpp

@@ -40,20 +40,20 @@ Error Mesh::load(const CString& filename, ResourceInitializer& init)
 	MeshLoader loader(init.m_tempAlloc);
 	MeshLoader loader(init.m_tempAlloc);
 	ANKI_CHECK(loader.load(filename))
 	ANKI_CHECK(loader.load(filename))
 
 
-	m_indicesCount = loader.getIndices().size();
+	m_indicesCount = loader.getIndices().getSize();
 
 
 	const auto& positions = loader.getPositions();
 	const auto& positions = loader.getPositions();
-	m_obb.setFromPointCloud(&positions[0], positions.size(),
+	m_obb.setFromPointCloud(&positions[0], positions.getSize(),
 		sizeof(Vec3), positions.getSizeInBytes());
 		sizeof(Vec3), positions.getSizeInBytes());
 	ANKI_ASSERT(m_indicesCount > 0);
 	ANKI_ASSERT(m_indicesCount > 0);
 	ANKI_ASSERT(m_indicesCount % 3 == 0 && "Expecting triangles");
 	ANKI_ASSERT(m_indicesCount % 3 == 0 && "Expecting triangles");
 
 
 	// Set the non-VBO members
 	// Set the non-VBO members
-	m_vertsCount = loader.getPositions().size();
+	m_vertsCount = loader.getPositions().getSize();
 	ANKI_ASSERT(m_vertsCount > 0);
 	ANKI_ASSERT(m_vertsCount > 0);
 
 
 	m_texChannelsCount = loader.getTextureChannelsCount();
 	m_texChannelsCount = loader.getTextureChannelsCount();
-	m_weights = loader.getWeights().size() > 1;
+	m_weights = loader.getWeights().getSize() > 1;
 
 
 	ANKI_CHECK(createBuffers(loader, init));
 	ANKI_CHECK(createBuffers(loader, init));
 
 
@@ -78,9 +78,9 @@ U32 Mesh::calcVertexSize() const
 Error Mesh::createBuffers(const MeshLoader& loader,
 Error Mesh::createBuffers(const MeshLoader& loader,
 	ResourceInitializer& init)
 	ResourceInitializer& init)
 {
 {
-	ANKI_ASSERT(m_vertsCount == loader.getPositions().size()
-		&& m_vertsCount == loader.getNormals().size()
-		&& m_vertsCount == loader.getTangents().size());
+	ANKI_ASSERT(m_vertsCount == loader.getPositions().getSize()
+		&& m_vertsCount == loader.getNormals().getSize()
+		&& m_vertsCount == loader.getTangents().getSize());
 
 
 	Error err = ErrorCode::NONE;
 	Error err = ErrorCode::NONE;
 
 
@@ -134,7 +134,7 @@ Error Mesh::createBuffers(const MeshLoader& loader,
 	GlClientBufferHandle clientIndexBuff;
 	GlClientBufferHandle clientIndexBuff;
 	ANKI_CHECK(clientIndexBuff.create(
 	ANKI_CHECK(clientIndexBuff.create(
 		cmdb, 
 		cmdb, 
-		getVectorSizeInBytes(loader.getIndices()), 
+		loader.getIndices().getSizeInBytes(), 
 		(void*)&loader.getIndices()[0]));
 		(void*)&loader.getIndices()[0]));
 	ANKI_CHECK(m_indicesBuff.create(
 	ANKI_CHECK(m_indicesBuff.create(
 		cmdb, GL_ELEMENT_ARRAY_BUFFER, clientIndexBuff, 0));
 		cmdb, GL_ELEMENT_ARRAY_BUFFER, clientIndexBuff, 0));
@@ -295,7 +295,7 @@ Error BucketMesh::load(const CString& filename, ResourceInitializer& init)
 			loader = &subLoader;
 			loader = &subLoader;
 
 
 			// Sanity checks
 			// Sanity checks
-			if(m_weights != (loader->getWeights().size() > 1))
+			if(m_weights != (loader->getWeights().getSize() > 1))
 			{
 			{
 				ANKI_LOGE("All sub meshes should have or not "
 				ANKI_LOGE("All sub meshes should have or not "
 					"have vertex weights");
 					"have vertex weights");
@@ -311,7 +311,7 @@ Error BucketMesh::load(const CString& filename, ResourceInitializer& init)
 			}
 			}
 
 
 			// Append
 			// Append
-			fullLoader.append(subLoader);
+			ANKI_CHECK(fullLoader.append(subLoader));
 		}
 		}
 		else
 		else
 		{
 		{
@@ -320,23 +320,23 @@ Error BucketMesh::load(const CString& filename, ResourceInitializer& init)
 			loader = &fullLoader;
 			loader = &fullLoader;
 
 
 			// Set properties
 			// Set properties
-			m_weights = loader->getWeights().size() > 1;
+			m_weights = loader->getWeights().getSize() > 1;
 			m_texChannelsCount = loader->getTextureChannelsCount();
 			m_texChannelsCount = loader->getTextureChannelsCount();
 		}
 		}
 
 
 		// Push back the new submesh
 		// Push back the new submesh
 		SubMesh& submesh = m_subMeshes[i];
 		SubMesh& submesh = m_subMeshes[i];
 
 
-		submesh.m_indicesCount = loader->getIndices().size();
+		submesh.m_indicesCount = loader->getIndices().getSize();
 		submesh.m_indicesOffset = m_indicesCount * sizeof(U16);
 		submesh.m_indicesOffset = m_indicesCount * sizeof(U16);
 
 
 		const auto& positions = loader->getPositions();
 		const auto& positions = loader->getPositions();
-		submesh.m_obb.setFromPointCloud(&positions[0], positions.size(),
+		submesh.m_obb.setFromPointCloud(&positions[0], positions.getSize(),
 			sizeof(Vec3), positions.getSizeInBytes());
 			sizeof(Vec3), positions.getSizeInBytes());
 
 
 		// Set the global numbers
 		// Set the global numbers
-		m_vertsCount += loader->getPositions().size();
-		m_indicesCount += loader->getIndices().size();
+		m_vertsCount += loader->getPositions().getSize();
+		m_indicesCount += loader->getIndices().getSize();
 
 
 		++i;
 		++i;
 		// Move to next
 		// Move to next
@@ -347,7 +347,7 @@ Error BucketMesh::load(const CString& filename, ResourceInitializer& init)
 	ANKI_CHECK(createBuffers(fullLoader, init));
 	ANKI_CHECK(createBuffers(fullLoader, init));
 
 
 	const auto& positions = fullLoader.getPositions();
 	const auto& positions = fullLoader.getPositions();
-	m_obb.setFromPointCloud(&positions[0], positions.size(),
+	m_obb.setFromPointCloud(&positions[0], positions.getSize(),
 		sizeof(Vec3), positions.getSizeInBytes());
 		sizeof(Vec3), positions.getSizeInBytes());
 
 
 	return err;
 	return err;

+ 121 - 152
src/resource/MeshLoader.cpp

@@ -56,18 +56,30 @@ using FixNormalsMap = std::unordered_map<
 
 
 //==============================================================================
 //==============================================================================
 MeshLoader::MeshLoader(TempResourceAllocator<U8>& alloc)
 MeshLoader::MeshLoader(TempResourceAllocator<U8>& alloc)
-:	m_positions(alloc),
-	m_normals(alloc),
-	m_normalsF16(alloc),
-	m_tangents(alloc),
-	m_tangentsF16(alloc),
-	m_texCoords(alloc),
-	m_texCoordsF16(alloc),
-	m_weights(alloc),
-	m_tris(alloc),
-	m_vertIndices(alloc)
+:	m_alloc(alloc)
 {}
 {}
 
 
+//==============================================================================
+MeshLoader::~MeshLoader()
+{
+	m_positions.destroy(m_alloc);
+
+	m_normals.destroy(m_alloc);
+	m_normalsF16.destroy(m_alloc);
+
+	m_tangents.destroy(m_alloc);
+	m_tangentsF16.destroy(m_alloc);
+
+	m_texCoords.destroy(m_alloc);
+	m_texCoordsF16.destroy(m_alloc);
+
+	m_weights.destroy(m_alloc);
+
+	m_tris.destroy(m_alloc);
+
+	m_vertIndices.destroy(m_alloc);
+}
+
 //==============================================================================
 //==============================================================================
 Error MeshLoader::load(const CString& filename)
 Error MeshLoader::load(const CString& filename)
 {
 {
@@ -75,170 +87,103 @@ Error MeshLoader::load(const CString& filename)
 
 
 		// Open the file
 		// Open the file
 	File file;
 	File file;
-	err = file.open(filename, 
+	ANKI_CHECK(file.open(filename, 
 		File::OpenFlag::READ | File::OpenFlag::BINARY 
 		File::OpenFlag::READ | File::OpenFlag::BINARY 
-		| File::OpenFlag::LITTLE_ENDIAN);
-	if(err)
-	{
-		ANKI_LOGE("Failed to open file");
-		goto cleanup;
-	}
+		| File::OpenFlag::LITTLE_ENDIAN));
 
 
 	// Magic word
 	// Magic word
 	char magic[8];
 	char magic[8];
-	err = file.read(magic, sizeof(magic));
-	if(err)
-	{
-		ANKI_LOGE("Read error");
-		goto cleanup;
-	}
+	ANKI_CHECK(file.read(magic, sizeof(magic)));
 	
 	
 	if(std::memcmp(magic, "ANKIMESH", 8))
 	if(std::memcmp(magic, "ANKIMESH", 8))
 	{
 	{
 		ANKI_LOGE("Incorrect magic word");
 		ANKI_LOGE("Incorrect magic word");
-		goto cleanup;
+		return ErrorCode::USER_DATA;
 	}
 	}
 
 
 	// Mesh name
 	// Mesh name
 	{
 	{
 		U32 strLen;
 		U32 strLen;
-		err = file.readU32(strLen);
-		if(err)
-		{
-			ANKI_LOGE("Read error");
-			goto cleanup;
-		}
-
-		err = file.seek(strLen, File::SeekOrigin::CURRENT);
-		if(err)
-		{
-			ANKI_LOGE("Read error");
-			goto cleanup;
-		}
+		ANKI_CHECK(file.readU32(strLen));
+		ANKI_CHECK(file.seek(strLen, File::SeekOrigin::CURRENT));
 	}
 	}
 
 
 	// Verts num
 	// Verts num
 	U32 vertsNum;
 	U32 vertsNum;
-	err = file.readU32(vertsNum);
-	if(err)
-	{
-		ANKI_LOGE("Read error");
-		goto cleanup;
-	}
+	ANKI_CHECK(file.readU32(vertsNum));
 
 
-	m_positions.resize(vertsNum);
+	ANKI_CHECK(m_positions.create(m_alloc, vertsNum));
 
 
 	// Vert coords
 	// Vert coords
 	for(Vec3& vertCoord : m_positions)
 	for(Vec3& vertCoord : m_positions)
 	{
 	{
 		for(U j = 0; j < 3; j++)
 		for(U j = 0; j < 3; j++)
 		{
 		{
-			 err = file.readF32(vertCoord[j]);
-			 if(err)
-			{
-				ANKI_LOGE("Read error");
-				goto cleanup;
-			}
+			ANKI_CHECK(file.readF32(vertCoord[j]));
 		}
 		}
 	}
 	}
 
 
 	// Faces num
 	// Faces num
 	U32 facesNum;
 	U32 facesNum;
-	err = file.readU32(facesNum);
-	if(err)
-	{
-		ANKI_LOGE("Read error");
-		goto cleanup;
-	}
+	ANKI_CHECK(file.readU32(facesNum));
 
 
-	m_tris.resize(facesNum);
+	ANKI_CHECK(m_tris.create(m_alloc, facesNum));
 
 
 	// Faces IDs
 	// Faces IDs
 	for(Triangle& tri : m_tris)
 	for(Triangle& tri : m_tris)
 	{
 	{
 		for(U j = 0; j < 3; j++)
 		for(U j = 0; j < 3; j++)
 		{
 		{
-			err = file.readU32(tri.m_vertIds[j]);
-			if(err)
-			{
-				ANKI_LOGE("Read error");
-				goto cleanup;
-			}
+			ANKI_CHECK(file.readU32(tri.m_vertIds[j]));
 
 
 			// a sanity check
 			// a sanity check
-			if(tri.m_vertIds[j] >= m_positions.size())
+			if(tri.m_vertIds[j] >= m_positions.getSize())
 			{
 			{
 				ANKI_LOGE("Vert index out of bounds");
 				ANKI_LOGE("Vert index out of bounds");
-				err = ErrorCode::USER_DATA;
-				goto cleanup;
+				return ErrorCode::USER_DATA;
 			}
 			}
 		}
 		}
 	}
 	}
 
 
 	// Tex coords num
 	// Tex coords num
 	U32 texCoordsNum;
 	U32 texCoordsNum;
-	err = file.readU32(texCoordsNum);
-	if(err)
-	{
-		ANKI_LOGE("Read error");
-		goto cleanup;
-	}
-
-	m_texCoords.resize(texCoordsNum);
+	ANKI_CHECK(file.readU32(texCoordsNum));
+	ANKI_CHECK(m_texCoords.create(m_alloc, texCoordsNum));
 
 
 	// Tex coords
 	// Tex coords
 	for(Vec2& texCoord : m_texCoords)
 	for(Vec2& texCoord : m_texCoords)
 	{
 	{
 		for(U32 i = 0; i < 2; i++)
 		for(U32 i = 0; i < 2; i++)
 		{
 		{
-			err = file.readF32(texCoord[i]);
-			if(err)
-			{
-				ANKI_LOGE("Read error");
-				goto cleanup;
-			}
+			ANKI_CHECK(file.readF32(texCoord[i]));
 		}
 		}
 	}
 	}
 
 
 	// Vert weights num
 	// Vert weights num
 	U32 weightsNum;
 	U32 weightsNum;
-	err = file.readU32(weightsNum);
-	if(err)
-	{
-		ANKI_LOGE("Read error");
-		goto cleanup;
-	}
-
-	m_weights.resize(weightsNum);
+	ANKI_CHECK(file.readU32(weightsNum));
+	ANKI_CHECK(m_weights.create(m_alloc, weightsNum));
 
 
 	// Vert weights
 	// Vert weights
 	for(VertexWeight& vw : m_weights)
 	for(VertexWeight& vw : m_weights)
 	{
 	{
 		// get the bone connections num
 		// get the bone connections num
 		U32 boneConnections;
 		U32 boneConnections;
-		err = file.readU32(boneConnections);
-		if(err)
-		{
-			ANKI_LOGE("Read error");
-			goto cleanup;
-		}
+		ANKI_CHECK(file.readU32(boneConnections));
 
 
 		// we treat as error if one vert doesnt have a bone
 		// we treat as error if one vert doesnt have a bone
 		if(boneConnections < 1)
 		if(boneConnections < 1)
 		{
 		{
 			ANKI_LOGE("Vert sould have at least one bone");
 			ANKI_LOGE("Vert sould have at least one bone");
-			err = ErrorCode::USER_DATA;
-			goto cleanup;
+			return ErrorCode::USER_DATA;
 		}
 		}
 
 
 		// and here is another possible error
 		// and here is another possible error
 		if(boneConnections > VertexWeight::MAX_BONES_PER_VERT)
 		if(boneConnections > VertexWeight::MAX_BONES_PER_VERT)
 		{
 		{
 			U32 tmp = VertexWeight::MAX_BONES_PER_VERT;
 			U32 tmp = VertexWeight::MAX_BONES_PER_VERT;
-			ANKI_LOGE("Cannot have more than %d "
-				"bones per vertex", tmp);
-			err = ErrorCode::USER_DATA;
-			goto cleanup;
+			ANKI_LOGE("Cannot have more than %d bones per vertex", tmp);
+			return ErrorCode::USER_DATA;
 		}
 		}
 
 
 		vw.m_bonesCount = boneConnections;
 		vw.m_bonesCount = boneConnections;
@@ -248,25 +193,19 @@ Error MeshLoader::load(const CString& filename)
 		{
 		{
 			// read bone id
 			// read bone id
 			U32 boneId;
 			U32 boneId;
-			err = file.readU32(boneId);
-			if(err)
-			{
-				ANKI_LOGE("Read error");
-				goto cleanup;
-			}
+			ANKI_CHECK(file.readU32(boneId));
 
 
 			vw.m_boneIds[i] = boneId;
 			vw.m_boneIds[i] = boneId;
 
 
 			// read the weight of that bone
 			// read the weight of that bone
 			F32 weight;
 			F32 weight;
-			err = file.readF32(weight);
+			ANKI_CHECK(file.readF32(weight));
 			vw.m_weights[i] = weight;
 			vw.m_weights[i] = weight;
 		}
 		}
 	} // end for all vert weights
 	} // end for all vert weights
 
 
 	err = doPostLoad();
 	err = doPostLoad();
 
 
-cleanup:
 	return err;
 	return err;
 }
 }
 
 
@@ -277,54 +216,54 @@ Error MeshLoader::doPostLoad()
 	Error err = ErrorCode::NONE;
 	Error err = ErrorCode::NONE;
 
 
 	// Sanity checks
 	// Sanity checks
-	if(m_positions.size() < 1 || m_tris.size() < 1)
+	if(m_positions.getSize() < 1 || m_tris.getSize() < 1)
 	{
 	{
 		ANKI_LOGE("Vert coords and tris must be filled");
 		ANKI_LOGE("Vert coords and tris must be filled");
-		err = ErrorCode::USER_DATA;
+		return ErrorCode::USER_DATA;
 	}
 	}
 
 
-	if(!err 
-		&& m_texCoords.size() != 0 
-		&& m_texCoords.size() != m_positions.size())
+	if(m_texCoords.getSize() != 0 
+		&& m_texCoords.getSize() != m_positions.getSize())
 	{
 	{
 		ANKI_LOGE("Tex coords num must be "
 		ANKI_LOGE("Tex coords num must be "
 			"zero or equal to the vertex "
 			"zero or equal to the vertex "
 			"coords num");
 			"coords num");
-		err = ErrorCode::USER_DATA;
+		return ErrorCode::USER_DATA;
 	}
 	}
 
 
-	if(!err 
-		&& m_weights.size() != 0 
-		&& m_weights.size() != m_positions.size())
+	if(m_weights.getSize() != 0 
+		&& m_weights.getSize() != m_positions.getSize())
 	{
 	{
 		ANKI_LOGE("Vert weights num must be zero or equal to the "
 		ANKI_LOGE("Vert weights num must be zero or equal to the "
 			"vertex coords num");
 			"vertex coords num");
-		err = ErrorCode::USER_DATA;
+		return ErrorCode::USER_DATA;
 	}
 	}
 
 
-	if(!err)
-	{
-		createAllNormals();
-		fixNormals();
+	ANKI_CHECK(createAllNormals());
+	//fixNormals();
 
 
-		if(m_texCoords.size() > 0)
-		{
-			createVertTangents();
-		}
-
-		createVertIndeces();
-		compressBuffers();
+	if(m_texCoords.getSize() > 0)
+	{
+		ANKI_CHECK(createVertTangents());
 	}
 	}
 
 
+	ANKI_CHECK(createVertIndeces());
+	ANKI_CHECK(compressBuffers());
+
 	return err;
 	return err;
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void MeshLoader::createVertIndeces()
+Error MeshLoader::createVertIndeces()
 {
 {
-	m_vertIndices.resize(m_tris.size() * 3);
+	Error err = m_vertIndices.create(m_alloc, m_tris.getSize() * 3);
+	if(err)
+	{
+		return err;
+	}
+	
 	U j = 0;
 	U j = 0;
-	for(U i = 0; i < m_tris.size(); ++i)
+	for(U i = 0; i < m_tris.getSize(); ++i)
 	{
 	{
 		m_vertIndices[j + 0] = m_tris[i].m_vertIds[0];
 		m_vertIndices[j + 0] = m_tris[i].m_vertIds[0];
 		m_vertIndices[j + 1] = m_tris[i].m_vertIds[1];
 		m_vertIndices[j + 1] = m_tris[i].m_vertIds[1];
@@ -332,10 +271,12 @@ void MeshLoader::createVertIndeces()
 
 
 		j += 3;
 		j += 3;
 	}
 	}
+
+	return err;
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void MeshLoader::createFaceNormals()
+Error MeshLoader::createFaceNormals()
 {
 {
 	for(Triangle& tri : m_tris)
 	for(Triangle& tri : m_tris)
 	{
 	{
@@ -354,12 +295,18 @@ void MeshLoader::createFaceNormals()
 			tri.m_normal = Vec3(1.0, 0.0, 0.0);
 			tri.m_normal = Vec3(1.0, 0.0, 0.0);
 		}
 		}
 	}
 	}
+
+	return ErrorCode::NONE;
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void MeshLoader::createVertNormals()
+Error MeshLoader::createVertNormals()
 {
 {
-	m_normals.resize(m_positions.size());
+	Error err = m_normals.create(m_alloc, m_positions.getSize());
+	if(err)
+	{
+		return err;
+	}
 
 
 	for(Vec3& vertNormal : m_normals)
 	for(Vec3& vertNormal : m_normals)
 	{
 	{
@@ -380,16 +327,27 @@ void MeshLoader::createVertNormals()
 			vertNormal.normalize();
 			vertNormal.normalize();
 		}
 		}
 	}
 	}
+
+	return err;
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void MeshLoader::createVertTangents()
+Error MeshLoader::createVertTangents()
 {
 {
-	m_tangents.resize(m_positions.size(), Vec4(0.0)); // alloc
-	MLVector<Vec3> bitagents(
-		m_positions.size(), Vec3(0.0), m_tangents.get_allocator());
+	Error err = m_tangents.create(m_alloc, m_positions.getSize(), Vec4(0.0));
+	if(err)
+	{
+		return err;
+	}
 
 
-	for(U32 i = 0; i < m_tris.size(); i++)
+	MLDArray<Vec3> bitagents;
+	err = bitagents.create(m_alloc, m_positions.getSize(), Vec3(0.0));
+	if(err)
+	{
+		return err;
+	}
+
+	for(U32 i = 0; i < m_tris.getSize(); i++)
 	{
 	{
 		const Triangle& tri = m_tris[i];
 		const Triangle& tri = m_tris[i];
 		const I i0 = tri.m_vertIds[0];
 		const I i0 = tri.m_vertIds[0];
@@ -434,7 +392,7 @@ void MeshLoader::createVertTangents()
 		bitagents[i2] += b;
 		bitagents[i2] += b;
 	}
 	}
 
 
-	for(U i = 0; i < m_tangents.size(); i++)
+	for(U i = 0; i < m_tangents.getSize(); i++)
 	{
 	{
 		Vec3 t = m_tangents[i].xyz();
 		Vec3 t = m_tangents[i].xyz();
 		const Vec3& n = m_normals[i];
 		const Vec3& n = m_normals[i];
@@ -456,15 +414,18 @@ void MeshLoader::createVertTangents()
 
 
 		m_tangents[i] = Vec4(t, w);
 		m_tangents[i] = Vec4(t, w);
 	}
 	}
+
+	bitagents.destroy(m_alloc);
+	return err;
 }
 }
 
 
 //==============================================================================
 //==============================================================================
 void MeshLoader::fixNormals()
 void MeshLoader::fixNormals()
 {
 {
-	FixNormalsMap map(10, Hasher(), Equal(), m_positions.get_allocator());
+	FixNormalsMap map(10, Hasher(), Equal(), m_alloc);
 
 
 	// For all verts
 	// For all verts
-	for(U i = 1; i < m_positions.size(); i++)
+	for(U i = 1; i < m_positions.getSize(); i++)
 	{
 	{
 		const Vec3& pos = m_positions[i];
 		const Vec3& pos = m_positions[i];
 		Vec3& norm = m_normals[i];
 		Vec3& norm = m_normals[i];
@@ -518,8 +479,9 @@ void MeshLoader::fixNormals()
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void MeshLoader::append(const MeshLoader& other)
+Error MeshLoader::append(const MeshLoader& other)
 {
 {
+#if 0
 	m_positions.insert(
 	m_positions.insert(
 		m_positions.end(), other.m_positions.begin(), other.m_positions.end());
 		m_positions.end(), other.m_positions.begin(), other.m_positions.end());
 
 
@@ -550,17 +512,22 @@ void MeshLoader::append(const MeshLoader& other)
 	{
 	{
 		m_vertIndices.push_back(bias + index);
 		m_vertIndices.push_back(bias + index);
 	}
 	}
+#endif
+	ANKI_ASSERT(0 && "TODO");
+	return ErrorCode::NONE;
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void MeshLoader::compressBuffers()
+Error MeshLoader::compressBuffers()
 {
 {
-	ANKI_ASSERT(m_positions.size() > 0);
+	ANKI_ASSERT(m_positions.getSize() > 0);
+
+	Error err = ErrorCode::NONE;
 
 
 	// Normals
 	// Normals
-	m_normalsF16.resize(m_normals.size());
+	ANKI_CHECK(m_normalsF16.create(m_alloc, m_normals.getSize()));
 
 
-	for(U i = 0; i < m_normals.size(); i++)
+	for(U i = 0; i < m_normals.getSize(); i++)
 	{
 	{
 		for(U j = 0; j < 3; j++)
 		for(U j = 0; j < 3; j++)
 		{
 		{
@@ -569,9 +536,9 @@ void MeshLoader::compressBuffers()
 	}
 	}
 
 
 	// Tangents
 	// Tangents
-	m_tangentsF16.resize(m_tangents.size());
+	ANKI_CHECK(m_tangentsF16.create(m_alloc, m_tangents.getSize()));
 
 
-	for(U i = 0; i < m_tangents.size(); i++)
+	for(U i = 0; i < m_tangents.getSize(); i++)
 	{
 	{
 		for(U j = 0; j < 4; j++)
 		for(U j = 0; j < 4; j++)
 		{
 		{
@@ -580,15 +547,17 @@ void MeshLoader::compressBuffers()
 	}
 	}
 
 
 	// Texture coords
 	// Texture coords
-	m_texCoordsF16.resize(m_texCoords.size());	
+	ANKI_CHECK(m_texCoordsF16.create(m_alloc, m_texCoords.getSize()));
 
 
-	for(U i = 0; i < m_texCoords.size(); i++)
+	for(U i = 0; i < m_texCoords.getSize(); i++)
 	{
 	{
 		for(U j = 0; j < 2; j++)
 		for(U j = 0; j < 2; j++)
 		{
 		{
 			m_texCoordsF16[i][j] = F16(m_texCoords[i][j]);
 			m_texCoordsF16[i][j] = F16(m_texCoords[i][j]);
 		}
 		}
 	}
 	}
+
+	return err;
 }
 }
 
 
 } // end namespace anki
 } // end namespace anki

+ 37 - 28
src/resource/ProgramPrePreprocessor.cpp

@@ -38,47 +38,47 @@ void ProgramPrePreprocessor::printSourceLines() const
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void ProgramPrePreprocessor::parseFile(const CString& filename)
+Error ProgramPrePreprocessor::parseFile(const CString& filename)
 {
 {
-	try
-	{
-		auto alloc = m_shaderSource.getAllocator();
+	auto alloc = m_shaderSource.getAllocator();
 
 
-		// Parse files recursively
-		parseFileForPragmas(
-			PPPString(filename, alloc), 
-			0);
+	// Parse files recursively
+	Error err = parseFileForPragmas(PPPString(filename, alloc), 0);
 
 
-		m_shaderSource = m_sourceLines.join("\n");
-	}
-	catch(Exception& e)
+	if(!err)
 	{
 	{
-		throw ANKI_EXCEPTION("Loading file failed: %s", &filename[0]) << e;
+		m_shaderSource = m_sourceLines.join("\n");
 	}
 	}
+	
+	return err;
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void ProgramPrePreprocessor::parseFileForPragmas(
+Error ProgramPrePreprocessor::parseFileForPragmas(
 	const PPPString& filename, U32 depth)
 	const PPPString& filename, U32 depth)
 {
 {
 	// first check the depth
 	// first check the depth
 	if(depth > MAX_DEPTH)
 	if(depth > MAX_DEPTH)
 	{
 	{
-		throw ANKI_EXCEPTION("The include depth is too high. "
+		ANKI_LOGE("The include depth is too high. "
 			"Probably circular includance");
 			"Probably circular includance");
+		return ErrorCode::USER_DATA;
 	}
 	}
 
 
+	Error err = ErrorCode::NONE;
+
 	// load file in lines
 	// load file in lines
 	auto alloc = m_shaderSource.getAllocator();
 	auto alloc = m_shaderSource.getAllocator();
 	PPPString txt(alloc);
 	PPPString txt(alloc);
 	PPPStringList lines(alloc);
 	PPPStringList lines(alloc);
 	File file;
 	File file;
-	file.open(filename.toCString(), File::OpenFlag::READ);
-	file.readAllText(txt);
+	ANKI_CHECK(file.open(filename.toCString(), File::OpenFlag::READ));
+	ANKI_CHECK(file.readAllText(txt));
 	lines = PPPStringList::splitString(txt.toCString(), '\n', alloc);
 	lines = PPPStringList::splitString(txt.toCString(), '\n', alloc);
 	if(lines.size() < 1)
 	if(lines.size() < 1)
 	{
 	{
-		throw ANKI_EXCEPTION("File is empty: %s", &filename[0]);
+		ANKI_LOGE("File is empty: %s", &filename[0]);
+		return ErrorCode::USER_DATA;
 	}
 	}
 
 
 	for(const PPPString& line : lines)
 	for(const PPPString& line : lines)
@@ -89,7 +89,9 @@ void ProgramPrePreprocessor::parseFileForPragmas(
 		{
 		{
 			Bool malformed = true;
 			Bool malformed = true;
 
 
-			if(parseType(line))
+			Bool found;
+			ANKI_CHECK(parseType(line, found));
+			if(found)
 			{
 			{
 				malformed = false; // All OK
 				malformed = false; // All OK
 			}
 			}
@@ -106,7 +108,7 @@ void ProgramPrePreprocessor::parseFileForPragmas(
 
 
 					filen = m_manager->fixResourceFilename(filen.toCString());
 					filen = m_manager->fixResourceFilename(filen.toCString());
 
 
-					parseFileForPragmas(filen, depth + 1);
+					ANKI_CHECK(parseFileForPragmas(filen, depth + 1));
 
 
 					malformed = false; // All OK
 					malformed = false; // All OK
 				}
 				}
@@ -114,7 +116,8 @@ void ProgramPrePreprocessor::parseFileForPragmas(
 
 
 			if(malformed)
 			if(malformed)
 			{
 			{
-				throw ANKI_EXCEPTION("Malformed pragma anki: %s", &line[0]);
+				ANKI_LOGE("Malformed pragma anki: %s", &line[0]);
+				return ErrorCode::USER_DATA;
 			}
 			}
 		}
 		}
 		else
 		else
@@ -126,15 +129,19 @@ void ProgramPrePreprocessor::parseFileForPragmas(
 	// Sanity checks
 	// Sanity checks
 	if(m_type == ShaderType::COUNT)
 	if(m_type == ShaderType::COUNT)
 	{
 	{
-		throw ANKI_EXCEPTION("Shader is missing the type");
+		ANKI_LOGE("Shader is missing the type");
+		return ErrorCode::USER_DATA;
 	}
 	}
+
+	return err;
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-Bool ProgramPrePreprocessor::parseType(const PPPString& line)
+Error ProgramPrePreprocessor::parseType(const PPPString& line, Bool& found)
 {
 {
+	Error err = ErrorCode::NONE;
 	U i;
 	U i;
-	Bool found = false;
+	found = false;
 
 
 	for(i = 0; i < static_cast<U>(ShaderType::COUNT); i++)
 	for(i = 0; i < static_cast<U>(ShaderType::COUNT); i++)
 	{
 	{
@@ -149,14 +156,16 @@ Bool ProgramPrePreprocessor::parseType(const PPPString& line)
 	{
 	{
 		if(m_type != ShaderType::COUNT)
 		if(m_type != ShaderType::COUNT)
 		{
 		{
-			throw ANKI_EXCEPTION("The shader type is already set. Line %s",
-				&line[0]);
+			ANKI_LOGE("The shader type is already set. Line %s", &line[0]);
+			err = ErrorCode::USER_DATA;
+		}
+		else
+		{
+			m_type = static_cast<ShaderType>(i);
 		}
 		}
-
-		m_type = static_cast<ShaderType>(i);
 	}
 	}
 
 
-	return found;
+	return err;
 }
 }
 
 
 } // end namespace anki
 } // end namespace anki

+ 2 - 1
src/resource/ProgramResource.cpp

@@ -27,7 +27,8 @@ Error ProgramResource::load(const CString& filename, const CString& extraSrc,
 {
 {
 	Error err = ErrorCode::NONE;
 	Error err = ErrorCode::NONE;
 
 
-	ProgramPrePreprocessor pars(filename, &manager);
+	ProgramPrePreprocessor pars(&manager);
+	ANKI_CHECK(pars.parseFile(filename));
 	TempResourceString source(extraSrc + pars.getShaderSource());
 	TempResourceString source(extraSrc + pars.getShaderSource());
 
 
 	GlDevice& gl = manager._getGlDevice();
 	GlDevice& gl = manager._getGlDevice();

+ 10 - 5
tests/resource/ResourceManager.cpp

@@ -46,21 +46,25 @@ ANKI_TEST(Resource, ResourceManager)
 
 
 	// Load and load again
 	// Load and load again
 	{
 	{
-		DummyResourcePointer a("blah", resources);
+		DummyResourcePointer a;
+		a.load("blah", resources);
 		auto refcount = a.getReferenceCount();
 		auto refcount = a.getReferenceCount();
 
 
-		DummyResourcePointer b("blah", resources);
+		DummyResourcePointer b;
+		b.load("blah", resources);
 		ANKI_TEST_EXPECT_EQ(b.getReferenceCount(), a.getReferenceCount());
 		ANKI_TEST_EXPECT_EQ(b.getReferenceCount(), a.getReferenceCount());
 		ANKI_TEST_EXPECT_EQ(a.getReferenceCount(), refcount + 1);
 		ANKI_TEST_EXPECT_EQ(a.getReferenceCount(), refcount + 1);
 
 
 		ANKI_TEST_EXPECT_EQ(b.get(), a.get());
 		ANKI_TEST_EXPECT_EQ(b.get(), a.get());
 
 
 		// Again
 		// Again
-		DummyResourcePointer c("blah", resources);
+		DummyResourcePointer c;
+		c.load("blah", resources);
 		ANKI_TEST_EXPECT_EQ(a.getReferenceCount(), refcount + 2);
 		ANKI_TEST_EXPECT_EQ(a.getReferenceCount(), refcount + 2);
 
 
 		// Load something else
 		// Load something else
-		DummyResourcePointer d("blih", resources);
+		DummyResourcePointer d;
+		d.load("blih", resources);
 		ANKI_TEST_EXPECT_EQ(a.getReferenceCount(), refcount + 2);
 		ANKI_TEST_EXPECT_EQ(a.getReferenceCount(), refcount + 2);
 	}
 	}
 
 
@@ -68,7 +72,8 @@ ANKI_TEST(Resource, ResourceManager)
 	{
 	{
 		try
 		try
 		{
 		{
-			DummyResourcePointer a("exception", resources);
+			DummyResourcePointer a;
+			a.load("exception", resources);
 		}
 		}
 		catch(...)
 		catch(...)
 		{}
 		{}