浏览代码

Removing boost and making more things to compile

Panagiotis Christopoulos Charitos 13 年之前
父节点
当前提交
c04fbd6b6e
共有 40 个文件被更改,包括 654 次插入581 次删除
  1. 2 2
      CMakeLists.txt
  2. 4 5
      include/anki/core/App.h
  3. 8 10
      include/anki/core/AsyncLoader.h
  4. 0 73
      include/anki/core/ParallelJob.h
  5. 64 7
      include/anki/core/ParallelManager.h
  6. 8 8
      include/anki/core/StdinListener.h
  7. 1 3
      include/anki/gl/BufferObject.h
  8. 5 2
      include/anki/resource/AsyncOperator.h
  9. 6 4
      include/anki/resource/Image.h
  10. 1 1
      include/anki/resource/Material.h
  11. 1 1
      include/anki/resource/MaterialCommon.h
  12. 0 4
      include/anki/resource/MaterialShaderProgramCreator.h
  13. 13 19
      include/anki/resource/Mesh.h
  14. 2 2
      include/anki/resource/Model.h
  15. 14 18
      include/anki/resource/PassLevelKey.h
  16. 0 4
      include/anki/resource/Script.h
  17. 51 0
      include/anki/util/Barrier.h
  18. 46 0
      include/anki/util/Filesystem.h
  19. 43 0
      include/anki/util/Functions.h
  20. 16 20
      include/anki/util/Object.h
  21. 1 1
      include/anki/util/Singleton.h
  22. 0 43
      include/anki/util/Util.h
  23. 27 27
      src/core/App.cpp
  24. 5 15
      src/core/AsyncLoader.cpp
  25. 0 64
      src/core/ParallelJob.cpp
  26. 54 4
      src/core/ParallelManager.cpp
  27. 8 17
      src/core/StdinListener.cpp
  28. 2 2
      src/resource/AsyncOperator.cpp
  29. 58 60
      src/resource/Image.cpp
  30. 8 6
      src/resource/Material.cpp
  31. 18 33
      src/resource/MaterialShaderProgramCreator.cpp
  32. 8 14
      src/resource/Mesh.cpp
  33. 4 9
      src/resource/Script.cpp
  34. 3 3
      src/resource/ShaderProgramPrePreprocessor.cpp
  35. 13 16
      src/resource/ShaderProgramResource.cpp
  36. 1 1
      src/scene/ParticleEmitterNode.cpp
  37. 115 0
      src/util/Filesystem.cpp
  38. 41 0
      src/util/Functions.cpp
  39. 0 74
      src/util/Util.cpp
  40. 3 9
      testapp/Main.cpp

+ 2 - 2
CMakeLists.txt

@@ -78,8 +78,8 @@ ENDIF()
 #
 # Libraries
 #
-FIND_PACKAGE(PNG 1.2 REQUIRED)
-FIND_PACKAGE(JPEG 62 REQUIRED)
+#FIND_PACKAGE(PNG REQUIRED)
+#FIND_PACKAGE(JPEG 62 REQUIRED)
 
 FIND_PACKAGE(Boost 1.46 REQUIRED)
 SET(Boost_USE_STATIC_LIBS ON)

+ 4 - 5
include/anki/core/App.h

@@ -4,7 +4,6 @@
 #include "anki/core/Logger.h"
 #include "anki/util/Singleton.h"
 #include <SDL/SDL.h>
-#include <boost/filesystem.hpp>
 
 namespace anki {
 
@@ -85,12 +84,12 @@ public:
 		return windowH;
 	}
 
-	const boost::filesystem::path& getSettingsPath() const
+	const std::string& getSettingsPath() const
 	{
 		return settingsPath;
 	}
 
-	const boost::filesystem::path& getCachePath() const
+	const std::string& getCachePath() const
 	{
 		return cachePath;
 	}
@@ -100,9 +99,9 @@ private:
 	uint windowW; ///< The main window width
 	uint windowH; ///< The main window height
 	/// The path that holds the configuration
-	boost::filesystem::path settingsPath;
+	std::string settingsPath;
 	/// This is used as a cache
-	boost::filesystem::path cachePath;
+	std::string cachePath;
 	float timerTick;
 	/// Terminal coloring for Unix terminals. Default on
 	bool terminalColoringEnabled;

+ 8 - 10
include/anki/core/AsyncLoader.h

@@ -3,14 +3,13 @@
 
 #include <list>
 #include <string>
-#include <boost/thread/thread.hpp>
-#include <boost/thread/mutex.hpp>
+#include <thread>
+#include <mutex>
 #include <SDL/SDL.h>
 
-
 namespace anki {
 
-
+/*
 /// Asynchronous loader
 ///
 /// It creates a thread that loads files on demand. It accepts requests (in the
@@ -71,19 +70,18 @@ private:
 
 	std::list<Request> requests;
 	std::list<Response> responses;
-	boost::mutex mutexReq; ///< Protect the requests container
-	boost::mutex mutexResp; ///< Protect the responses container
-	boost::thread thread;
-	boost::condition_variable condVar;
+	std::mutex mutexReq; ///< Protect the requests container
+	std::mutex mutexResp; ///< Protect the responses container
+	std::thread thread;
+	std::condition_variable condVar;
 
 	/// The thread function. It waits for something in the requests
 	/// container
 	void workingFunc();
 	void start(); ///< Start thread
 };
-
+*/
 
 } // end namespace
 
-
 #endif

+ 0 - 73
include/anki/core/ParallelJob.h

@@ -1,73 +0,0 @@
-#ifndef ANKI_CORE_PARALLEL_JOB_H
-#define ANKI_CORE_PARALLEL_JOB_H
-
-#include <boost/thread.hpp>
-
-
-namespace anki {
-
-
-class ParallelManager;
-class ParallelJob;
-
-
-/// The base class of the parameters the we pass in the job
-struct ParallelJobParameters
-{};
-
-
-/// The callback that we feed to the job
-typedef void (*ParallelJobCallback)(ParallelJobParameters&, const ParallelJob&);
-
-
-/// The thread that executes a ParallelJobCallback
-class ParallelJob
-{
-public:
-	/// Constructor
-	ParallelJob(int id, const ParallelManager& manager,
-		boost::barrier& barrier);
-
-	/// @name Accessors
-	/// @{
-	uint getId() const
-	{
-		return id;
-	}
-
-	const ParallelManager& getManager() const
-	{
-		return manager;
-	}
-	/// @}
-
-	/// Assign new job to the thread
-	void assignNewJob(ParallelJobCallback callback,
-		ParallelJobParameters& jobParams);
-
-private:
-	uint id; ///< An ID
-	boost::thread thread; ///< Runs the workingFunc
-	boost::mutex mutex; ///< Protect the ParallelJob::job
-	boost::condition_variable condVar; ///< To wake up the thread
-	boost::barrier& barrier; ///< For synchronization
-	ParallelJobCallback callback; ///< Its NULL if there are no pending job
-	ParallelJobParameters* params;
-	/// Know your father and pass him to the jobs
-	const ParallelManager& manager;
-
-	/// Start thread
-	void start()
-	{
-		thread = boost::thread(&ParallelJob::workingFunc, this);
-	}
-
-	/// Thread loop
-	void workingFunc();
-};
-
-
-} // end namespace
-
-
-#endif

+ 64 - 7
include/anki/core/ParallelManager.h

@@ -1,15 +1,71 @@
 #ifndef ANKI_CORE_PARALLEL_MANAGER_H
 #define ANKI_CORE_PARALLEL_MANAGER_H
 
-#include "anki/core/ParallelJob.h"
-#include <boost/thread.hpp>
+#include "anki/util/Barrier.h"
+#include "anki/util/Singleton.h"
+#include <thread>
 #include <boost/ptr_container/ptr_vector.hpp>
 
-
 namespace anki {
 
+class ParallelManager;
+class ParallelJob;
+
+/// The base class of the parameters the we pass in the job
+struct ParallelJobParameters
+{};
+
+/// The callback that we feed to the job
+typedef void (*ParallelJobCallback)(ParallelJobParameters&, const ParallelJob&);
+
+/// The thread that executes a ParallelJobCallback
+class ParallelJob
+{
+public:
+	/// Constructor
+	ParallelJob(uint32_t id, const ParallelManager* manager,
+		Barrier* barrier);
 
-/// The job manager
+	/// @name Accessors
+	/// @{
+	uint32_t getId() const
+	{
+		return id;
+	}
+
+	const ParallelManager& getManager() const
+	{
+		return *manager;
+	}
+	/// @}
+
+	/// Assign new job to the thread
+	void assignNewJob(ParallelJobCallback callback,
+		ParallelJobParameters& jobParams);
+
+private:
+	uint32_t id; ///< An ID
+	std::thread thread; ///< Runs the workingFunc
+	std::mutex mutex; ///< Protect the ParallelJob::job
+	std::condition_variable condVar; ///< To wake up the thread
+	Barrier* barrier; ///< For synchronization
+	ParallelJobCallback callback; ///< Its NULL if there are no pending job
+	ParallelJobParameters* params;
+	/// Know your father and pass him to the jobs
+	const ParallelManager* manager;
+
+	/// Start thread
+	void start()
+	{
+		thread = std::thread(&ParallelJob::workingFunc, this);
+	}
+
+	/// Thread loop
+	void workingFunc();
+};
+
+/// Parallel job dispatcher.You feed it with jobs and sends them for
+/// execution in parallel and then waits for all to finish
 class ParallelManager
 {
 public:
@@ -46,11 +102,12 @@ public:
 
 private:
 	boost::ptr_vector<ParallelJob> jobs; ///< Worker threads
-	boost::scoped_ptr<boost::barrier> barrier; ///< Synchronization barrier
+	std::unique_ptr<Barrier> barrier; ///< Synchronization barrier
 };
 
+/// Singleton
+typedef Singleton<ParallelManager> ParallelManagerSingleton;
 
-} // end namespace
-
+} // end namespace anki
 
 #endif

