Browse Source

Moved certain platform-specific functionality to the utility layer

BearishSun 10 years ago
parent
commit
b5b05448e1

+ 6 - 7
BansheeCore/BansheeCore.vcxproj

@@ -152,7 +152,7 @@
     <Link>
       <SubSystem>NotSet</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;IPHLPAPI.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../lib/x86/$(Configuration);../Dependencies/lib/x86/Debug</AdditionalLibraryDirectories>
       <ImportLibrary>..\lib\x86\$(Configuration)\$(TargetName).lib</ImportLibrary>
     </Link>
@@ -172,7 +172,7 @@
     <Link>
       <SubSystem>NotSet</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;IPHLPAPI.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../lib/$(Platform)/$(Configuration);../Dependencies/lib/x64/Debug</AdditionalLibraryDirectories>
       <ImportLibrary>..\lib\$(Platform)\$(Configuration)\$(TargetName).lib</ImportLibrary>
     </Link>
@@ -198,7 +198,7 @@
       <GenerateDebugInformation>false</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;IPHLPAPI.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../lib/x86/$(Configuration);../Dependencies/lib/x86/Release</AdditionalLibraryDirectories>
       <ImportLibrary>..\lib\x86\$(Configuration)\$(TargetName).lib</ImportLibrary>
     </Link>
@@ -225,7 +225,7 @@
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;IPHLPAPI.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../lib/x86/$(Configuration);../Dependencies/lib/x86/DebugRelease</AdditionalLibraryDirectories>
       <ImportLibrary>..\lib\x86\$(Configuration)\$(TargetName).lib</ImportLibrary>
     </Link>
@@ -251,7 +251,7 @@
       <GenerateDebugInformation>false</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;IPHLPAPI.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../lib/$(Platform)/$(Configuration);../Dependencies/lib/x64/Release</AdditionalLibraryDirectories>
       <ImportLibrary>..\lib\$(Platform)\$(Configuration)\$(TargetName).lib</ImportLibrary>
     </Link>
@@ -278,7 +278,7 @@
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;IPHLPAPI.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../lib/$(Platform)/$(Configuration);../Dependencies/lib/x64/DebugRelease</AdditionalLibraryDirectories>
       <ImportLibrary>..\lib\$(Platform)\$(Configuration)\$(TargetName).lib</ImportLibrary>
     </Link>
@@ -554,7 +554,6 @@
     <ClCompile Include="Source\BsViewport.cpp" />
     <ClCompile Include="Source\BsSceneObject.cpp" />
     <ClCompile Include="Source\BsComponent.cpp" />
-    <ClCompile Include="Source\Win32\BsWin32BrowseDialogs.cpp" />
     <ClCompile Include="Source\Win32\BsWin32Platform.cpp" />
     <ClCompile Include="Source\Win32\BsWin32FolderMonitor.cpp" />
   </ItemGroup>

+ 0 - 3
BansheeCore/BansheeCore.vcxproj.filters

@@ -862,9 +862,6 @@
     <ClCompile Include="Source\Win32\BsWin32Platform.cpp">
       <Filter>Source Files\Platform</Filter>
     </ClCompile>
-    <ClCompile Include="Source\Win32\BsWin32BrowseDialogs.cpp">
-      <Filter>Source Files\Platform</Filter>
-    </ClCompile>
     <ClCompile Include="Source\BsShaderIncludeImporter.cpp">
       <Filter>Source Files\Importer</Filter>
     </ClCompile>

+ 0 - 8
BansheeCore/Include/BsCommonTypes.h

@@ -346,14 +346,6 @@ namespace BansheeEngine
 
 		TextureAddressingMode u, v, w;
 	};
