Browse Source

Added wide strings
Added custom string allocators

Marko Pintera 12 năm trước cách đây
mục cha
commit
ea7362503f
36 tập tin đã thay đổi với 623 bổ sung546 xóa
  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 GUILayoutOptions& layoutOptions, const GUIElementStyle* style = nullptr);
 
-		void setText(const CM::String& text);
+		void setText(const CM::WString& text);
 
 	protected:
 		~GUILabel();

+ 1 - 1
BansheeEngine/Include/BsGUISkin.h

@@ -14,6 +14,6 @@ namespace BansheeEngine
 	private:
 		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
 {
-	const std::string SystemName = "BansheeForwardRenderer";
+	const CM::String SystemName = "BansheeForwardRenderer";
 
 	class BS_FWDRND_EXPORT ForwardRendererFactory : public CM::RendererFactory
 	{
 	public:
 		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>();
 	}
 
-	const std::string& ForwardRendererFactory::name() const
+	const String& ForwardRendererFactory::name() const
 	{
 		return SystemName;
 	}

+ 3 - 3
CamelotClient/BsGUITabbedTitleBar.cpp

@@ -30,7 +30,7 @@ namespace BansheeEditor
 
 	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"));
 
 		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"));
 		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);
 		mMainLayout = &mMainArea->getLayout().addLayoutX();

+ 1 - 1
CamelotClient/CmTestTextSprite.cpp

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

+ 1 - 1
CamelotCore/Include/CmRenderSystemCapabilities.h

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

+ 2 - 7
CamelotCore/Include/CmRenderSystemFactory.h

@@ -1,21 +1,16 @@
 #pragma once
 
-#include <string>
-#include <memory>
+#include "CmPrerequisites.h"
 
 namespace CamelotFramework
 {
 	class RenderSystem;
-}
-
-namespace CamelotFramework
-{
 	typedef std::shared_ptr<RenderSystem> RenderSystemPtr;
 
 	class RenderSystemFactory
 	{
 	public:
 		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:
 		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)
 		{
-			std::ostringstream stringStream;
+			StringStream stringStream;
 			for(auto iter = includes->begin(); iter != includes->end(); ++iter)
 			{
 				if(*iter != nullptr)

+ 2 - 2
CamelotD3D11RenderSystem/Include/CmD3D11RenderSystemFactory.h

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

+ 2 - 2
CamelotD3D9Renderer/Include/CmD3D9RenderSystemFactory.h

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

+ 1 - 1
CamelotD3D9Renderer/Source/CmD3D9Driver.cpp

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

+ 1 - 1
CamelotFreeImgImporter/Source/CmFreeImgImporter.cpp

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

+ 2 - 2
CamelotGLRenderer/Include/CmGLRenderSystemFactory.h

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

+ 1 - 1
CamelotGLRenderer/Source/CmWin32GLSupport.cpp

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

+ 4 - 12
CamelotUtility/Include/CmDebug.h

@@ -10,10 +10,10 @@ namespace CamelotFramework
 	class CM_UTILITY_EXPORT Debug
 	{
 	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);
 
 		Log& getLog() { return mLog; }
@@ -26,14 +26,6 @@ namespace CamelotFramework
 
 	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 LOGINFO(x) CamelotFramework::gDebug().logInfo((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 
 	{
 	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) {}
 	};
 	class CM_UTILITY_EXPORT FileNotFoundException : public Exception
 	{
 	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) {}
 	};
 	class CM_UTILITY_EXPORT IOException : public Exception
 	{
 	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) {}
 	};
 	class CM_UTILITY_EXPORT InvalidStateException : public Exception
 	{
 	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) {}
 	};
 	class CM_UTILITY_EXPORT InvalidParametersException : public Exception
 	{
 	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) {}
 	};
 	class CM_UTILITY_EXPORT ItemIdentityException : public Exception
 	{
 	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) {}
 	};
 	class CM_UTILITY_EXPORT InternalErrorException : public Exception
 	{
 	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) {}
 	};
 	class CM_UTILITY_EXPORT RenderingAPIException : public Exception
 	{
 	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) {}
 	};
 	class CM_UTILITY_EXPORT RuntimeAssertionException : public Exception
 	{
 	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) {}
 	};
 

