瀏覽代碼

Added wide strings
Added custom string allocators

Marko Pintera 12 年之前
父節點
當前提交
ea7362503f
共有 36 個文件被更改,包括 623 次插入546 次删除
  1. 1 1
      BansheeEngine/Include/BsGUILabel.h
  2. 1 1
      BansheeEngine/Include/BsGUISkin.h
  3. 2 2
      BansheeForwardRenderer/Include/BsForwardRendererFactory.h
  4. 1 1
      BansheeForwardRenderer/Source/BsForwardRendererFactory.cpp
  5. 3 3
      CamelotClient/BsGUITabbedTitleBar.cpp
  6. 1 1
      CamelotClient/CmTestTextSprite.cpp
  7. 1 1
      CamelotCore/Include/CmRenderSystemCapabilities.h
  8. 2 7
      CamelotCore/Include/CmRenderSystemFactory.h
  9. 1 1
      CamelotCore/Include/CmRendererFactory.h
  10. 1 1
      CamelotCore/Source/CmGpuProgram.cpp
  11. 2 2
      CamelotD3D11RenderSystem/Include/CmD3D11RenderSystemFactory.h
  12. 2 2
      CamelotD3D9Renderer/Include/CmD3D9RenderSystemFactory.h
  13. 1 1
      CamelotD3D9Renderer/Source/CmD3D9Driver.cpp
  14. 1 1
      CamelotFreeImgImporter/Source/CmFreeImgImporter.cpp
  15. 2 2
      CamelotGLRenderer/Include/CmGLRenderSystemFactory.h
  16. 1 1
      CamelotGLRenderer/Source/CmWin32GLSupport.cpp
  17. 4 12
      CamelotUtility/Include/CmDebug.h
  18. 9 9
      CamelotUtility/Include/CmException.h
  19. 2 2
      CamelotUtility/Include/CmFileSerializer.h
  20. 67 2
      CamelotUtility/Include/CmPath.h
  21. 2 2
      CamelotUtility/Include/CmRTTIField.h
  22. 1 1
      CamelotUtility/Include/CmRTTIManagedDataBlockField.h
  23. 2 2
      CamelotUtility/Include/CmRTTIPlainField.h
  24. 2 2
      CamelotUtility/Include/CmRTTIReflectableField.h
  25. 2 2
      CamelotUtility/Include/CmRTTIReflectablePtrField.h
  26. 38 38
      CamelotUtility/Include/CmRTTIType.h
  27. 323 69
      CamelotUtility/Include/CmString.h
  28. 4 4
      CamelotUtility/Source/CmDebug.cpp
  29. 1 1
      CamelotUtility/Source/CmException.cpp
  30. 2 2
      CamelotUtility/Source/CmFileSerializer.cpp
  31. 10 10
      CamelotUtility/Source/CmFileSystem.cpp
  32. 2 2
      CamelotUtility/Source/CmRTTIType.cpp
  33. 125 355
      CamelotUtility/Source/CmString.cpp
  34. 1 1
      CamelotUtility/Source/CmUUID.cpp
  35. 1 2
      CamelotUtility/Source/CmWorkQueue.cpp
  36. 2 0
      TODO.txt

+ 1 - 1
BansheeEngine/Include/BsGUILabel.h

@@ -14,7 +14,7 @@ namespace BansheeEngine
 		static GUILabel* create(GUIWidget& parent, const CM::WString& text, const GUIElementStyle* style = nullptr);
 		static GUILabel* create(GUIWidget& parent, const CM::WString& text, const GUIElementStyle* style = nullptr);
 		static GUILabel* create(GUIWidget& parent, const CM::WString& text, const GUILayoutOptions& layoutOptions, const GUIElementStyle* style = nullptr);
 		static GUILabel* create(GUIWidget& parent, const CM::WString& text, const GUILayoutOptions& layoutOptions, const GUIElementStyle* style = nullptr);
 
 
-		void setText(const CM::String& text);
+		void setText(const CM::WString& text);
 
 
 	protected:
 	protected:
 		~GUILabel();
 		~GUILabel();

+ 1 - 1
BansheeEngine/Include/BsGUISkin.h

@@ -14,6 +14,6 @@ namespace BansheeEngine
 	private:
 	private:
 		static GUIElementStyle DefaultStyle;
 		static GUIElementStyle DefaultStyle;
 
 
-		CM::unordered_map<std::string, GUIElementStyle>::type mStyles;
+		CM::unordered_map<CM::String, GUIElementStyle>::type mStyles;
 	};
 	};
 }
 }

+ 2 - 2
BansheeForwardRenderer/Include/BsForwardRendererFactory.h

@@ -5,12 +5,12 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	const std::string SystemName = "BansheeForwardRenderer";
+	const CM::String SystemName = "BansheeForwardRenderer";
 
 
 	class BS_FWDRND_EXPORT ForwardRendererFactory : public CM::RendererFactory
 	class BS_FWDRND_EXPORT ForwardRendererFactory : public CM::RendererFactory
 	{
 	{
 	public:
 	public:
 		virtual CM::RendererPtr create();
 		virtual CM::RendererPtr create();
-		virtual const std::string& name() const;
+		virtual const CM::String& name() const;
 	};
 	};
 }
 }

+ 1 - 1
BansheeForwardRenderer/Source/BsForwardRendererFactory.cpp

@@ -11,7 +11,7 @@ namespace BansheeEngine
 		return cm_shared_ptr<ForwardRenderer>();
 		return cm_shared_ptr<ForwardRenderer>();
 	}
 	}
 
 
-	const std::string& ForwardRendererFactory::name() const
+	const String& ForwardRendererFactory::name() const
 	{
 	{
 		return SystemName;
 		return SystemName;
 	}
 	}

+ 3 - 3
CamelotClient/BsGUITabbedTitleBar.cpp

@@ -30,7 +30,7 @@ namespace BansheeEditor
 
 
 	void TabbedTitleBar::insertTab(UINT32 idx, const CM::String& name)
 	void TabbedTitleBar::insertTab(UINT32 idx, const CM::String& name)
 	{
 	{
-		GUIToggle* newTabToggle = GUIToggle::create(*this, name, EngineGUI::instance().getSkin().getStyle("TabbedBarBtn"));
+		GUIToggle* newTabToggle = GUIToggle::create(*this, toWString(name), EngineGUI::instance().getSkin().getStyle("TabbedBarBtn"));
 		GUITexture* newDragDropElement = GUITexture::create(*this, GUIImageScaleMode::StretchToFit, EngineGUI::instance().getSkin().getStyle("TabbedBarDropArea"));
 		GUITexture* newDragDropElement = GUITexture::create(*this, GUIImageScaleMode::StretchToFit, EngineGUI::instance().getSkin().getStyle("TabbedBarDropArea"));
 
 
 		idx = Math::Clamp(idx, 0U, (UINT32)mTabButtons.size());
 		idx = Math::Clamp(idx, 0U, (UINT32)mTabButtons.size());
@@ -71,8 +71,8 @@ namespace BansheeEditor
 		GUITexture* dragDropElement = GUITexture::create(*this, GUILayoutOptions::expandableX(13, 20), GUIImageScaleMode::StretchToFit, getSkin()->getStyle("TabbedBarDropArea"));
 		GUITexture* dragDropElement = GUITexture::create(*this, GUILayoutOptions::expandableX(13, 20), GUIImageScaleMode::StretchToFit, getSkin()->getStyle("TabbedBarDropArea"));
 		mLastDropElement = dragDropElement;
 		mLastDropElement = dragDropElement;
 
 
-		mMinBtn = GUIButton::create(*this, "", getSkin()->getStyle("WinMinimizeBtn"));
-		mCloseBtn = GUIButton::create(*this, "", getSkin()->getStyle("WinCloseBtn"));
+		mMinBtn = GUIButton::create(*this, L"", getSkin()->getStyle("WinMinimizeBtn"));
+		mCloseBtn = GUIButton::create(*this, L"", getSkin()->getStyle("WinCloseBtn"));
 
 
 		GUIFixedSpace& space3 = mMainArea->getLayout().addSpace(1);
 		GUIFixedSpace& space3 = mMainArea->getLayout().addSpace(1);
 		mMainLayout = &mMainArea->getLayout().addLayoutX();
 		mMainLayout = &mMainArea->getLayout().addLayoutX();

+ 1 - 1
CamelotClient/CmTestTextSprite.cpp

@@ -29,7 +29,7 @@ namespace CamelotFramework
 	{
 	{
 		setSkin(&EngineGUI::instance().getSkin());
 		setSkin(&EngineGUI::instance().getSkin());
 
 
-		GUILabel::create(*this, text);
+		GUILabel::create(*this, toWString(text));
 	}
 	}
 
 
 	void TestTextSprite::update()
 	void TestTextSprite::update()

+ 1 - 1
CamelotCore/Include/CmRenderSystemCapabilities.h

@@ -191,7 +191,7 @@ namespace CamelotFramework
 
 
 		String toString() const 
 		String toString() const 
 		{
 		{
-			StringUtil::StrStreamType str;
+			StringStream str;
 			str << major << "." << minor << "." << release << "." << build;
 			str << major << "." << minor << "." << release << "." << build;
 			return str.str();
 			return str.str();
 		}
 		}

+ 2 - 7
CamelotCore/Include/CmRenderSystemFactory.h

@@ -1,21 +1,16 @@
 #pragma once
 #pragma once
 
 
-#include <string>
-#include <memory>
+#include "CmPrerequisites.h"
 
 
 namespace CamelotFramework
 namespace CamelotFramework
 {
 {
 	class RenderSystem;
 	class RenderSystem;
-}
-
-namespace CamelotFramework
-{
 	typedef std::shared_ptr<RenderSystem> RenderSystemPtr;
 	typedef std::shared_ptr<RenderSystem> RenderSystemPtr;
 
 
 	class RenderSystemFactory
 	class RenderSystemFactory
 	{
 	{
 	public:
 	public:
 		virtual void create() = 0;
 		virtual void create() = 0;
-		virtual const std::string& name() const = 0;
+		virtual const String& name() const = 0;
 	};
 	};
 }
 }

+ 1 - 1
CamelotCore/Include/CmRendererFactory.h

@@ -8,6 +8,6 @@ namespace CamelotFramework
 	{
 	{
 	public:
 	public:
 		virtual RendererPtr create() = 0;
 		virtual RendererPtr create() = 0;
-		virtual const std::string& name() const = 0;
+		virtual const String& name() const = 0;
 	};
 	};
 }
 }

+ 1 - 1
CamelotCore/Source/CmGpuProgram.cpp