-
-	/**
-	 * @brief Represents a MAC (ethernet) address.
-	 */
-	struct MACAddress
-	{
-		UINT8 value[6];
-	};
     
 	/**
 	 * @brief	References a subset of surfaces within a texture

+ 0 - 87
BansheeCore/Include/BsPlatform.h

@@ -44,18 +44,6 @@ namespace BansheeEngine
 		BottomRight
 	};
 
-	/**
-	 * @brief	Possible type of platform file dialogs.
-	 */
-	enum class FileDialogType
-	{
-		OpenFile = 0x0, 
-		OpenFolder = 0x1, 
-		Save = 0x2,
-		Multiselect = 0x10000,
-		TypeMask = 0xFFFF
-	};
-
 	/**
 	 * @brief	Types of mouse buttons provided by the OS.
 	 */
@@ -340,52 +328,6 @@ namespace BansheeEngine
 		 */
 		static void resetNonClientAreas(const RenderWindowCore& window);
 
-		/**
-		 * @brief	Adds a string to the clipboard.
-		 *
-		 * @note	Thread safe.
-		 */
-		static void copyToClipboard(const WString& string);
-
-		/**
-		 * @brief	Reads a string from the clipboard and returns it. If there is no
-		 * 			string in the clipboard it returns an empty string.
-		 *
-		 * @note	Both wide and normal strings will be read, but normal strings will be converted to
-		 * 			a wide string before returning.
-		 *
-		 *			Thread safe.
-		 */
-		static WString copyFromClipboard();
-
-		/**
-		 * @brief	Converts a keyboard key-code to a Unicode character.
-		 *
-		 * @note	Normally this will output a single character, but it can happen it outputs multiple 
-		 *			in case a accent/diacritic character could not be combined with the virtual key into 
-		 *			a single character.
-		 */
-		static WString keyCodeToUnicode(UINT32 keyCode);
-
-		/**
-		 * @brief	Populates the provided buffer with a MAC address of the first available
-		 *			adapter, if one exists. If no adapters exist, returns false.
-		 */
-		static bool getMACAddress(MACAddress& address);
-
-		/**
-		 * @brief	Creates a new universally unique identifier and returns it as a string.
-		 */
-		static String generateUUID();
-
-		/**
-		 * @brief	Queries the internal system performance counter you can use for very precise time
-		 * 			measurements. Value is in milliseconds.
-		 *
-		 * @note	Thread safe.
-		 */
-		static double queryPerformanceTimerMs();
-
 		/**
 		 * @brief	Creates a drop target that you can use for tracking OS drag and drop operations performed over
 		 * 			a certain area on the specified window.
@@ -406,35 +348,6 @@ namespace BansheeEngine
 		 */
 		static void destroyDropTarget(OSDropTarget& target);
 