+ 2 - 2
CamelotUtility/Include/CmFileSerializer.h

@@ -12,8 +12,8 @@ namespace CamelotFramework
 		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:
 		std::ofstream mOutputStream;

+ 67 - 2
CamelotUtility/Include/CmPath.h

@@ -6,14 +6,14 @@
 namespace CamelotFramework
 {
 	/**
-	 * @brief	Various utility methods for handling file paths.
+	 * @brief	Various string manipulations of file paths.
 	 */
 	class Path
 	{
 	public:
 		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)
@@ -28,5 +28,70 @@ namespace CamelotFramework
 			else
 				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 arraySizeSetter;
 
-		std::string mName;
+		String mName;
 		UINT16 mUniqueId;
 		bool mIsVectorType;
 		SerializableFieldType mType;
@@ -122,7 +122,7 @@ namespace CamelotFramework
 
 	protected:
 		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->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	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);
 			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	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
 
@@ -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	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)
 		{
 			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	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);
 		}
@@ -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	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)
 		{
 			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	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);
 		}
@@ -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	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)
 		{
 			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) {}
 
 		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);
 			genericField->checkIsPlain(false);
@@ -68,7 +68,7 @@ namespace CamelotFramework
 		}
 
 		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);
 			genericField->checkIsPlain(true);
@@ -78,7 +78,7 @@ namespace CamelotFramework
 		}
 
 		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), 
 				"Invalid data type for complex field. It needs to derive from CamelotFramework::IReflectable.");
@@ -91,7 +91,7 @@ namespace CamelotFramework
 		}
 
 		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), 
 				"Invalid data type for complex field. It needs to derive from CamelotFramework::IReflectable.");
@@ -104,7 +104,7 @@ namespace CamelotFramework
 		}
 
 		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);
 			genericField->checkIsDataBlock();
@@ -115,7 +115,7 @@ namespace CamelotFramework
 
 
 		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), 
 				"Invalid data type for complex field. It needs to derive from CamelotFramework::IReflectable.");
@@ -128,7 +128,7 @@ namespace CamelotFramework
 		}
 
 		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), 
 				"Invalid data type for complex field. It needs to derive from CamelotFramework::IReflectable.");
@@ -141,7 +141,7 @@ namespace CamelotFramework
 		}
 
 		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);
 			genericField->checkIsPlain(false);
@@ -151,7 +151,7 @@ namespace CamelotFramework
 		}
 
 		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);
 			genericField->checkIsPlain(true);
@@ -161,7 +161,7 @@ namespace CamelotFramework
 		}	
 
 		template <class ObjectType>
-		IReflectable& getReflectableValue(ObjectType* object, const std::string& name)
+		IReflectable& getReflectableValue(ObjectType* object, const String& name)
 		{
 			RTTIField* genericField = findField(name);
 			genericField->checkIsComplex(false);
@@ -171,7 +171,7 @@ namespace CamelotFramework
 		}
 
 		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);
 			genericField->checkIsComplex(true);
@@ -181,7 +181,7 @@ namespace CamelotFramework
 		}
 
 		template <class ObjectType>
-		ManagedDataBlock getDataBlockValue(ObjectType* object, const std::string& name)
+		ManagedDataBlock getDataBlockValue(ObjectType* object, const String& name)
 		{
 			RTTIField* genericField = findField(name);
 			genericField->checkIsDataBlock();
@@ -191,7 +191,7 @@ namespace CamelotFramework
 		}
 
 		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);
 			genericField->checkIsComplexPtr(false);
@@ -201,7 +201,7 @@ namespace CamelotFramework
 		}
 
 		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);
 			genericField->checkIsComplexPtr(true);
@@ -211,14 +211,14 @@ namespace CamelotFramework
 		}
 
 		template <class ObjectType>