+ 8 - 8
include/anki/core/StdinListener.h

@@ -1,15 +1,14 @@
 #ifndef ANKI_CORE_STDIN_LISTENER_H
 #define ANKI_CORE_STDIN_LISTENER_H
 
-#include <boost/thread/thread.hpp>
-#include <boost/thread/mutex.hpp>
+#include "anki/util/Singleton.h"
+#include <thread>
+#include <mutex>
 #include <string>
 #include <queue>
 
-
 namespace anki {
 
-
 /// The listener of the stdin.
 /// It initiates a thread that constantly reads the stdin and puts the results
 /// in a queue
@@ -24,14 +23,15 @@ public:
 
 private:
 	std::queue<std::string> q;
-	boost::mutex mtx; ///< Protect the queue
-	boost::thread thrd; ///< The thread
+	std::mutex mtx; ///< Protect the queue
+	std::thread thrd; ///< The thread
 
 	void workingFunc(); ///< The thread function
 };
 
+/// Singleton
+typedef Singleton<StdinListener> StdinListenerSingleton;
 
-} // end namespace
-
+} // end namespace anki
 
 #endif

+ 1 - 3
include/anki/gl/BufferObject.h

@@ -17,13 +17,11 @@ public:
 	/// @name Constructors/Destructor
 	/// @{
 	BufferObject()
-		: glId(0)
 	{}
 
 	/// Default constructor @see create
 	BufferObject(GLenum target, uint32_t sizeInBytes,
 		const void* dataPtr, GLenum usage)
-		: glId(0)
 	{
 		create(target, sizeInBytes, dataPtr, usage);
 	}
@@ -122,7 +120,7 @@ private:
 	/// Opt to save a few glBindBuffer calls
 	static const thread_local BufferObject* lastBindedBo; 
 
-	GLuint glId; ///< The OpenGL id of the BO
+	GLuint glId = 0; ///< The OpenGL id of the BO
 
 	/// Used in glBindBuffer(target, glId) and its for easy access so we
 	/// wont have to query the GL driver. Its the type of the buffer eg

+ 5 - 2
include/anki/resource/AsyncOperator.h

@@ -3,12 +3,13 @@
 
 #include <list>
 #include <string>
-#include <boost/thread/thread.hpp>
-#include <boost/thread/mutex.hpp>
+#include <thread>
+#include <mutex>
 
 
 namespace anki {
 
+/*
 
 /// Asynchronous operator
 ///
@@ -82,6 +83,8 @@ private:
 	void start(); ///< Start thread
 };
 
+*/
+
 
 } // end namespace
 

+ 6 - 4
include/anki/resource/Image.h

@@ -1,8 +1,10 @@
 #ifndef ANKI_RESOURCE_IMAGE_H
 #define ANKI_RESOURCE_IMAGE_H
 
-#include "anki/util/Util.h"
+#include "anki/util/Functions.h"
 #include <vector>
+#include <iosfwd>
+#include <cstdint>
 
 namespace anki {
 
@@ -69,7 +71,7 @@ public:
 	/// Get image size in bytes
 	size_t getDataSize() const
 	{
-		return Util::getVectorSizeInBytes(data);
+		return getVectorSizeInBytes(data);
 	}
 
 	DataCompression getDataCompression() const
@@ -84,8 +86,8 @@ public:
 	void load(const char* filename);
 
 private:
-	uint32_t width; ///< Image width
-	uint32_t height; ///< Image height
+	uint32_t width = 0; ///< Image width
+	uint32_t height = 0; ///< Image height
 	ColorType type; ///< Image color type
 	std::vector<uint8_t> data; ///< Image data
 	DataCompression dataCompression;

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

@@ -35,7 +35,7 @@ public:
 
 	/// Given a pair of pass and level it returns a pointer to a
 	/// shader program uniform variable. The pointer may be nullptr
-	typedef PassLevelHashMap<const ShaderProgramUniformVariable*>::Type
+	typedef PassLevelHashMap<const ShaderProgramUniformVariable*>
 		PassLevelToShaderProgramUniformVariableHashMap;
 
 	/// @name Constructors & destructor

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

@@ -9,7 +9,7 @@ namespace anki {
 
 
 /// Given a pair of pass and level it returns a pointer to a shader program
-typedef PassLevelHashMap<class ShaderProgram*>::Type
+typedef PassLevelHashMap<class ShaderProgram*>
 	PassLevelToShaderProgramHashMap;
 
 

+ 0 - 4
include/anki/resource/MaterialShaderProgramCreator.h

@@ -4,10 +4,8 @@
 #include "anki/util/StringList.h"
 #include <boost/property_tree/ptree_fwd.hpp>
 
-
 namespace anki {
 
-
 /// Creator of shader programs. This class parses between
 /// <shaderProgam></shaderProgram> located inside a <material></material>
 /// and creates the source of a custom program.
@@ -49,8 +47,6 @@ private:
 	void parseOperationTag(const boost::property_tree::ptree& pt);
 };
 
-
 } // end namespace
 
-
 #endif

+ 13 - 19
include/anki/resource/Mesh.h

@@ -1,18 +1,15 @@
 #ifndef ANKI_RESOURCE_MESH_H
 #define ANKI_RESOURCE_MESH_H
 
-#include <boost/array.hpp>
+#include <array>
 #include "anki/math/Math.h"
 #include "anki/gl/Vbo.h"
 #include "anki/collision/Obb.h"
 
-
 namespace anki {
 
-
 class MeshLoader;
 
-
 /// This is the interface class for meshes. Its interface because the skin
 /// nodes override it
 class MeshBase
@@ -38,10 +35,10 @@ public:
 	/// Get a VBO. Its nullptr if it does not exist
 	virtual const Vbo* getVbo(VboId id) const = 0;
 
-	virtual uint getTextureChannelsNumber() const = 0;
-	virtual uint getLodsNumber() const = 0;
-	virtual uint getIndicesNumber(uint lod) const = 0;
-	virtual uint getVerticesNumber(uint lod) const = 0;
+	virtual uint32_t getTextureChannelsNumber() const = 0;
+	virtual uint32_t getLodsNumber() const = 0;
+	virtual uint32_t getIndicesNumber(uint32_t lod) const = 0;
+	virtual uint32_t getVerticesNumber(uint32_t lod) const = 0;
 
 	virtual const Obb& getBoundingShape() const = 0;
 	/// @}
@@ -65,12 +62,11 @@ public:
 	/// @}
 };
 
-
 /// Mesh Resource. It contains the geometry packed in VBOs
 class Mesh: public MeshBase
 {
 public:
-	typedef boost::array<Vbo, VBOS_NUMBER> VbosArray;
+	typedef std::array<Vbo, VBOS_NUMBER> VbosArray;
 
 	/// @name Constructors
 	/// @{
@@ -100,25 +96,25 @@ public:
 	}
 
 	/// Implements MeshBase::getTextureChannelsNumber
-	uint getTextureChannelsNumber() const
+	uint32_t getTextureChannelsNumber() const
 	{
 		return vbos[VBO_TEX_COORDS].isCreated() ? 1 : 0;
 	}
 
 	/// Implements MeshBase::getLodsNumber
-	uint getLodsNumber() const
+	uint32_t getLodsNumber() const
 	{
 		return 1;
 	}
 
 	/// Implements MeshBase::getIndicesNumber
-	uint getIndicesNumber(uint) const
+	uint32_t getIndicesNumber(uint32_t) const
 	{
 		return vertIdsNum;
 	}
 
 	/// Implements MeshBase::getVerticesNumber
-	uint getVerticesNumber(uint) const
+	uint32_t getVerticesNumber(uint32_t) const
 	{
 		return vertsNum;
 	}
@@ -135,16 +131,14 @@ public:
 
 private:
 	VbosArray vbos; ///< The vertex buffer objects
-	uint vertIdsNum; ///< The number of vertex IDs
+	uint32_t vertIdsNum; ///< The number of vertex IDs
 	Obb visibilityShape;
-	uint vertsNum;
+	uint32_t vertsNum;
 
 	/// Create the VBOs using the mesh data
 	void createVbos(const MeshLoader& meshData);
 };
 