-		/**
-		 * @brief	Displays a platform specific file/folder open/save dialog.
-		 *
-		 * @param	type		Type of dialog to open.
-		 * @param	defaultPath	Initial path the dialog will be set to once opened.
-		 * @param	filterList	Semi-colon separated list of file names or types to display in the dialog, e.g. "exe;txt;png".
-		 *						Ignored if dialog is to display folders instead of files.
-		 * @param	paths		Output list of selected file or folder paths (if any).
-		 *
-		 * @return	True if file was selected and false if selection was canceled.
-		 */
-		static bool openBrowseDialog(FileDialogType type, const Path& defaultPath, const WString& filterList,
-			Vector<Path>& paths);
-
-		/**
-		 * @brief	Terminates the current process.
-		 * 			
-		 * @param	force	True if the process should be forcefully terminated with no cleanup.
-		 */
-		static void terminate(bool force = false);
-
-		/**
-		 * @brief	Opens the provided file or folder using the default application for that file type, as specified
-		 * 			by the operating system.
-		 *
-		 * @param	path	Absolute path to the file or folder to open.
-		 */
-		static void open(const Path& path);
-
 		/**
 		 * @brief	Message pump. Processes OS messages and returns when it's free.
 		 *

+ 1 - 1
BansheeCore/Source/BsProfilerCPU.cpp

@@ -26,7 +26,7 @@ namespace BansheeEngine
 
 	inline double ProfilerCPU::Timer::getCurrentTime() 
 	{
-		return Platform::queryPerformanceTimerMs();
+		return PlatformUtility::queryPerformanceTimerMs();
 	}
 
 	ProfilerCPU::TimerPrecise::TimerPrecise()

+ 1 - 1
BansheeCore/Source/BsUUID.cpp

@@ -8,6 +8,6 @@ namespace BansheeEngine
 {
 	String UUIDGenerator::generateRandom()
 	{
-		return Platform::generateUUID();
+		return PlatformUtility::generateUUID();
 	}
 };

+ 0 - 137
BansheeCore/Source/Win32/BsWin32Platform.cpp

@@ -7,7 +7,6 @@
 #include "Win32/BsWin32Defs.h"
 #include "Win32/BsWin32DropTarget.h"
 #include "Win32/BsWin32PlatformData.h"
-#include <iphlpapi.h>
 
 namespace BansheeEngine
 {
@@ -245,137 +244,6 @@ namespace BansheeEngine
 			mData->mNonClientAreas.erase(iterFind);
 	}
 
-	void Platform::copyToClipboard(const WString& string)
-	{
-		HANDLE hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (string.size() + 1) * sizeof(WString::value_type));
-		WString::value_type* buffer = (WString::value_type*)GlobalLock(hData);
-
-		string.copy(buffer, string.size());
-		buffer[string.size()] = '\0';
-
-		GlobalUnlock(hData);
-
-		if(OpenClipboard(NULL))
-		{
-			EmptyClipboard();
-			SetClipboardData(CF_UNICODETEXT, hData);
-			CloseClipboard();
-		}
-		else
-		{
-			GlobalFree(hData);
-		}
-	}
-
-	WString Platform::copyFromClipboard()
-	{
-		if(OpenClipboard(NULL))
-		{
-			HANDLE hData = GetClipboardData(CF_UNICODETEXT);
-
-			if(hData != NULL)
-			{
-				WString::value_type* buffer = (WString::value_type*)GlobalLock(hData);
-				WString string(buffer);
-				GlobalUnlock(hData);
-
-				CloseClipboard();
-				return string;
-			}
-			else
-			{
-				CloseClipboard();
-				return L"";
-			}			
-		}
-
-		return L"";
-	}
-
-	WString Platform::keyCodeToUnicode(UINT32 keyCode)
-	{
-		static HKL keyboardLayout = GetKeyboardLayout(0);
-		static UINT8 keyboarState[256];
-
-		if (GetKeyboardState(keyboarState) == FALSE)
-			return 0;
-
-		UINT virtualKey = MapVirtualKeyExW(keyCode, 1, keyboardLayout);
-
-		wchar_t output[2];
-		int count = ToUnicodeEx(virtualKey, keyCode, keyboarState, output, 2, 0, keyboardLayout);
-		if (count > 0)
-			return WString(output, count);
-
-		return StringUtil::WBLANK;
-	}
-
-	bool Platform::getMACAddress(MACAddress& address)
-	{
-		std::memset(&address, 0, sizeof(address));
-
-		PIP_ADAPTER_INFO adapterInfo = bs_alloc<IP_ADAPTER_INFO>();
-		
-		ULONG len = sizeof(IP_ADAPTER_INFO);
-		DWORD rc = GetAdaptersInfo(adapterInfo, &len);
-
-		if (rc == ERROR_BUFFER_OVERFLOW)
-		{
-			bs_free(adapterInfo);
-			adapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(bs_alloc(len));
-		}
-		else if (rc != ERROR_SUCCESS)
-		{
-			bs_free(adapterInfo);
-			return false;
-		}
-
-		if (GetAdaptersInfo(adapterInfo, &len) == NO_ERROR)
-		{
-			PIP_ADAPTER_INFO curAdapter = nullptr;
-			curAdapter = adapterInfo;
-
-			while (curAdapter)
-			{
-				if (curAdapter->Type == MIB_IF_TYPE_ETHERNET && curAdapter->AddressLength == sizeof(address))
-				{
-					std::memcpy(&address, curAdapter->Address, curAdapter->AddressLength);
-					return true;
-				}
-
-				curAdapter = curAdapter->Next;
-			}
-		}
-
-		bs_free(adapterInfo);
-		return false;
-	}
-
-	String Platform::generateUUID()
-	{
-		UUID uuid;
-		UuidCreate(&uuid);
-
-		UINT8* uuidStr;
-		UuidToStringA(&uuid, &uuidStr);
-
-		String output((char*)uuidStr);
-		RpcStringFreeA(&uuidStr);
-
-		return output;
-	}
-
-	double Platform::queryPerformanceTimerMs()
-	{
-		LARGE_INTEGER counterValue;
-		QueryPerformanceCounter(&counterValue);
-		
-		LARGE_INTEGER counterFreq;
-		QueryPerformanceFrequency(&counterFreq);
-
-		return (double)counterValue.QuadPart / (counterFreq.QuadPart * 0.001);
-	}
-
 	OSDropTarget& Platform::createDropTarget(const RenderWindow* window, int x, int y, unsigned int width, unsigned int height)
 	{
 		Win32DropTarget* win32DropTarget = nullptr;
@@ -428,11 +296,6 @@ namespace BansheeEngine
 		BS_PVT_DELETE(OSDropTarget, &target);
 	}
 
-	void Platform::open(const Path& path)
-	{
-		ShellExecute(nullptr, "open", path.toString().c_str(), nullptr, nullptr, SW_SHOWNORMAL);
-	}
-
 	void Platform::_messagePump()
 	{
 		MSG  msg;

+ 1 - 1
BansheeEditorExec/BsEditorExec.cpp

@@ -78,7 +78,7 @@ int CALLBACK WinMain(
 	}
 	__except (gCrashHandler().reportCrash(GetExceptionInformation()))
 	{
-		Platform::terminate(true);
+		PlatformUtility::terminate(true);
 	}
 
 #if BS_DEBUG_MODE

+ 2 - 2
BansheeEngine/Source/BsGUIInputBox.cpp

@@ -1225,12 +1225,12 @@ namespace BansheeEngine
 
 	void GUIInputBox::copyText()
 	{
-		Platform::copyToClipboard(getSelectedText());
+		PlatformUtility::copyToClipboard(getSelectedText());
 	}
 
 	void GUIInputBox::pasteText()
 	{
-		WString textInClipboard = Platform::copyFromClipboard();
+		WString textInClipboard = PlatformUtility::copyFromClipboard();
 
 		UINT32 charIdx = gGUIManager().getInputCaretTool()->getCharIdxAtCaretPos();
 

+ 1 - 1
BansheeEngine/Source/BsShortcutKey.cpp

@@ -83,7 +83,7 @@ namespace BansheeEngine
 		}
 		else
 		{
-			charStr = Platform::keyCodeToUnicode((UINT32)button);
+			charStr = PlatformUtility::keyCodeToUnicode((UINT32)button);
 			StringUtil::toUpperCase(charStr);
 		}
 

+ 9 - 6
BansheeUtility/BansheeUtility.vcxproj

@@ -131,7 +131,7 @@
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ImportLibrary>..\lib\x86\$(Configuration)\$(TargetName).lib</ImportLibrary>
-      <AdditionalDependencies>DbgHelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>DbgHelp.lib;IPHLPAPI.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../Dependencies/lib/x86/Debug</AdditionalLibraryDirectories>
       <SubSystem>NotSet</SubSystem>
       <NoEntryPoint>false</NoEntryPoint>
@@ -152,7 +152,7 @@
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ImportLibrary>..\lib\$(Platform)\$(Configuration)\$(TargetName).lib</ImportLibrary>
-      <AdditionalDependencies>DbgHelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>DbgHelp.lib;IPHLPAPI.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../Dependencies/lib/x64/Debug</AdditionalLibraryDirectories>
       <SubSystem>NotSet</SubSystem>
       <NoEntryPoint>false</NoEntryPoint>
@@ -179,7 +179,7 @@
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <ImportLibrary>..\lib\x86\$(Configuration)\$(TargetName).lib</ImportLibrary>
-      <AdditionalDependencies>DbgHelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>DbgHelp.lib;IPHLPAPI.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../Dependencies/lib/x86/Release</AdditionalLibraryDirectories>
       <NoEntryPoint>false</NoEntryPoint>
     </Link>
@@ -203,7 +203,7 @@
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <ImportLibrary>..\lib\x86\$(Configuration)\$(TargetName).lib</ImportLibrary>
-      <AdditionalDependencies>DbgHelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>DbgHelp.lib;IPHLPAPI.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../Dependencies/lib/x86/DebugRelease</AdditionalLibraryDirectories>
       <NoEntryPoint>false</NoEntryPoint>
     </Link>
@@ -229,7 +229,7 @@
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <ImportLibrary>..\lib\$(Platform)\$(Configuration)\$(TargetName).lib</ImportLibrary>
-      <AdditionalDependencies>DbgHelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>DbgHelp.lib;IPHLPAPI.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../Dependencies/lib/x64/Release</AdditionalLibraryDirectories>
       <NoEntryPoint>false</NoEntryPoint>
     </Link>
@@ -253,7 +253,7 @@
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <ImportLibrary>..\lib\$(Platform)\$(Configuration)\$(TargetName).lib</ImportLibrary>
-      <AdditionalDependencies>DbgHelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>DbgHelp.lib;IPHLPAPI.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>../Dependencies/lib/x64/DebugRelease</AdditionalLibraryDirectories>
       <NoEntryPoint>false</NoEntryPoint>
     </Link>
@@ -294,8 +294,10 @@
     <ClCompile Include="Source\BsSphere.cpp" />
     <ClCompile Include="Source\BsTexAtlasGenerator.cpp" />
     <ClCompile Include="Source\ThirdParty\md5.cpp" />
+    <ClCompile Include="Source\Win32\BsWin32BrowseDialogs.cpp" />
     <ClCompile Include="Source\Win32\BsWin32CrashHandler.cpp" />
     <ClCompile Include="Source\Win32\BsWin32FileSystem.cpp" />
+    <ClCompile Include="Source\Win32\BsWin32PlatformUtility.cpp" />
     <ClCompile Include="Source\Win32\BsWin32Timer.cpp" />
     <ClInclude Include="Include\BsAny.h" />
     <ClInclude Include="Include\BsBinaryCloner.h" />
@@ -308,6 +310,7 @@
     <ClInclude Include="Include\BsMatrixNxM.h" />
     <ClInclude Include="Include\BsMessageHandler.h" />
     <ClInclude Include="Include\BsMessageHandlerFwd.h" />
+    <ClInclude Include="Include\BsPlatformUtility.h" />
     <ClInclude Include="Include\BsRect3.h" />
     <ClInclude Include="Include\BsBinaryDiff.h" />
     <ClInclude Include="Include\BsSerializedObject.h" />

+ 9 - 0
BansheeUtility/BansheeUtility.vcxproj.filters

@@ -308,6 +308,9 @@
     <ClInclude Include="Include\BsCrashHandler.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsPlatformUtility.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsThreadPool.cpp">
@@ -490,5 +493,11 @@
     <ClCompile Include="Source\Win32\BsWin32Timer.cpp">
       <Filter>Source Files\Win32</Filter>
     </ClCompile>
+    <ClCompile Include="Source\Win32\BsWin32PlatformUtility.cpp">
+      <Filter>Source Files\Win32</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\Win32\BsWin32BrowseDialogs.cpp">
+      <Filter>Source Files\Win32</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 2 - 1
BansheeUtility/Include/BsException.h

@@ -157,9 +157,10 @@ namespace BansheeEngine
 	// won't continue past this point (e.g. if a function needs to return a value otherwise).
 #ifndef BS_EXCEPT
 #define BS_EXCEPT(type, desc)	\
-	{                           \
+		{                           \
 	static_assert((std::is_base_of<BansheeEngine::Exception, type##>::value), "Invalid exception type (" #type ") for BS_EXCEPT macro. It needs to derive from BansheeEngine::Exception."); \
 	gCrashHandler().reportCrash(#type, desc, __PRETTY_FUNCTION__, __FILE__, __LINE__); \
+	PlatformUtility::terminate(true); \
 	throw type##(desc, __PRETTY_FUNCTION__, __FILE__, __LINE__); \
 	}
 #endif

+ 108 - 0
BansheeUtility/Include/BsPlatformUtility.h

@@ -0,0 +1,108 @@
+#pragma once
+
+namespace BansheeEngine
+{
+	struct MACAddress;
+
+	/**
+	 * @brief	Possible type of platform file dialogs.
+	 */
+	enum class FileDialogType
+	{
+		OpenFile = 0x0, 
+		OpenFolder = 0x1, 
+		Save = 0x2,
+		Multiselect = 0x10000,
+		TypeMask = 0xFFFF
+	};
+
+	/**
+	 * @brief	Provides access to various operating system specific utility functions.
+	 */
+	class BS_UTILITY_EXPORT PlatformUtility
+	{
+	public:
+		/**
+		 * @brief	Terminates the current process.
+		 * 			
+		 * @param	force	True if the process should be forcefully terminated with no cleanup.
+		 */
+		static void terminate(bool force = false);
+
+		/**
+		 * @brief	Queries the internal system performance counter you can use for very precise time
+		 * 			measurements. Value is in milliseconds.
+		 *
+		 * @note	Thread safe.
+		 */
+		static double queryPerformanceTimerMs();
+
+		/**
+		 * @brief	Adds a string to the clipboard.
+		 *
+		 * @note	Thread safe.
+		 */
+		static void copyToClipboard(const WString& string);
+
+		/**
+		 * @brief	Reads a string from the clipboard and returns it. If there is no
+		 * 			string in the clipboard it returns an empty string.
+		 *
+		 * @note	Both wide and normal strings will be read, but normal strings will be converted to
+		 * 			a wide string before returning.
+		 *
+		 *			Thread safe.
+		 */
+		static WString copyFromClipboard();
+
+		/**
+		 * @brief	Converts a keyboard key-code to a Unicode character.
+		 *
+		 * @note	Normally this will output a single character, but it can happen it outputs multiple 
+		 *			in case a accent/diacritic character could not be combined with the virtual key into 
+		 *			a single character.
+		 */
+		static WString keyCodeToUnicode(UINT32 keyCode);
+
+		/**
+		 * @brief	Populates the provided buffer with a MAC address of the first available
+		 *			adapter, if one exists. If no adapters exist, returns false.
+		 */
+		static bool getMACAddress(MACAddress& address);
+
+		/**
+		 * @brief	Creates a new universally unique identifier and returns it as a string.
+		 */
+		static String generateUUID();
+
+		/**
+		 * @brief	Opens the provided file or folder using the default application for that file type, as specified
+		 * 			by the operating system.
+		 *
+		 * @param	path	Absolute path to the file or folder to open.
+		 */
+		static void open(const Path& path);
+
+		/**
+		 * @brief	Displays a platform specific file/folder open/save dialog.
+		 *
+		 * @param	type		Type of dialog to open.
+		 * @param	defaultPath	Initial path the dialog will be set to once opened.
+		 * @param	filterList	Semi-colon separated list of file names or types to display in the dialog, e.g. "exe;txt;png".
+		 *						Ignored if dialog is to display folders instead of files.
+		 * @param	paths		Output list of selected file or folder paths (if any).
+		 *
+		 * @return	True if file was selected and false if selection was canceled.
+		 */
+		static bool openBrowseDialog(FileDialogType type, const Path& defaultPath, const WString& filterList,
+			Vector<Path>& paths);
+	};
+
+	/**
+	 * @brief Represents a MAC (ethernet) address.
+	 */
+	struct MACAddress
+	{
+		UINT8 value[6];
+	};
+}