-		UINT32 getArraySize(ObjectType* object, const std::string& name)
+		UINT32 getArraySize(ObjectType* object, const String& name)
 		{
 			RTTIField* field = findField(name);
 			return field->getArraySize(object);
 		}
 
 		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);
 			field->setArraySize(object, size);
@@ -232,7 +232,7 @@ namespace CamelotFramework
 		 *
 		 * @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
@@ -397,7 +397,7 @@ namespace CamelotFramework
 		/* 			FIELDS OPERATING DIRECTLY ON SERIALIZABLE OBJECT            */
 		/************************************************************************/
 		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)
 		{
 			addPlainField<ObjectType, DataType>(name, uniqueId, 
@@ -406,7 +406,7 @@ namespace CamelotFramework
 		}
 
 		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)
 		{
 			addReflectableField<ObjectType, DataType>(name, uniqueId, 
@@ -415,7 +415,7 @@ namespace CamelotFramework
 		}
 
 		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)
 		{
 			addReflectablePtrField<ObjectType, DataType>(name, uniqueId, 
@@ -424,7 +424,7 @@ namespace CamelotFramework
 		}
 
 		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)
 		{
 			addPlainArrayField<ObjectType, DataType>(name, uniqueId, 
@@ -435,7 +435,7 @@ namespace CamelotFramework
 		}	
 
 		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)
 		{
 			addReflectableArrayField<ObjectType, DataType>(name, uniqueId, 
@@ -446,7 +446,7 @@ namespace CamelotFramework
 		}
 
 		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)
 		{
 			addReflectablePtrArrayField<ObjectType, DataType>(name, uniqueId, 
@@ -457,7 +457,7 @@ namespace CamelotFramework
 		}
 
 		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)
 		{
 			addDataBlockField<ObjectType>(name, uniqueId, 
@@ -473,7 +473,7 @@ namespace CamelotFramework
 		/*		(Needs an extra pointer to the actual object)					*/
 		/************************************************************************/
 		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*), 
 			void (InterfaceType::*setter)(ObjectType*, DataType&), UINT64 flags = 0)
 		{
@@ -489,7 +489,7 @@ namespace CamelotFramework
 		}
 
 		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*), 
 			void (InterfaceType::*setter)(ObjectType*, DataType&), UINT64 flags = 0)
 		{
@@ -499,7 +499,7 @@ namespace CamelotFramework
 		}
 
 		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*), 
 			void (InterfaceType::*setter)(ObjectType*, std::shared_ptr<DataType>), UINT64 flags = 0)
 		{
@@ -509,7 +509,7 @@ namespace CamelotFramework
 		}
 
 		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), 
 			UINT32 (InterfaceType::*getSize)(ObjectType*), 
 			void (InterfaceType::*setter)(ObjectType*, UINT32, DataType&), 
@@ -529,7 +529,7 @@ namespace CamelotFramework
 		}	
 
 		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), 
 			UINT32 (InterfaceType::*getSize)(ObjectType*), 
 			void (InterfaceType::*setter)(ObjectType*, UINT32, DataType&), 
@@ -543,7 +543,7 @@ namespace CamelotFramework
 		}
 
 		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), 
 			UINT32 (InterfaceType::*getSize)(ObjectType*), 
 			void (InterfaceType::*setter)(ObjectType*, UINT32, std::shared_ptr<DataType>), 
@@ -557,7 +557,7 @@ namespace CamelotFramework
 		}
 
 		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, 
 			UINT8* (customAllocator)(ObjectType*, UINT32) = 0)
 		{
@@ -578,7 +578,7 @@ namespace CamelotFramework
 
 	private:
 		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 = 
 				cm_new<RTTIPlainField<DataType, ObjectType>>();
@@ -587,7 +587,7 @@ namespace CamelotFramework
 		}
 		
 		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), 
 				"Invalid data type for complex field. It needs to derive from CamelotFramework::IReflectable.");
@@ -599,7 +599,7 @@ namespace CamelotFramework
 		}
 
 		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), 
 				"Invalid data type for complex field. It needs to derive from CamelotFramework::IReflectable.");