-
-} // end namespace
-
+} // end namespace anki
 
 #endif

+ 2 - 2
include/anki/resource/Model.h

@@ -19,7 +19,7 @@ public:
 	/// For garbage collection
 	typedef boost::ptr_vector<Vao> VaosContainer;
 	/// Map to get the VAO given a PassLod key
-	typedef PassLevelHashMap<Vao*>::Type PassLevelToVaoMap;
+	typedef PassLevelHashMap<Vao*> PassLevelToVaoMap;
 
 	virtual ~ModelPatchBase()
 	{}
@@ -66,7 +66,7 @@ class ModelPatch: public ModelPatchBase
 {
 public:
 	/// Map to get the VAO given a PassLod key
-	typedef PassLevelHashMap<Vao>::Type PassLevelToVaoMap;
+	typedef PassLevelHashMap<Vao> PassLevelToVaoMap;
 
 	ModelPatch(const char* meshFName, const char* mtlFName);
 	~ModelPatch();

+ 14 - 18
include/anki/resource/PassLevelKey.h

@@ -1,28 +1,30 @@
 #ifndef ANKI_RESOURCE_PASS_LEVEL_KEY_H
 #define ANKI_RESOURCE_PASS_LEVEL_KEY_H
 
-#include <boost/unordered_map.hpp>
-
+#include <unordered_map>
+#include <cstdint>
+#include <cstdlib>
 
 namespace anki {
 
-
 /// XXX
 struct PassLevelKey
 {
-	uint pass;
-	uint level;
+	uint32_t pass = 0;
+	uint32_t level = 0;
 
 	PassLevelKey()
-		: pass(0), level(0)
 	{}
 
-	PassLevelKey(uint pass_, uint level_)
+	PassLevelKey(const PassLevelKey& b)
+		: pass(b.pass), level(b.level)
+	{}
+
+	PassLevelKey(uint32_t pass_, uint32_t level_)
 		: pass(pass_), level(level_)
 	{}
 };
 
-
 /// Create hash functor
 struct PassLevelKeyCreateHash
 {
@@ -32,7 +34,6 @@ struct PassLevelKeyCreateHash
 	}
 };
 
-
 /// Values comparisons functor
 struct PassLevelKeyComparision
 {
@@ -43,17 +44,12 @@ struct PassLevelKeyComparision
 	}
 };
 
-
-/// XXX
+/// Define an unorderer map with key the PassLevelKey and type given by a
+/// template parameter
 template<typename T>
-struct PassLevelHashMap
-{
-	typedef boost::unordered_map<PassLevelKey, T,
-		PassLevelKeyCreateHash, PassLevelKeyComparision> Type;
-};
-
+using PassLevelHashMap = std::unordered_map<
+	PassLevelKey, T, PassLevelKeyCreateHash, PassLevelKeyComparision>;
 
 } // end namespace
 
-
 #endif

+ 0 - 4
include/anki/resource/Script.h

@@ -3,10 +3,8 @@
 
 #include <string>
 
-
 namespace anki {
 
-
 /// Python script resource
 class Script
 {
@@ -17,8 +15,6 @@ private:
 	std::string source;
 };
 
-
 } // end namespace
 
-
 #endif

+ 51 - 0
include/anki/util/Barrier.h

@@ -0,0 +1,51 @@
+#ifndef ANKI_UTIL_BARRIER_H
+#define ANKI_UTIL_BARRIER_H
+
+#include "anki/util/Assert.h"
+#include <thread>
+#include <condition_variable>
+#include <mutex>
+
+namespace anki {
+
+/// A barrier for thread synchronization. It works just like boost::barrier
+class Barrier
+{
+public:
+	Barrier(uint32_t count_)
+		: threshold(count_), count(count_), generation(0)
+	{
+		ANKI_ASSERT(count_ != 0);
+	}
+
+	bool wait()
+	{
+		std::unique_lock<std::mutex> lock(mtx);
+		uint32_t gen = generation;
+
+		if(--count == 0)
+		{
+			generation++;
+			count = threshold;
+			cond.notify_all();
+			return true;
+		}
+
+		while(gen == generation)
+		{
+			cond.wait(lock);
+		}
+		return false;
+	}
+
+private:
+	std::mutex mtx;
+	std::condition_variable cond;
+	uint32_t threshold;
+	uint32_t count;
+	uint32_t generation;
+};
+
+} // end namespace anki
+
+#endif

+ 46 - 0
include/anki/util/Filesystem.h

@@ -0,0 +1,46 @@
+#ifndef ANKI_UTIL_FILESYSTEM_H
+#define ANKI_UTIL_FILESYSTEM_H
+
+#include "anki/util/StringList.h"
+#include <string>
+
+namespace anki {
+
+/// @addtogroup util
+/// @{
+/// @addtogroup filesystem
+/// @{
+
+/// Get file extension
+/// @param[in] filename The file to open
+/// @return nullptr on failure and if the dot is the last character
+extern const char* getFileExtension(const char* filename);
+
+/// Open a text file and return its contents into a string
+extern std::string readFile(const char* filename);
+
+/// Open a text file and return its lines into a string vector
+extern StringList readFileLines(const char* filename);
+
+/// File exists?
+extern bool fileExists(const char* filename);
+
+/// Directory exists?
+extern bool directoryExists(const char* filename);
+
+/// rm -rf
+extern void removeDirectory(const char* dir);
+
+/// mkdir
+extern void createDirectory(const char* dir);
+
+/// Convert a POSIX path to a platform native path. It actually replaces /
+/// with \ in windows
+extern void toNativePath(const char* path);
+
+/// @}
+/// @}
+
+} // end namespace anki
+
+#endif

+ 43 - 0
include/anki/util/Functions.h

@@ -0,0 +1,43 @@
+/// @file
+/// Contains misc functions
+
+#ifndef ANKI_UTIL_FUNCTIONS_H
+#define ANKI_UTIL_FUNCTIONS_H
+
+#include <cstdint>
+#include <cstdlib> // For size_t
+
+namespace anki {
+
+/// @addtogroup util
+/// @{
+/// @addtogroup misc
+/// @{
+
+/// Pick a random number from min to max
+extern int randRange(int min, int max);
+
+/// Pick a random number from min to max
+extern uint32_t randRange(uint32_t min, uint32_t max);
+
+/// Pick a random number from min to max
+extern float randRange(float min, float max);
+
+/// Pick a random number from min to max
+extern double randRange(double min, double max);
+
+extern float randFloat(float max);
+
+/// Get the size in bytes of a vector
+template<typename Vec>
+extern size_t getVectorSizeInBytes(const Vec& v)
+{
+	return v.size() * sizeof(typename Vec::value_type);
+}
+
+/// @}
+/// @}
+
+} // end namespace anki
+
+#endif

+ 16 - 20
include/anki/util/Object.h

@@ -3,13 +3,10 @@
 
 #include "anki/util/Assert.h"
 #include <vector>
-#include <boost/foreach.hpp>
 #include <boost/range/iterator_range.hpp>
 
-
 namespace anki {
 
-
 /// A hierarchical object
 template<typename T>
 class Object
@@ -22,30 +19,30 @@ public:
 	typedef boost::iterator_range<typename Container::iterator>
 		MutableIteratorRange;
 
-	/// Calls addChild if parent is not NULL
-	/// @exception Exception
+	/// Calls addChild if parent is not nullptr
 	Object(Value* self_, Value* parent_)
-		: self(self_), parent(NULL)
+		: self(self_)
 	{
-		ANKI_ASSERT(self != NULL && "Self can't be nullptr");
-		if(parent_ != NULL)
+		ANKI_ASSERT(self != nullptr && "Self can't be nullptr");
+		parent = parent_;
+		if(parent != nullptr)
 		{
-			parent_->addChild(self);
+			parent->addChild(self);
 		}
 	}
 
-	/// Delete childs from the last entered to the first and update parent
+	/// Delete children from the last entered to the first and update parent
 	virtual ~Object()
 	{
-		if(parent != NULL)
+		if(parent != nullptr)
 		{
 			parent->removeChild(self);
 		}
 
-		// Remove all children
-		BOOST_FOREACH(Value* child, childs)
+		// Remove all children (fast version)
+		for(Value* child : childs)
 		{
-			child->parent = NULL;
+			child->parent = nullptr;
 		}
 	}
 
@@ -78,8 +75,8 @@ public:
 	/// Add a new child
 	void addChild(Value* child)
 	{
-		ANKI_ASSERT(child != NULL && "Null arg");
-		ANKI_ASSERT(child->parent ==  NULL && "Child already has parent");
+		ANKI_ASSERT(child != nullptr && "Null arg");
+		ANKI_ASSERT(child->parent ==  nullptr && "Child already has parent");
 
 		child->parent = self;
 		childs.push_back(child);
@@ -88,7 +85,8 @@ public:
 	/// Remove a child
 	void removeChild(Value* child)
 	{
-		ANKI_ASSERT(child != NULL && "Null arg");
+		ANKI_ASSERT(child != nullptr && "Null arg");
+		ANKI_ASSERT(child->parent == self);
 
 		typename Container::iterator it =
 			std::find(childs.begin(), childs.end(), child);
@@ -96,7 +94,7 @@ public:
 		ANKI_ASSERT(it != childs.end() && "Child not found");
 
 		childs.erase(it);
-		child->parent = NULL;
+		child->parent = nullptr;
 	}
 
 private:
@@ -105,8 +103,6 @@ private:
 	Container childs;
 };
 
-
 } // end namespace
 