+ 1 - 0
BansheeUtility/Include/BsPrerequisitesUtil.h

@@ -66,4 +66,5 @@
 #include "BsPath.h"
 #include "BsStringID.h"
 #include "BsEvent.h"
+#include "BsPlatformUtility.h"
 #include "BsCrashHandler.h"

+ 2 - 10
BansheeCore/Source/Win32/BsWin32BrowseDialogs.cpp → BansheeUtility/Source/Win32/BsWin32BrowseDialogs.cpp

@@ -1,4 +1,4 @@
-#include "BsPlatform.h"
+#include "BsPrerequisitesUtil.h"
 #include <atlbase.h>
 #include <ShObjIdl.h>
 
@@ -71,7 +71,7 @@ namespace BansheeEngine
 		}
 	}
 
-	bool Platform::openBrowseDialog(FileDialogType type, const Path& defaultPath, const WString& filterList,
+	bool PlatformUtility::openBrowseDialog(FileDialogType type, const Path& defaultPath, const WString& filterList,
 		Vector<Path>& paths)
 	{
 		// Init COM library.
@@ -150,12 +150,4 @@ namespace BansheeEngine
 		CoUninitialize();
 		return finalResult;
 	}
-
-	void Platform::terminate(bool force)
-	{
-		if (!force)
-			PostQuitMessage(0);
-		else
-			TerminateProcess(GetCurrentProcess(), 0);
-	}
 }