@@ -614,7 +614,7 @@ namespace CamelotFramework
 		}
 
 		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)
 		{
 			RTTIPlainField<DataType, ObjectType>* newField = 
@@ -624,7 +624,7 @@ namespace CamelotFramework
 		}	
 
 		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_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::IReflectable, DataType>::value), 
@@ -637,7 +637,7 @@ namespace CamelotFramework
 		}
 
 		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_STATIC_ASSERT_MSG((boost::is_base_of<CamelotFramework::IReflectable, DataType>::value), 
@@ -653,7 +653,7 @@ namespace CamelotFramework
 		}
 
 		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 = 
 				cm_new<RTTIManagedDataBlockField<ManagedDataBlock, ObjectType>>();

+ 323 - 69
CamelotUtility/Include/CmString.h

@@ -62,24 +62,25 @@ namespace __gnu_cxx
 
 #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
 	*  @{
@@ -92,7 +93,14 @@ namespace CamelotFramework {
     class CM_UTILITY_EXPORT StringUtil
     {
 	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
             TABs and so on.
@@ -101,7 +109,7 @@ namespace CamelotFramework {
                 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 );
+        static void trim(WString& str, bool left = true, bool right = true);
 
         /** Returns a StringVector that contains all the substrings delimited
             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
                 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
             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
                 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.
         */
-        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.
         */
-        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.
         @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);
 
+        /** 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.
         @param pattern The pattern to compare with.
         @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);
 
-        /** 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.
         @param str String to test
@@ -185,8 +210,14 @@ namespace CamelotFramework {
         */
         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 replaceWhat Sub-string to find and replace
 		@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);
 
+		/** 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
         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. */
     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);
 
-    /** 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. */
     CM_UTILITY_EXPORT bool isNumber(const String& val);
 	/** @} */

+ 4 - 4
CamelotUtility/Source/CmDebug.cpp

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

+ 1 - 1
CamelotUtility/Source/CmException.cpp

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

+ 2 - 2
CamelotUtility/Source/CmFileSerializer.cpp

@@ -19,7 +19,7 @@ namespace CamelotFramework
 		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);
 
@@ -31,7 +31,7 @@ namespace CamelotFramework
 		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);
 		

+ 10 - 10
CamelotUtility/Source/CmFileSystem.cpp

@@ -98,7 +98,7 @@ namespace CamelotFramework
 
 	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 false;
@@ -106,7 +106,7 @@ namespace CamelotFramework
 
 	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 false;
@@ -114,24 +114,24 @@ namespace CamelotFramework
 
 	void FileSystem::createDir(const String& fullPath)
 	{
-		boost::filesystem::create_directory(fullPath);
+		boost::filesystem::create_directory(fullPath.c_str());
 	}
 
 	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)
 	{
-		boost::filesystem::directory_iterator dirIter(dirPath);
+		boost::filesystem::directory_iterator dirIter(dirPath.c_str());
 
 		vector<String>::type foundFiles;
 		
 		while(dirIter != boost::filesystem::directory_iterator())
 		{
 			if(boost::filesystem::is_regular_file(dirIter->path()))
-				foundFiles.push_back(dirIter->path().string());
+				foundFiles.push_back(dirIter->path().string().c_str());
 
 			dirIter++;
 		}
@@ -141,22 +141,22 @@ namespace CamelotFramework
 
 	String FileSystem::getCurrentPath()
 	{
-		return boost::filesystem::current_path().string();
+		return boost::filesystem::current_path().string().c_str();
 	}
 
 	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)
 	{
-		boost::filesystem::path p(path);
+		boost::filesystem::path p(path.c_str());
 
 		if(!is_directory(p))
 		{
 			boost::filesystem::path dir = p.parent_path();
-			return dir.string();
+			return dir.string().c_str();
 		}
 
 		return path;

+ 2 - 2
CamelotUtility/Source/CmRTTIType.cpp

@@ -14,7 +14,7 @@ namespace CamelotFramework
 		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; });
 