-
 #endif

+ 1 - 1
include/anki/util/Singleton.h

@@ -65,6 +65,6 @@ thread_local typename SingletonThreadSafe<T>::Value*
 
 /// @}
 
-} // end namespace
+} // end namespace anki
 
 #endif

+ 0 - 43
include/anki/util/Util.h

@@ -1,43 +0,0 @@
-#ifndef ANKI_UTIL_UTIL_H
-#define ANKI_UTIL_UTIL_H
-
-#include <string>
-#include <vector>
-
-namespace anki {
-
-/// Contains a few useful functions
-class Util
-{
-public:
-	/// Pick a random number from min to max
-	static int randRange(int min, int max);
-
-	/// Pick a random number from min to max
-	static uint randRange(uint32_t min, uint32_t max);
-
-	/// Pick a random number from min to max
-	static float randRange(float min, float max);
-
-	/// Pick a random number from min to max
-	static double randRange(double min, double max);
-
-	static float randFloat(float max);
-
-	/// Open a text file and return its contents into a string
-	static std::string readFile(const char* filename);
-
-	/// Open a text file and return its lines into a string vector
-	static std::vector<std::string> getFileLines(const char* filename);
-
-	/// Get the size in bytes of a vector
-	template<typename Vec>
-	static size_t getVectorSizeInBytes(const Vec& v)
-	{
-		return v.size() * sizeof(typename Vec::value_type);
-	}
-};
-
-} // end namespace
-
-#endif

+ 27 - 27
src/core/App.cpp

@@ -2,12 +2,12 @@
 #include "anki/core/Logger.h"
 #include "anki/util/Exception.h"
 #include "anki/util/Platform.h"
+#include "anki/util/Filesystem.h"
 #include <GL/glew.h>
 #include <sstream>
 #include <SDL/SDL.h>
 #include <iostream>
 #include <iomanip>
-#include <boost/filesystem.hpp>
 #include <boost/algorithm/string.hpp>
 
 namespace anki {
@@ -20,20 +20,20 @@ void App::handleLoggerMessages(const Logger::Info& info)
 
 	switch(info.type)
 	{
-		case Logger::LMT_NORMAL:
-			out = &std::cout;
-			x = "Info";
-			break;
-
-		case Logger::LMT_ERROR:
-			out = &std::cerr;
-			x = "Error";
-			break;
-
-		case Logger::LMT_WARNING:
-			out = &std::cerr;
-			x = "Warn";
-			break;
+	case Logger::LMT_NORMAL:
+		out = &std::cout;
+		x = "Info";
+		break;
+
+	case Logger::LMT_ERROR:
+		out = &std::cerr;
+		x = "Error";
+		break;
+
+	case Logger::LMT_WARNING:
+		out = &std::cerr;
+		x = "Warn";
+		break;
 	}
 
 	(*out) << "(" << info.file << ":" << info.line << " "<< info.func 
@@ -56,8 +56,8 @@ void App::parseCommandLineArgs(int argc, char* argv[])
 		}
 		else
 		{
-			std::cerr << "Incorrect command line argument \"" << arg 
-				<< "\"" << std::endl;
+			std::cerr << "Incorrect command line argument: " << arg
+				<< std::endl;
 			abort();
 		}
 	}
@@ -142,22 +142,22 @@ void App::initWindow()
 //==============================================================================
 void App::initDirs()
 {
-	settingsPath = boost::filesystem::path(getenv("HOME")) / ".anki";
-	if(!boost::filesystem::exists(settingsPath))
+	settingsPath = std::string(getenv("HOME")) + "/.anki";
+	if(!directoryExists(settingsPath.c_str()))
 	{
-		ANKI_LOGI("Creating settings dir \"" << settingsPath.string() << "\"");
-		boost::filesystem::create_directory(settingsPath);
+		ANKI_LOGI("Creating settings dir: " << settingsPath);
+		createDirectory(settingsPath.c_str());
 	}
 
-	cachePath = settingsPath / "cache";
-	if(boost::filesystem::exists(cachePath))
+	cachePath = settingsPath + "/cache";
+	if(directoryExists(cachePath.c_str()))
 	{
-		ANKI_LOGI("Deleting dir \"" << cachePath.string() << "\"");
-		boost::filesystem::remove_all(cachePath);
+		ANKI_LOGI("Deleting dir \"" << cachePath << "\"");
+		removeDirectory(cachePath.c_str());
 	}
 
-	ANKI_LOGI("Creating cache dir \"" << cachePath.string() << "\"");
-	boost::filesystem::create_directory(cachePath);
+	ANKI_LOGI("Creating cache dir \"" << cachePath << "\"");
+	createDirectory(cachePath.c_str());
 }
 
 //==============================================================================

+ 5 - 15
src/core/AsyncLoader.cpp

@@ -2,12 +2,8 @@
 #include "anki/core/Logger.h"
 #include "anki/core/App.h"
 
-
 namespace anki {
-
-
-//==============================================================================
-// start                                                                       =
+/*
 //==============================================================================
 void AsyncLoader::start()
 {
@@ -15,25 +11,19 @@ void AsyncLoader::start()
 	thread = boost::thread(&AsyncLoader::workingFunc, this);
 }
 
-
-//==============================================================================
-// load                                                                        =
 //==============================================================================
 void AsyncLoader::load(const char* filename, LoadCallback loadCallback,
 	void* storage)
 {
-	ANKI_LOGI("New load request for \"" << filename << "\"");
-	boost::mutex::scoped_lock lock(mutexReq);
+	ANKI_LOGI("New load request for: " << filename);
+	mutexReq.lock();
 	Request f = {filename, loadCallback, storage};
 	requests.push_back(f);
-	lock.unlock();
+	mutexReq.unlock();
 
 	condVar.notify_one();
 }
 
-
-//==============================================================================
-// workingFunc                                                                 =
 //==============================================================================
 void AsyncLoader::workingFunc()
 {
@@ -98,6 +88,6 @@ bool AsyncLoader::pollForFinished(std::string& filename, void* buff, bool& ok)
 	ok = resp.ok;
 	return true;
 }
-
+*/
 
 } // end namespace

+ 0 - 64
src/core/ParallelJob.cpp

@@ -1,64 +0,0 @@
-#include "anki/core/ParallelJob.h"
-#include "anki/core/ParallelManager.h"
-
-
-namespace anki {
-
-
-//==============================================================================
-// Constructor                                                                 =
-//==============================================================================
-ParallelJob::ParallelJob(int id_, const ParallelManager& manager_,
-	boost::barrier& barrier_)
-	: id(id_), barrier(barrier_), callback(NULL), manager(manager_)
-{
-	start();
-}
-
-
-//==============================================================================
-// assignNewJob                                                                =
-//==============================================================================
-void ParallelJob::assignNewJob(ParallelJobCallback callback_,
-	ParallelJobParameters& jobParams_)
-{
-	boost::mutex::scoped_lock lock(mutex);
-	callback = callback_;
-	params = &jobParams_;
-
-	lock.unlock();
-	condVar.notify_one();
-}
-
-
-//==============================================================================
-// workingFunc                                                                 =
-//==============================================================================
-void ParallelJob::workingFunc()
-{
-	while(1)
-	{
-		// Wait for something
-		{
-			boost::mutex::scoped_lock lock(mutex);
-			while(callback == NULL)
-			{
-				condVar.wait(lock);
-			}
-		}
-
-		// Exec
-		callback(*params, *this);
-
-		// Nullify
-		{
-			boost::mutex::scoped_lock lock(mutex);
-			callback = NULL;
-		}
-
-		barrier.wait();
-	}
-}
-
-
-} // end namespace

+ 54 - 4
src/core/ParallelManager.cpp

@@ -1,19 +1,69 @@
 #include "anki/core/ParallelManager.h"
 