+ 151 - 0
BansheeUtility/Source/Win32/BsWin32PlatformUtility.cpp

@@ -0,0 +1,151 @@
+#include "BsPrerequisitesUtil.h"
+#include <windows.h>
+#include <iphlpapi.h>
+
+namespace BansheeEngine
+{
+	void PlatformUtility::terminate(bool force)
+	{
+		if (!force)
+			PostQuitMessage(0);
+		else
+			TerminateProcess(GetCurrentProcess(), 0);
+	}
+
+	double PlatformUtility::queryPerformanceTimerMs()
+	{
+		LARGE_INTEGER counterValue;
+		QueryPerformanceCounter(&counterValue);
+
+		LARGE_INTEGER counterFreq;
+		QueryPerformanceFrequency(&counterFreq);
+
+		return (double)counterValue.QuadPart / (counterFreq.QuadPart * 0.001);
+	}
+
+
+	void PlatformUtility::copyToClipboard(const WString& string)
+	{
+		HANDLE hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (string.size() + 1) * sizeof(WString::value_type));
+		WString::value_type* buffer = (WString::value_type*)GlobalLock(hData);
+
+		string.copy(buffer, string.size());
+		buffer[string.size()] = '\0';
+
+		GlobalUnlock(hData);
+
+		if (OpenClipboard(NULL))
+		{
+			EmptyClipboard();
+			SetClipboardData(CF_UNICODETEXT, hData);
+			CloseClipboard();
+		}
+		else
+		{
+			GlobalFree(hData);
+		}
+	}
+
+	WString PlatformUtility::copyFromClipboard()
+	{
+		if (OpenClipboard(NULL))
+		{
+			HANDLE hData = GetClipboardData(CF_UNICODETEXT);
+
+			if (hData != NULL)
+			{
+				WString::value_type* buffer = (WString::value_type*)GlobalLock(hData);
+				WString string(buffer);
+				GlobalUnlock(hData);
+
+				CloseClipboard();
+				return string;
+			}
+			else
+			{
+				CloseClipboard();
+				return L"";
+			}
+		}
+
+		return L"";
+	}
+
+	WString PlatformUtility::keyCodeToUnicode(UINT32 keyCode)
+	{
+		static HKL keyboardLayout = GetKeyboardLayout(0);
+		static UINT8 keyboarState[256];
+
+		if (GetKeyboardState(keyboarState) == FALSE)
+			return 0;
+
+		UINT virtualKey = MapVirtualKeyExW(keyCode, 1, keyboardLayout);
+
+		wchar_t output[2];
+		int count = ToUnicodeEx(virtualKey, keyCode, keyboarState, output, 2, 0, keyboardLayout);
+		if (count > 0)
+			return WString(output, count);
+
+		return StringUtil::WBLANK;
+	}
+
+	bool PlatformUtility::getMACAddress(MACAddress& address)
+	{
+		std::memset(&address, 0, sizeof(address));
+
+		PIP_ADAPTER_INFO adapterInfo = bs_alloc<IP_ADAPTER_INFO>();
+
+		ULONG len = sizeof(IP_ADAPTER_INFO);
+		DWORD rc = GetAdaptersInfo(adapterInfo, &len);
+
+		if (rc == ERROR_BUFFER_OVERFLOW)
+		{
+			bs_free(adapterInfo);
+			adapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(bs_alloc(len));
+		}
+		else if (rc != ERROR_SUCCESS)
+		{
+			bs_free(adapterInfo);
+			return false;
+		}
+
+		if (GetAdaptersInfo(adapterInfo, &len) == NO_ERROR)
+		{
+			PIP_ADAPTER_INFO curAdapter = nullptr;
+			curAdapter = adapterInfo;
+
+			while (curAdapter)
+			{
+				if (curAdapter->Type == MIB_IF_TYPE_ETHERNET && curAdapter->AddressLength == sizeof(address))
+				{
+					std::memcpy(&address, curAdapter->Address, curAdapter->AddressLength);
+					return true;
+				}
+
+				curAdapter = curAdapter->Next;
+			}
+		}
+
+		bs_free(adapterInfo);
+		return false;
+	}
+
+	String PlatformUtility::generateUUID()
+	{
+		UUID uuid;
+		UuidCreate(&uuid);
+
+		UINT8* uuidStr;
+		UuidToStringA(&uuid, &uuidStr);
+
+		String output((char*)uuidStr);
+		RpcStringFreeA(&uuidStr);
+
+		return output;
+	}
+
+	void PlatformUtility::open(const Path& path)
+	{
+		ShellExecute(nullptr, "open", path.toString().c_str(), nullptr, nullptr, SW_SHOWNORMAL);
+	}
+}