@@ -53,7 +53,7 @@ namespace CamelotFramework
     {
     {
 		if(includes != nullptr)
 		if(includes != nullptr)
 		{
 		{
-			std::ostringstream stringStream;
+			StringStream stringStream;
 			for(auto iter = includes->begin(); iter != includes->end(); ++iter)
 			for(auto iter = includes->begin(); iter != includes->end(); ++iter)
 			{
 			{
 				if(*iter != nullptr)
 				if(*iter != nullptr)

+ 2 - 2
CamelotD3D11RenderSystem/Include/CmD3D11RenderSystemFactory.h

@@ -7,13 +7,13 @@
 
 
 namespace CamelotFramework
 namespace CamelotFramework
 {
 {
-	const std::string SystemName = "D3D11RenderSystem";
+	const String SystemName = "D3D11RenderSystem";
 
 
 	class D3D11RenderSystemFactory : public RenderSystemFactory
 	class D3D11RenderSystemFactory : public RenderSystemFactory
 	{
 	{
 	public:
 	public:
 		virtual void create();
 		virtual void create();
-		virtual const std::string& name() const { return SystemName; }
+		virtual const String& name() const { return SystemName; }
 
 
 	private:
 	private:
 		class InitOnStart
 		class InitOnStart

+ 2 - 2
CamelotD3D9Renderer/Include/CmD3D9RenderSystemFactory.h

@@ -7,13 +7,13 @@
 
 
 namespace CamelotFramework
 namespace CamelotFramework
 {
 {
-	const std::string SystemName = "D3D9RenderSystem";
+	const String SystemName = "D3D9RenderSystem";
 
 
 	class D3D9RenderSystemFactory : public RenderSystemFactory
 	class D3D9RenderSystemFactory : public RenderSystemFactory
 	{
 	{
 		public:
 		public:
 			virtual void create();
 			virtual void create();
-			virtual const std::string& name() const { return SystemName; }
+			virtual const String& name() const { return SystemName; }
 
 
 		private:
 		private:
 			class InitOnStart
 			class InitOnStart

+ 1 - 1
CamelotD3D9Renderer/Source/CmD3D9Driver.cpp

@@ -74,7 +74,7 @@ namespace CamelotFramework
 
 
 	String D3D9Driver::DriverDescription() const
 	String D3D9Driver::DriverDescription() const
 	{       
 	{       
-		StringUtil::StrStreamType str;
+		StringStream str;
 		str << "Monitor-" << (mAdapterNumber+1) << "-" << mAdapterIdentifier.Description;
 		str << "Monitor-" << (mAdapterNumber+1) << "-" << mAdapterIdentifier.Description;
 		String driverDescription(str.str());
 		String driverDescription(str.str());
 		StringUtil::trim(driverDescription);
 		StringUtil::trim(driverDescription);

+ 1 - 1
CamelotFreeImgImporter/Source/CmFreeImgImporter.cpp

@@ -34,7 +34,7 @@ namespace CamelotFramework
 		FreeImage_Initialise(false);
 		FreeImage_Initialise(false);
 
 
 		// Register codecs
 		// Register codecs
-		StringUtil::StrStreamType strExt;
+		StringStream strExt;
 		strExt << "Supported formats: ";
 		strExt << "Supported formats: ";
 		bool first = true;
 		bool first = true;
 		for (int i = 0; i < FreeImage_GetFIFCount(); ++i)
 		for (int i = 0; i < FreeImage_GetFIFCount(); ++i)

+ 2 - 2
CamelotGLRenderer/Include/CmGLRenderSystemFactory.h

@@ -7,13 +7,13 @@
 
 
 namespace CamelotFramework
 namespace CamelotFramework
 {
 {
-	const std::string SystemName = "GLRenderSystem";
+	const String SystemName = "GLRenderSystem";
 
 
 	class GLRenderSystemFactory : public RenderSystemFactory
 	class GLRenderSystemFactory : public RenderSystemFactory
 	{
 	{
 	public:
 	public:
 		virtual void create();
 		virtual void create();
-		virtual const std::string& name() const { return SystemName; }
+		virtual const String& name() const { return SystemName; }
 
 
 	private:
 	private:
 		class InitOnStart
 		class InitOnStart

+ 1 - 1
CamelotGLRenderer/Source/CmWin32GLSupport.cpp

@@ -225,7 +225,7 @@ namespace CamelotFramework
 			if (_wglGetExtensionsStringARB)
 			if (_wglGetExtensionsStringARB)
 			{
 			{
 				std::istringstream wglexts(_wglGetExtensionsStringARB(hdc));
 				std::istringstream wglexts(_wglGetExtensionsStringARB(hdc));
-				std::string ext;
+				String ext;
 				while (wglexts >> ext)
 				while (wglexts >> ext)
 				{
 				{
 					if (ext == "WGL_ARB_pixel_format")
 					if (ext == "WGL_ARB_pixel_format")

+ 4 - 12
CamelotUtility/Include/CmDebug.h

@@ -10,10 +10,10 @@ namespace CamelotFramework
 	class CM_UTILITY_EXPORT Debug
 	class CM_UTILITY_EXPORT Debug
 	{
 	{
 	public:
 	public:
-		void logDebug(std::string msg);
-		void logInfo(std::string msg);
-		void logWarning(std::string msg);
-		void logError(std::string msg);
+		void logDebug(const String& msg);
+		void logInfo(const String& msg);
+		void logWarning(const String& msg);
+		void logError(const String& msg);
 		void log(const String& msg, const String& channel);
 		void log(const String& msg, const String& channel);
 
 
 		Log& getLog() { return mLog; }
 		Log& getLog() { return mLog; }
@@ -26,14 +26,6 @@ namespace CamelotFramework
 
 
 	CM_UTILITY_EXPORT Debug& gDebug();
 	CM_UTILITY_EXPORT Debug& gDebug();
 
 
-	template <typename T>
-	std::string toStr(T number)
-	{
-		std::ostringstream ss;
-		ss << number;
-		return ss.str();
-	}
-
 #define LOGDBG(x) CamelotFramework::gDebug().logDebug((x));
 #define LOGDBG(x) CamelotFramework::gDebug().logDebug((x));
 #define LOGINFO(x) CamelotFramework::gDebug().logInfo((x));
 #define LOGINFO(x) CamelotFramework::gDebug().logInfo((x));
 #define LOGWRN(x) CamelotFramework::gDebug().logWarning((x));
 #define LOGWRN(x) CamelotFramework::gDebug().logWarning((x));

+ 9 - 9
CamelotUtility/Include/CmException.h

@@ -78,55 +78,55 @@ namespace CamelotFramework
 	class CM_UTILITY_EXPORT NotImplementedException : public Exception 
 	class CM_UTILITY_EXPORT NotImplementedException : public Exception 
 	{
 	{
 	public:
 	public:
-		NotImplementedException(const std::string& inDescription, const std::string& inSource, const char* inFile, long inLine)
+		NotImplementedException(const String& inDescription, const String& inSource, const char* inFile, long inLine)
 			: Exception("NotImplementedException", inDescription, inSource, inFile, inLine) {}
 			: Exception("NotImplementedException", inDescription, inSource, inFile, inLine) {}
 	};
 	};
 	class CM_UTILITY_EXPORT FileNotFoundException : public Exception
 	class CM_UTILITY_EXPORT FileNotFoundException : public Exception
 	{
 	{
 	public:
 	public:
-		FileNotFoundException(const std::string& inDescription, const std::string& inSource, const char* inFile, long inLine)
+		FileNotFoundException(const String& inDescription, const String& inSource, const char* inFile, long inLine)
 			: Exception("FileNotFoundException", inDescription, inSource, inFile, inLine) {}
 			: Exception("FileNotFoundException", inDescription, inSource, inFile, inLine) {}
 	};
 	};
 	class CM_UTILITY_EXPORT IOException : public Exception
 	class CM_UTILITY_EXPORT IOException : public Exception
 	{
 	{
 	public:
 	public:
-		IOException(const std::string& inDescription, const std::string& inSource, const char* inFile, long inLine)
+		IOException(const String& inDescription, const String& inSource, const char* inFile, long inLine)
 			: Exception("IOException", inDescription, inSource, inFile, inLine) {}
 			: Exception("IOException", inDescription, inSource, inFile, inLine) {}
 	};
 	};
 	class CM_UTILITY_EXPORT InvalidStateException : public Exception
 	class CM_UTILITY_EXPORT InvalidStateException : public Exception
 	{
 	{
 	public:
 	public:
-		InvalidStateException(const std::string& inDescription, const std::string& inSource, const char* inFile, long inLine)
+		InvalidStateException(const String& inDescription, const String& inSource, const char* inFile, long inLine)
 			: Exception("InvalidStateException", inDescription, inSource, inFile, inLine) {}
 			: Exception("InvalidStateException", inDescription, inSource, inFile, inLine) {}
 	};
 	};
 	class CM_UTILITY_EXPORT InvalidParametersException : public Exception
 	class CM_UTILITY_EXPORT InvalidParametersException : public Exception
 	{
 	{
 	public:
 	public:
-		InvalidParametersException(const std::string& inDescription, const std::string& inSource, const char* inFile, long inLine)
+		InvalidParametersException(const String& inDescription, const String& inSource, const char* inFile, long inLine)
 			: Exception("InvalidParametersException", inDescription, inSource, inFile, inLine) {}
 			: Exception("InvalidParametersException", inDescription, inSource, inFile, inLine) {}
 	};
 	};
 	class CM_UTILITY_EXPORT ItemIdentityException : public Exception
 	class CM_UTILITY_EXPORT ItemIdentityException : public Exception
 	{
 	{
 	public:
 	public:
-		ItemIdentityException(const std::string& inDescription, const std::string& inSource, const char* inFile, long inLine)
+		ItemIdentityException(const String& inDescription, const String& inSource, const char* inFile, long inLine)
 			: Exception("ItemIdentityException", inDescription, inSource, inFile, inLine) {}
 			: Exception("ItemIdentityException", inDescription, inSource, inFile, inLine) {}
 	};
 	};
 	class CM_UTILITY_EXPORT InternalErrorException : public Exception
 	class CM_UTILITY_EXPORT InternalErrorException : public Exception
 	{
 	{
 	public:
 	public:
-		InternalErrorException(const std::string& inDescription, const std::string& inSource, const char* inFile, long inLine)
+		InternalErrorException(const String& inDescription, const String& inSource, const char* inFile, long inLine)
 			: Exception("InternalErrorException", inDescription, inSource, inFile, inLine) {}
 			: Exception("InternalErrorException", inDescription, inSource, inFile, inLine) {}
 	};
 	};
 	class CM_UTILITY_EXPORT RenderingAPIException : public Exception
 	class CM_UTILITY_EXPORT RenderingAPIException : public Exception
 	{
 	{
 	public:
 	public:
-		RenderingAPIException(const std::string& inDescription, const std::string& inSource, const char* inFile, long inLine)
+		RenderingAPIException(const String& inDescription, const String& inSource, const char* inFile, long inLine)
 			: Exception("RenderingAPIException", inDescription, inSource, inFile, inLine) {}
 			: Exception("RenderingAPIException", inDescription, inSource, inFile, inLine) {}
 	};
 	};
 	class CM_UTILITY_EXPORT RuntimeAssertionException : public Exception
 	class CM_UTILITY_EXPORT RuntimeAssertionException : public Exception
 	{
 	{
 	public:
 	public:
-		RuntimeAssertionException(const std::string& inDescription, const std::string& inSource, const char* inFile, long inLine)
+		RuntimeAssertionException(const String& inDescription, const String& inSource, const char* inFile, long inLine)
 			: Exception("RuntimeAssertionException", inDescription, inSource, inFile, inLine) {}
 			: Exception("RuntimeAssertionException", inDescription, inSource, inFile, inLine) {}
 	};
 	};
 
 

+ 2 - 2
CamelotUtility/Include/CmFileSerializer.h

@@ -12,8 +12,8 @@ namespace CamelotFramework
 		FileSerializer();
 		FileSerializer();
 		~FileSerializer();
 		~FileSerializer();
 
 
-		void encode(IReflectable* object, std::string fileLocation);
-		std::shared_ptr<IReflectable> decode(std::string fileLocation);
+		void encode(IReflectable* object, String fileLocation);
+		std::shared_ptr<IReflectable> decode(String fileLocation);
 
 
 	private:
 	private:
 		std::ofstream mOutputStream;
 		std::ofstream mOutputStream;

+ 67 - 2
CamelotUtility/Include/CmPath.h

@@ -6,14 +6,14 @@
 namespace CamelotFramework
 namespace CamelotFramework
 {
 {
 	/**
 	/**
-	 * @brief	Various utility methods for handling file paths.
+	 * @brief	Various string manipulations of file paths.
 	 */
 	 */
 	class Path
 	class Path
 	{
 	{
 	public:
 	public:
 		static String getExtension(const String& path)
 		static String getExtension(const String& path)
 		{
 		{
-			return boost::filesystem::extension(path);
+			return boost::filesystem::extension(boost::filesystem::path(path.c_str())).c_str();
 		}
 		}
 
 
 		static bool hasExtension(const String& path, const String& extension)
 		static bool hasExtension(const String& path, const String& extension)
@@ -28,5 +28,70 @@ namespace CamelotFramework
 			else
 			else
 				return base + '/' + name;
 				return base + '/' + name;
 		}
 		}
+
+		/**
+		 * @brief	Method for standardizing paths - use forward slashes only, end with slash.
+		 */
+		String standardisePath(const String& inPath)
+		{
+			String path = inPath;
+
+			std::replace(path.begin(), path.end(), '\\', '/');
+			if(path[path.length() - 1] != '/')
+				path += '/';
+
+			return path;
+		}
+
+		/**
+		 * @brief	Method for splitting a fully qualified filename into the base name and path.
+		 */
+		void splitFilename(const String& qualifiedName, String& outBasename, String& outPath)
+		{
+			String path = qualifiedName;
+			// Replace \ with / first
+			std::replace( path.begin(), path.end(), '\\', '/' );
+			// split based on final /
+			size_t i = path.find_last_of('/');
+
+			if (i == String::npos)
+			{
+				outPath.clear();
+				outBasename = qualifiedName;
+			}
+			else
+			{
+				outBasename = path.substr(i+1, path.size() - i - 1);
+				outPath = path.substr(0, i+1);
+			}
+		}
+
+		/**
+		 * @brief	Method for splitting a filename into the base name and extension.
+		 */
+		void splitBaseFilename(const String& fullName, String& outBasename, String& outExtension)
+		{
+			size_t i = fullName.find_last_of(".");
+			if (i == CamelotFramework::String::npos)
+			{
+				outExtension.clear();
+				outBasename = fullName;
+			}
+			else
+			{
+				outExtension = fullName.substr(i+1);
+				outBasename = fullName.substr(0, i);
+			}
+		}
+
+		/**
+		 * @brief	Method for splitting a fully qualified filename into the base name, extension and path.
+		 */
+		void splitFullFilename(const String& qualifiedName, String& outBasename, String& outExtention, String& outPath)
+		{
+			String fullName;
+			splitFilename(qualifiedName, fullName, outPath);
+			splitBaseFilename(fullName, outBasename, outExtention);
+		}
 	};
 	};
 }
 }

+ 2 - 2
CamelotUtility/Include/CmRTTIField.h

@@ -67,7 +67,7 @@ namespace CamelotFramework
 		boost::any arraySizeGetter;
 		boost::any arraySizeGetter;
 		boost::any arraySizeSetter;
 		boost::any arraySizeSetter;
 
 
-		std::string mName;
+		String mName;
 		UINT16 mUniqueId;
 		UINT16 mUniqueId;
 		bool mIsVectorType;
 		bool mIsVectorType;
 		SerializableFieldType mType;
 		SerializableFieldType mType;
@@ -122,7 +122,7 @@ namespace CamelotFramework
 
 
 	protected:
 	protected:
 		void initAll(boost::any valueGetter, boost::any valueSetter, boost::any arraySizeGetter, boost::any arraySizeSetter,
 		void initAll(boost::any valueGetter, boost::any valueSetter, boost::any arraySizeGetter, boost::any arraySizeSetter,
-			std::string mName, UINT16 mUniqueId, bool mIsVectorType, SerializableFieldType type, UINT64 flags)
+			String mName, UINT16 mUniqueId, bool mIsVectorType, SerializableFieldType type, UINT64 flags)
 		{
 		{
 			this->valueGetter = valueGetter;
 			this->valueGetter = valueGetter;
 			this->valueSetter = valueSetter;
 			this->valueSetter = valueSetter;

+ 1 - 1
CamelotUtility/Include/CmRTTIManagedDataBlockField.h

@@ -32,7 +32,7 @@ namespace CamelotFramework
 		 * @param	flags		Various flags you can use to specialize how systems handle this field
 		 * @param	flags		Various flags you can use to specialize how systems handle this field
 		 * @param	customAllocator (optional) Custom allocator that will be used when de-serializing DataBlock memory.
 		 * @param	customAllocator (optional) Custom allocator that will be used when de-serializing DataBlock memory.
 		 */
 		 */
-		void initSingle(const std::string& name, UINT16 uniqueId, boost::any getter, boost::any setter, UINT64 flags, boost::any customAllocator = boost::any())
+		void initSingle(const String& name, UINT16 uniqueId, boost::any getter, boost::any setter, UINT64 flags, boost::any customAllocator = boost::any())
 		{
 		{
 			initAll(getter, setter, nullptr, nullptr, name, uniqueId, false, SerializableFT_DataBlock, flags);
 			initAll(getter, setter, nullptr, nullptr, name, uniqueId, false, SerializableFT_DataBlock, flags);
 			mCustomAllocator = customAllocator;
 			mCustomAllocator = customAllocator;

+ 2 - 2
CamelotUtility/Include/CmRTTIPlainField.h

@@ -150,7 +150,7 @@ namespace CamelotFramework
 		 * @param	setter  	The setter method for the field. Can be null. Must be a specific signature: void(ObjectType*, DataType)
 		 * @param	setter  	The setter method for the field. Can be null. Must be a specific signature: void(ObjectType*, DataType)
 		 * @param	flags		Various flags you can use to specialize how systems handle this field
 		 * @param	flags		Various flags you can use to specialize how systems handle this field
 		 */
 		 */
-		void initSingle(const std::string& name, UINT16 uniqueId, boost::any getter, boost::any setter, UINT64 flags)
+		void initSingle(const String& name, UINT16 uniqueId, boost::any getter, boost::any setter, UINT64 flags)
 		{
 		{
 			int typeId = RTTIPlainType<DataType>::id; // Just making sure provided type has a type ID
 			int typeId = RTTIPlainType<DataType>::id; // Just making sure provided type has a type ID
 
 
@@ -176,7 +176,7 @@ namespace CamelotFramework
 		 * @param	setSize 	Setter method that allows you to resize an array. Can be null. Must be a specific signature: void(ObjectType*, UINT32)
 		 * @param	setSize 	Setter method that allows you to resize an array. Can be null. Must be a specific signature: void(ObjectType*, UINT32)
 		 * @param	flags		Various flags you can use to specialize how systems handle this field
 		 * @param	flags		Various flags you can use to specialize how systems handle this field
 		 */
 		 */
-		void initArray(const std::string& name, UINT16 uniqueId, boost::any getter, 
+		void initArray(const String& name, UINT16 uniqueId, boost::any getter, 
 			boost::any getSize, boost::any setter, boost::any setSize, UINT64 flags)
 			boost::any getSize, boost::any setter, boost::any setSize, UINT64 flags)
 		{
 		{
 			int typeId = RTTIPlainType<DataType>::id; // Just making sure provided type has a type ID
 			int typeId = RTTIPlainType<DataType>::id; // Just making sure provided type has a type ID

+ 2 - 2
CamelotUtility/Include/CmRTTIReflectableField.h

@@ -34,7 +34,7 @@ namespace CamelotFramework
 		 * @param	setter  	The setter method for the field. Can be null. Must be a specific signature: void(ObjectType*, DataType)
 		 * @param	setter  	The setter method for the field. Can be null. Must be a specific signature: void(ObjectType*, DataType)
 		 * @param	flags		Various flags you can use to specialize how systems handle this field
 		 * @param	flags		Various flags you can use to specialize how systems handle this field
 		 */
 		 */
-		void initSingle(const std::string& name, UINT16 uniqueId, boost::any getter, boost::any setter, UINT64 flags)
+		void initSingle(const String& name, UINT16 uniqueId, boost::any getter, boost::any setter, UINT64 flags)
 		{
 		{
 			initAll(getter, setter, nullptr, nullptr, name, uniqueId, false, SerializableFT_Reflectable, flags);
 			initAll(getter, setter, nullptr, nullptr, name, uniqueId, false, SerializableFT_Reflectable, flags);
 		}
 		}
@@ -53,7 +53,7 @@ namespace CamelotFramework
 		 * @param	setSize 	Setter method that allows you to resize an array. Can be null. Can be null. Must be a specific signature: void(ObjectType*, UINT32)
 		 * @param	setSize 	Setter method that allows you to resize an array. Can be null. Can be null. Must be a specific signature: void(ObjectType*, UINT32)
 		 * @param	flags		Various flags you can use to specialize how systems handle this field
 		 * @param	flags		Various flags you can use to specialize how systems handle this field
 		 */
 		 */
-		void initArray(const std::string& name, UINT16 uniqueId, boost::any getter, 
+		void initArray(const String& name, UINT16 uniqueId, boost::any getter, 
 			boost::any getSize, boost::any setter, boost::any setSize, UINT64 flags)
 			boost::any getSize, boost::any setter, boost::any setSize, UINT64 flags)
 		{
 		{
 			initAll(getter, setter, getSize, setSize, name, uniqueId, true, SerializableFT_Reflectable, flags);
 			initAll(getter, setter, getSize, setSize, name, uniqueId, true, SerializableFT_Reflectable, flags);

+ 2 - 2
CamelotUtility/Include/CmRTTIReflectablePtrField.h

@@ -36,7 +36,7 @@ namespace CamelotFramework
 		 * @param	setter  	The setter method for the field. Can be null. Must be a specific signature: void(ObjectType*, DataType*)
 		 * @param	setter  	The setter method for the field. Can be null. Must be a specific signature: void(ObjectType*, DataType*)
 		 * @param	flags		Various flags you can use to specialize how systems handle this field
 		 * @param	flags		Various flags you can use to specialize how systems handle this field
 		 */
 		 */
-		void initSingle(const std::string& name, UINT16 uniqueId, boost::any getter, boost::any setter, UINT64 flags)
+		void initSingle(const String& name, UINT16 uniqueId, boost::any getter, boost::any setter, UINT64 flags)
 		{
 		{
 			initAll(getter, setter, nullptr, nullptr, name, uniqueId, false, SerializableFT_ReflectablePtr, flags);
 			initAll(getter, setter, nullptr, nullptr, name, uniqueId, false, SerializableFT_ReflectablePtr, flags);
 		}
 		}
@@ -55,7 +55,7 @@ namespace CamelotFramework
 		 * @param	setSize 	Setter method that allows you to resize an array. Can be null. Can be null. Must be a specific signature: void(ObjectType*, UINT32)
 		 * @param	setSize 	Setter method that allows you to resize an array. Can be null. Can be null. Must be a specific signature: void(ObjectType*, UINT32)
 		 * @param	flags		Various flags you can use to specialize how systems handle this field
 		 * @param	flags		Various flags you can use to specialize how systems handle this field
 		 */
 		 */
-		void initArray(const std::string& name, UINT16 uniqueId, boost::any getter, 
+		void initArray(const String& name, UINT16 uniqueId, boost::any getter, 
 			boost::any getSize, boost::any setter, boost::any setSize, UINT64 flags)
 			boost::any getSize, boost::any setter, boost::any setSize, UINT64 flags)
 		{
 		{
 			initAll(getter, setter, getSize, setSize, name, uniqueId, true, SerializableFT_ReflectablePtr, flags);
 			initAll(getter, setter, getSize, setSize, name, uniqueId, true, SerializableFT_ReflectablePtr, flags);

+ 38 - 38
CamelotUtility/Include/CmRTTIType.h

@@ -58,7 +58,7 @@ namespace CamelotFramework
 		virtual void onDeserializationEnded(IReflectable* obj) {}
 		virtual void onDeserializationEnded(IReflectable* obj) {}
 
 
 		template <class ObjectType, class DataType>
 		template <class ObjectType, class DataType>
-		void setPlainValue(ObjectType* object, const std::string& name, DataType& value)
+		void setPlainValue(ObjectType* object, const String& name, DataType& value)
 		{
 		{
 			RTTIField* genericField = findField(name);
 			RTTIField* genericField = findField(name);
 			genericField->checkIsPlain(false);
 			genericField->checkIsPlain(false);
@@ -68,7 +68,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template <class ObjectType, class DataType>
 		template <class ObjectType, class DataType>
-		void setPlainArrayValue(ObjectType* object, const std::string& name, UINT32 index, DataType& value)
+		void setPlainArrayValue(ObjectType* object, const String& name, UINT32 index, DataType& value)
 		{
 		{
 			RTTIField* genericField = findField(name);
 			RTTIField* genericField = findField(name);
 			genericField->checkIsPlain(true);
 			genericField->checkIsPlain(true);
@@ -78,7 +78,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template <class ObjectType, class DataType>
 		template <class ObjectType, class DataType>
-		void setReflectableValue(ObjectType* object, const std::string& name, DataType& value)
+		void setReflectableValue(ObjectType* object, const String& name, DataType& value)
 		{
 		{
 			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::IReflectable, DataType>::value), 
 			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::IReflectable, DataType>::value), 
 				"Invalid data type for complex field. It needs to derive from CamelotFramework::IReflectable.");
 				"Invalid data type for complex field. It needs to derive from CamelotFramework::IReflectable.");
@@ -91,7 +91,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template <class ObjectType, class DataType>
 		template <class ObjectType, class DataType>
-		void setReflectableArrayValue(ObjectType* object, const std::string& name, UINT32 index, DataType& value)
+		void setReflectableArrayValue(ObjectType* object, const String& name, UINT32 index, DataType& value)
 		{
 		{
 			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::IReflectable, DataType>::value), 
 			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::IReflectable, DataType>::value), 
 				"Invalid data type for complex field. It needs to derive from CamelotFramework::IReflectable.");
 				"Invalid data type for complex field. It needs to derive from CamelotFramework::IReflectable.");
@@ -104,7 +104,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template <class ObjectType>
 		template <class ObjectType>
-		void setDataBlockValue(ObjectType* object, const std::string& name, ManagedDataBlock value)
+		void setDataBlockValue(ObjectType* object, const String& name, ManagedDataBlock value)
 		{
 		{
 			RTTIField* genericField = findField(name);
 			RTTIField* genericField = findField(name);
 			genericField->checkIsDataBlock();
 			genericField->checkIsDataBlock();
@@ -115,7 +115,7 @@ namespace CamelotFramework
 
 
 
 
 		template <class ObjectType, class DataType>
 		template <class ObjectType, class DataType>
-		void setReflectablePtrValue(ObjectType* object, const std::string& name, std::shared_ptr<DataType> value)
+		void setReflectablePtrValue(ObjectType* object, const String& name, std::shared_ptr<DataType> value)
 		{
 		{
 			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::IReflectable, DataType>::value), 
 			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::IReflectable, DataType>::value), 
 				"Invalid data type for complex field. It needs to derive from CamelotFramework::IReflectable.");
 				"Invalid data type for complex field. It needs to derive from CamelotFramework::IReflectable.");
@@ -128,7 +128,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template <class ObjectType, class DataType>
 		template <class ObjectType, class DataType>
-		void setReflectablePtrArrayValue(ObjectType* object, const std::string& name, UINT32 index, std::shared_ptr<DataType> value)
+		void setReflectablePtrArrayValue(ObjectType* object, const String& name, UINT32 index, std::shared_ptr<DataType> value)
 		{
 		{
 			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::IReflectable, DataType>::value), 
 			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::IReflectable, DataType>::value), 
 				"Invalid data type for complex field. It needs to derive from CamelotFramework::IReflectable.");
 				"Invalid data type for complex field. It needs to derive from CamelotFramework::IReflectable.");
@@ -141,7 +141,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template <class ObjectType, class DataType>
 		template <class ObjectType, class DataType>
-		void getPlainValue(ObjectType* object, const std::string& name, DataType& value)
+		void getPlainValue(ObjectType* object, const String& name, DataType& value)
 		{
 		{
 			RTTIField* genericField = findField(name);
 			RTTIField* genericField = findField(name);
 			genericField->checkIsPlain(false);
 			genericField->checkIsPlain(false);
@@ -151,7 +151,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template <class ObjectType, class DataType>
 		template <class ObjectType, class DataType>
-		void getPlainArrayValue(ObjectType* object, const std::string& name, UINT32 index, DataType& value)
+		void getPlainArrayValue(ObjectType* object, const String& name, UINT32 index, DataType& value)
 		{
 		{
 			RTTIField* genericField = findField(name);
 			RTTIField* genericField = findField(name);
 			genericField->checkIsPlain(true);
 			genericField->checkIsPlain(true);
@@ -161,7 +161,7 @@ namespace CamelotFramework
 		}	
 		}	
 
 
 		template <class ObjectType>
 		template <class ObjectType>
-		IReflectable& getReflectableValue(ObjectType* object, const std::string& name)
+		IReflectable& getReflectableValue(ObjectType* object, const String& name)
 		{
 		{
 			RTTIField* genericField = findField(name);
 			RTTIField* genericField = findField(name);
 			genericField->checkIsComplex(false);
 			genericField->checkIsComplex(false);
@@ -171,7 +171,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template <class ObjectType>
 		template <class ObjectType>
-		IReflectable& getReflectableArrayValue(ObjectType* object, const std::string& name, UINT32 index)
+		IReflectable& getReflectableArrayValue(ObjectType* object, const String& name, UINT32 index)
 		{
 		{
 			RTTIField* genericField = findField(name);
 			RTTIField* genericField = findField(name);
 			genericField->checkIsComplex(true);
 			genericField->checkIsComplex(true);
@@ -181,7 +181,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template <class ObjectType>
 		template <class ObjectType>
-		ManagedDataBlock getDataBlockValue(ObjectType* object, const std::string& name)
+		ManagedDataBlock getDataBlockValue(ObjectType* object, const String& name)
 		{
 		{
 			RTTIField* genericField = findField(name);
 			RTTIField* genericField = findField(name);
 			genericField->checkIsDataBlock();
 			genericField->checkIsDataBlock();
@@ -191,7 +191,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template <class ObjectType>
 		template <class ObjectType>
-		std::shared_ptr<IReflectable> getReflectablePtrValue(ObjectType* object, const std::string& name)
+		std::shared_ptr<IReflectable> getReflectablePtrValue(ObjectType* object, const String& name)
 		{
 		{
 			RTTIField* genericField = findField(name);
 			RTTIField* genericField = findField(name);
 			genericField->checkIsComplexPtr(false);
 			genericField->checkIsComplexPtr(false);
@@ -201,7 +201,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template <class ObjectType>
 		template <class ObjectType>
-		std::shared_ptr<IReflectable> getReflectablePtrArrayValue(ObjectType* object, const std::string& name, UINT32 index)
+		std::shared_ptr<IReflectable> getReflectablePtrArrayValue(ObjectType* object, const String& name, UINT32 index)
 		{
 		{
 			RTTIField* genericField = findField(name);
 			RTTIField* genericField = findField(name);
 			genericField->checkIsComplexPtr(true);
 			genericField->checkIsComplexPtr(true);
@@ -211,14 +211,14 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template <class ObjectType>
 		template <class ObjectType>
-		UINT32 getArraySize(ObjectType* object, const std::string& name)
+		UINT32 getArraySize(ObjectType* object, const String& name)
 		{
 		{
 			RTTIField* field = findField(name);
 			RTTIField* field = findField(name);
 			return field->getArraySize(object);
 			return field->getArraySize(object);
 		}
 		}
 
 
 		template <class ObjectType>
 		template <class ObjectType>
-		void setArraySize(ObjectType* object, const std::string& name, UINT32 size)
+		void setArraySize(ObjectType* object, const String& name, UINT32 size)
 		{
 		{
 			RTTIField* field = findField(name);
 			RTTIField* field = findField(name);
 			field->setArraySize(object, size);
 			field->setArraySize(object, size);
@@ -232,7 +232,7 @@ namespace CamelotFramework
 		 *
 		 *
 		 * @param	name	The name of the field.
 		 * @param	name	The name of the field.
 		 */
 		 */
-		RTTIField* findField(const std::string& name);
+		RTTIField* findField(const String& name);
 
 
 		/**
 		/**
 		 * @brief	Tries to find a field with the specified unique ID. Doesn't throw an exception
 		 * @brief	Tries to find a field with the specified unique ID. Doesn't throw an exception
@@ -397,7 +397,7 @@ namespace CamelotFramework
 		/* 			FIELDS OPERATING DIRECTLY ON SERIALIZABLE OBJECT            */
 		/* 			FIELDS OPERATING DIRECTLY ON SERIALIZABLE OBJECT            */
 		/************************************************************************/
 		/************************************************************************/
 		template<class ObjectType, class DataType>
 		template<class ObjectType, class DataType>
-		void addPlainField(const std::string& name, UINT32 uniqueId, DataType& (ObjectType::*getter)(), 
+		void addPlainField(const String& name, UINT32 uniqueId, DataType& (ObjectType::*getter)(), 
 			void (ObjectType::*setter)(DataType&) = nullptr, UINT64 flags = 0)
 			void (ObjectType::*setter)(DataType&) = nullptr, UINT64 flags = 0)
 		{
 		{
 			addPlainField<ObjectType, DataType>(name, uniqueId, 
 			addPlainField<ObjectType, DataType>(name, uniqueId, 
@@ -406,7 +406,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template<class ObjectType, class DataType>
 		template<class ObjectType, class DataType>
-		void addReflectableField(const std::string& name, UINT32 uniqueId, DataType& (ObjectType::*getter)(), 
+		void addReflectableField(const String& name, UINT32 uniqueId, DataType& (ObjectType::*getter)(), 
 			void (ObjectType::*setter)(DataType&) = nullptr, UINT64 flags = 0)
 			void (ObjectType::*setter)(DataType&) = nullptr, UINT64 flags = 0)
 		{
 		{
 			addReflectableField<ObjectType, DataType>(name, uniqueId, 
 			addReflectableField<ObjectType, DataType>(name, uniqueId, 
@@ -415,7 +415,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template<class ObjectType, class DataType>
 		template<class ObjectType, class DataType>
-		void addReflectablePtrField(const std::string& name, UINT32 uniqueId, std::shared_ptr<DataType> (ObjectType::*getter)(), 
+		void addReflectablePtrField(const String& name, UINT32 uniqueId, std::shared_ptr<DataType> (ObjectType::*getter)(), 
 			void (ObjectType::*setter)(std::shared_ptr<DataType>) = nullptr, UINT64 flags = 0)
 			void (ObjectType::*setter)(std::shared_ptr<DataType>) = nullptr, UINT64 flags = 0)
 		{
 		{
 			addReflectablePtrField<ObjectType, DataType>(name, uniqueId, 
 			addReflectablePtrField<ObjectType, DataType>(name, uniqueId, 
@@ -424,7 +424,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template<class ObjectType, class DataType>
 		template<class ObjectType, class DataType>
-		void addPlainArrayField(const std::string& name, UINT32 uniqueId, DataType& (ObjectType::*getter)(UINT32), UINT32 (ObjectType::*getSize)(), 
+		void addPlainArrayField(const String& name, UINT32 uniqueId, DataType& (ObjectType::*getter)(UINT32), UINT32 (ObjectType::*getSize)(), 
 			void (ObjectType::*setter)(UINT32, DataType&) = nullptr, void(ObjectType::*setSize)(UINT32) = nullptr, UINT64 flags = 0)
 			void (ObjectType::*setter)(UINT32, DataType&) = nullptr, void(ObjectType::*setSize)(UINT32) = nullptr, UINT64 flags = 0)
 		{
 		{
 			addPlainArrayField<ObjectType, DataType>(name, uniqueId, 
 			addPlainArrayField<ObjectType, DataType>(name, uniqueId, 
@@ -435,7 +435,7 @@ namespace CamelotFramework
 		}	
 		}	
 
 
 		template<class ObjectType, class DataType>
 		template<class ObjectType, class DataType>
-		void addReflectableArrayField(const std::string& name, UINT32 uniqueId, DataType& (ObjectType::*getter)(UINT32), UINT32 (ObjectType::*getSize)(), 
+		void addReflectableArrayField(const String& name, UINT32 uniqueId, DataType& (ObjectType::*getter)(UINT32), UINT32 (ObjectType::*getSize)(), 
 			void (ObjectType::*setter)(UINT32, DataType&) = nullptr, void(ObjectType::*setSize)(UINT32) = nullptr, UINT64 flags = 0)
 			void (ObjectType::*setter)(UINT32, DataType&) = nullptr, void(ObjectType::*setSize)(UINT32) = nullptr, UINT64 flags = 0)
 		{
 		{
 			addReflectableArrayField<ObjectType, DataType>(name, uniqueId, 
 			addReflectableArrayField<ObjectType, DataType>(name, uniqueId, 
@@ -446,7 +446,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template<class ObjectType, class DataType>
 		template<class ObjectType, class DataType>
-		void addReflectablePtrArrayField(const std::string& name, UINT32 uniqueId, std::shared_ptr<DataType> (ObjectType::*getter)(UINT32), UINT32 (ObjectType::*getSize)(), 
+		void addReflectablePtrArrayField(const String& name, UINT32 uniqueId, std::shared_ptr<DataType> (ObjectType::*getter)(UINT32), UINT32 (ObjectType::*getSize)(), 
 			void (ObjectType::*setter)(UINT32, std::shared_ptr<DataType>) = nullptr, void(ObjectType::*setSize)(UINT32) = nullptr, UINT64 flags = 0)
 			void (ObjectType::*setter)(UINT32, std::shared_ptr<DataType>) = nullptr, void(ObjectType::*setSize)(UINT32) = nullptr, UINT64 flags = 0)
 		{
 		{
 			addReflectablePtrArrayField<ObjectType, DataType>(name, uniqueId, 
 			addReflectablePtrArrayField<ObjectType, DataType>(name, uniqueId, 
@@ -457,7 +457,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template<class ObjectType>
 		template<class ObjectType>
-		void addDataBlockField(const std::string& name, UINT32 uniqueId, ManagedDataBlock (ObjectType::*getter)(), 
+		void addDataBlockField(const String& name, UINT32 uniqueId, ManagedDataBlock (ObjectType::*getter)(), 
 			void (ObjectType::*setter)(ManagedDataBlock) = nullptr, UINT64 flags = 0, UINT8* (customAllocator)(ObjectType*, UINT32) = 0)
 			void (ObjectType::*setter)(ManagedDataBlock) = nullptr, UINT64 flags = 0, UINT8* (customAllocator)(ObjectType*, UINT32) = 0)
 		{
 		{
 			addDataBlockField<ObjectType>(name, uniqueId, 
 			addDataBlockField<ObjectType>(name, uniqueId, 
@@ -473,7 +473,7 @@ namespace CamelotFramework
 		/*		(Needs an extra pointer to the actual object)					*/
 		/*		(Needs an extra pointer to the actual object)					*/
 		/************************************************************************/
 		/************************************************************************/
 		template<class InterfaceType, class ObjectType, class DataType>
 		template<class InterfaceType, class ObjectType, class DataType>
-		void addPlainField(const std::string& name, UINT32 uniqueId, 
+		void addPlainField(const String& name, UINT32 uniqueId, 
 			DataType& (InterfaceType::*getter)(ObjectType*), 
 			DataType& (InterfaceType::*getter)(ObjectType*), 
 			void (InterfaceType::*setter)(ObjectType*, DataType&), UINT64 flags = 0)
 			void (InterfaceType::*setter)(ObjectType*, DataType&), UINT64 flags = 0)
 		{
 		{
@@ -489,7 +489,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template<class InterfaceType, class ObjectType, class DataType>
 		template<class InterfaceType, class ObjectType, class DataType>
-		void addReflectableField(const std::string& name, UINT32 uniqueId, 
+		void addReflectableField(const String& name, UINT32 uniqueId, 
 			DataType& (InterfaceType::*getter)(ObjectType*), 
 			DataType& (InterfaceType::*getter)(ObjectType*), 
 			void (InterfaceType::*setter)(ObjectType*, DataType&), UINT64 flags = 0)
 			void (InterfaceType::*setter)(ObjectType*, DataType&), UINT64 flags = 0)
 		{
 		{
@@ -499,7 +499,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template<class InterfaceType, class ObjectType, class DataType>
 		template<class InterfaceType, class ObjectType, class DataType>
-		void addReflectablePtrField(const std::string& name, UINT32 uniqueId, 
+		void addReflectablePtrField(const String& name, UINT32 uniqueId, 
 			std::shared_ptr<DataType> (InterfaceType::*getter)(ObjectType*), 
 			std::shared_ptr<DataType> (InterfaceType::*getter)(ObjectType*), 
 			void (InterfaceType::*setter)(ObjectType*, std::shared_ptr<DataType>), UINT64 flags = 0)
 			void (InterfaceType::*setter)(ObjectType*, std::shared_ptr<DataType>), UINT64 flags = 0)
 		{
 		{
@@ -509,7 +509,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template<class InterfaceType, class ObjectType, class DataType>
 		template<class InterfaceType, class ObjectType, class DataType>
-		void addPlainArrayField(const std::string& name, UINT32 uniqueId, 
+		void addPlainArrayField(const String& name, UINT32 uniqueId, 
 			DataType& (InterfaceType::*getter)(ObjectType*, UINT32), 
 			DataType& (InterfaceType::*getter)(ObjectType*, UINT32), 
 			UINT32 (InterfaceType::*getSize)(ObjectType*), 
 			UINT32 (InterfaceType::*getSize)(ObjectType*), 
 			void (InterfaceType::*setter)(ObjectType*, UINT32, DataType&), 
 			void (InterfaceType::*setter)(ObjectType*, UINT32, DataType&), 
@@ -529,7 +529,7 @@ namespace CamelotFramework
 		}	
 		}	
 
 
 		template<class InterfaceType, class ObjectType, class DataType>
 		template<class InterfaceType, class ObjectType, class DataType>
-		void addReflectableArrayField(const std::string& name, UINT32 uniqueId, 
+		void addReflectableArrayField(const String& name, UINT32 uniqueId, 
 			DataType& (InterfaceType::*getter)(ObjectType*, UINT32), 
 			DataType& (InterfaceType::*getter)(ObjectType*, UINT32), 
 			UINT32 (InterfaceType::*getSize)(ObjectType*), 
 			UINT32 (InterfaceType::*getSize)(ObjectType*), 
 			void (InterfaceType::*setter)(ObjectType*, UINT32, DataType&), 
 			void (InterfaceType::*setter)(ObjectType*, UINT32, DataType&), 
@@ -543,7 +543,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template<class InterfaceType, class ObjectType, class DataType>
 		template<class InterfaceType, class ObjectType, class DataType>
-		void addReflectablePtrArrayField(const std::string& name, UINT32 uniqueId, 
+		void addReflectablePtrArrayField(const String& name, UINT32 uniqueId, 
 			std::shared_ptr<DataType> (InterfaceType::*getter)(ObjectType*, UINT32), 
 			std::shared_ptr<DataType> (InterfaceType::*getter)(ObjectType*, UINT32), 
 			UINT32 (InterfaceType::*getSize)(ObjectType*), 
 			UINT32 (InterfaceType::*getSize)(ObjectType*), 
 			void (InterfaceType::*setter)(ObjectType*, UINT32, std::shared_ptr<DataType>), 
 			void (InterfaceType::*setter)(ObjectType*, UINT32, std::shared_ptr<DataType>), 
@@ -557,7 +557,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template<class InterfaceType, class ObjectType>
 		template<class InterfaceType, class ObjectType>
-		void addDataBlockField(const std::string& name, UINT32 uniqueId, ManagedDataBlock (InterfaceType::*getter)(ObjectType*), 
+		void addDataBlockField(const String& name, UINT32 uniqueId, ManagedDataBlock (InterfaceType::*getter)(ObjectType*), 
 			void (InterfaceType::*setter)(ObjectType*, ManagedDataBlock), UINT64 flags = 0, 
 			void (InterfaceType::*setter)(ObjectType*, ManagedDataBlock), UINT64 flags = 0, 
 			UINT8* (customAllocator)(ObjectType*, UINT32) = 0)
 			UINT8* (customAllocator)(ObjectType*, UINT32) = 0)
 		{
 		{
@@ -578,7 +578,7 @@ namespace CamelotFramework
 
 
 	private:
 	private:
 		template<class ObjectType, class DataType>
 		template<class ObjectType, class DataType>
-		void addPlainField(const std::string& name, UINT32 uniqueId, boost::any getter, boost::any setter, UINT64 flags)
+		void addPlainField(const String& name, UINT32 uniqueId, boost::any getter, boost::any setter, UINT64 flags)
 		{
 		{
 			RTTIPlainField<DataType, ObjectType>* newField = 
 			RTTIPlainField<DataType, ObjectType>* newField = 
 				cm_new<RTTIPlainField<DataType, ObjectType>>();
 				cm_new<RTTIPlainField<DataType, ObjectType>>();
@@ -587,7 +587,7 @@ namespace CamelotFramework
 		}
 		}
 		
 		
 		template<class ObjectType, class DataType>
 		template<class ObjectType, class DataType>
-		void addReflectableField(const std::string& name, UINT32 uniqueId, boost::any getter, boost::any setter, UINT64 flags)
+		void addReflectableField(const String& name, UINT32 uniqueId, boost::any getter, boost::any setter, UINT64 flags)
 		{
 		{
 			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::IReflectable, DataType>::value), 
 			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::IReflectable, DataType>::value), 
 				"Invalid data type for complex field. It needs to derive from CamelotFramework::IReflectable.");
 				"Invalid data type for complex field. It needs to derive from CamelotFramework::IReflectable.");
@@ -599,7 +599,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template<class ObjectType, class DataType>
 		template<class ObjectType, class DataType>
-		void addReflectablePtrField(const std::string& name, UINT32 uniqueId, boost::any getter, boost::any setter, UINT64 flags)
+		void addReflectablePtrField(const String& name, UINT32 uniqueId, boost::any getter, boost::any setter, UINT64 flags)
 		{
 		{
 			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::IReflectable, DataType>::value), 
 			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::IReflectable, DataType>::value), 
 				"Invalid data type for complex field. It needs to derive from CamelotFramework::IReflectable.");
 				"Invalid data type for complex field. It needs to derive from CamelotFramework::IReflectable.");
@@ -614,7 +614,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template<class ObjectType, class DataType>
 		template<class ObjectType, class DataType>
-		void addPlainArrayField(const std::string& name, UINT32 uniqueId, boost::any getter, boost::any getSize, 
+		void addPlainArrayField(const String& name, UINT32 uniqueId, boost::any getter, boost::any getSize, 
 			boost::any setter, boost::any setSize, UINT64 flags)
 			boost::any setter, boost::any setSize, UINT64 flags)
 		{
 		{
 			RTTIPlainField<DataType, ObjectType>* newField = 
 			RTTIPlainField<DataType, ObjectType>* newField = 
@@ -624,7 +624,7 @@ namespace CamelotFramework
 		}	
 		}	
 
 
 		template<class ObjectType, class DataType>
 		template<class ObjectType, class DataType>
-		void addReflectableArrayField(const std::string& name, UINT32 uniqueId, boost::any getter, boost::any getSize, 
+		void addReflectableArrayField(const String& name, UINT32 uniqueId, boost::any getter, boost::any getSize, 
 			boost::any setter, boost::any setSize, UINT64 flags)
 			boost::any setter, boost::any setSize, UINT64 flags)
 		{
 		{
 			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::IReflectable, DataType>::value), 
 			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::IReflectable, DataType>::value), 
@@ -637,7 +637,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template<class ObjectType, class DataType>
 		template<class ObjectType, class DataType>
-		void addReflectablePtrArrayField(const std::string& name, UINT32 uniqueId, boost::any getter, boost::any getSize, 
+		void addReflectablePtrArrayField(const String& name, UINT32 uniqueId, boost::any getter, boost::any getSize, 
 			boost::any setter, boost::any setSize, UINT64 flags)
 			boost::any setter, boost::any setSize, UINT64 flags)
 		{
 		{
 			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::IReflectable, DataType>::value), 
 			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::IReflectable, DataType>::value), 
@@ -653,7 +653,7 @@ namespace CamelotFramework
 		}
 		}
 
 
 		template<class ObjectType>
 		template<class ObjectType>
-		void addDataBlockField(const std::string& name, UINT32 uniqueId, boost::any getter, boost::any setter, UINT64 flags, boost::any customAllocator = boost::any())
+		void addDataBlockField(const String& name, UINT32 uniqueId, boost::any getter, boost::any setter, UINT64 flags, boost::any customAllocator = boost::any())
 		{
 		{
 			RTTIManagedDataBlockField<ManagedDataBlock, ObjectType>* newField = 
 			RTTIManagedDataBlockField<ManagedDataBlock, ObjectType>* newField = 
 				cm_new<RTTIManagedDataBlockField<ManagedDataBlock, ObjectType>>();
 				cm_new<RTTIManagedDataBlockField<ManagedDataBlock, ObjectType>>();

+ 323 - 69
CamelotUtility/Include/CmString.h

@@ -62,24 +62,25 @@ namespace __gnu_cxx
 
 
 #endif
 #endif
 
 
-namespace CamelotFramework {
+namespace CamelotFramework 
+{
+	template <typename T>
+	struct BasicString 
+	{ 
+		typedef typename std::basic_string<T, std::char_traits<T>, StdAlloc<T>> type; 
+	}; 
 
 
-#if CM_WCHAR_T_STRINGS
-		typedef std::wstring _StringBase;
-#else
-		typedef std::string _StringBase;
-#endif
+	template <typename T>
+	struct BasicStringStream
+	{ 
+		typedef typename std::basic_stringstream<T, std::char_traits<T>, StdAlloc<T>> type; 
+	}; 
 
 
-#if CM_WCHAR_T_STRINGS
-		typedef std::basic_stringstream<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > _StringStreamBase;
-#else
-		typedef std::basic_stringstream<char,std::char_traits<char>,std::allocator<char> > _StringStreamBase;
-#endif
+	typedef BasicString<wchar_t>::type WString;
+	typedef BasicString<char>::type String;
 
 
-		typedef _StringBase String;
-		typedef _StringStreamBase StringStream;
-		typedef StringStream stringstream;
-		typedef String WString; // TODO - A temporary value I'll use for things that will need Unicode. I don't use Unicode yet though
+	typedef BasicStringStream<wchar_t>::type WStringStream;
+	typedef BasicStringStream<char>::type StringStream;
 
 
 	/** \addtogroup Core
 	/** \addtogroup Core
 	*  @{
 	*  @{
@@ -92,7 +93,14 @@ namespace CamelotFramework {
     class CM_UTILITY_EXPORT StringUtil
     class CM_UTILITY_EXPORT StringUtil
     {
     {
 	public:
 	public:
-		typedef StringStream StrStreamType;
+        /** Removes any whitespace characters, be it standard space or
+            TABs and so on.
+            @remarks
+                The user may specify wether they want to trim only the
+                beginning or the end of the String ( the default action is
+                to trim both).
+        */
+        static void trim(String& str, bool left = true, bool right = true);
 
 
         /** Removes any whitespace characters, be it standard space or
         /** Removes any whitespace characters, be it standard space or
             TABs and so on.
             TABs and so on.
@@ -101,7 +109,7 @@ namespace CamelotFramework {
                 beginning or the end of the String ( the default action is
                 beginning or the end of the String ( the default action is
                 to trim both).
                 to trim both).
         */
         */
-        static void trim( String& str, bool left = true, bool right = true );
+        static void trim(WString& str, bool left = true, bool right = true);
 
 
         /** Returns a StringVector that contains all the substrings delimited
         /** Returns a StringVector that contains all the substrings delimited
             by the characters in the passed <code>delims</code> argument.
             by the characters in the passed <code>delims</code> argument.
@@ -111,7 +119,17 @@ namespace CamelotFramework {
                 maxSplits The maximum number of splits to perform (0 for unlimited splits). If this
                 maxSplits The maximum number of splits to perform (0 for unlimited splits). If this
                 parameters is > 0, the splitting process will stop after this many splits, left to right.
                 parameters is > 0, the splitting process will stop after this many splits, left to right.
         */
         */
-		static vector<String>::type split( const String& str, const String& delims = "\t\n ", unsigned int maxSplits = 0);
+		static vector<String>::type split(const String& str, const String& delims = "\t\n ", unsigned int maxSplits = 0);
+
+		/** Returns a StringVector that contains all the substrings delimited
+            by the characters in the passed <code>delims</code> argument.
+            @param
+                delims A list of delimiter characters to split by
+            @param
+                maxSplits The maximum number of splits to perform (0 for unlimited splits). If this
+                parameters is > 0, the splitting process will stop after this many splits, left to right.
+        */
+		static vector<WString>::type split(const WString& str, const WString& delims = L"\t\n ", unsigned int maxSplits = 0);
 
 
 		/** Returns a StringVector that contains all the substrings delimited
 		/** Returns a StringVector that contains all the substrings delimited
             by the characters in the passed <code>delims</code> argument, 
             by the characters in the passed <code>delims</code> argument, 
@@ -125,16 +143,37 @@ namespace CamelotFramework {
                 maxSplits The maximum number of splits to perform (0 for unlimited splits). If this
                 maxSplits The maximum number of splits to perform (0 for unlimited splits). If this
                 parameters is > 0, the splitting process will stop after this many splits, left to right.
                 parameters is > 0, the splitting process will stop after this many splits, left to right.
         */
         */
-		static vector<String>::type tokenise( const String& str, const String& delims = "\t\n ", const String& doubleDelims = "\"", unsigned int maxSplits = 0);
+		static vector<String>::type tokenise(const String& str, const String& delims = "\t\n ", const String& doubleDelims = "\"", unsigned int maxSplits = 0);
+
+		/** Returns a StringVector that contains all the substrings delimited
+            by the characters in the passed <code>delims</code> argument, 
+			or in the <code>doubleDelims</code> argument, which is used to include (normal) 
+			delimeters in the tokenised string. For example, "strings like this".
+            @param
+                delims A list of delimiter characters to split by
+			@param
+                delims A list of double delimeters characters to tokenise by
+            @param
+                maxSplits The maximum number of splits to perform (0 for unlimited splits). If this
+                parameters is > 0, the splitting process will stop after this many splits, left to right.
+        */
+		static vector<WString>::type tokenise(const WString& str, const WString& delims = L"\t\n ", const WString& doubleDelims = L"\"", unsigned int maxSplits = 0);
 
 
 		/** Lower-cases all the characters in the string.
 		/** Lower-cases all the characters in the string.
         */
         */
-        static void toLowerCase( String& str );
+        static void toLowerCase(String& str);
+
+		/** Lower-cases all the characters in the string.
+        */
+        static void toLowerCase(WString& str);
 
 
         /** Upper-cases all the characters in the string.
         /** Upper-cases all the characters in the string.
         */
         */
-        static void toUpperCase( String& str );
+        static void toUpperCase(String& str);
 
 
+        /** Upper-cases all the characters in the string.
+        */
+        static void toUpperCase(WString& str);
 
 
         /** Returns whether the string begins with the pattern passed in.
         /** Returns whether the string begins with the pattern passed in.
         @param pattern The pattern to compare with.
         @param pattern The pattern to compare with.
@@ -143,6 +182,13 @@ namespace CamelotFramework {
         */
         */
         static bool startsWith(const String& str, const String& pattern, bool lowerCase = true);
         static bool startsWith(const String& str, const String& pattern, bool lowerCase = true);
 
 
+        /** Returns whether the string begins with the pattern passed in.
+        @param pattern The pattern to compare with.
+        @param lowerCase If true, the start of the string will be lower cased before
+            comparison, pattern should also be in lower case.
+        */
+        static bool startsWith(const WString& str, const WString& pattern, bool lowerCase = true);
+
         /** Returns whether the string ends with the pattern passed in.
         /** Returns whether the string ends with the pattern passed in.
         @param pattern The pattern to compare with.
         @param pattern The pattern to compare with.
         @param lowerCase If true, the end of the string will be lower cased before
         @param lowerCase If true, the end of the string will be lower cased before
@@ -150,33 +196,12 @@ namespace CamelotFramework {
         */
         */
         static bool endsWith(const String& str, const String& pattern, bool lowerCase = true);
         static bool endsWith(const String& str, const String& pattern, bool lowerCase = true);
 
 
-        /** Method for standardising paths - use forward slashes only, end with slash.
-        */
-        static String standardisePath( const String &init);
-
-        /** Method for splitting a fully qualified filename into the base name
-            and path.
-        @remarks
-            Path is standardised as in standardisePath
+        /** Returns whether the string ends with the pattern passed in.
+        @param pattern The pattern to compare with.
+        @param lowerCase If true, the end of the string will be lower cased before
+            comparison, pattern should also be in lower case.
         */
         */
-        static void splitFilename(const String& qualifiedName,
-            String& outBasename, String& outPath);
-
-		/** Method for splitting a fully qualified filename into the base name,
-		extension and path.
-		@remarks
-		Path is standardised as in standardisePath
-		*/
-		static void splitFullFilename(const CamelotFramework::String& qualifiedName, 
-			CamelotFramework::String& outBasename, CamelotFramework::String& outExtention, 
-			CamelotFramework::String& outPath);
-
-		/** Method for splitting a filename into the base name
-		and extension.
-		*/
-		static void splitBaseFilename(const CamelotFramework::String& fullName, 
-			CamelotFramework::String& outBasename, CamelotFramework::String& outExtention);
-
+        static bool endsWith(const WString& str, const WString& pattern, bool lowerCase = true);
 
 
         /** Simple pattern-matching routine allowing a wildcard pattern.
         /** Simple pattern-matching routine allowing a wildcard pattern.
         @param str String to test
         @param str String to test
@@ -185,8 +210,14 @@ namespace CamelotFramework {
         */
         */
         static bool match(const String& str, const String& pattern, bool caseSensitive = true);
         static bool match(const String& str, const String& pattern, bool caseSensitive = true);
 
 
+		/** Simple pattern-matching routine allowing a wildcard pattern.
+        @param str String to test
+        @param pattern Pattern to match against; can include simple '*' wildcards
+        @param caseSensitive Whether the match is case sensitive or not
+        */
+        static bool match(const WString& str, const WString& pattern, bool caseSensitive = true);
 
 
-		/** replace all instances of a sub-string with a another sub-string.
+		/** Replace all instances of a sub-string with a another sub-string.
 		@param source Source string
 		@param source Source string
 		@param replaceWhat Sub-string to find and replace
 		@param replaceWhat Sub-string to find and replace
 		@param replaceWithWhat Sub-string to replace with (the new sub-string)
 		@param replaceWithWhat Sub-string to replace with (the new sub-string)
@@ -194,26 +225,255 @@ namespace CamelotFramework {
 		*/
 		*/
 		static const String replaceAll(const String& source, const String& replaceWhat, const String& replaceWithWhat);
 		static const String replaceAll(const String& source, const String& replaceWhat, const String& replaceWithWhat);
 
 
+		/** Replace all instances of a sub-string with a another sub-string.
+		@param source Source string
+		@param replaceWhat Sub-string to find and replace
+		@param replaceWithWhat Sub-string to replace with (the new sub-string)
+		@returns An updated string with the sub-string replaced
+		*/
+		static const WString replaceAll(const WString& source, const WString& replaceWhat, const WString& replaceWithWhat);
+
         /// Constant blank string, useful for returning by ref where local does not exist
         /// Constant blank string, useful for returning by ref where local does not exist
         static const String BLANK;
         static const String BLANK;
+
+		/// Constant blank string, useful for returning by ref where local does not exist
+		static const WString WBLANK;
+
+	private:
+		template <class T>
+		static typename vector<typename BasicString<T>::type>::type splitInternal(const typename BasicString<T>::type& str, const typename BasicString<T>::type& delims, unsigned int maxSplits)
+		{
+			vector<BasicString<T>::type>::type ret;
+			// Pre-allocate some space for performance
+			ret.reserve(maxSplits ? maxSplits+1 : 10);    // 10 is guessed capacity for most case
+
+			unsigned int numSplits = 0;
+
+			// Use STL methods 
+			size_t start, pos;
+			start = 0;
+			do 
+			{
+				pos = str.find_first_of(delims, start);
+				if (pos == start)
+				{
+					// Do nothing
+					start = pos + 1;
+				}
+				else if (pos == BasicString<T>::type::npos || (maxSplits && numSplits == maxSplits))
+				{
+					// Copy the rest of the string
+					ret.push_back(str.substr(start));
+					break;
+				}
+				else
+				{
+					// Copy up to delimiter
+					ret.push_back(str.substr(start, pos - start));
+					start = pos + 1;
+				}
+				// parse up to next real data
+				start = str.find_first_not_of(delims, start);
+				++numSplits;
+
+			} while (pos != BasicString<T>::type::npos);
+
+			return ret;
+		}
+
+		template <class T>
+		static typename vector<typename BasicString<T>::type>::type tokeniseInternal(const typename BasicString<T>::type& str, const typename BasicString<T>::type& singleDelims, 
+			const typename BasicString<T>::type& doubleDelims, unsigned int maxSplits)
+		{
+			vector<BasicString<T>::type>::type ret;
+			// Pre-allocate some space for performance
+			ret.reserve(maxSplits ? maxSplits + 1 : 10);    // 10 is guessed capacity for most case
+
+			unsigned int numSplits = 0;
+			BasicString<T>::type delims = singleDelims + doubleDelims;
+
+			// Use STL methods 
+			size_t start, pos;
+			T curDoubleDelim = 0;
+			start = 0;
+			do 
+			{
+				if (curDoubleDelim != 0)
+				{
+					pos = str.find(curDoubleDelim, start);
+				}
+				else
+				{
+					pos = str.find_first_of(delims, start);
+				}
+
+				if (pos == start)
+				{
+					T curDelim = str.at(pos);
+					if (doubleDelims.find_first_of(curDelim) != BasicString<T>::type::npos)
+					{
+						curDoubleDelim = curDelim;
+					}
+					// Do nothing
+					start = pos + 1;
+				}
+				else if (pos == BasicString<T>::type::npos || (maxSplits && numSplits == maxSplits))
+				{
+					if (curDoubleDelim != 0)
+					{
+						//Missing closer. Warn or throw exception?
+					}
+					// Copy the rest of the string
+					ret.push_back( str.substr(start) );
+					break;
+				}
+				else
+				{
+					if (curDoubleDelim != 0)
+					{
+						curDoubleDelim = 0;
+					}
+
+					// Copy up to delimiter
+					ret.push_back( str.substr(start, pos - start) );
+					start = pos + 1;
+				}
+				if (curDoubleDelim == 0)
+				{
+					// parse up to next real data
+					start = str.find_first_not_of(singleDelims, start);
+				}
+
+				++numSplits;
+
+			} while (pos != BasicString<T>::type::npos);
+
+			return ret;
+		}
+
+		template <class T>
+		static bool startsWithInternal(const typename BasicString<T>::type& str, const typename BasicString<T>::type& pattern, bool lowerCase)
+		{
+			size_t thisLen = str.length();
+			size_t patternLen = pattern.length();
+			if (thisLen < patternLen || patternLen == 0)
+				return false;
+
+			BasicString<T>::type startOfThis = str.substr(0, patternLen);
+			if (lowerCase)
+				StringUtil::toLowerCase(startOfThis);
+
+			return (startOfThis == pattern);
+		}
+
+		template <class T>
+		static bool endsWithInternal(const typename BasicString<T>::type& str, const typename BasicString<T>::type& pattern, bool lowerCase)
+		{
+			size_t thisLen = str.length();
+			size_t patternLen = pattern.length();
+			if (thisLen < patternLen || patternLen == 0)
+				return false;
+
+			BasicString<T>::type endOfThis = str.substr(thisLen - patternLen, patternLen);
+			if (lowerCase)
+				StringUtil::toLowerCase(endOfThis);
+
+			return (endOfThis == pattern);
+		}
+
+		template <class T>
+		static bool matchInternal(const typename BasicString<T>::type& str, const typename BasicString<T>::type& pattern, bool caseSensitive)
+		{
+			BasicString<T>::type tmpStr = str;
+			BasicString<T>::type tmpPattern = pattern;
+			if (!caseSensitive)
+			{
+				StringUtil::toLowerCase(tmpStr);
+				StringUtil::toLowerCase(tmpPattern);
+			}
+
+			BasicString<T>::type::const_iterator strIt = tmpStr.begin();
+			BasicString<T>::type::const_iterator patIt = tmpPattern.begin();
+			BasicString<T>::type::const_iterator lastWildCardIt = tmpPattern.end();
+			while (strIt != tmpStr.end() && patIt != tmpPattern.end())
+			{
+				if (*patIt == '*')
+				{
+					lastWildCardIt = patIt;
+					// Skip over looking for next character
+					++patIt;
+					if (patIt == tmpPattern.end())
+					{
+						// Skip right to the end since * matches the entire rest of the string
+						strIt = tmpStr.end();
+					}
+					else
+					{
+						// scan until we find next pattern character
+						while(strIt != tmpStr.end() && *strIt != *patIt)
+							++strIt;
+					}
+				}
+				else
+				{
+					if (*patIt != *strIt)
+					{
+						if (lastWildCardIt != tmpPattern.end())
+						{
+							// The last wildcard can match this incorrect sequence
+							// rewind pattern to wildcard and keep searching
+							patIt = lastWildCardIt;
+							lastWildCardIt = tmpPattern.end();
+						}
+						else
+						{
+							// no wildwards left
+							return false;
+						}
+					}
+					else
+					{
+						++patIt;
+						++strIt;
+					}
+				}
+
+			}
+
+			// If we reached the end of both the pattern and the string, we succeeded
+			if (patIt == tmpPattern.end() && strIt == tmpStr.end())
+				return true;
+			else
+				return false;
+		}
+
+		template <class T>
+		static const typename BasicString<T>::type replaceAllInternal(const typename BasicString<T>::type& source, 
+			const typename BasicString<T>::type& replaceWhat, const typename BasicString<T>::type& replaceWithWhat)
+		{
+			BasicString<T>::type result = source;
+			BasicString<T>::type::size_type pos = 0;
+			while(1)
+			{
+				pos = result.find(replaceWhat,pos);
+				if (pos == BasicString<T>::type::npos) break;
+				result.replace(pos,replaceWhat.size(), replaceWithWhat);
+				pos += replaceWithWhat.size();
+			}
+			return result;
+		}
     };
     };
 
 
 
 
-#if CM_COMPILER == CM_COMPILER_GNUC && CM_COMP_VER >= 310 && !defined(STLPORT)
-#   if CM_COMP_VER < 430
-	typedef ::__gnu_cxx::hash< _StringBase > _StringHash;
-#   else
-	typedef ::std::tr1::hash< _StringBase > _StringHash;
-#   endif
-#elif CM_COMPILER == CM_COMPILER_MSVC && CM_COMP_VER >= 1600 && !defined(STLPORT) // VC++ 10.0
-	typedef ::std::tr1::hash< _StringBase > _StringHash;
-#elif !defined( _STLP_HASH_FUN_H )
-	typedef stdext::hash_compare< _StringBase, std::less< _StringBase > > _StringHash;
-#else
-	typedef std::hash< _StringBase > _StringHash;
-#endif 
-	/** @} */
-	/** @} */
+	/**
+	* @brief	Converts a narrow string to a wide string.
+	*/
+	CM_UTILITY_EXPORT WString toWString(const String& source);
+
+	/**
+	* @brief	Converts a wide string to a narrow string.
+	*/
+	CM_UTILITY_EXPORT String toString(const WString& source);
 
 
 	    /** Converts a float to a String. */
 	    /** Converts a float to a String. */
     CM_UTILITY_EXPORT String toString(float val, unsigned short precision = 6, 
     CM_UTILITY_EXPORT String toString(float val, unsigned short precision = 6, 
@@ -347,12 +607,6 @@ namespace CamelotFramework {
     */
     */
     CM_UTILITY_EXPORT bool parseBool(const String& val, bool defaultValue = 0);
     CM_UTILITY_EXPORT bool parseBool(const String& val, bool defaultValue = 0);
 
 
-    /** Pareses a StringVector from a string.
-    @remarks
-        Strings must not contain spaces since space is used as a delimiter in
-        the output.
-    */
-    CM_UTILITY_EXPORT vector<CamelotFramework::String>::type parseStringVector(const String& val);
     /** Checks the String is a valid number value. */
     /** Checks the String is a valid number value. */
     CM_UTILITY_EXPORT bool isNumber(const String& val);
     CM_UTILITY_EXPORT bool isNumber(const String& val);
 	/** @} */
 	/** @} */

+ 4 - 4
CamelotUtility/Source/CmDebug.cpp

@@ -7,22 +7,22 @@
 
 
 namespace CamelotFramework
 namespace CamelotFramework
 {
 {
-	void Debug::logDebug(std::string msg)
+	void Debug::logDebug(const String& msg)
 	{
 	{
 		mLog.logMsg(msg, "GlobalDebug");
 		mLog.logMsg(msg, "GlobalDebug");
 	}
 	}
 
 
-	void Debug::logInfo(std::string msg)
+	void Debug::logInfo(const String& msg)
 	{
 	{
 		mLog.logMsg(msg, "GlobalInfo");
 		mLog.logMsg(msg, "GlobalInfo");
 	}
 	}
 
 
-	void Debug::logWarning(std::string msg)
+	void Debug::logWarning(const String& msg)
 	{
 	{
 		mLog.logMsg(msg, "GlobalWarning");
 		mLog.logMsg(msg, "GlobalWarning");
 	}
 	}
 
 
-	void Debug::logError(std::string msg)
+	void Debug::logError(const String& msg)
 	{
 	{
 		mLog.logMsg(msg, "GlobalError");
 		mLog.logMsg(msg, "GlobalError");
 	}
 	}

+ 1 - 1
CamelotUtility/Source/CmException.cpp

@@ -28,7 +28,7 @@ namespace CamelotFramework
     {
     {
 		if (mFullDesc.empty())
 		if (mFullDesc.empty())
 		{
 		{
-			std::stringstream desc;
+			StringStream desc;
 
 
 			desc<< "CAMELOT EXCEPTION(" << mTypeName << "): "
 			desc<< "CAMELOT EXCEPTION(" << mTypeName << "): "
 				<< mDescription 
 				<< mDescription 

+ 2 - 2
CamelotUtility/Source/CmFileSerializer.cpp

@@ -19,7 +19,7 @@ namespace CamelotFramework
 		cm_free<ScratchAlloc>(mWriteBuffer);
 		cm_free<ScratchAlloc>(mWriteBuffer);
 	}
 	}
 
 
-	void FileSerializer::encode(IReflectable* object, std::string fileLocation)
+	void FileSerializer::encode(IReflectable* object, String fileLocation)
 	{
 	{
 		mOutputStream.open(fileLocation.c_str(), std::ios::out | std::ios::binary);
 		mOutputStream.open(fileLocation.c_str(), std::ios::out | std::ios::binary);
 
 
@@ -31,7 +31,7 @@ namespace CamelotFramework
 		mOutputStream.clear();
 		mOutputStream.clear();
 	}
 	}
 
 
-	std::shared_ptr<IReflectable> FileSerializer::decode(std::string fileLocation)
+	std::shared_ptr<IReflectable> FileSerializer::decode(String fileLocation)
 	{
 	{
 		mInputStream.open(fileLocation.c_str(), std::ios::in | std::ios::ate | std::ios::binary);
 		mInputStream.open(fileLocation.c_str(), std::ios::in | std::ios::ate | std::ios::binary);
 		
 		

+ 10 - 10
CamelotUtility/Source/CmFileSystem.cpp

@@ -98,7 +98,7 @@ namespace CamelotFramework
 
 
 	bool FileSystem::fileExists(const String& fullPath)
 	bool FileSystem::fileExists(const String& fullPath)
 	{
 	{
-		if(boost::filesystem::exists(fullPath) && !boost::filesystem::is_directory(fullPath))
+		if(boost::filesystem::exists(fullPath.c_str()) && !boost::filesystem::is_directory(fullPath.c_str()))
 			return true;
 			return true;
 
 
 		return false;
 		return false;
@@ -106,7 +106,7 @@ namespace CamelotFramework
 
 
 	bool FileSystem::dirExists(const String& fullPath)
 	bool FileSystem::dirExists(const String& fullPath)
 	{
 	{
-		if(boost::filesystem::exists(fullPath) && boost::filesystem::is_directory(fullPath))
+		if(boost::filesystem::exists(fullPath.c_str()) && boost::filesystem::is_directory(fullPath.c_str()))
 			return true;
 			return true;
 
 
 		return false;
 		return false;
@@ -114,24 +114,24 @@ namespace CamelotFramework
 
 
 	void FileSystem::createDir(const String& fullPath)
 	void FileSystem::createDir(const String& fullPath)
 	{
 	{
-		boost::filesystem::create_directory(fullPath);
+		boost::filesystem::create_directory(fullPath.c_str());
 	}
 	}
 
 
 	void FileSystem::deleteDir(const String& fullPath)
 	void FileSystem::deleteDir(const String& fullPath)
 	{
 	{
-		boost::filesystem::remove_all(fullPath);
+		boost::filesystem::remove_all(fullPath.c_str());
 	}
 	}
 
 
 	vector<String>::type FileSystem::getFiles(const String& dirPath)
 	vector<String>::type FileSystem::getFiles(const String& dirPath)
 	{
 	{
-		boost::filesystem::directory_iterator dirIter(dirPath);
+		boost::filesystem::directory_iterator dirIter(dirPath.c_str());
 
 
 		vector<String>::type foundFiles;
 		vector<String>::type foundFiles;
 		
 		
 		while(dirIter != boost::filesystem::directory_iterator())
 		while(dirIter != boost::filesystem::directory_iterator())
 		{
 		{
 			if(boost::filesystem::is_regular_file(dirIter->path()))
 			if(boost::filesystem::is_regular_file(dirIter->path()))
-				foundFiles.push_back(dirIter->path().string());
+				foundFiles.push_back(dirIter->path().string().c_str());
 
 
 			dirIter++;
 			dirIter++;
 		}
 		}
@@ -141,22 +141,22 @@ namespace CamelotFramework
 
 
 	String FileSystem::getCurrentPath()
 	String FileSystem::getCurrentPath()
 	{
 	{
-		return boost::filesystem::current_path().string();
+		return boost::filesystem::current_path().string().c_str();
 	}
 	}
 
 
 	bool FileSystem::isValidFileName(const String& name)
 	bool FileSystem::isValidFileName(const String& name)
 	{
 	{
-		return boost::filesystem::portable_file_name(name);
+		return boost::filesystem::portable_file_name(name.c_str());
 	}
 	}
 
 
 	String FileSystem::getDirectoryPath(const String& path)
 	String FileSystem::getDirectoryPath(const String& path)
 	{
 	{
-		boost::filesystem::path p(path);
+		boost::filesystem::path p(path.c_str());
 
 
 		if(!is_directory(p))
 		if(!is_directory(p))
 		{
 		{
 			boost::filesystem::path dir = p.parent_path();
 			boost::filesystem::path dir = p.parent_path();
-			return dir.string();
+			return dir.string().c_str();
 		}
 		}
 
 
 		return path;
 		return path;

+ 2 - 2
CamelotUtility/Source/CmRTTIType.cpp

@@ -14,7 +14,7 @@ namespace CamelotFramework
 		mFields.clear();
 		mFields.clear();
 	}
 	}
 
 
-	RTTIField* RTTITypeBase::findField(const std::string& name)
+	RTTIField* RTTITypeBase::findField(const String& name)
 	{
 	{
 		auto foundElement = std::find_if(mFields.begin(), mFields.end(), [&name](RTTIField* x) { return x->mName == name; });
 		auto foundElement = std::find_if(mFields.begin(), mFields.end(), [&name](RTTIField* x) { return x->mName == name; });
 
 
@@ -54,7 +54,7 @@ namespace CamelotFramework
 				"Field with the same ID already exists.");
 				"Field with the same ID already exists.");
 		}
 		}
 
 
-		std::string& name = field->mName;
+		String& name = field->mName;
 		auto foundElementByName = std::find_if(mFields.begin(), mFields.end(), [&name](RTTIField* x) { return x->mName == name; });
 		auto foundElementByName = std::find_if(mFields.begin(), mFields.end(), [&name](RTTIField* x) { return x->mName == name; });
 
 
 		if(foundElementByName != mFields.end())
 		if(foundElementByName != mFields.end())

+ 125 - 355
CamelotUtility/Source/CmString.cpp

@@ -37,36 +37,13 @@ THE SOFTWARE.
 #include "CmVector4.h"
 #include "CmVector4.h"
 #include "CmException.h"
 #include "CmException.h"
 
 
-namespace CamelotFramework {
-
-	//-----------------------------------------------------------------------
+namespace CamelotFramework 
+{
 	const String StringUtil::BLANK;
 	const String StringUtil::BLANK;
-	//-----------------------------------------------------------------------
+	const WString StringUtil::WBLANK;
+
     void StringUtil::trim(String& str, bool left, bool right)
     void StringUtil::trim(String& str, bool left, bool right)
     {
     {
-        /*
-        size_t lspaces, rspaces, len = length(), i;
-
-        lspaces = rspaces = 0;
-
-        if( left )
-        {
-            // Find spaces / tabs on the left
-            for( i = 0;
-                i < len && ( at(i) == ' ' || at(i) == '\t' || at(i) == '\r');
-                ++lspaces, ++i );
-        }
-        
-        if( right && lspaces < len )
-        {
-            // Find spaces / tabs on the right
-            for( i = len - 1;
-                i >= 0 && ( at(i) == ' ' || at(i) == '\t' || at(i) == '\r');
-                rspaces++, i-- );
-        }
-
-        *this = substr(lspaces, len-lspaces-rspaces);
-        */
         static const String delims = " \t\r";
         static const String delims = " \t\r";
         if(right)
         if(right)
             str.erase(str.find_last_not_of(delims)+1); // trim right
             str.erase(str.find_last_not_of(delims)+1); // trim right
@@ -74,308 +51,113 @@ namespace CamelotFramework {
             str.erase(0, str.find_first_not_of(delims)); // trim left
             str.erase(0, str.find_first_not_of(delims)); // trim left
     }
     }
 
 
-    //-----------------------------------------------------------------------
-    vector<CamelotFramework::String>::type StringUtil::split( const String& str, const String& delims, unsigned int maxSplits)
+	void StringUtil::trim(WString& str, bool left, bool right)
+	{
+		static const WString delims = L" \t\r";
+		if(right)
+			str.erase(str.find_last_not_of(delims)+1); // trim right
+		if(left)
+			str.erase(0, str.find_first_not_of(delims)); // trim left
+	}
+
+    vector<String>::type StringUtil::split(const String& str, const String& delims, unsigned int maxSplits)
     {
     {
-        vector<CamelotFramework::String>::type ret;
-        // Pre-allocate some space for performance
-        ret.reserve(maxSplits ? maxSplits+1 : 10);    // 10 is guessed capacity for most case
-
-        unsigned int numSplits = 0;
-
-        // Use STL methods 
-        size_t start, pos;
-        start = 0;
-        do 
-        {
-            pos = str.find_first_of(delims, start);
-            if (pos == start)
-            {
-                // Do nothing
-                start = pos + 1;
-            }
-            else if (pos == String::npos || (maxSplits && numSplits == maxSplits))
-            {
-                // Copy the rest of the string
-                ret.push_back( str.substr(start) );
-                break;
-            }
-            else
-            {
-                // Copy up to delimiter
-                ret.push_back( str.substr(start, pos - start) );
-                start = pos + 1;
-            }
-            // parse up to next real data
-            start = str.find_first_not_of(delims, start);
-            ++numSplits;
-
-        } while (pos != String::npos);
-
-
-
-        return ret;
+        return splitInternal<char>(str, delims, maxSplits);
     }
     }
-	//-----------------------------------------------------------------------
-	vector<CamelotFramework::String>::type StringUtil::tokenise( const String& str, const String& singleDelims, const String& doubleDelims, unsigned int maxSplits)
-	{
-        vector<CamelotFramework::String>::type ret;
-        // Pre-allocate some space for performance
-        ret.reserve(maxSplits ? maxSplits+1 : 10);    // 10 is guessed capacity for most case
-
-        unsigned int numSplits = 0;
-		String delims = singleDelims + doubleDelims;
-
-		// Use STL methods 
-        size_t start, pos;
-		char curDoubleDelim = 0;
-        start = 0;
-        do 
-        {
-			if (curDoubleDelim != 0)
-			{
-				pos = str.find(curDoubleDelim, start);
-			}
-			else
-			{
-				pos = str.find_first_of(delims, start);
-			}
-
-            if (pos == start)
-            {
-				char curDelim = str.at(pos);
-				if (doubleDelims.find_first_of(curDelim) != String::npos)
-				{
-					curDoubleDelim = curDelim;
-				}
-                // Do nothing
-                start = pos + 1;
-            }
-            else if (pos == String::npos || (maxSplits && numSplits == maxSplits))
-            {
-				if (curDoubleDelim != 0)
-				{
-					//Missing closer. Warn or throw exception?
-				}
-                // Copy the rest of the string
-                ret.push_back( str.substr(start) );
-                break;
-            }
-            else
-            {
-				if (curDoubleDelim != 0)
-				{
-					curDoubleDelim = 0;
-				}
-
-				// Copy up to delimiter
-				ret.push_back( str.substr(start, pos - start) );
-				start = pos + 1;
-            }
-			if (curDoubleDelim == 0)
-			{
-				// parse up to next real data
-				start = str.find_first_not_of(singleDelims, start);
-			}
-            
-            ++numSplits;
 
 
-        } while (pos != String::npos);
+	vector<WString>::type StringUtil::split(const WString& str, const WString& delims, unsigned int maxSplits)
+	{
+		return splitInternal<wchar_t>(str, delims, maxSplits);
+	}
 
 
-        return ret;
+	vector<String>::type StringUtil::tokenise(const String& str, const String& singleDelims, const String& doubleDelims, unsigned int maxSplits)
+	{
+        return tokeniseInternal<char>(str, singleDelims, doubleDelims, maxSplits);
     }
     }
-    //-----------------------------------------------------------------------
+
+	vector<WString>::type StringUtil::tokenise(const WString& str, const WString& singleDelims, const WString& doubleDelims, unsigned int maxSplits)
+	{
+		return tokeniseInternal<wchar_t>(str, singleDelims, doubleDelims, maxSplits);
+	}
+
     void StringUtil::toLowerCase(String& str)
     void StringUtil::toLowerCase(String& str)
     {
     {
-        std::transform(
-            str.begin(),
-            str.end(),
-            str.begin(),
-			tolower);
+        std::transform(str.begin(), str.end(), str.begin(), tolower);
     }
     }
 
 
-    //-----------------------------------------------------------------------
+	void StringUtil::toLowerCase(WString& str)
+	{
+		std::transform(str.begin(), str.end(), str.begin(), tolower);
+	}
+
     void StringUtil::toUpperCase(String& str) 
     void StringUtil::toUpperCase(String& str) 
     {
     {
-        std::transform(
-            str.begin(),
-            str.end(),
-            str.begin(),
-			toupper);
+        std::transform(str.begin(), str.end(), str.begin(), toupper);
     }
     }
-    //-----------------------------------------------------------------------
+
+	void StringUtil::toUpperCase(WString& str) 
+	{
+		std::transform(str.begin(), str.end(), str.begin(), toupper);
+	}
+
     bool StringUtil::startsWith(const String& str, const String& pattern, bool lowerCase)
     bool StringUtil::startsWith(const String& str, const String& pattern, bool lowerCase)
     {
     {
-        size_t thisLen = str.length();
-        size_t patternLen = pattern.length();
-        if (thisLen < patternLen || patternLen == 0)
-            return false;
+        return startsWithInternal<char>(str, pattern, lowerCase);
+    }
 
 
-        String startOfThis = str.substr(0, patternLen);
-        if (lowerCase)
-            StringUtil::toLowerCase(startOfThis);
+	bool StringUtil::startsWith(const WString& str, const WString& pattern, bool lowerCase)
+	{
+		return startsWithInternal<wchar_t>(str, pattern, lowerCase);
+	}
 
 
-        return (startOfThis == pattern);
-    }
-    //-----------------------------------------------------------------------
     bool StringUtil::endsWith(const String& str, const String& pattern, bool lowerCase)
     bool StringUtil::endsWith(const String& str, const String& pattern, bool lowerCase)
     {
     {
-        size_t thisLen = str.length();
-        size_t patternLen = pattern.length();
-        if (thisLen < patternLen || patternLen == 0)
-            return false;
+        return endsWithInternal<char>(str, pattern, lowerCase);
+    }
 
 
-        String endOfThis = str.substr(thisLen - patternLen, patternLen);
-        if (lowerCase)
-            StringUtil::toLowerCase(endOfThis);
+	bool StringUtil::endsWith(const WString& str, const WString& pattern, bool lowerCase)
+	{
+		return endsWithInternal<wchar_t>(str, pattern, lowerCase);
+	}
 
 
-        return (endOfThis == pattern);
-    }
-    //-----------------------------------------------------------------------
-    String StringUtil::standardisePath(const String& init)
+    bool StringUtil::match(const String& str, const String& pattern, bool caseSensitive)
     {
     {
-        String path = init;
+        return matchInternal<char>(str, pattern, caseSensitive);
+    }
 
 
-        std::replace( path.begin(), path.end(), '\\', '/' );
-        if( path[path.length() - 1] != '/' )
-            path += '/';
+	bool StringUtil::match(const WString& str, const WString& pattern, bool caseSensitive)
+	{
+		return matchInternal<wchar_t>(str, pattern, caseSensitive);
+	}
 
 
-        return path;
-    }
-    //-----------------------------------------------------------------------
-    void StringUtil::splitFilename(const String& qualifiedName, 
-        String& outBasename, String& outPath)
-    {
-        String path = qualifiedName;
-        // Replace \ with / first
-        std::replace( path.begin(), path.end(), '\\', '/' );
-        // split based on final /
-        size_t i = path.find_last_of('/');
-
-        if (i == String::npos)
-        {
-            outPath.clear();
-			outBasename = qualifiedName;
-        }
-        else
-        {
-            outBasename = path.substr(i+1, path.size() - i - 1);
-            outPath = path.substr(0, i+1);
-        }
+	const String StringUtil::replaceAll(const String& source, const String& replaceWhat, const String& replaceWithWhat)
+	{
+		return replaceAllInternal<char>(source, replaceWhat, replaceWithWhat);
+	}
 
 
-    }
-	//-----------------------------------------------------------------------
-	void StringUtil::splitBaseFilename(const CamelotFramework::String& fullName, 
-		CamelotFramework::String& outBasename, CamelotFramework::String& outExtention)
+	const WString StringUtil::replaceAll(const WString& source, const WString& replaceWhat, const WString& replaceWithWhat)
 	{
 	{
-		size_t i = fullName.find_last_of(".");
-		if (i == CamelotFramework::String::npos)
-		{
-			outExtention.clear();
-			outBasename = fullName;
-		}
-		else
-		{
-			outExtention = fullName.substr(i+1);
-			outBasename = fullName.substr(0, i);
-		}
+		return replaceAllInternal<wchar_t>(source, replaceWhat, replaceWithWhat);
 	}
 	}
-	// ----------------------------------------------------------------------------------------------------------------------------------------------
-	void StringUtil::splitFullFilename(	const CamelotFramework::String& qualifiedName, 
-		CamelotFramework::String& outBasename, CamelotFramework::String& outExtention, CamelotFramework::String& outPath )
+
+	/************************************************************************/
+	/* 						VARIOUS TO STRING CONVERSIONS                   */
+	/************************************************************************/
+
+	WString toWString(const String& source)
 	{
 	{
-		CamelotFramework::String fullName;
-		splitFilename( qualifiedName, fullName, outPath );
-		splitBaseFilename( fullName, outBasename, outExtention );
+		return WString(source.begin(), source.end());
 	}
 	}
-    //-----------------------------------------------------------------------
-    bool StringUtil::match(const String& str, const String& pattern, bool caseSensitive)
-    {
-        String tmpStr = str;
-		String tmpPattern = pattern;
-        if (!caseSensitive)
-        {
-            StringUtil::toLowerCase(tmpStr);
-            StringUtil::toLowerCase(tmpPattern);
-        }
-
-        String::const_iterator strIt = tmpStr.begin();
-        String::const_iterator patIt = tmpPattern.begin();
-		String::const_iterator lastWildCardIt = tmpPattern.end();
-        while (strIt != tmpStr.end() && patIt != tmpPattern.end())
-        {
-            if (*patIt == '*')
-            {
-				lastWildCardIt = patIt;
-                // Skip over looking for next character
-                ++patIt;
-                if (patIt == tmpPattern.end())
-				{
-					// Skip right to the end since * matches the entire rest of the string
-					strIt = tmpStr.end();
-				}
-				else
-                {
-					// scan until we find next pattern character
-                    while(strIt != tmpStr.end() && *strIt != *patIt)
-                        ++strIt;
-                }
-            }
-            else
-            {
-                if (*patIt != *strIt)
-                {
-					if (lastWildCardIt != tmpPattern.end())
-					{
-						// The last wildcard can match this incorrect sequence
-						// rewind pattern to wildcard and keep searching
-						patIt = lastWildCardIt;
-						lastWildCardIt = tmpPattern.end();
-					}
-					else
-					{
-						// no wildwards left
-						return false;
-					}
-                }
-                else
-                {
-                    ++patIt;
-                    ++strIt;
-                }
-            }
-
-        }
-		// If we reached the end of both the pattern and the string, we succeeded
-		if (patIt == tmpPattern.end() && strIt == tmpStr.end())
-		{
-        	return true;
-		}
-		else
-		{
-			return false;
-		}
 
 
-    }
-	//-----------------------------------------------------------------------
-	const String StringUtil::replaceAll(const String& source, const String& replaceWhat, const String& replaceWithWhat)
+	String toString(const WString& source)
 	{
 	{
-		String result = source;
-        String::size_type pos = 0;
-		while(1)
-		{
-			pos = result.find(replaceWhat,pos);
-			if (pos == String::npos) break;
-			result.replace(pos,replaceWhat.size(),replaceWithWhat);
-            pos += replaceWithWhat.size();
-		}
-		return result;
+		return String(source.begin(), source.end());
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(float val, unsigned short precision, 
 	String toString(float val, unsigned short precision, 
 		unsigned short width, char fill, std::ios::fmtflags flags)
 		unsigned short width, char fill, std::ios::fmtflags flags)
 	{
 	{
-		stringstream stream;
+		StringStream stream;
 		stream.precision(precision);
 		stream.precision(precision);
 		stream.width(width);
 		stream.width(width);
 		stream.fill(fill);
 		stream.fill(fill);
@@ -384,23 +166,23 @@ namespace CamelotFramework {
 		stream << val;
 		stream << val;
 		return stream.str();
 		return stream.str();
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(Radian val, unsigned short precision, 
 	String toString(Radian val, unsigned short precision, 
 		unsigned short width, char fill, std::ios::fmtflags flags)
 		unsigned short width, char fill, std::ios::fmtflags flags)
 	{
 	{
 		return toString(val.valueAngleUnits(), precision, width, fill, flags);
 		return toString(val.valueAngleUnits(), precision, width, fill, flags);
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(Degree val, unsigned short precision, 
 	String toString(Degree val, unsigned short precision, 
 		unsigned short width, char fill, std::ios::fmtflags flags)
 		unsigned short width, char fill, std::ios::fmtflags flags)
 	{
 	{
 		return toString(val.valueAngleUnits(), precision, width, fill, flags);
 		return toString(val.valueAngleUnits(), precision, width, fill, flags);
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(int val, 
 	String toString(int val, 
 		unsigned short width, char fill, std::ios::fmtflags flags)
 		unsigned short width, char fill, std::ios::fmtflags flags)
 	{
 	{
-		stringstream stream;
+		StringStream stream;
 		stream.width(width);
 		stream.width(width);
 		stream.fill(fill);
 		stream.fill(fill);
 		if (flags)
 		if (flags)
@@ -408,12 +190,11 @@ namespace CamelotFramework {
 		stream << val;
 		stream << val;
 		return stream.str();
 		return stream.str();
 	}
 	}
-	//-----------------------------------------------------------------------
+
 #if CM_ARCH_TYPE == CM_ARCHITECTURE_64 || CM_PLATFORM == CM_PLATFORM_APPLE
 #if CM_ARCH_TYPE == CM_ARCHITECTURE_64 || CM_PLATFORM == CM_PLATFORM_APPLE
-	String toString(unsigned int val, 
-		unsigned short width, char fill, std::ios::fmtflags flags)
+	String toString(unsigned int val, unsigned short width, char fill, std::ios::fmtflags flags)
 	{
 	{
-		stringstream stream;
+		StringStream stream;
 		stream.width(width);
 		stream.width(width);
 		stream.fill(fill);
 		stream.fill(fill);
 		if (flags)
 		if (flags)
@@ -421,11 +202,10 @@ namespace CamelotFramework {
 		stream << val;
 		stream << val;
 		return stream.str();
 		return stream.str();
 	}
 	}
-	//-----------------------------------------------------------------------
-	String toString(size_t val, 
-		unsigned short width, char fill, std::ios::fmtflags flags)
+
+	String toString(size_t val, unsigned short width, char fill, std::ios::fmtflags flags)
 	{
 	{
-		stringstream stream;
+		StringStream stream;
 		stream.width(width);
 		stream.width(width);
 		stream.fill(fill);
 		stream.fill(fill);
 		if (flags)
 		if (flags)
@@ -434,11 +214,10 @@ namespace CamelotFramework {
 		return stream.str();
 		return stream.str();
 	}
 	}
 #if CM_COMPILER == CM_COMPILER_MSVC
 #if CM_COMPILER == CM_COMPILER_MSVC
-	//-----------------------------------------------------------------------
-	String toString(unsigned long val, 
-		unsigned short width, char fill, std::ios::fmtflags flags)
+
+	String toString(unsigned long val, unsigned short width, char fill, std::ios::fmtflags flags)
 	{
 	{
-		stringstream stream;
+		StringStream stream;
 		stream.width(width);
 		stream.width(width);
 		stream.fill(fill);
 		stream.fill(fill);
 		if (flags)
 		if (flags)
@@ -448,12 +227,11 @@ namespace CamelotFramework {
 	}
 	}
 
 
 #endif
 #endif
-	//-----------------------------------------------------------------------
+
 #else
 #else
-	String toString(size_t val, 
-		unsigned short width, char fill, std::ios::fmtflags flags)
+	String toString(size_t val, unsigned short width, char fill, std::ios::fmtflags flags)
 	{
 	{
-		stringstream stream;
+		StringStream stream;
 		stream.width(width);
 		stream.width(width);
 		stream.fill(fill);
 		stream.fill(fill);
 		if (flags)
 		if (flags)
@@ -461,11 +239,10 @@ namespace CamelotFramework {
 		stream << val;
 		stream << val;
 		return stream.str();
 		return stream.str();
 	}
 	}
-	//-----------------------------------------------------------------------
-	String toString(unsigned long val, 
-		unsigned short width, char fill, std::ios::fmtflags flags)
+
+	String toString(unsigned long val, unsigned short width, char fill, std::ios::fmtflags flags)
 	{
 	{
-		stringstream stream;
+		StringStream stream;
 		stream.width(width);
 		stream.width(width);
 		stream.fill(fill);
 		stream.fill(fill);
 		if (flags)
 		if (flags)
@@ -473,11 +250,10 @@ namespace CamelotFramework {
 		stream << val;
 		stream << val;
 		return stream.str();
 		return stream.str();
 	}
 	}
-	//-----------------------------------------------------------------------
-	String toString(unsigned long long int val, 
-		unsigned short width, char fill, std::ios::fmtflags flags)
+
+	String toString(unsigned long long int val, unsigned short width, char fill, std::ios::fmtflags flags)
 	{
 	{
-		stringstream stream;
+		StringStream stream;
 		stream.width(width);
 		stream.width(width);
 		stream.fill(fill);
 		stream.fill(fill);
 		if (flags)
 		if (flags)
@@ -485,12 +261,11 @@ namespace CamelotFramework {
 		stream << val;
 		stream << val;
 		return stream.str();
 		return stream.str();
 	}
 	}
-	//-----------------------------------------------------------------------
 #endif
 #endif
 	String toString(long val, 
 	String toString(long val, 
 		unsigned short width, char fill, std::ios::fmtflags flags)
 		unsigned short width, char fill, std::ios::fmtflags flags)
 	{
 	{
-		stringstream stream;
+		StringStream stream;
 		stream.width(width);
 		stream.width(width);
 		stream.fill(fill);
 		stream.fill(fill);
 		if (flags)
 		if (flags)
@@ -498,31 +273,31 @@ namespace CamelotFramework {
 		stream << val;
 		stream << val;
 		return stream.str();
 		return stream.str();
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(const Vector2& val)
 	String toString(const Vector2& val)
 	{
 	{
-		stringstream stream;
+		StringStream stream;
 		stream << val.x << " " << val.y;
 		stream << val.x << " " << val.y;
 		return stream.str();
 		return stream.str();
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(const Vector3& val)
 	String toString(const Vector3& val)
 	{
 	{
-		stringstream stream;
+		StringStream stream;
 		stream << val.x << " " << val.y << " " << val.z;
 		stream << val.x << " " << val.y << " " << val.z;
 		return stream.str();
 		return stream.str();
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(const Vector4& val)
 	String toString(const Vector4& val)
 	{
 	{
-		stringstream stream;
+		StringStream stream;
 		stream << val.x << " " << val.y << " " << val.z << " " << val.w;
 		stream << val.x << " " << val.y << " " << val.z << " " << val.w;
 		return stream.str();
 		return stream.str();
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(const Matrix3& val)
 	String toString(const Matrix3& val)
 	{
 	{
-		stringstream stream;
+		StringStream stream;
 		stream << val[0][0] << " " 
 		stream << val[0][0] << " " 
 			<< val[0][1] << " "             
 			<< val[0][1] << " "             
 			<< val[0][2] << " "             
 			<< val[0][2] << " "             
@@ -534,7 +309,7 @@ namespace CamelotFramework {
 			<< val[2][2];
 			<< val[2][2];
 		return stream.str();
 		return stream.str();
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(bool val, bool yesNo)
 	String toString(bool val, bool yesNo)
 	{
 	{
 		if (val)
 		if (val)
@@ -558,10 +333,10 @@ namespace CamelotFramework {
 				return "false";
 				return "false";
 			}
 			}
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(const Matrix4& val)
 	String toString(const Matrix4& val)
 	{
 	{
-		stringstream stream;
+		StringStream stream;
 		stream << val[0][0] << " " 
 		stream << val[0][0] << " " 
 			<< val[0][1] << " "             
 			<< val[0][1] << " "             
 			<< val[0][2] << " "             
 			<< val[0][2] << " "             
@@ -580,24 +355,24 @@ namespace CamelotFramework {
 			<< val[3][3];
 			<< val[3][3];
 		return stream.str();
 		return stream.str();
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(const Quaternion& val)
 	String toString(const Quaternion& val)
 	{
 	{
-		stringstream stream;
+		StringStream stream;
 		stream  << val.w << " " << val.x << " " << val.y << " " << val.z;
 		stream  << val.w << " " << val.x << " " << val.y << " " << val.z;
 		return stream.str();
 		return stream.str();
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(const Color& val)
 	String toString(const Color& val)
 	{
 	{
-		stringstream stream;
+		StringStream stream;
 		stream << val.r << " " << val.g << " " << val.b << " " << val.a;
 		stream << val.r << " " << val.g << " " << val.b << " " << val.a;
 		return stream.str();
 		return stream.str();
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(const vector<CamelotFramework::String>::type& val)
 	String toString(const vector<CamelotFramework::String>::type& val)
 	{
 	{
-		stringstream stream;
+		StringStream stream;
 		vector<CamelotFramework::String>::type::const_iterator i, iend, ibegin;
 		vector<CamelotFramework::String>::type::const_iterator i, iend, ibegin;
 		ibegin = val.begin();
 		ibegin = val.begin();
 		iend = val.end();
 		iend = val.end();
@@ -610,7 +385,7 @@ namespace CamelotFramework {
 		}
 		}
 		return stream.str();
 		return stream.str();
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	float parseFloat(const String& val, float defaultValue)
 	float parseFloat(const String& val, float defaultValue)
 	{
 	{
 		// Use istringstream for direct correspondence with toString
 		// Use istringstream for direct correspondence with toString
@@ -620,7 +395,7 @@ namespace CamelotFramework {
 
 
 		return ret;
 		return ret;
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	int parseInt(const String& val, int defaultValue)
 	int parseInt(const String& val, int defaultValue)
 	{
 	{
 		// Use istringstream for direct correspondence with toString
 		// Use istringstream for direct correspondence with toString
@@ -630,7 +405,7 @@ namespace CamelotFramework {
 
 
 		return ret;
 		return ret;
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	unsigned int parseUnsignedInt(const String& val, unsigned int defaultValue)
 	unsigned int parseUnsignedInt(const String& val, unsigned int defaultValue)
 	{
 	{
 		// Use istringstream for direct correspondence with toString
 		// Use istringstream for direct correspondence with toString
@@ -640,7 +415,7 @@ namespace CamelotFramework {
 
 
 		return ret;
 		return ret;
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	long parseLong(const String& val, long defaultValue)
 	long parseLong(const String& val, long defaultValue)
 	{
 	{
 		// Use istringstream for direct correspondence with toString
 		// Use istringstream for direct correspondence with toString
@@ -650,7 +425,7 @@ namespace CamelotFramework {
 
 
 		return ret;
 		return ret;
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	unsigned long parseUnsignedLong(const String& val, unsigned long defaultValue)
 	unsigned long parseUnsignedLong(const String& val, unsigned long defaultValue)
 	{
 	{
 		// Use istringstream for direct correspondence with toString
 		// Use istringstream for direct correspondence with toString
@@ -660,7 +435,7 @@ namespace CamelotFramework {
 
 
 		return ret;
 		return ret;
 	}
 	}
-	//-----------------------------------------------------------------------
+
 	bool parseBool(const String& val, bool defaultValue)
 	bool parseBool(const String& val, bool defaultValue)
 	{
 	{
 		if ((StringUtil::startsWith(val, "true") || StringUtil::startsWith(val, "yes")
 		if ((StringUtil::startsWith(val, "true") || StringUtil::startsWith(val, "yes")
@@ -672,12 +447,7 @@ namespace CamelotFramework {
 		else
 		else
 			return defaultValue;
 			return defaultValue;
 	}
 	}
-	//-----------------------------------------------------------------------
-	vector<CamelotFramework::String>::type parseStringVector(const String& val)
-	{
-		return StringUtil::split(val);
-	}
-	//-----------------------------------------------------------------------
+
 	bool isNumber(const String& val)
 	bool isNumber(const String& val)
 	{
 	{
 		StringStream str(val);
 		StringStream str(val);
@@ -685,7 +455,7 @@ namespace CamelotFramework {
 		str >> tst;
 		str >> tst;
 		return !str.fail() && str.eof();
 		return !str.fail() && str.eof();
 	}
 	}
-	//----------------------------------------------------------------------
+
 	void __string_throwDataOverflowException()
 	void __string_throwDataOverflowException()
 	{
 	{
 		CM_EXCEPT(InternalErrorException, "Data overflow! Size doesn't fit into 32 bits.");
 		CM_EXCEPT(InternalErrorException, "Data overflow! Size doesn't fit into 32 bits.");

+ 1 - 1
CamelotUtility/Source/CmUUID.cpp

@@ -13,6 +13,6 @@ namespace CamelotFramework
 
 
 		uuid newUUID = gen();
 		uuid newUUID = gen();
 
 
-		return to_string(newUUID);
+		return to_string(newUUID).c_str();
 	}
 	}
 };
 };

+ 1 - 2
CamelotUtility/Source/CmWorkQueue.cpp

@@ -396,8 +396,7 @@ namespace CamelotFramework {
 		else
 		else
 		{
 		{
 			// no response, delete request
 			// no response, delete request
-			gDebug().logWarning("warning: no handler processed request "
-				+ toString(r->getID()) + ", channel " + toString(r->getChannel()));
+			gDebug().logWarning("warning: no handler processed request " + toString(r->getID()) + ", channel " + toString(r->getChannel()));
 
 
 			cm_delete<ScratchAlloc>(r);
 			cm_delete<ScratchAlloc>(r);
 		}
 		}

+ 2 - 0
TODO.txt

@@ -22,6 +22,8 @@ I call waitUntilLoaded too many times. Sometimes 5-6 times in a single function.
 GUIWidget::updateMeshes leaks. If I leave the game running I can see memory continously going up
 GUIWidget::updateMeshes leaks. If I leave the game running I can see memory continously going up
 
 
 IMMEDIATE:
 IMMEDIATE:
+ - Get rid of querying mouse states on each mouse event - Include button states in each event?
+ - Handle capital leters - include shift, alt, ctrl, caps states in KeyEvent
  - Add window-management command to DeferredRenderContext - I already have resource management commands
  - Add window-management command to DeferredRenderContext - I already have resource management commands
    there, few window related ones won't hurt. I can always split the class if needed.
    there, few window related ones won't hurt. I can always split the class if needed.
      - Possibly add guards to render target classes so they aren't accidentaly accessed from the render thread (similar to how Texture is handled)
      - Possibly add guards to render target classes so they aren't accidentaly accessed from the render thread (similar to how Texture is handled)