@@ -54,7 +54,7 @@ namespace CamelotFramework
 				"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; });
 
 		if(foundElementByName != mFields.end())

+ 125 - 355
CamelotUtility/Source/CmString.cpp

@@ -37,36 +37,13 @@ THE SOFTWARE.
 #include "CmVector4.h"
 #include "CmException.h"
 
-namespace CamelotFramework {
-
-	//-----------------------------------------------------------------------
+namespace CamelotFramework 
+{
 	const String StringUtil::BLANK;
-	//-----------------------------------------------------------------------
+	const WString StringUtil::WBLANK;
+
     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";
         if(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
     }
 
-    //-----------------------------------------------------------------------
-    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)
     {
-        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) 
     {
-        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)
     {
-        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)
     {
-        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, 
 		unsigned short width, char fill, std::ios::fmtflags flags)
 	{
-		stringstream stream;
+		StringStream stream;
 		stream.precision(precision);
 		stream.width(width);
 		stream.fill(fill);
@@ -384,23 +166,23 @@ namespace CamelotFramework {
 		stream << val;
 		return stream.str();
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(Radian val, unsigned short precision, 
 		unsigned short width, char fill, std::ios::fmtflags flags)
 	{
 		return toString(val.valueAngleUnits(), precision, width, fill, flags);
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(Degree val, unsigned short precision, 
 		unsigned short width, char fill, std::ios::fmtflags flags)
 	{
 		return toString(val.valueAngleUnits(), precision, width, fill, flags);
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(int val, 
 		unsigned short width, char fill, std::ios::fmtflags flags)
 	{
-		stringstream stream;
+		StringStream stream;
 		stream.width(width);
 		stream.fill(fill);
 		if (flags)
@@ -408,12 +190,11 @@ namespace CamelotFramework {
 		stream << val;
 		return stream.str();
 	}
-	//-----------------------------------------------------------------------
+
 #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.fill(fill);
 		if (flags)
@@ -421,11 +202,10 @@ namespace CamelotFramework {
 		stream << val;
 		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.fill(fill);
 		if (flags)
@@ -434,11 +214,10 @@ namespace CamelotFramework {
 		return stream.str();
 	}
 #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.fill(fill);
 		if (flags)
@@ -448,12 +227,11 @@ namespace CamelotFramework {
 	}
 
 #endif
-	//-----------------------------------------------------------------------
+
 #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.fill(fill);
 		if (flags)
@@ -461,11 +239,10 @@ namespace CamelotFramework {
 		stream << val;
 		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.fill(fill);
 		if (flags)
@@ -473,11 +250,10 @@ namespace CamelotFramework {
 		stream << val;
 		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.fill(fill);
 		if (flags)
@@ -485,12 +261,11 @@ namespace CamelotFramework {
 		stream << val;
 		return stream.str();
 	}
-	//-----------------------------------------------------------------------
 #endif
 	String toString(long val, 
 		unsigned short width, char fill, std::ios::fmtflags flags)
 	{
-		stringstream stream;
+		StringStream stream;
 		stream.width(width);
 		stream.fill(fill);
 		if (flags)
@@ -498,31 +273,31 @@ namespace CamelotFramework {
 		stream << val;
 		return stream.str();
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(const Vector2& val)
 	{
-		stringstream stream;
+		StringStream stream;
 		stream << val.x << " " << val.y;
 		return stream.str();
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(const Vector3& val)
 	{
-		stringstream stream;
+		StringStream stream;
 		stream << val.x << " " << val.y << " " << val.z;
 		return stream.str();
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(const Vector4& val)
 	{
-		stringstream stream;
+		StringStream stream;
 		stream << val.x << " " << val.y << " " << val.z << " " << val.w;
 		return stream.str();
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(const Matrix3& val)
 	{
-		stringstream stream;
+		StringStream stream;
 		stream << val[0][0] << " " 
 			<< val[0][1] << " "             
 			<< val[0][2] << " "             
@@ -534,7 +309,7 @@ namespace CamelotFramework {
 			<< val[2][2];
 		return stream.str();
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(bool val, bool yesNo)
 	{
 		if (val)
@@ -558,10 +333,10 @@ namespace CamelotFramework {
 				return "false";
 			}
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(const Matrix4& val)
 	{
-		stringstream stream;
+		StringStream stream;
 		stream << val[0][0] << " " 
 			<< val[0][1] << " "             
 			<< val[0][2] << " "             
@@ -580,24 +355,24 @@ namespace CamelotFramework {
 			<< val[3][3];
 		return stream.str();
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(const Quaternion& val)
 	{
-		stringstream stream;
+		StringStream stream;
 		stream  << val.w << " " << val.x << " " << val.y << " " << val.z;
 		return stream.str();
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(const Color& val)
 	{
-		stringstream stream;
+		StringStream stream;
 		stream << val.r << " " << val.g << " " << val.b << " " << val.a;
 		return stream.str();
 	}
-	//-----------------------------------------------------------------------
+
 	String toString(const vector<CamelotFramework::String>::type& val)
 	{
-		stringstream stream;
+		StringStream stream;
 		vector<CamelotFramework::String>::type::const_iterator i, iend, ibegin;
 		ibegin = val.begin();
 		iend = val.end();
@@ -610,7 +385,7 @@ namespace CamelotFramework {
 		}
 		return stream.str();
 	}
-	//-----------------------------------------------------------------------
+
 	float parseFloat(const String& val, float defaultValue)
 	{
 		// Use istringstream for direct correspondence with toString
@@ -620,7 +395,7 @@ namespace CamelotFramework {
 
 		return ret;
 	}
-	//-----------------------------------------------------------------------
+
 	int parseInt(const String& val, int defaultValue)
 	{
 		// Use istringstream for direct correspondence with toString
@@ -630,7 +405,7 @@ namespace CamelotFramework {
 
 		return ret;
 	}
-	//-----------------------------------------------------------------------
+
 	unsigned int parseUnsignedInt(const String& val, unsigned int defaultValue)
 	{
 		// Use istringstream for direct correspondence with toString
@@ -640,7 +415,7 @@ namespace CamelotFramework {
 
 		return ret;
 	}
-	//-----------------------------------------------------------------------
+
 	long parseLong(const String& val, long defaultValue)
 	{
 		// Use istringstream for direct correspondence with toString
@@ -650,7 +425,7 @@ namespace CamelotFramework {
 
 		return ret;
 	}
-	//-----------------------------------------------------------------------
+
 	unsigned long parseUnsignedLong(const String& val, unsigned long defaultValue)
 	{
 		// Use istringstream for direct correspondence with toString
@@ -660,7 +435,7 @@ namespace CamelotFramework {
 
 		return ret;
 	}
-	//-----------------------------------------------------------------------
+
 	bool parseBool(const String& val, bool defaultValue)
 	{
 		if ((StringUtil::startsWith(val, "true") || StringUtil::startsWith(val, "yes")
@@ -672,12 +447,7 @@ namespace CamelotFramework {
 		else
 			return defaultValue;
 	}
-	//-----------------------------------------------------------------------
-	vector<CamelotFramework::String>::type parseStringVector(const String& val)
-	{
-		return StringUtil::split(val);
-	}
-	//-----------------------------------------------------------------------
+
 	bool isNumber(const String& val)
 	{
 		StringStream str(val);
@@ -685,7 +455,7 @@ namespace CamelotFramework {
 		str >> tst;
 		return !str.fail() && str.eof();
 	}
-	//----------------------------------------------------------------------
+
 	void __string_throwDataOverflowException()
 	{
 		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();
 
-		return to_string(newUUID);
+		return to_string(newUUID).c_str();
 	}
 };

+ 1 - 2
CamelotUtility/Source/CmWorkQueue.cpp

@@ -396,8 +396,7 @@ namespace CamelotFramework {
 		else
 		{
 			// 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);
 		}

+ 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
 
 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
    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)