+ 3 - 3
SBansheeEditor/Source/BsScriptBrowseDialog.cpp

@@ -21,7 +21,7 @@ namespace BansheeEngine
 		FileDialogType type = (FileDialogType)((UINT32)FileDialogType::OpenFile | (UINT32)FileDialogType::Multiselect);
 
 		Vector<Path> paths;
-		if (Platform::openBrowseDialog(type, defaultFolderNative, filterListNative, paths))
+		if (PlatformUtility::openBrowseDialog(type, defaultFolderNative, filterListNative, paths))
 		{
 			MonoArray* pathArray = mono_array_new(MonoManager::instance().getDomain(),
 				mono_get_string_class(), (UINT32)paths.size());
@@ -51,7 +51,7 @@ namespace BansheeEngine
 		FileDialogType type = FileDialogType::OpenFolder;
 
 		Vector<Path> paths;
-		if (Platform::openBrowseDialog(type, defaultFolderNative, L"", paths))
+		if (PlatformUtility::openBrowseDialog(type, defaultFolderNative, L"", paths))
 		{
 			if (paths.size() > 0)
 				*outPath = MonoUtil::wstringToMono(MonoManager::instance().getDomain(), paths[0].toWString());
@@ -75,7 +75,7 @@ namespace BansheeEngine
 		FileDialogType type = FileDialogType::Save;
 
 		Vector<Path> paths;
-		if (Platform::openBrowseDialog(type, defaultFolderNative, filterListNative, paths))
+		if (PlatformUtility::openBrowseDialog(type, defaultFolderNative, filterListNative, paths))
 		{
 			if (paths.size() > 0)
 				*outPath = MonoUtil::wstringToMono(MonoManager::instance().getDomain(), paths[0].toWString());

+ 1 - 1
SBansheeEditor/Source/BsScriptEditorApplication.cpp

@@ -199,6 +199,6 @@ namespace BansheeEngine
 	{
 		Path nativePath = MonoUtil::monoToWString(path);
 
-		Platform::open(nativePath);
+		PlatformUtility::open(nativePath);
 	}
 }