-
 namespace anki {
 
+//==============================================================================
+// ParallelJob                                                                 =
+//==============================================================================
+
+//==============================================================================
+ParallelJob::ParallelJob(uint32_t id_, const ParallelManager* manager_,
+	Barrier* barrier_)
+	: id(id_), barrier(barrier_), callback(nullptr), manager(manager_)
+{
+	start();
+}
+
+//==============================================================================
+void ParallelJob::assignNewJob(ParallelJobCallback callback_,
+	ParallelJobParameters& jobParams_)
+{
+	mutex.lock();
+	callback = callback_;
+	params = &jobParams_;
+	mutex.unlock();
+	condVar.notify_one();
+}
+
+//==============================================================================
+void ParallelJob::workingFunc()
+{
+	while(1)
+	{
+		// Wait for something
+		{
+			std::unique_lock<std::mutex> lock(mutex);
+			while(callback == nullptr)
+			{
+				condVar.wait(lock);
+			}
+		}
+
+		// Exec
+		callback(*params, *this);
+
+		// Nullify
+		{
+			std::lock_guard<std::mutex> lock(mutex);
+			callback = nullptr;
+		}
+
+		barrier->wait();
+	}
+}
 
 //==============================================================================
-// init                                                                        =
+// ParallelManager                                                             =
+//==============================================================================
+
 //==============================================================================
 void ParallelManager::init(uint threadsNum)
 {
-	barrier.reset(new boost::barrier(threadsNum + 1));
+	barrier.reset(new Barrier(threadsNum + 1));
 
 	for(uint i = 0; i < threadsNum; i++)
 	{
-		jobs.push_back(new ParallelJob(i, *this, *barrier.get()));
+		jobs.push_back(new ParallelJob(i, this, barrier.get()));
 	}
 }
 

+ 8 - 17
src/core/StdinListener.cpp

@@ -1,37 +1,32 @@
 #include "anki/core/StdinListener.h"
-
+#include <array>
+#include <unistd.h>
 
 namespace anki {
 
-
-//==============================================================================
-// workingFunc                                                                 =
 //==============================================================================
 void StdinListener::workingFunc()
 {
-	char buff[512];
+	std::array<char, 512> buff;
 
 	while(1)
 	{
-		int m = read(0, buff, sizeof(buff));
+		int m = read(0, &buff[0], sizeof(buff));
 		buff[m] = '\0';
 		//cout << "read: " << buff << endl;
 		{
-			boost::mutex::scoped_lock lock(mtx);
-			q.push(buff);
+			std::lock_guard<std::mutex> lock(mtx);
+			q.push(&buff[0]);
 			//cout << "size:" << q.size() << endl;
 		}
 	}
 }
 
-
-//==============================================================================
-// getLine                                                                     =
 //==============================================================================
 std::string StdinListener::getLine()
 {
 	std::string ret;
-	boost::mutex::scoped_lock lock(mtx);
+	std::lock_guard<std::mutex> lock(mtx);
 	//cout << "_size:" << q.size() << endl;
 	if(!q.empty())
 	{
@@ -41,14 +36,10 @@ std::string StdinListener::getLine()
 	return ret;
 }
 
-
-//==============================================================================
-// start                                                                       =
 //==============================================================================
 void StdinListener::start()
 {
-	thrd = boost::thread(&StdinListener::workingFunc, this);
+	thrd = std::thread(&StdinListener::workingFunc, this);
 }
 
-
 } // end namespace

+ 2 - 2
src/resource/AsyncOperator.cpp

@@ -4,7 +4,7 @@
 
 
 namespace anki {
-
+/*
 
 //==============================================================================
 void AsyncOperator::start()
@@ -108,6 +108,6 @@ uint AsyncOperator::execPostLoad(float maxTime)
 
 	return count;
 }
-
+*/
 
 } // end namespace

+ 58 - 60
src/resource/Image.cpp

@@ -1,9 +1,9 @@
 #include "anki/resource/Image.h"
 #include "anki/util/Exception.h"
 #include "anki/core/Logger.h"
+#include "anki/util/Filesystem.h"
+#include "anki/util/Assert.h"
 #include <png.h>
-#include <boost/filesystem.hpp> // For file extensions
-#include <boost/algorithm/string.hpp> // For to_lower
 #include <fstream>
 
 namespace anki {
@@ -100,7 +100,7 @@ void Image::loadCompressedTga(std::fstream& fs, uint32_t& bpp)
 					throw ANKI_EXCEPTION("Cannot read image data");
 				}
 
-				data[currentbyte		] = colorbuffer[2];
+				data[currentbyte] = colorbuffer[2];
 				data[currentbyte + 1] = colorbuffer[1];
 				data[currentbyte + 2] = colorbuffer[0];
 
@@ -130,8 +130,8 @@ void Image::loadCompressedTga(std::fstream& fs, uint32_t& bpp)
 			for(int counter = 0; counter < chunkheader; counter++)
 			{
 				data[currentbyte] = colorbuffer[2];
-				data[currentbyte+1] = colorbuffer[1];
-				data[currentbyte+2] = colorbuffer[0];
+				data[currentbyte + 1] = colorbuffer[1];
+				data[currentbyte + 2] = colorbuffer[0];
 
 				if(bytesPerPxl == 4)
 				{
@@ -273,7 +273,6 @@ bool Image::loadPng(const char* filename, std::string& err) throw()
 	// PNG lib knows that we already have read the header
 	png_set_sig_bytes(pngPtr, PNG_SIG_SIZE);
 
-	//
 	// Read info and make conversions
 	// This loop reads info, if not acceptable it calls libpng funcs to change
 	// them and re-runs the loop
@@ -290,30 +289,30 @@ bool Image::loadPng(const char* filename, std::string& err) throw()
 		// 1) Convert the color types
 		switch(colorType)
 		{
-			case PNG_COLOR_TYPE_PALETTE:
-				err = "Converting PNG_COLOR_TYPE_PALETTE to "
-					"PNG_COLOR_TYPE_RGB or PNG_COLOR_TYPE_RGBA";
-				png_set_palette_to_rgb(pngPtr);
-				goto again;
-				break;
-			case PNG_COLOR_TYPE_GRAY:
-				// do nothing
-				break;
-			case PNG_COLOR_TYPE_GRAY_ALPHA:
-				err = "Cannot accept PNG_COLOR_TYPE_GRAY_ALPHA. "
-					"Converting to PNG_COLOR_TYPE_GRAY";
-				png_set_strip_alpha(pngPtr);
-				goto again;
-				break;
-			case PNG_COLOR_TYPE_RGB:
-				// do nothing
-				break;
-			case PNG_COLOR_TYPE_RGBA:
-				// do nothing
-				break;
-			default:
-				throw ANKI_EXCEPTION("Forgot to handle a color type");
-				break;
+		case PNG_COLOR_TYPE_PALETTE:
+			err = "Converting PNG_COLOR_TYPE_PALETTE to "
+				"PNG_COLOR_TYPE_RGB or PNG_COLOR_TYPE_RGBA";
+			png_set_palette_to_rgb(pngPtr);
+			goto again;
+			break;
+		case PNG_COLOR_TYPE_GRAY:
+			// do nothing
+			break;
+		case PNG_COLOR_TYPE_GRAY_ALPHA:
+			err = "Cannot accept PNG_COLOR_TYPE_GRAY_ALPHA. "
+				"Converting to PNG_COLOR_TYPE_GRAY";
+			png_set_strip_alpha(pngPtr);
+			goto again;
+			break;
+		case PNG_COLOR_TYPE_RGB:
+			// do nothing
+			break;
+		case PNG_COLOR_TYPE_RGBA:
+			// do nothing
+			break;
+		default:
+			throw ANKI_EXCEPTION("Forgot to handle a color type");
+			break;
 		}
 
 		// 2) Convert the bit depths
@@ -337,16 +336,15 @@ bool Image::loadPng(const char* filename, std::string& err) throw()
 	}
 
 	// Sanity checks
-	if((bitDepth != 8) ||
-		(colorType != PNG_COLOR_TYPE_GRAY &&
-			colorType != PNG_COLOR_TYPE_RGB &&
-			colorType != PNG_COLOR_TYPE_RGBA))
+	if((bitDepth != 8)
+		|| (colorType != PNG_COLOR_TYPE_GRAY
+			&& colorType != PNG_COLOR_TYPE_RGB
+			&& colorType != PNG_COLOR_TYPE_RGBA))
 	{
 		err = "Sanity checks failed";
 		goto cleanup;
 	}
 
-	//
 	// Read this sucker
 	//
 	rowbytes = png_get_rowbytes(pngPtr, infoPtr);
@@ -364,25 +362,25 @@ bool Image::loadPng(const char* filename, std::string& err) throw()
 	//
 	switch(colorType)
 	{
-		case PNG_COLOR_TYPE_GRAY:
-			type = CT_R;
-			break;
-		case PNG_COLOR_TYPE_RGB:
-			type = CT_RGB;
-			break;
-		case PNG_COLOR_TYPE_RGBA:
-			type = CT_RGBA;
-			break;
-		default:
-			err = "See file";
-			goto cleanup;
+	case PNG_COLOR_TYPE_GRAY:
+		type = CT_R;
+		break;
+	case PNG_COLOR_TYPE_RGB:
+		type = CT_RGB;
+		break;
+	case PNG_COLOR_TYPE_RGBA:
+		type = CT_RGBA;
+		break;
+	default:
+		err = "See file";
+		goto cleanup;
 	}
 
 	ok = true;
 
 	// Cleanup
 	//
-	cleanup:
+cleanup:
 
 	if(pngPtr)
 	{
@@ -409,17 +407,17 @@ bool Image::loadPng(const char* filename, std::string& err) throw()
 void Image::load(const char* filename)
 {
 	// get the extension
-	std::string ext = boost::filesystem::path(filename).extension().string();
-	boost::to_lower(ext);
+	const char* ext = getFileExtension(filename);
+	ANKI_ASSERT(ext);
 
 	// load from this extension
 	try
 	{
-		if(ext == ".tga")
+		if(strcmp(ext, "tga") == 0)
 		{
 			loadTga(filename);
 		}
-		else if(ext == ".png")
+		else if(strcmp(ext, "png") == 0)
 		{
 			std::string err;
 			if(!loadPng(filename, err))
@@ -427,7 +425,7 @@ void Image::load(const char* filename)
 				throw ANKI_EXCEPTION(err);
 			}
 		}
-		else if(ext == ".dds")
+		else if(strcmp(ext, "dds") == 0)
 		{
 			loadDds(filename);
 		}
@@ -438,7 +436,7 @@ void Image::load(const char* filename)
 	}
 	catch(std::exception& e)
 	{
-		throw ANKI_EXCEPTION("File \"" + filename + "\"") << e;
+		throw ANKI_EXCEPTION("File " + filename) << e;
 	}
 }
 
@@ -614,9 +612,9 @@ void Image::loadDds(const char* filename)
 	DDS_header hdr;
 	in.read((char*)&hdr, sizeof(hdr));
 
-	if(hdr.data.dwMagic != DDS_MAGIC || hdr.data.dwSize != 124 ||
-		!(hdr.data.dwFlags & DDSD_PIXELFORMAT) ||
-		!(hdr.data.dwFlags & DDSD_CAPS))
+	if(hdr.data.dwMagic != DDS_MAGIC || hdr.data.dwSize != 124
+		|| !(hdr.data.dwFlags & DDSD_PIXELFORMAT)
+		|| !(hdr.data.dwFlags & DDSD_CAPS))
 	{
 		throw ANKI_EXCEPTION("Incorrect DDS header");
 	}
@@ -659,9 +657,9 @@ void Image::loadDds(const char* filename)
 
 	if(li->compressed)
 	{
-		size_t size = std::max(li->divSize, x) /
-			li->divSize * std::max(li->divSize, y) /
-			li->divSize * li->blockBytes;
+		size_t size = std::max(li->divSize, x)
+			/ li->divSize * std::max(li->divSize, y)
+			/ li->divSize * li->blockBytes;
 		//assert( size == hdr.dwPitchOrLinearSize );
 		//assert( hdr.dwFlags & DDSD_LINEARSIZE );
 		data.resize(size);

+ 8 - 6
src/resource/Material.cpp

@@ -2,6 +2,7 @@
 #include "anki/misc/PropertyTree.h"
 #include "anki/resource/MaterialShaderProgramCreator.h"
 #include "anki/core/App.h"
+#include "anki/util/Filesystem.h"
 #include "anki/resource/ShaderProgramResource.h"
 #include "anki/resource/TextureResource.h"
 #include <boost/property_tree/ptree.hpp>
@@ -233,25 +234,26 @@ std::string Material::createShaderProgSourceToCache(const std::string& source)
 	std::string prefix = std::to_string(h);
 
 	// Create path
-	boost::filesystem::path newfPathName =
-		AppSingleton::get().getCachePath() / (prefix + ".glsl");
+	std::string newfPathName =
+		AppSingleton::get().getCachePath() + "/" + prefix + ".glsl";
+	toNativePath(newfPathName.c_str());
 
 	// If file not exists write it
-	if(!boost::filesystem::exists(newfPathName))
+	if(!fileExists(newfPathName.c_str()))
 	{
 		// If not create it
-		std::ofstream f(newfPathName.string().c_str());
+		std::ofstream f(newfPathName.c_str());
 		if(!f.is_open())
 		{
 			throw ANKI_EXCEPTION("Cannot open file for writing: " 
-				+ newfPathName.string());
+				+ newfPathName);
 		}
 
 		f.write(source.c_str(), source.length());
 		f.close();
 	}
 
-	return newfPathName.string();
+	return newfPathName;
 }
 
 //==============================================================================

+ 18 - 33
src/resource/MaterialShaderProgramCreator.cpp

@@ -1,15 +1,11 @@
 #include "anki/resource/MaterialShaderProgramCreator.h"
 #include "anki/util/Assert.h"
 #include "anki/util/Exception.h"
-#include <boost/foreach.hpp>
 #include <boost/property_tree/ptree.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/regex.hpp>
-
+#include <regex>
 
 namespace anki {
 
-
 //==============================================================================
 MaterialShaderProgramCreator::MaterialShaderProgramCreator(
 	const boost::property_tree::ptree& pt)
@@ -17,24 +13,22 @@ MaterialShaderProgramCreator::MaterialShaderProgramCreator(
 	parseShaderProgramTag(pt);
 }
 
-
 //==============================================================================
 MaterialShaderProgramCreator::~MaterialShaderProgramCreator()
 {}
 
-
 //==============================================================================
 void MaterialShaderProgramCreator::parseShaderProgramTag(
 	const boost::property_tree::ptree& pt)
 {
 	using namespace boost::property_tree;
 
-	BOOST_FOREACH(const ptree::value_type& v, pt)
+	for(const ptree::value_type& v : pt)
 	{
 		if(v.first != "shader")
 		{
-			throw ANKI_EXCEPTION("Expected \"shader\" tag and not: " + 
-				v.first);
+			throw ANKI_EXCEPTION("Expected \"shader\" tag and not: "
+				+ v.first);
 		}
 		
 		parseShaderTag(v.second);
@@ -44,26 +38,23 @@ void MaterialShaderProgramCreator::parseShaderProgramTag(
 	//std::cout << source << std::endl;
 }
 
-
 //==============================================================================
 void MaterialShaderProgramCreator::parseShaderTag(
 	const boost::property_tree::ptree& pt)
 {
 	using namespace boost::property_tree;
 
-	//
 	// <type></type>
 	//
 	const std::string& type = pt.get<std::string>("type");
 	srcLines.push_back("#pragma anki start " + type + "Shader");
 
-	//
 	// <includes></includes>
 	//
 	std::vector<std::string> includeLines;
 
 	const ptree& includesPt = pt.get_child("includes");
-	BOOST_FOREACH(const ptree::value_type& v, includesPt)
+	for(const ptree::value_type& v : includesPt)
 	{
 		if(v.first != "include")
 		{
@@ -79,7 +70,6 @@ void MaterialShaderProgramCreator::parseShaderTag(
 	//std::sort(includeLines.begin(), includeLines.end(), compareStrings);
 	srcLines.insert(srcLines.end(), includeLines.begin(), includeLines.end());
 
-	//
 	// <inputs></inputs>
 	//
 	boost::optional<const ptree&> insPt = pt.get_child_optional("inputs");
@@ -88,12 +78,12 @@ void MaterialShaderProgramCreator::parseShaderTag(
 		// Store the source of the uniform vars
 		std::vector<std::string> uniformsLines;
 	
-		BOOST_FOREACH(const ptree::value_type& v, insPt.get())
+		for(const ptree::value_type& v : insPt.get())
 		{
 			if(v.first != "input")
 			{
-				throw ANKI_EXCEPTION("Expected \"input\" tag and not: " + 
-					v.first);
+				throw ANKI_EXCEPTION("Expected \"input\" tag and not: "
+					+  v.first);
 			}
 
 			const ptree& inPt = v.second;
@@ -108,19 +98,18 @@ void MaterialShaderProgramCreator::parseShaderTag(
 			uniformsLines.end());
 	}
 
-	//
 	// <operations></operations>
 	//
 	srcLines.push_back("\nvoid main()\n{");
 
 	const ptree& opsPt = pt.get_child("operations");
 
-	BOOST_FOREACH(const ptree::value_type& v, opsPt)
+	for(const ptree::value_type& v : opsPt)
 	{
 		if(v.first != "operation")
 		{
-			throw ANKI_EXCEPTION("Expected \"operation\" tag and not: " + 
-				v.first);
+			throw ANKI_EXCEPTION("Expected \"operation\" tag and not: "
+				+ v.first);
 		}
 
 		const ptree& opPt = v.second;
@@ -130,7 +119,6 @@ void MaterialShaderProgramCreator::parseShaderTag(
 	srcLines.push_back("}\n");
 }
 
-
 //==============================================================================
 void MaterialShaderProgramCreator::parseInputTag(
 	const boost::property_tree::ptree& pt, std::string& line)
@@ -143,7 +131,6 @@ void MaterialShaderProgramCreator::parseInputTag(
 	line = "uniform " + type + " " + name + ";";
 }
 
-
 //==============================================================================
 void MaterialShaderProgramCreator::parseOperationTag(
 	const boost::property_tree::ptree& pt)
@@ -160,7 +147,7 @@ void MaterialShaderProgramCreator::parseOperationTag(
 	std::string operationOut;
 	if(retTypeOpt)
 	{
-		operationOut = "operationOut" + boost::lexical_cast<std::string>(id);
+		operationOut = "operationOut" + std::to_string(id);
 	}
 	
 	// <function>functionName</function>
@@ -180,9 +167,9 @@ void MaterialShaderProgramCreator::parseOperationTag(
 		
 			if(v.first != "argument")
 			{
-				throw ANKI_EXCEPTION("Operation " +
-					boost::lexical_cast<std::string>(id) + 
-					": Expected \"argument\" tag and not: " + v.first);
+				throw ANKI_EXCEPTION("Operation "
+					+ std::to_string(id)
+					+ ": Expected \"argument\" tag and not: " + v.first);
 			}
 
 			const std::string& argName = v.second.data();
@@ -194,10 +181,10 @@ void MaterialShaderProgramCreator::parseOperationTag(
 	std::stringstream line;
 	line << "#if defined(" << funcName << "_DEFINED)";
 
-	boost::regex expr("^operationOut[0-9]*$");
-	BOOST_FOREACH(const std::string& arg, argsList)
+	std::regex expr("^operationOut[0-9]*$");
+	for(const std::string& arg : argsList)
 	{
-		if(boost::regex_match(arg, expr))
+		if(std::regex_match(arg, expr))
 		{
 			line << " && defined(" << arg << "_DEFINED)";
 		}
@@ -223,7 +210,6 @@ void MaterialShaderProgramCreator::parseOperationTag(
 	srcLines.push_back(line.str());
 }
 
-
 //==============================================================================
 bool MaterialShaderProgramCreator::compareStrings(
 	const std::string& a, const std::string& b)
@@ -231,5 +217,4 @@ bool MaterialShaderProgramCreator::compareStrings(
 	return a < b;
 }
 
-
 } // end namespace

+ 8 - 14
src/resource/Mesh.cpp

@@ -2,14 +2,11 @@
 #include "anki/resource/Material.h"
 #include "anki/resource/MeshLoader.h"
 #include "anki/gl/Vbo.h"
-#include "anki/util/Util.h"
+#include "anki/util/Functions.h"
 #include <fstream>
-#include <boost/lexical_cast.hpp>
-
 
 namespace anki {
 
-
 //==============================================================================
 void Mesh::load(const char* filename)
 {
@@ -20,7 +17,6 @@ void Mesh::load(const char* filename)
 
 	try
 	{
-		//
 		// Sanity checks
 		//
 		if(meshData.getVertIndeces().size() < 1
@@ -36,29 +32,28 @@ void Mesh::load(const char* filename)
 	}
 	catch(std::exception& e)
 	{
-		throw ANKI_EXCEPTION("Mesh \"" + filename + "\"") << e;
+		throw ANKI_EXCEPTION("Mesh loading failed: " + filename) << e;
 	}
 }
 
-
 //==============================================================================
 void Mesh::createVbos(const MeshLoader& meshData)
 {
 	vbos[VBO_INDICES].create(
 		GL_ELEMENT_ARRAY_BUFFER,
-		Util::getVectorSizeInBytes(meshData.getVertIndeces()),
+		getVectorSizeInBytes(meshData.getVertIndeces()),
 		&meshData.getVertIndeces()[0],
 		GL_STATIC_DRAW);
 
 	vbos[VBO_POSITIONS].create(
 		GL_ARRAY_BUFFER,
-		Util::getVectorSizeInBytes(meshData.getVertCoords()),
+		getVectorSizeInBytes(meshData.getVertCoords()),
 		&meshData.getVertCoords()[0],
 		GL_STATIC_DRAW);
 
 	vbos[VBO_NORMALS].create(
 		GL_ARRAY_BUFFER,
-		Util::getVectorSizeInBytes(meshData.getVertNormals()),
+		getVectorSizeInBytes(meshData.getVertNormals()),
 		&meshData.getVertNormals()[0],
 		GL_STATIC_DRAW);
 
@@ -66,7 +61,7 @@ void Mesh::createVbos(const MeshLoader& meshData)
 	{
 		vbos[VBO_TANGENTS].create(
 			GL_ARRAY_BUFFER,
-			Util::getVectorSizeInBytes(meshData.getVertTangents()),
+			getVectorSizeInBytes(meshData.getVertTangents()),
 			&meshData.getVertTangents()[0],
 			GL_STATIC_DRAW);
 	}
@@ -75,7 +70,7 @@ void Mesh::createVbos(const MeshLoader& meshData)
 	{
 		vbos[VBO_TEX_COORDS].create(
 			GL_ARRAY_BUFFER,
-			Util::getVectorSizeInBytes(meshData.getTexCoords()),
+			getVectorSizeInBytes(meshData.getTexCoords()),
 			&meshData.getTexCoords()[0],
 			GL_STATIC_DRAW);
 	}
@@ -84,11 +79,10 @@ void Mesh::createVbos(const MeshLoader& meshData)
 	{
 		vbos[VBO_WEIGHTS].create(
 			GL_ARRAY_BUFFER,
-			Util::getVectorSizeInBytes(meshData.getVertWeights()),
+			getVectorSizeInBytes(meshData.getVertWeights()),
 			&meshData.getVertWeights()[0],
 			GL_STATIC_DRAW);
 	}
 }
 
-
 } // end namespace

+ 4 - 9
src/resource/Script.cpp

@@ -1,22 +1,17 @@
 #include "anki/resource/Script.h"
-#include "anki/util/Util.h"
+#include "anki/util/Filesystem.h"
 #include "anki/util/Exception.h"
 
-
 namespace anki {
 
-
-//==============================================================================
-// load                                                                        =
 //==============================================================================
 void Script::load(const char* filename)
 {
-	source = Util::readFile(filename);
+	source = readFile(filename);
 	if(source.length() < 1)
 	{
-		throw ANKI_EXCEPTION("Cannot load script \"" + filename + "\"");
+		throw ANKI_EXCEPTION("Cannot load script: " + filename);
 	}
 }
 
-
-} // end namespace
+} // end namespace anki

+ 3 - 3
src/resource/ShaderProgramPrePreprocessor.cpp

@@ -1,6 +1,6 @@
 #include "anki/resource/ShaderProgramPrePreprocessor.h"
 #include "anki/misc/Parser.h"
-#include "anki/util/Util.h"
+#include "anki/util/Filesystem.h"
 #include "anki/util/Exception.h"
 #include <iomanip>
 #include <cstring>
@@ -52,10 +52,10 @@ void ShaderProgramPrePreprocessor::parseFileForPragmas(
 	}
 
 	// load file in lines
-	std::vector<std::string> lines = Util::getFileLines(filename.c_str());
+	StringList lines = readFileLines(filename.c_str());
 	if(lines.size() < 1)
 	{
-		throw ANKI_EXCEPTION("File \"" + filename + "\": Cannot open or empty");
+		throw ANKI_EXCEPTION("Cannot open file or empty: " + filename);
 	}
 
 	scanner::Scanner scanner(filename.c_str(), false);

+ 13 - 16
src/resource/ShaderProgramResource.cpp

@@ -1,12 +1,11 @@
 #include "anki/resource/ShaderProgramResource.h"
 #include "anki/resource/ShaderProgramPrePreprocessor.h"
 #include "anki/core/App.h" // To get cache dir
-#include "anki/util/Util.h"
+#include "anki/util/Filesystem.h"
 #include "anki/util/Exception.h"
-#include <boost/filesystem.hpp>
-#include <boost/unordered_map.hpp>
 #include <fstream>
 #include <sstream>
+#include <unordered_map>
 
 namespace anki {
 
@@ -15,7 +14,7 @@ void ShaderProgramResource::load(const char* filename)
 {
 	ShaderProgramPrePreprocessor pars(filename);
 
-	boost::array<const char*, 128> trfVarsArr = {{nullptr}};
+	std::array<const char*, 128> trfVarsArr = {{nullptr}};
 	if(pars.getTranformFeedbackVaryings().size() > 0)
 	{
 		uint i;
@@ -38,40 +37,38 @@ void ShaderProgramResource::load(const char* filename)
 std::string ShaderProgramResource::createSrcCodeToCache(
 	const char* sProgFPathName, const char* preAppendedSrcCode)
 {
-	using namespace boost::filesystem;
-
 	if(strlen(preAppendedSrcCode) < 1)
 	{
 		return sProgFPathName;
 	}
 
 	// Create suffix
-	boost::hash<std::string> stringHash;
+	std::hash<std::string> stringHash;
 	std::size_t h = stringHash(preAppendedSrcCode);
 	std::string suffix = std::to_string(h);
 
 	//
-	path newfPathName = AppSingleton::get().getCachePath() 
-		/ (path(sProgFPathName).filename().string() + "." + suffix);
+	std::string newfPathName = AppSingleton::get().getCachePath()
+		+ "/" + suffix + ".glsl";
 
-	if(exists(newfPathName))
+	if(fileExists(newfPathName.c_str()))
 	{
-		return newfPathName.string();
+		return newfPathName;
 	}
 
-	std::string src_ = Util::readFile(sProgFPathName);
+	std::string src_ = readFile(sProgFPathName);
 	std::string src = preAppendedSrcCode + src_;
 
-	std::ofstream f(newfPathName.string().c_str());
+	std::ofstream f(newfPathName.c_str());
 	if(!f.is_open())
 	{
-		throw ANKI_EXCEPTION("Cannot open file for writing \"" 
-			+ newfPathName.string() + "\"");
+		throw ANKI_EXCEPTION("Cannot open file for writing: "
+			+ newfPathName);
 	}
 
 	f.write(src.c_str(), src.length());
 
-	return newfPathName.string();
+	return newfPathName;
 }
 
 } // end namespace

+ 1 - 1
src/scene/ParticleEmitterNode.cpp

@@ -6,7 +6,7 @@
 #include "anki/physics/RigidBody.h"
 #include "anki/core/App.h"
 #include "anki/scene/Scene.h"
-#include "anki/util/Util.h"
+#include "anki/util/Functions.h"
 
 
 namespace anki {

+ 115 - 0
src/util/Filesystem.cpp

@@ -0,0 +1,115 @@
+#include "anki/util/Filesystem.h"
+#include "anki/util/Exception.h"
+#include "anki/util/Assert.h"
+#include <fstream>
+#include <cstring>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <ftw.h>
+
+namespace anki {
+
+//==============================================================================
+const char* getFileExtension(const char* filename)
+{
+	ANKI_ASSERT(filename);
+	const char* pc = strrchr(filename, '.');
+
+	if(pc == nullptr)
+	{
+		return nullptr;
+	}
+
+	++pc;
+	return (*pc == '\0') ? nullptr : pc;
+}
+
+//==============================================================================
+std::string readFile(const char* filename)
+{
+	std::ifstream file(filename);
+	if (!file.is_open())
+	{
+		throw ANKI_EXCEPTION("Cannot open file: " + filename);
+	}
+
+	return std::string((std::istreambuf_iterator<char>(file)),
+		std::istreambuf_iterator<char>());
+}
+
+//==============================================================================
+StringList readFileLines(const char* filename)
+{
+	std::ifstream ifs(filename);
+	if(!ifs.is_open())
+	{
+		throw ANKI_EXCEPTION("Cannot open file: " + filename);
+	}
+
+	StringList lines;
+	std::string temp;
+	while(getline(ifs, temp))
+	{
+		lines.push_back(temp);
+	}
+	return lines;
+}
+
+//==============================================================================
+bool fileExists(const char* filename)
+{
+	ANKI_ASSERT(filename);
+	struct stat s;
+	stat(filename, &s);
+	return S_ISREG(s.st_mode);
+}
+
+//==============================================================================
+bool directoryExists(const char* filename)
+{
+	ANKI_ASSERT(filename);
+	struct stat s;
+	stat(filename, &s);
+	return S_ISDIR(s.st_mode);
+}
+
+//==============================================================================
+static int rmDir(const char* fpath, const struct stat* sb, int typeflag,
+	struct FTW* ftwbuf)
+{
+	int rv = remove(fpath);
+
+	if(rv)
+	{
+		throw ANKI_EXCEPTION(strerror(errno) + ": " + filename);
+	}
+
+	return rv;
+}
+
+void removeDirectory(const char* dir)
+{
+	nftw(path, rmDir, 64, FTW_DEPTH | FTW_PHYS);
+}
+
+//==============================================================================
+void createDirectory(const char* dir)
+{
+	if(directoryExists(dir))
+	{
+		return;
+	}
+
+	if(mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH))
+	{
+		throw ANKI_EXCEPTION(strerror(errno) + ": " + filename);
+	}
+}
+
+//==============================================================================
+void toNativePath(const char* path)
+{
+	ANKI_ASSERT(path);
+}
+
+} // end namespace anki

+ 41 - 0
src/util/Functions.cpp

@@ -0,0 +1,41 @@
+#include "anki/util/Functions.h"
+#include <cstdlib>
+#include <cmath>
+#include <cstring>
+
+namespace anki {
+
+//==============================================================================
+int randRange(int min, int max)
+{
+	return (rand() % (max - min + 1)) + min;
+}
+
+//==============================================================================
+uint32_t randRange(uint32_t min, uint32_t max)
+{
+	return (rand() % (max - min + 1)) + min;
+}
+
+//==============================================================================
+float randRange(float min, float max)
+{
+	float r = (float)rand() / (float)RAND_MAX;
+	return min + r * (max - min);
+}
+
+//==============================================================================
+double randRange(double min, double max)
+{
+	double r = (double)rand() / (double)RAND_MAX;
+	return min + r * (max - min);
+}
+
+//==============================================================================
+float randFloat(float max)
+{
+	float r = float(rand()) / float(RAND_MAX);
+	return r * max;
+}
+
+} // end namespace anki

+ 0 - 74
src/util/Util.cpp

@@ -1,74 +0,0 @@
-#include "anki/util/Util.h"
-#include "anki/util/Exception.h"
-#include <cstdlib>
-#include <cmath>
-#include <cstring>
-#include <fstream>
-
-namespace anki {
-
-//==============================================================================
-int Util::randRange(int min, int max)
-{
-	return (rand() % (max - min + 1)) + min;
-}
-
-//==============================================================================
-uint Util::randRange(uint32_t min, uint32_t max)
-{
-	return (rand() % (max - min + 1)) + min;
-}
-
-//==============================================================================
-float Util::randRange(float min, float max)
-{
-	float r = (float)rand() / (float)RAND_MAX;
-	return min + r * (max - min);
-}
-
-//==============================================================================
-double Util::randRange(double min, double max)
-{
-	double r = (double)rand() / (double)RAND_MAX;
-	return min + r * (max - min);
-}
-
-//==============================================================================
-std::string Util::readFile(const char* filename)
-{
-	std::ifstream file(filename);
-	if (!file.is_open())
-	{
-		throw ANKI_EXCEPTION("Cannot open file \"" + filename + "\"");
-	}
-
-	return std::string((std::istreambuf_iterator<char>(file)),
-		std::istreambuf_iterator<char>());
-}
-
-//==============================================================================
-std::vector<std::string> Util::getFileLines(const char* filename)
-{
-	std::ifstream ifs(filename);
-	if(!ifs.is_open())
-	{
-		throw ANKI_EXCEPTION("Cannot open file \"" + filename + "\"");
-	}
-
-	std::vector<std::string> lines;
-	std::string temp;
-	while(getline(ifs, temp))
-	{
-		lines.push_back(temp);
-	}
-	return lines;
-}
-
-//==============================================================================
-float Util::randFloat(float max)
-{
-	float r = float(rand()) / float(RAND_MAX);
-	return r * max;
-}
-
-} // end namespace

+ 3 - 9
testapp/Main.cpp

@@ -3,16 +3,13 @@
 #include <fstream>
 
 #include "anki/input/Input.h"
-#include "anki/scene/PerspectiveCamera.h"
-#include "anki/scene/OrthographicCamera.h"
+#include "anki/scene/Camera.h"
 #include "anki/math/Math.h"
 #include "anki/renderer/Renderer.h"
 #include "anki/ui/UiPainter.h"
 #include "anki/core/App.h"
 #include "anki/resource/Mesh.h"
 #include "anki/scene/Light.h"
-#include "anki/scene/PointLight.h"
-#include "anki/scene/SpotLight.h"
 #include "anki/resource/Material.h"
 #include "anki/scene/Scene.h"
 #include "anki/resource/SkelAnim.h"
@@ -30,12 +27,10 @@
 #include "anki/scene/ModelNode.h"
 #include "anki/resource/Model.h"
 #include "anki/core/Logger.h"
-#include "anki/util/Util.h"
+#include "anki/util/Filesystem.h"
 #include "anki/util/HighRezTimer.h"
 #include "anki/scene/SkinNode.h"
 #include "anki/resource/Skin.h"
-#include "anki/scene/MaterialRuntime.h"
-#include "anki/core/Globals.h"
 #include "anki/ui/UiFtFontLoader.h"
 #include "anki/ui/UiFont.h"
 #include "anki/event/EventManager.h"
@@ -44,7 +39,6 @@
 #include "anki/resource/ShaderProgramPrePreprocessor.h"
 #include "anki/resource/Material.h"
 #include "anki/core/ParallelManager.h"
-#include "anki/renderer/PhysDbgDrawer.h"
 #include <boost/algorithm/string.hpp>
 
 
@@ -341,7 +335,7 @@ void mainLoopExtra()
 	if(InputSingleton::get().getKey(SDL_SCANCODE_Y) == 1)
 	{
 		ANKI_LOGI("Exec script");
-		ScriptManagerSingleton::get().execScript(Util::readFile("test.py").c_str());
+		ScriptManagerSingleton::get().execScript(readFile("test.py").c_str());
 	}
 
 	mover->getLocalTransform().getRotation().reorthogonalize();