Просмотр исходного кода

Reorganized some code in order to delete many small source files

Marko Pintera 11 лет назад
Родитель
Сommit
716de5f09a
52 измененных файлов с 1752 добавлено и 1945 удалено
  1. 1 1
      BansheeEditor/Source/BsEditorApplication.cpp
  2. 0 1
      BansheeEditorExec/BsEditorExec.cpp
  3. 2 32
      BansheeEngine/Include/BsCamera.h
  4. 6 13
      CamelotCore/CamelotCore.vcxproj
  5. 18 39
      CamelotCore/CamelotCore.vcxproj.filters
  6. 0 12
      CamelotCore/Include/BsCommonStructs.h
  7. 320 325
      CamelotCore/Include/BsCommonTypes.h
  8. 0 1
      CamelotCore/Include/BsGPUProfiler.h
  9. 0 14
      CamelotCore/Include/BsProfilerFwd.h
  10. 0 18
      CamelotCore/Include/BsThreadPolicy.h
  11. 0 3
      CamelotCore/Include/CmApplication.h
  12. 0 1
      CamelotCore/Include/CmBindableGpuParamBlock.h
  13. 0 1
      CamelotCore/Include/CmBlendState.h
  14. 0 1
      CamelotCore/Include/CmCPUProfiler.h
  15. 0 1
      CamelotCore/Include/CmCommandQueue.h
  16. 0 1
      CamelotCore/Include/CmCoreThreadAccessor.h
  17. 0 1
      CamelotCore/Include/CmDepthStencilState.h
  18. 1 1
      CamelotCore/Include/CmFolderMonitor.h
  19. 0 1
      CamelotCore/Include/CmGpuBuffer.h
  20. 0 1
      CamelotCore/Include/CmGpuBufferView.h
  21. 0 1
      CamelotCore/Include/CmGpuParamBlock.h
  22. 0 1
      CamelotCore/Include/CmGpuParamBlockBuffer.h
  23. 0 1
      CamelotCore/Include/CmGpuParamDesc.h
  24. 0 1
      CamelotCore/Include/CmHardwareBuffer.h
  25. 0 1
      CamelotCore/Include/CmMaterial.h
  26. 0 1
      CamelotCore/Include/CmPass.h
  27. 29 6
      CamelotCore/Include/CmPrerequisites.h
  28. 0 1
      CamelotCore/Include/CmRasterizerState.h
  29. 0 1
      CamelotCore/Include/CmRenderSystem.h
  30. 0 1
      CamelotCore/Include/CmSamplerState.h
  31. 0 1
      CamelotCore/Include/CmShader.h
  32. 0 1
      CamelotCore/Include/CmTextureView.h
  33. 0 1
      CamelotCore/Include/CmViewport.h
  34. 41 41
      CamelotCore/Include/Win32/CmPlatformWndProc.h
  35. 9 9
      CamelotCore/Include/Win32/CmWin32Defs.h
  36. 100 100
      CamelotCore/Include/Win32/CmWin32FolderMonitor.h
  37. 0 15
      CamelotCore/Include/stdafx.h
  38. 0 8
      CamelotCore/Include/targetver.h
  39. 0 14
      CamelotCore/Source/BsThreadPolicy.cpp
  40. 0 14
      CamelotCore/Source/CmApplication.cpp
  41. 1 1
      CamelotCore/Source/Win32/CmPlatformImpl.cpp
  42. 544 544
      CamelotCore/Source/Win32/CmPlatformWndProc.cpp
  43. 665 665
      CamelotCore/Source/Win32/CmWin32FolderMonitor.cpp
  44. 0 8
      CamelotCore/Source/stdafx.cpp
  45. 0 1
      CamelotD3D11RenderSystem/Include/CmD3D11GpuBuffer.h
  46. 0 1
      CamelotD3D11RenderSystem/Include/CmD3D11Mappings.h
  47. 1 1
      CamelotD3D11RenderSystem/Source/CmD3D11RenderWindow.cpp
  48. 2 31
      CamelotD3D9Renderer/Include/CmD3D9Mappings.h
  49. 1 1
      CamelotD3D9Renderer/Source/CmD3D9RenderWindow.cpp
  50. 0 1
      CamelotGLRenderer/Include/CmGLGpuParamBlockBuffer.h
  51. 1 1
      CamelotGLRenderer/Source/CmWin32Window.cpp
  52. 10 3
      CamelotOISInput/Source/CmOISPlugin.cpp

+ 1 - 1
BansheeEditor/Source/BsEditorApplication.cpp

@@ -28,7 +28,7 @@
 #include "BsRenderable.h"
 #include "BsDbgTestGameObjectRef.h"
 #include "BsVirtualInput.h"
-#include "CmWin32FolderMonitor.h"
+#include "CmFolderMonitor.h"
 #include "BsProjectLibrary.h"
 #include "BsCamera.h"
 #include "BsGUIWidget.h"

+ 0 - 1
BansheeEditorExec/BsEditorExec.cpp

@@ -1,4 +1,3 @@
-#include "stdafx.h"
 #include <windows.h>
 
 #include "BsEditorApplication.h"

+ 2 - 32
BansheeEngine/Include/BsCamera.h

@@ -1,32 +1,4 @@
-/*
------------------------------------------------------------------------------
-This source file is part of OGRE
-    (Object-oriented Graphics Rendering Engine)
-For the latest info, see http://www.ogre3d.org
-
-Copyright (c) 2000-2011 Torus Knot Software Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
-#ifndef __Camera_H__
-#define __Camera_H__
+#pragma once
 
 // Default options
 #include "BsPrerequisites.h"
@@ -42,7 +14,6 @@ THE SOFTWARE.
 #include "CmIndexData.h"
 #include "CmPlane.h"
 #include "CmQuaternion.h"
-#include "CmCommonEnums.h"
 #include "CmRay.h"
 #include "CmComponent.h"
 
@@ -549,5 +520,4 @@ namespace BansheeEngine {
 	 /** @} */
 	 /** @} */
 
-} 
-#endif
+}

+ 6 - 13
CamelotCore/CamelotCore.vcxproj

@@ -272,10 +272,7 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
-    <ClInclude Include="Include\BsCommonStructs.h" />
-    <ClInclude Include="Include\BsProfilerFwd.h" />
     <ClInclude Include="Include\BsRenderStats.h" />
-    <ClInclude Include="Include\BsThreadPolicy.h" />
     <ClInclude Include="Include\CmBindableGpuParamBlock.h" />
     <ClInclude Include="Include\CmBindableGpuParams.h" />
     <ClInclude Include="Include\CmCoreThread.h" />
@@ -306,6 +303,7 @@
     <ClInclude Include="Include\CmPixelDataRTTI.h" />
     <ClInclude Include="Include\CmPixelUtil.h" />
     <ClInclude Include="Include\CmPixelVolume.h" />
+    <ClInclude Include="Include\CmPlatform.h" />
     <ClInclude Include="Include\CmPlatformWndProc.h" />
     <ClInclude Include="Include\CmProfiler.h" />
     <ClInclude Include="Include\CmQueryManager.h" />
@@ -317,7 +315,7 @@
     <ClInclude Include="Include\CmApplication.h" />
     <ClInclude Include="Include\CmBlendStateRTTI.h" />
     <ClInclude Include="Include\CmCommandQueue.h" />
-    <ClInclude Include="Include\CmCommonEnums.h" />
+    <ClInclude Include="Include\BsCommonTypes.h" />
     <ClInclude Include="Include\CmComponentRTTI.h" />
     <ClInclude Include="Include\CmCoreObject.h" />
     <ClInclude Include="Include\CmCoreObjectManager.h" />
@@ -368,7 +366,6 @@
     <ClInclude Include="Include\CmMeshData.h" />
     <ClInclude Include="Include\CmMeshDataRTTI.h" />
     <ClInclude Include="Include\CmMultiRenderTexture.h" />
-    <ClInclude Include="Include\CmPlatform.h" />
     <ClInclude Include="Include\CmPass.h" />
     <ClInclude Include="Include\CmPassRTTI.h" />
     <ClInclude Include="Include\CmPrerequisites.h" />
@@ -411,18 +408,15 @@
     <ClInclude Include="Include\CmComponent.h" />
     <ClInclude Include="Include\CmShader.h" />
     <ClInclude Include="Include\CmBlendState.h" />
-    <ClInclude Include="Include\CmWin32Defs.h" />
-    <ClInclude Include="Include\CmWin32FolderMonitor.h" />
-    <ClInclude Include="Include\stdafx.h" />
-    <ClInclude Include="Include\targetver.h" />
     <ClInclude Include="Include\CmVertexDeclarationRTTI.h" />
     <ClInclude Include="Include\CmTechnique.h" />
     <ClInclude Include="Include\Win32\CmPlatformImpl.h" />
+    <ClInclude Include="Include\Win32\CmWin32Defs.h" />
     <ClInclude Include="Include\Win32\CmWin32DropTarget.h" />
+    <ClInclude Include="Include\Win32\CmWin32FolderMonitor.h" />
     <ClInclude Include="Source\CmMeshRTTI.h" />
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="Source\BsThreadPolicy.cpp" />
     <ClCompile Include="Source\CmBindableGpuParamBlock.cpp" />
     <ClCompile Include="Source\CmBindableGpuParams.cpp" />
     <ClCompile Include="Source\CmCoreThread.cpp" />
@@ -473,7 +467,6 @@
     <ClCompile Include="Source\CmPixelUtil.cpp" />
     <ClCompile Include="Source\CmPixelVolume.cpp" />
     <ClCompile Include="Source\CmPlatform.cpp" />
-    <ClCompile Include="Source\CmPlatformWndProc.cpp" />
     <ClCompile Include="Source\CmProfiler.cpp" />
     <ClCompile Include="Source\CmQueryManager.cpp" />
     <ClCompile Include="Source\CmRenderer.cpp" />
@@ -521,9 +514,9 @@
     <ClCompile Include="Source\CmViewport.cpp" />
     <ClCompile Include="Source\CmSceneObject.cpp" />
     <ClCompile Include="Source\CmComponent.cpp" />
-    <ClCompile Include="Source\CmWin32FolderMonitor.cpp" />
-    <ClCompile Include="Source\stdafx.cpp" />
     <ClCompile Include="Source\Win32\CmPlatformImpl.cpp" />
+    <ClCompile Include="Source\Win32\CmPlatformWndProc.cpp" />
+    <ClCompile Include="Source\Win32\CmWin32FolderMonitor.cpp" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">

+ 18 - 39
CamelotCore/CamelotCore.vcxproj.filters

@@ -96,12 +96,6 @@
     <ClInclude Include="Include\CmViewport.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="Include\stdafx.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\targetver.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="Include\CmPrerequisites.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -267,9 +261,6 @@
     <ClInclude Include="Include\CmVertexDeclaration.h">
       <Filter>Header Files\RenderSystem</Filter>
     </ClInclude>
-    <ClInclude Include="Include\CmCommonEnums.h">
-      <Filter>Header Files\Utility</Filter>
-    </ClInclude>
     <ClInclude Include="Include\CmIndexBuffer.h">
       <Filter>Header Files\RenderSystem</Filter>
     </ClInclude>
@@ -426,18 +417,12 @@
     <ClInclude Include="Include\CmPlatformWndProc.h">
       <Filter>Header Files\Win32</Filter>
     </ClInclude>
-    <ClInclude Include="Include\CmWin32Defs.h">
-      <Filter>Header Files\Win32</Filter>
-    </ClInclude>
     <ClInclude Include="Include\CmProfiler.h">
       <Filter>Header Files</Filter>
     </ClInclude>
     <ClInclude Include="Include\CmCPUProfiler.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="Include\CmPlatform.h">
-      <Filter>Header Files\Platform</Filter>
-    </ClInclude>
     <ClInclude Include="Include\Win32\CmWin32DropTarget.h">
       <Filter>Header Files\Platform</Filter>
     </ClInclude>
@@ -501,27 +486,15 @@
     <ClInclude Include="Include\CmResourceManifestRTTI.h">
       <Filter>Header Files\RTTI</Filter>
     </ClInclude>
-    <ClInclude Include="Include\CmWin32FolderMonitor.h">
-      <Filter>Header Files\Platform</Filter>
-    </ClInclude>
     <ClInclude Include="Include\CmFolderMonitor.h">
       <Filter>Header Files\Platform</Filter>
     </ClInclude>
-    <ClInclude Include="Include\BsThreadPolicy.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsCommonStructs.h">
-      <Filter>Header Files\Utility</Filter>
-    </ClInclude>
     <ClInclude Include="Include\CmUUID.h">
       <Filter>Header Files</Filter>
     </ClInclude>
     <ClInclude Include="Include\CmGpuProgramManager.h">
       <Filter>Header Files\RenderSystem</Filter>
     </ClInclude>
-    <ClInclude Include="Include\BsProfilerFwd.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="Include\BsGPUProfiler.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -534,6 +507,18 @@
     <ClInclude Include="Include\CmVideoModeInfo.h">
       <Filter>Header Files\RenderSystem</Filter>
     </ClInclude>
+    <ClInclude Include="Include\Win32\CmWin32Defs.h">
+      <Filter>Header Files\Win32</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\Win32\CmWin32FolderMonitor.h">
+      <Filter>Header Files\Platform</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmPlatform.h">
+      <Filter>Header Files\Platform</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCommonTypes.h">
+      <Filter>Header Files\Utility</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CmApplication.cpp">
@@ -542,9 +527,6 @@
     <ClCompile Include="Source\CmViewport.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Source\stdafx.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="Source\CmGpuProgram.cpp">
       <Filter>Source Files\RenderSystem</Filter>
     </ClCompile>
@@ -761,9 +743,6 @@
     <ClCompile Include="Source\Win32\CmPlatformImpl.cpp">
       <Filter>Source Files\Win32</Filter>
     </ClCompile>
-    <ClCompile Include="Source\CmPlatformWndProc.cpp">
-      <Filter>Source Files\Win32</Filter>
-    </ClCompile>
     <ClCompile Include="Source\CmProfiler.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
@@ -818,12 +797,6 @@
     <ClCompile Include="Source\CmResourceManifest.cpp">
       <Filter>Source Files\Resources</Filter>
     </ClCompile>
-    <ClCompile Include="Source\CmWin32FolderMonitor.cpp">
-      <Filter>Source Files\Platform</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsThreadPolicy.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="Source\CmUUID.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
@@ -842,5 +815,11 @@
     <ClCompile Include="Source\CmMaterialManager.cpp">
       <Filter>Source Files\Material</Filter>
     </ClCompile>
+    <ClCompile Include="Source\Win32\CmPlatformWndProc.cpp">
+      <Filter>Source Files\Win32</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\Win32\CmWin32FolderMonitor.cpp">
+      <Filter>Source Files\Platform</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 0 - 12
CamelotCore/Include/BsCommonStructs.h

@@ -1,12 +0,0 @@
-#pragma once
-
-namespace BansheeEngine
-{
-	/**
-	* @brief Represents a MAC (ethernet) address.
-	*/
-	struct MACAddress
-	{
-		UINT8 value[6];
-	};
-}

+ 320 - 325
CamelotCore/Include/CmCommonEnums.h → CamelotCore/Include/BsCommonTypes.h

@@ -1,326 +1,321 @@
-#pragma once
-
-#include "CmString.h"
-
-#if defined ( CM_GCC_VISIBILITY )
-#   pragma GCC visibility push(default)
-#endif
-
-#include <utility>
-#include <sstream>
-
-#if defined ( CM_GCC_VISIBILITY )
-#   pragma GCC visibility pop
-#endif
-
-namespace BansheeEngine 
-{
-	/**
-	 * @brief	Factors used when blending new pixels with existing pixels.
-	 */
-    enum BlendFactor
-    {
-		BF_ONE, /**< Use a value of one for all pixel components. */
-		BF_ZERO, /**< Use a value of zero for all pixel components. */
-		BF_DEST_COLOR, /**< Use the existing pixel value. */
-		BF_SOURCE_COLOR, /**< Use the newly generated pixel value. */
-		BF_INV_DEST_COLOR, /**< Use the inverse of the existing value. */
-		BF_INV_SOURCE_COLOR, /**< Use the inverse of the newly generated pixel value. */
-		BF_DEST_ALPHA, /**< Use the existing alpha value. */
-		BF_SOURCE_ALPHA, /**< Use the newly generated alpha value. */
-		BF_INV_DEST_ALPHA, /**< Use the inverse of the existing alpha value. */
-		BF_INV_SOURCE_ALPHA /**< Use the inverse of the newly generated alpha value. */
-    };
-
-	/**
-	 * @brief	Operations that determines how are blending factors combined.
-	 */
-	enum BlendOperation
-	{
-		BO_ADD, /**< Blend factors are added together. */
-		BO_SUBTRACT, /**< Blend factors are subtracted in "srcFactor - dstFactor" order. */
-		BO_REVERSE_SUBTRACT, /**< Blend factors are subtracted in "dstFactor - srcFactor" order. */
-		BO_MIN, /**< Minimum of the two factors is chosen. */
-		BO_MAX /**< Maximum of the two factors is chosen. */
-	};
-
-	/**
-	 * @brief	Comparison functions used for the depth/stencil buffer.
-	 */
-    enum CompareFunction
-    {
-		CMPF_ALWAYS_FAIL, /**< Operation will always fail. */
-		CMPF_ALWAYS_PASS, /**< Operation will always pass. */
-		CMPF_LESS, /**< Operation will pass if the new value is less than existing value. */
-        CMPF_LESS_EQUAL, /**< Operation will pass if the new value is less or equal than existing value. */
-        CMPF_EQUAL, /**< Operation will pass if the new value is equal to the existing value. */
-        CMPF_NOT_EQUAL, /**< Operation will pass if the new value is not equal to the existing value. */
-        CMPF_GREATER_EQUAL, /**< Operation will pass if the new value greater or equal than the existing value. */
-        CMPF_GREATER /**< Operation will pass if the new value greater than the existing value. */
-    };
-
-	/**
-	 * @brief	Types of texture addressing modes that determine what happens when texture
-	 *			coordinates are outside of the valid range.
-	 */
-    enum TextureAddressingMode
-    {
-		TAM_WRAP, /**< Coordinates wrap back to the valid range. */
-		TAM_MIRROR, /**< Coordinates flip every time the size of the valid range is passed. */
-		TAM_CLAMP, /**< Coordinates are clamped within the valid range. */
-		TAM_BORDER /**< Coordinates outside of the valid range will return a separately set border color. */
-    };
-
-	/**
-	 * @brief	Types of available filtering situations.
-	 */
-    enum FilterType
-    {
-		FT_MIN, /**< The filter used when shrinking a texture. */
-        FT_MAG, /**< The filter used when magnifying a texture. */
-        FT_MIP /**< The filter used when filtering between mipmaps. */
-    };
-
-	/**
-	 * @brief	Filtering options for textures.
-	 */
-    enum FilterOptions
-    {
-		FO_NONE = 0, /**< Use no filtering. Only relevant for mipmap filtering. */
-		FO_POINT = 1, /**< Filter using the nearest found pixel. Most basic filtering. */
-		FO_LINEAR = 2, /**< Average a 2x2 pixel area, signifies bilinear filtering for texture, trilinear for mipmaps. */
-		FO_ANISOTROPIC = 3, /**< More advanced filtering that improves quality when viewing textures at a steep angle */
-		FO_USE_COMPARISON = 4 /**< Specifies that the sampled values will be compared against existing sampled data. Should be OR-ed with other filtering options. */
-    };
-
-	/**
-	 * @brief	Types of frame buffers.
-	 */
-	enum FrameBufferType
-	{
-		FBT_COLOR = 0x1,
-		FBT_DEPTH = 0x2,
-		FBT_STENCIL = 0x4
-	};
-
-	/**
-	 * @brief	Types of culling that determine how (and if) hardware discards faces with certain
-	 *			winding order. Winding order can be used for determining front or back facing polygons by
-	 *			checking the order of its vertices from the render perspective.
-	 */
-    enum CullingMode
-    {
-		CULL_NONE = 1, /**< Hardware performs no culling and renders both sides. */
-		CULL_CLOCKWISE = 2, /**< Hardware culls faces that have a clockwise vertex ordering. */
-        CULL_COUNTERCLOCKWISE = 3 /**< Hardware culls faces that have a counter-clockwise vertex ordering. */
-    };
-
-	/**
-	 * @brief	Polygon mode to use when rasterizing.
-	 */
-    enum PolygonMode
-    {
-		PM_WIREFRAME = 1, /**< Render as wireframe showing only polygon outlines. */
-        PM_SOLID = 2 /**< Render as solid showing whole polygons. */
-    };
-
-	/**
-	 * @brief	Types of action that can happen on the stencil buffer.
-	 */
-	enum StencilOperation
-	{
-		SOP_KEEP, /**< Leave the stencil buffer unchanged. */
-		SOP_ZERO, /**< Set the stencil value to zero. */
-		SOP_REPLACE, /**< Replace the stencil value with the reference value. */
-		SOP_INCREMENT, /**< Increase the stencil value by 1, clamping at the maximum value. */
-		SOP_DECREMENT, /**< Decrease the stencil value by 1, clamping at 0. */
-		SOP_INCREMENT_WRAP, /**< Increase the stencil value by 1, wrapping back to 0 when incrementing past the maximum value. */
-		SOP_DECREMENT_WRAP, /**< Decrease the stencil value by 1, wrapping when decrementing 0. */
-		SOP_INVERT /**< Invert the bits of the stencil buffer. */
-	};
-
-	/**
-	* @brief	These values represent a hint to the driver when locking a hardware buffer.
-	*
-	*			GBL_WRITE_ONLY - Allows you to write to the buffer. Can cause a CPU-GPU sync point
-	*			so avoid using it often (i.e. every frame) as that might limit your performance significantly.
-	*			GBL_WRITE_ONLY_DISCARD - Allows you to write to the buffer. Tells the driver to completely discard the contents of the 
-	*			buffer you are writing to. The driver will (most likely) internally allocate another buffer with same specifications 
-	*			(which is fairly fast) and you will avoid CPU-GPU stalls.
-	*			GBL_WRITE_ONLY_NO_OVERWRITE - Allows you to write to the buffer. Guarantees the driver that you will not be updating any part of 
-	*			the buffer that is currently used. This will also avoid CPU-GPU stalls, without requiring you to discard the entire buffer. However 
-	*			it is hard to guarantee when GPU has finished using a buffer.
-	*			GBL_READ_ONLY - Allows you to read from a buffer. Be aware that reading is usually a very slow operation.
-	*			GBL_READ_WRITE - Allows you to both read and write to a buffer. 
-	*/
-	enum GpuLockOptions
-	{
-        GBL_READ_WRITE,
-		GBL_WRITE_ONLY_DISCARD,
-		GBL_READ_ONLY,
-        GBL_WRITE_ONLY_NO_OVERWRITE,
-		GBL_WRITE_ONLY	
-	};
-
-	/**
-	 * @brief	Values that represent hardware buffer usage. These usually determine in what
-	 *			type of memory is buffer placed in, however that depends on rendering API.
-	 * 
-	 *			GBU_STATIC - Signifies that you don't plan on modifying the buffer often (or at all)
-	 *			after creation. Modifying such buffer will involve a larger performance hit.
-	 *			GBU_DYNAMIC - Signifies that you will modify this buffer fairly often.
-	 */
-	enum GpuBufferUsage 
-	{
-        GBU_STATIC = 1,
-		GBU_DYNAMIC = 2
-	};
-
-	/**
-	 * @brief	Types of generic GPU buffers that may be attached to GPU programs.
-	 *
-	 *			GBT_STRUCTURED - Buffer containing an array of structures. Structure parameters
-	 *			can usually be easily accessed from within the GPU program.
-	 *			GBT_RAW - Buffer containing raw bytes. It is up to the user to interpret the data.
-	 *			GBT_INDIRECTARGUMENT - Special type of buffer allowing you to specify arguments for
-	 *			draw operations inside the buffer instead of providing them directly. Useful when you want
-	 *			to control drawing directly from GPU.
-	 *			GBT_APPENDCONSUME - A stack-like buffer that allows you to add or remove elements to/from the buffer
-	 *			from within the GPU program.
-	 */
-	enum GpuBufferType
-	{
-		GBT_STRUCTURED,
-		GBT_RAW,
-		GBT_INDIRECTARGUMENT,
-		GBT_APPENDCONSUME
-	};
-
-	/**
-	 * @brief	Different types of GPU views that control how GPU sees a hardware buffer.
-	 *
-	 *			GVU_DEFAULT - Buffer is seen as a default shader resource, used primarily for reading. (e.g. a texture for sampling)
-	 *			GVU_RENDERTARGET - Buffer is seen as a render target that color pixels will be written to after pixel shader stage.
-	 *			GVU_DEPTHSTENCIL - Buffer is seen as a depth stencil target that depth and stencil information is written to.
-	 *			GVU_RANDOMWRITE - Buffer that allows you to write to any part of it from within a GPU program.
-	 */
-	enum GpuViewUsage
-	{
-		GVU_DEFAULT = 0x01,
-		GVU_RENDERTARGET = 0x02,
-		GVU_DEPTHSTENCIL = 0x04,
-		GVU_RANDOMWRITE = 0x08
-	};
-
-	/**
-	 * @brief	Type of parameter block usages. Signifies how often will parameter blocks be changed.
-	 *
-	 *			GPBU_STATIC - Buffer will be rarely, if ever, updated.
-	 *			GPBU_DYNAMIC - Buffer will be updated often (e.g. every frame).
-	 */
-	enum GpuParamBlockUsage
-	{
-		GPBU_STATIC,
-		GPBU_DYNAMIC
-	};
-
-	/**
-	 * @brief	Type of GPU parameter.
-	 *
-	 *			GPT_DATA - Raw data type like float, Vector3, Color, etc.
-	 *			GPT_OBJECT - Reference to some GPU object like Texture, Sampler, etc.
-	 */
-	enum GpuParamType
-	{
-		GPT_DATA,
-		GPT_OBJECT
-	};
-
-	/**
-	 * @brief	Type of GPU data parameters that can be used as inputs to a GPU program.
-	 */
-	enum GpuParamDataType
-	{
-		GPDT_FLOAT1 = 1,
-		GPDT_FLOAT2 = 2,
-		GPDT_FLOAT3 = 3,
-		GPDT_FLOAT4 = 4,
-		GPDT_MATRIX_2X2 = 11,
-		GPDT_MATRIX_2X3 = 12,
-		GPDT_MATRIX_2X4 = 13,
-		GPDT_MATRIX_3X2 = 14,
-		GPDT_MATRIX_3X3 = 15,
-		GPDT_MATRIX_3X4 = 16,
-		GPDT_MATRIX_4X2 = 17,
-		GPDT_MATRIX_4X3 = 18,
-		GPDT_MATRIX_4X4 = 19,
-		GPDT_INT1 = 20,
-		GPDT_INT2 = 21,
-		GPDT_INT3 = 22,
-		GPDT_INT4 = 23,
-		GPDT_BOOL = 24,
-		GPDT_STRUCT = 25,
-		GPDT_UNKNOWN = 0xffff
-	};
-
-	/**
-	 * @brief	Type of GPU object parameters that can be used as inputs to a GPU program.
-	 */
-	enum GpuParamObjectType
-	{
-		GPOT_SAMPLER1D = 1,
-		GPOT_SAMPLER2D = 2,
-		GPOT_SAMPLER3D = 3,
-		GPOT_SAMPLERCUBE = 4,
-		GPOT_TEXTURE1D = 11,
-		GPOT_TEXTURE2D = 12,
-		GPOT_TEXTURE3D = 13,
-		GPOT_TEXTURECUBE = 14,
-		GPOT_RWTEXTURE1D = 21,
-		GPOT_RWTEXTURE2D = 22,
-		GPOT_RWTEXTURE3D = 23,
-		GPOT_BYTE_BUFFER = 32,
-		GPOT_STRUCTURED_BUFFER = 33,
-		GPOT_RWTYPED_BUFFER = 41,
-		GPOT_RWBYTE_BUFFER = 42,
-		GPOT_RWSTRUCTURED_BUFFER = 43,
-		GPOT_RWSTRUCTURED_BUFFER_WITH_COUNTER = 44,
-		GPOT_RWAPPEND_BUFFER = 45,
-		GPOT_RWCONSUME_BUFFER = 46,
-		GPOT_UNKNOWN = 0xffff
-	};
-
-	/**
-	 * @brief	These values represent a hint to the driver when writing
-	 * 			to a GPU buffer.
-	 * 			
-	 *			Normal - Default flag with least restrictions. Can cause a CPU-GPU sync point
-	 *			so avoid using it often (i.e. every frame) as that might limit your performance significantly.
-	 *			Discard - Tells the driver to completely discard the contents of the buffer you are writing
-	 *			to. The driver will (most likely) internally allocate another buffer with same specifications (which is fairly fast)
-	 *			and you will avoid CPU-GPU stalls. 
-	 *			NoOverwrite - Guarantees the driver that you will not be updating any part of the buffer that is currently used.
-	 *			This will also avoid CPU-GPU stalls, without requiring you to discard the entire buffer. However it is hard to
-	 *			guarantee when GPU has finished using a buffer.
-	 */
-	enum class BufferWriteType
-	{
-		Normal,
-		Discard,
-		NoOverwrite
-	};
-
-	/**
-	 * @brief	Texture addressing mode, per component.
-	 */
-	struct UVWAddressingMode
-	{
-		UVWAddressingMode()
-			:u(TAM_WRAP), v(TAM_WRAP), w(TAM_WRAP)
-		{ }
-
-		TextureAddressingMode u, v, w;
-	};
-    
-	typedef Map<String, String> NameValuePairList;
+#pragma once
+
+namespace BansheeEngine 
+{
+	/**
+	 * @brief	Factors used when blending new pixels with existing pixels.
+	 */
+    enum BlendFactor
+    {
+		BF_ONE, /**< Use a value of one for all pixel components. */
+		BF_ZERO, /**< Use a value of zero for all pixel components. */
+		BF_DEST_COLOR, /**< Use the existing pixel value. */
+		BF_SOURCE_COLOR, /**< Use the newly generated pixel value. */
+		BF_INV_DEST_COLOR, /**< Use the inverse of the existing value. */
+		BF_INV_SOURCE_COLOR, /**< Use the inverse of the newly generated pixel value. */
+		BF_DEST_ALPHA, /**< Use the existing alpha value. */
+		BF_SOURCE_ALPHA, /**< Use the newly generated alpha value. */
+		BF_INV_DEST_ALPHA, /**< Use the inverse of the existing alpha value. */
+		BF_INV_SOURCE_ALPHA /**< Use the inverse of the newly generated alpha value. */
+    };
+
+	/**
+	 * @brief	Operations that determines how are blending factors combined.
+	 */
+	enum BlendOperation
+	{
+		BO_ADD, /**< Blend factors are added together. */
+		BO_SUBTRACT, /**< Blend factors are subtracted in "srcFactor - dstFactor" order. */
+		BO_REVERSE_SUBTRACT, /**< Blend factors are subtracted in "dstFactor - srcFactor" order. */
+		BO_MIN, /**< Minimum of the two factors is chosen. */
+		BO_MAX /**< Maximum of the two factors is chosen. */
+	};
+
+	/**
+	 * @brief	Comparison functions used for the depth/stencil buffer.
+	 */
+    enum CompareFunction
+    {
+		CMPF_ALWAYS_FAIL, /**< Operation will always fail. */
+		CMPF_ALWAYS_PASS, /**< Operation will always pass. */
+		CMPF_LESS, /**< Operation will pass if the new value is less than existing value. */
+        CMPF_LESS_EQUAL, /**< Operation will pass if the new value is less or equal than existing value. */
+        CMPF_EQUAL, /**< Operation will pass if the new value is equal to the existing value. */
+        CMPF_NOT_EQUAL, /**< Operation will pass if the new value is not equal to the existing value. */
+        CMPF_GREATER_EQUAL, /**< Operation will pass if the new value greater or equal than the existing value. */
+        CMPF_GREATER /**< Operation will pass if the new value greater than the existing value. */
+    };
+
+	/**
+	 * @brief	Types of texture addressing modes that determine what happens when texture
+	 *			coordinates are outside of the valid range.
+	 */
+    enum TextureAddressingMode
+    {
+		TAM_WRAP, /**< Coordinates wrap back to the valid range. */
+		TAM_MIRROR, /**< Coordinates flip every time the size of the valid range is passed. */
+		TAM_CLAMP, /**< Coordinates are clamped within the valid range. */
+		TAM_BORDER /**< Coordinates outside of the valid range will return a separately set border color. */
+    };
+
+	/**
+	 * @brief	Types of available filtering situations.
+	 */
+    enum FilterType
+    {
+		FT_MIN, /**< The filter used when shrinking a texture. */
+        FT_MAG, /**< The filter used when magnifying a texture. */
+        FT_MIP /**< The filter used when filtering between mipmaps. */
+    };
+
+	/**
+	 * @brief	Filtering options for textures.
+	 */
+    enum FilterOptions
+    {
+		FO_NONE = 0, /**< Use no filtering. Only relevant for mipmap filtering. */
+		FO_POINT = 1, /**< Filter using the nearest found pixel. Most basic filtering. */
+		FO_LINEAR = 2, /**< Average a 2x2 pixel area, signifies bilinear filtering for texture, trilinear for mipmaps. */
+		FO_ANISOTROPIC = 3, /**< More advanced filtering that improves quality when viewing textures at a steep angle */
+		FO_USE_COMPARISON = 4 /**< Specifies that the sampled values will be compared against existing sampled data. Should be OR-ed with other filtering options. */
+    };
+
+	/**
+	 * @brief	Types of frame buffers.
+	 */
+	enum FrameBufferType
+	{
+		FBT_COLOR = 0x1,
+		FBT_DEPTH = 0x2,
+		FBT_STENCIL = 0x4
+	};
+
+	/**
+	 * @brief	Types of culling that determine how (and if) hardware discards faces with certain
+	 *			winding order. Winding order can be used for determining front or back facing polygons by
+	 *			checking the order of its vertices from the render perspective.
+	 */
+    enum CullingMode
+    {
+		CULL_NONE = 1, /**< Hardware performs no culling and renders both sides. */
+		CULL_CLOCKWISE = 2, /**< Hardware culls faces that have a clockwise vertex ordering. */
+        CULL_COUNTERCLOCKWISE = 3 /**< Hardware culls faces that have a counter-clockwise vertex ordering. */
+    };
+
+	/**
+	 * @brief	Polygon mode to use when rasterizing.
+	 */
+    enum PolygonMode
+    {
+		PM_WIREFRAME = 1, /**< Render as wireframe showing only polygon outlines. */
+        PM_SOLID = 2 /**< Render as solid showing whole polygons. */
+    };
+
+	/**
+	 * @brief	Types of action that can happen on the stencil buffer.
+	 */
+	enum StencilOperation
+	{
+		SOP_KEEP, /**< Leave the stencil buffer unchanged. */
+		SOP_ZERO, /**< Set the stencil value to zero. */
+		SOP_REPLACE, /**< Replace the stencil value with the reference value. */
+		SOP_INCREMENT, /**< Increase the stencil value by 1, clamping at the maximum value. */
+		SOP_DECREMENT, /**< Decrease the stencil value by 1, clamping at 0. */
+		SOP_INCREMENT_WRAP, /**< Increase the stencil value by 1, wrapping back to 0 when incrementing past the maximum value. */
+		SOP_DECREMENT_WRAP, /**< Decrease the stencil value by 1, wrapping when decrementing 0. */
+		SOP_INVERT /**< Invert the bits of the stencil buffer. */
+	};
+
+	/**
+	* @brief	These values represent a hint to the driver when locking a hardware buffer.
+	*
+	*			GBL_WRITE_ONLY - Allows you to write to the buffer. Can cause a CPU-GPU sync point
+	*			so avoid using it often (i.e. every frame) as that might limit your performance significantly.
+	*			GBL_WRITE_ONLY_DISCARD - Allows you to write to the buffer. Tells the driver to completely discard the contents of the 
+	*			buffer you are writing to. The driver will (most likely) internally allocate another buffer with same specifications 
+	*			(which is fairly fast) and you will avoid CPU-GPU stalls.
+	*			GBL_WRITE_ONLY_NO_OVERWRITE - Allows you to write to the buffer. Guarantees the driver that you will not be updating any part of 
+	*			the buffer that is currently used. This will also avoid CPU-GPU stalls, without requiring you to discard the entire buffer. However 
+	*			it is hard to guarantee when GPU has finished using a buffer.
+	*			GBL_READ_ONLY - Allows you to read from a buffer. Be aware that reading is usually a very slow operation.
+	*			GBL_READ_WRITE - Allows you to both read and write to a buffer. 
+	*/
+	enum GpuLockOptions
+	{
+        GBL_READ_WRITE,
+		GBL_WRITE_ONLY_DISCARD,
+		GBL_READ_ONLY,
+        GBL_WRITE_ONLY_NO_OVERWRITE,
+		GBL_WRITE_ONLY	
+	};
+
+	/**
+	 * @brief	Values that represent hardware buffer usage. These usually determine in what
+	 *			type of memory is buffer placed in, however that depends on rendering API.
+	 * 
+	 *			GBU_STATIC - Signifies that you don't plan on modifying the buffer often (or at all)
+	 *			after creation. Modifying such buffer will involve a larger performance hit.
+	 *			GBU_DYNAMIC - Signifies that you will modify this buffer fairly often.
+	 */
+	enum GpuBufferUsage 
+	{
+        GBU_STATIC = 1,
+		GBU_DYNAMIC = 2
+	};
+
+	/**
+	 * @brief	Types of generic GPU buffers that may be attached to GPU programs.
+	 *
+	 *			GBT_STRUCTURED - Buffer containing an array of structures. Structure parameters
+	 *			can usually be easily accessed from within the GPU program.
+	 *			GBT_RAW - Buffer containing raw bytes. It is up to the user to interpret the data.
+	 *			GBT_INDIRECTARGUMENT - Special type of buffer allowing you to specify arguments for
+	 *			draw operations inside the buffer instead of providing them directly. Useful when you want
+	 *			to control drawing directly from GPU.
+	 *			GBT_APPENDCONSUME - A stack-like buffer that allows you to add or remove elements to/from the buffer
+	 *			from within the GPU program.
+	 */
+	enum GpuBufferType
+	{
+		GBT_STRUCTURED,
+		GBT_RAW,
+		GBT_INDIRECTARGUMENT,
+		GBT_APPENDCONSUME
+	};
+
+	/**
+	 * @brief	Different types of GPU views that control how GPU sees a hardware buffer.
+	 *
+	 *			GVU_DEFAULT - Buffer is seen as a default shader resource, used primarily for reading. (e.g. a texture for sampling)
+	 *			GVU_RENDERTARGET - Buffer is seen as a render target that color pixels will be written to after pixel shader stage.
+	 *			GVU_DEPTHSTENCIL - Buffer is seen as a depth stencil target that depth and stencil information is written to.
+	 *			GVU_RANDOMWRITE - Buffer that allows you to write to any part of it from within a GPU program.
+	 */
+	enum GpuViewUsage
+	{
+		GVU_DEFAULT = 0x01,
+		GVU_RENDERTARGET = 0x02,
+		GVU_DEPTHSTENCIL = 0x04,
+		GVU_RANDOMWRITE = 0x08
+	};
+
+	/**
+	 * @brief	Type of parameter block usages. Signifies how often will parameter blocks be changed.
+	 *
+	 *			GPBU_STATIC - Buffer will be rarely, if ever, updated.
+	 *			GPBU_DYNAMIC - Buffer will be updated often (e.g. every frame).
+	 */
+	enum GpuParamBlockUsage
+	{
+		GPBU_STATIC,
+		GPBU_DYNAMIC
+	};
+
+	/**
+	 * @brief	Type of GPU parameter.
+	 *
+	 *			GPT_DATA - Raw data type like float, Vector3, Color, etc.
+	 *			GPT_OBJECT - Reference to some GPU object like Texture, Sampler, etc.
+	 */
+	enum GpuParamType
+	{
+		GPT_DATA,
+		GPT_OBJECT
+	};
+
+	/**
+	 * @brief	Type of GPU data parameters that can be used as inputs to a GPU program.
+	 */
+	enum GpuParamDataType
+	{
+		GPDT_FLOAT1 = 1,
+		GPDT_FLOAT2 = 2,
+		GPDT_FLOAT3 = 3,
+		GPDT_FLOAT4 = 4,
+		GPDT_MATRIX_2X2 = 11,
+		GPDT_MATRIX_2X3 = 12,
+		GPDT_MATRIX_2X4 = 13,
+		GPDT_MATRIX_3X2 = 14,
+		GPDT_MATRIX_3X3 = 15,
+		GPDT_MATRIX_3X4 = 16,
+		GPDT_MATRIX_4X2 = 17,
+		GPDT_MATRIX_4X3 = 18,
+		GPDT_MATRIX_4X4 = 19,
+		GPDT_INT1 = 20,
+		GPDT_INT2 = 21,
+		GPDT_INT3 = 22,
+		GPDT_INT4 = 23,
+		GPDT_BOOL = 24,
+		GPDT_STRUCT = 25,
+		GPDT_UNKNOWN = 0xffff
+	};
+
+	/**
+	 * @brief	Type of GPU object parameters that can be used as inputs to a GPU program.
+	 */
+	enum GpuParamObjectType
+	{
+		GPOT_SAMPLER1D = 1,
+		GPOT_SAMPLER2D = 2,
+		GPOT_SAMPLER3D = 3,
+		GPOT_SAMPLERCUBE = 4,
+		GPOT_TEXTURE1D = 11,
+		GPOT_TEXTURE2D = 12,
+		GPOT_TEXTURE3D = 13,
+		GPOT_TEXTURECUBE = 14,
+		GPOT_RWTEXTURE1D = 21,
+		GPOT_RWTEXTURE2D = 22,
+		GPOT_RWTEXTURE3D = 23,
+		GPOT_BYTE_BUFFER = 32,
+		GPOT_STRUCTURED_BUFFER = 33,
+		GPOT_RWTYPED_BUFFER = 41,
+		GPOT_RWBYTE_BUFFER = 42,
+		GPOT_RWSTRUCTURED_BUFFER = 43,
+		GPOT_RWSTRUCTURED_BUFFER_WITH_COUNTER = 44,
+		GPOT_RWAPPEND_BUFFER = 45,
+		GPOT_RWCONSUME_BUFFER = 46,
+		GPOT_UNKNOWN = 0xffff
+	};
+
+	/**
+	 * @brief	These values represent a hint to the driver when writing
+	 * 			to a GPU buffer.
+	 * 			
+	 *			Normal - Default flag with least restrictions. Can cause a CPU-GPU sync point
+	 *			so avoid using it often (i.e. every frame) as that might limit your performance significantly.
+	 *			Discard - Tells the driver to completely discard the contents of the buffer you are writing
+	 *			to. The driver will (most likely) internally allocate another buffer with same specifications (which is fairly fast)
+	 *			and you will avoid CPU-GPU stalls. 
+	 *			NoOverwrite - Guarantees the driver that you will not be updating any part of the buffer that is currently used.
+	 *			This will also avoid CPU-GPU stalls, without requiring you to discard the entire buffer. However it is hard to
+	 *			guarantee when GPU has finished using a buffer.
+	 */
+	enum class BufferWriteType
+	{
+		Normal,
+		Discard,
+		NoOverwrite
+	};
+
+	/**
+	 * @brief	Texture addressing mode, per component.
+	 */
+	struct UVWAddressingMode
+	{
+		UVWAddressingMode()
+			:u(TAM_WRAP), v(TAM_WRAP), w(TAM_WRAP)
+		{ }
+
+		TextureAddressingMode u, v, w;
+	};
+
+	/**
+	* @brief Represents a MAC (ethernet) address.
+	*/
+	struct MACAddress
+	{
+		UINT8 value[6];
+	};
+    
+	typedef Map<String, String> NameValuePairList;
 }

+ 0 - 1
CamelotCore/Include/BsGPUProfiler.h

@@ -2,7 +2,6 @@
 
 #include "CmPrerequisites.h"
 #include "CmModule.h"
-#include "BsProfilerFwd.h"
 
 namespace BansheeEngine
 {

+ 0 - 14
CamelotCore/Include/BsProfilerFwd.h

@@ -1,14 +0,0 @@
-#pragma once
-
-#include "CmPrerequisites.h"
-
-namespace BansheeEngine
-{
-	typedef std::basic_string<char, std::char_traits<char>, StdAlloc<char, ProfilerAlloc>> ProfilerString;
-
-	template <typename T, typename A = StdAlloc<T, ProfilerAlloc>>
-	using ProfilerVector = std::vector<T, A>;
-
-	template <typename T, typename A = StdAlloc<T, ProfilerAlloc>>
-	using ProfilerStack = std::stack<T, std::deque<T, A>>;
-}

+ 0 - 18
CamelotCore/Include/BsThreadPolicy.h

@@ -1,18 +0,0 @@
-#pragma once
-
-#include "CmPrerequisites.h"
-#include "CmProfiler.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Banshee thread policy that performs special startup/shutdown on threads
-	 *			managed by thread pool.
-	 */
-	class CM_EXPORT ThreadBansheePolicy
-	{
-	public:
-		static void onThreadStarted(const String& name);
-		static void onThreadEnded(const String& name);
-	};
-}

+ 0 - 3
CamelotCore/Include/CmApplication.h

@@ -59,9 +59,6 @@ namespace BansheeEngine
 			 */
 			void shutDown();
 
-			// DEPRECATED
-			UINT64 getAppWindowId();
-
 			/**
 			 * @brief	
 			 */

+ 0 - 1
CamelotCore/Include/CmBindableGpuParamBlock.h

@@ -1,7 +1,6 @@
 #pragma once
 
 #include "CmPrerequisites.h"
-#include "CmCommonEnums.h"
 #include "CmCoreObject.h"
 
 namespace BansheeEngine

+ 0 - 1
CamelotCore/Include/CmBlendState.h

@@ -2,7 +2,6 @@
 
 #include "CmPrerequisites.h"
 #include "CmResource.h"
-#include "CmCommonEnums.h"
 
 namespace BansheeEngine
 {

+ 0 - 1
CamelotCore/Include/CmCPUProfiler.h

@@ -1,7 +1,6 @@
 #pragma once
 
 #include "CmPrerequisites.h"
-#include "BsProfilerFwd.h"
 
 namespace BansheeEngine
 {

+ 0 - 1
CamelotCore/Include/CmCommandQueue.h

@@ -2,7 +2,6 @@
 
 #include "CmPrerequisites.h"
 #include "CmAsyncOp.h"
-#include "CmCommonEnums.h"
 #include <functional>
 
 namespace BansheeEngine

+ 0 - 1
CamelotCore/Include/CmCoreThreadAccessor.h

@@ -1,7 +1,6 @@
 #pragma once
 
 #include "CmPrerequisites.h"
-#include "CmCommonEnums.h"
 #include "CmRenderSystem.h"
 #include "CmCommandQueue.h"
 #include "CmAsyncOp.h"

+ 0 - 1
CamelotCore/Include/CmDepthStencilState.h

@@ -1,7 +1,6 @@
 #pragma once
 
 #include "CmPrerequisites.h"
-#include "CmCommonEnums.h"
 #include "CmResource.h"
 
 namespace BansheeEngine

+ 1 - 1
CamelotCore/Include/CmFolderMonitor.h

@@ -3,5 +3,5 @@
 #include "CmPrerequisites.h"
 
 #if CM_PLATFORM == CM_PLATFORM_WIN32
-#include "CmWin32FolderMonitor.h"
+#include "Win32/CmWin32FolderMonitor.h"
 #endif

+ 0 - 1
CamelotCore/Include/CmGpuBuffer.h

@@ -1,7 +1,6 @@
 #pragma once
 
 #include "CmPrerequisites.h"
-#include "CmCommonEnums.h"
 #include "CmGpuBufferView.h"
 #include "CmCoreObject.h"
 

+ 0 - 1
CamelotCore/Include/CmGpuBufferView.h

@@ -1,7 +1,6 @@
 #pragma once
 
 #include "CmPrerequisites.h"
-#include "CmCommonEnums.h"
 
 namespace BansheeEngine
 {

+ 0 - 1
CamelotCore/Include/CmGpuParamBlock.h

@@ -1,7 +1,6 @@
 #pragma once
 
 #include "CmPrerequisites.h"
-#include "CmCommonEnums.h"
 #include "CmCoreObject.h"
 
 namespace BansheeEngine

+ 0 - 1
CamelotCore/Include/CmGpuParamBlockBuffer.h

@@ -1,7 +1,6 @@
 #pragma once
 
 #include "CmPrerequisites.h"
-#include "CmCommonEnums.h"
 #include "CmCoreObject.h"
 
 namespace BansheeEngine

+ 0 - 1
CamelotCore/Include/CmGpuParamDesc.h

@@ -1,7 +1,6 @@
 #pragma once
 
 #include "CmPrerequisites.h"
-#include "CmCommonEnums.h"
 
 namespace BansheeEngine
 {

+ 0 - 1
CamelotCore/Include/CmHardwareBuffer.h

@@ -1,7 +1,6 @@
 #pragma once
 
 #include "CmPrerequisites.h"
-#include "CmCommonEnums.h"
 
 namespace BansheeEngine 
 {

+ 0 - 1
CamelotCore/Include/CmMaterial.h

@@ -8,7 +8,6 @@
 #include "CmVector4.h"
 #include "CmMatrix3.h"
 #include "CmMatrix4.h"
-#include "CmCommonEnums.h"
 
 namespace BansheeEngine
 {

+ 0 - 1
CamelotCore/Include/CmPass.h

@@ -1,7 +1,6 @@
 #pragma once
 
 #include "CmPrerequisites.h"
-#include "CmCommonEnums.h"
 #include "CmCoreThreadAccessor.h"
 #include "CmColor.h"
 #include "CmIReflectable.h"

+ 29 - 6
CamelotCore/Include/CmPrerequisites.h

@@ -5,7 +5,6 @@
 #define CM_MAX_MULTIPLE_RENDER_TARGETS 8
 #define CM_FORCE_SINGLETHREADED_RENDERING 0
 
-//----------------------------------------------------------------------------
 // Windows Settings
 #if CM_PLATFORM == CM_PLATFORM_WIN32
 
@@ -33,7 +32,7 @@
 #       define CM_DEBUG_MODE 0
 #   endif
 
-#endif // CM_PLATFORM == CM_PLATFORM_WIN32
+#endif
 
 // Linux/Apple Settings
 #if CM_PLATFORM == CM_PLATFORM_LINUX || CM_PLATFORM == CM_PLATFORM_APPLE
@@ -60,9 +59,6 @@
 
 namespace BansheeEngine 
 {
-// Pre-declare classes
-// Allows use of pointers in header files without including individual .h
-// so decreases dependencies between files
     class Color;
     class GpuProgram;
     class GpuProgramManager;
@@ -331,6 +327,33 @@ namespace BansheeEngine
 	 * @param	callback	The callback.
 	 */
 	void CM_EXPORT deferredCall(std::function<void()> callback);
+
+	// Special types for use by profilers
+	typedef std::basic_string<char, std::char_traits<char>, StdAlloc<char, ProfilerAlloc>> ProfilerString;
+
+	template <typename T, typename A = StdAlloc<T, ProfilerAlloc>>
+	using ProfilerVector = std::vector<T, A>;
+
+	template <typename T, typename A = StdAlloc<T, ProfilerAlloc>>
+	using ProfilerStack = std::stack<T, std::deque<T, A>>;
+
+	/**
+	* @brief	Banshee thread policy that performs special startup/shutdown on threads
+	*			managed by thread pool.
+	*/
+	class CM_EXPORT ThreadBansheePolicy
+	{
+	public:
+		static void onThreadStarted(const String& name)
+		{
+			MemStack::beginThread();
+		}
+
+		static void onThreadEnded(const String& name)
+		{
+			MemStack::endThread();
+		}
+	};
 }
 
-#include "BsCommonStructs.h"
+#include "BsCommonTypes.h"

+ 0 - 1
CamelotCore/Include/CmRasterizerState.h

@@ -1,7 +1,6 @@
 #pragma once
 
 #include "CmPrerequisites.h"
-#include "CmCommonEnums.h"
 #include "CmResource.h"
 
 namespace BansheeEngine

+ 0 - 1
CamelotCore/Include/CmRenderSystem.h

@@ -6,7 +6,6 @@
 #include "CmString.h"
 
 #include "CmSamplerState.h"
-#include "CmCommonEnums.h"
 #include "BsRenderStats.h"
 #include "CmCommandQueue.h"
 #include "CmDrawOps.h"

+ 0 - 1
CamelotCore/Include/CmSamplerState.h

@@ -1,7 +1,6 @@
 #pragma once
 
 #include "CmPrerequisites.h"
-#include "CmCommonEnums.h"
 #include "CmMatrix4.h"
 #include "CmString.h"
 #include "CmPixelUtil.h"

+ 0 - 1
CamelotCore/Include/CmShader.h

@@ -2,7 +2,6 @@
 
 #include "CmPrerequisites.h"
 #include "CmResource.h"
-#include "CmCommonEnums.h"
 
 namespace BansheeEngine
 {

+ 0 - 1
CamelotCore/Include/CmTextureView.h

@@ -2,7 +2,6 @@
 
 #include "CmPrerequisites.h"
 #include "CmCoreObject.h"
-#include "CmCommonEnums.h"
 
 namespace BansheeEngine
 {

+ 0 - 1
CamelotCore/Include/CmViewport.h

@@ -1,7 +1,6 @@
 #pragma once
 
 #include "CmPrerequisites.h"
-#include "CmCommonEnums.h"
 #include "CmColor.h"
 #include "CmRectI.h"
 #include "CmRectF.h"

+ 41 - 41
CamelotCore/Include/CmPlatformWndProc.h → CamelotCore/Include/Win32/CmPlatformWndProc.h

@@ -1,42 +1,42 @@
-#pragma once
-
-#include "CmPlatform.h"
-#include "CmWin32Defs.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Contains the main message loop
-	 *
-	 * @note	This is separated from the main Platform because we don't want to include various Windows
-	 * 			defines in a lot of our code that includes "Platform.h".
-	 */
-	class CM_EXPORT PlatformWndProc : public Platform
-	{
-	public:
-		/**
-		 * @brief	Main message loop callback that processes messages received from windows.
-		 */
-		static LRESULT CALLBACK _win32WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
-
-	private:
-		static bool isShiftPressed;
-		static bool isCtrlPressed;
-
-		/**
-		 * @brief	Translate engine non client area to win32 non client area.
-		 */
-		static LRESULT translateNonClientAreaType(NonClientAreaBorderType type);
-
-		/**
-		 * @brief	Method triggerend whenever a mouse event happens.
-		 */
-		static void getMouseData(HWND hWnd, WPARAM wParam, LPARAM lParam, Vector2I& mousePos, OSPointerButtonStates& btnStates);
-
-		/**
-		 * @brief	Converts a virtual key code into an input command, if possible. Returns true
-		 *			if conversion was done.
-		 */
-		static bool getCommand(unsigned int virtualKeyCode, InputCommandType& command);
-	};
+#pragma once
+
+#include "CmPlatform.h"
+#include "CmWin32Defs.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Contains the main message loop
+	 *
+	 * @note	This is separated from the main Platform because we don't want to include various Windows
+	 * 			defines in a lot of our code that includes "Platform.h".
+	 */
+	class CM_EXPORT PlatformWndProc : public Platform
+	{
+	public:
+		/**
+		 * @brief	Main message loop callback that processes messages received from windows.
+		 */
+		static LRESULT CALLBACK _win32WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+	private:
+		static bool isShiftPressed;
+		static bool isCtrlPressed;
+
+		/**
+		 * @brief	Translate engine non client area to win32 non client area.
+		 */
+		static LRESULT translateNonClientAreaType(NonClientAreaBorderType type);
+
+		/**
+		 * @brief	Method triggerend whenever a mouse event happens.
+		 */
+		static void getMouseData(HWND hWnd, WPARAM wParam, LPARAM lParam, Vector2I& mousePos, OSPointerButtonStates& btnStates);
+
+		/**
+		 * @brief	Converts a virtual key code into an input command, if possible. Returns true
+		 *			if conversion was done.
+		 */
+		static bool getCommand(unsigned int virtualKeyCode, InputCommandType& command);
+	};
 }

+ 9 - 9
CamelotCore/Include/CmWin32Defs.h → CamelotCore/Include/Win32/CmWin32Defs.h

@@ -1,10 +1,10 @@
-#define WIN32_LEAN_AND_MEAN
-#if !defined(NOMINMAX) && defined(_MSC_VER)
-#	define NOMINMAX // Required to stop windows.h messing up std::min
-#endif
-#include <windows.h>
-#include <windowsx.h>
-#include <oleidl.h>
-
-#define WM_CM_SETCAPTURE WM_USER + 101
+#define WIN32_LEAN_AND_MEAN
+#if !defined(NOMINMAX) && defined(_MSC_VER)
+#	define NOMINMAX // Required to stop windows.h messing up std::min
+#endif
+#include <windows.h>
+#include <windowsx.h>
+#include <oleidl.h>
+
+#define WM_CM_SETCAPTURE WM_USER + 101
 #define WM_CM_RELEASECAPTURE WM_USER + 102

+ 100 - 100
CamelotCore/Include/CmWin32FolderMonitor.h → CamelotCore/Include/Win32/CmWin32FolderMonitor.h

@@ -1,101 +1,101 @@
-#pragma once
-
-#include "CmPrerequisites.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	These values types of notifications we would like to receive
-	 *			when we start a FolderMonitor on a certain folder.
-	 */
-	enum class FolderChange
-	{
-		FileName = 0x0001, /**< Called when filename changes. */
-		DirName = 0x0002, /**< Called when directory name changes. */
-		Attributes = 0x0004, /**< Called when attributes changes. */
-		Size = 0x0008, /**< Called when file size changes. */
-		LastWrite = 0x0010, /**< Called when file is written to. */
-		LastAccess = 0x0020, /**< Called when file is accessed. */
-		Creation = 0x0040, /**< Called when file is created. */
-		Security = 0x0080 /**< Called when file security descriptor changes. */
-	};
-
-	/**
-	 * @brief	Allows you to monitor a file system folder for changes. Depending on the flags
-	 *			set this monitor can notify you when file is changed/moved/renamed, etc.
-	 */
-	class CM_EXPORT FolderMonitor
-	{
-		struct Pimpl;
-		class FileNotifyInfo;
-		struct FolderWatchInfo;
-	public:
-		FolderMonitor();
-		~FolderMonitor();
-
-		/**
-		 * @brief	Starts monitoring a folder at the specified path.
-		 *
-		 * @param	folderPath		Absolute path to the folder you want to monitor.
-		 * @param	subdirectories	If true, provided folder and all of its subdirectories will be monitored
-		 *							for changes. Otherwise only the provided folder will be monitored.
-		 * @param	changeFilter	A set of flags you may OR together. Different notification events will
-		 *							trigger depending on which flags you set.
-		 */
-		void startMonitor(const Path& folderPath, bool subdirectories, FolderChange changeFilter);
-
-		/**
-		 * @brief	Stops monitoring the folder at the specified path.
-		 */
-		void stopMonitor(const Path& folderPath);
-
-		/**
-		 * @brief	Stops monitoring all folders that are currently being monitored.
-		 */
-		void stopMonitorAll();
-
-		/**
-		 * @brief	Callbacks will only get fired after update is called().
-		 * 			
-		 * @note	Internal method.
-		 */
-		void _update();
-
-		/**
-		 * @brief	Triggers when a file is modified. Provides
-		 *			full path to the file.
-		 */
-		Event<void(const Path&)> onModified;
-
-		/**
-		 * @brief	Triggers when a file/folder is adeed. Provides
-		 *			full path to the file/folder.
-		 */
-		Event<void(const Path&)> onAdded;
-
-		/**
-		 * @brief	Triggers when a file/folder is removed. Provides
-		 *			full path to the file/folder.
-		 */
-		Event<void(const Path&)> onRemoved;
-
-		/**
-		 * @brief	Triggers when a file/folder is renamed. Provides
-		 *			full path to the old and new name.
-		 */
-		Event<void(const Path&, const Path&)> onRenamed;
-
-	private:
-		Pimpl* mPimpl;
-
-		/**
-		 * @brief	Worker method that monitors the IO ports for any modification notifications.
-		 */
-		void workerThreadMain();
-
-		/**
-		 * @brief	Called by the worker thread whenever a modification notification is received.
-		 */
-		void handleNotifications(FileNotifyInfo& notifyInfo, FolderWatchInfo& watchInfo);
-	};
+#pragma once
+
+#include "CmPrerequisites.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	These values types of notifications we would like to receive
+	 *			when we start a FolderMonitor on a certain folder.
+	 */
+	enum class FolderChange
+	{
+		FileName = 0x0001, /**< Called when filename changes. */
+		DirName = 0x0002, /**< Called when directory name changes. */
+		Attributes = 0x0004, /**< Called when attributes changes. */
+		Size = 0x0008, /**< Called when file size changes. */
+		LastWrite = 0x0010, /**< Called when file is written to. */
+		LastAccess = 0x0020, /**< Called when file is accessed. */
+		Creation = 0x0040, /**< Called when file is created. */
+		Security = 0x0080 /**< Called when file security descriptor changes. */
+	};
+
+	/**
+	 * @brief	Allows you to monitor a file system folder for changes. Depending on the flags
+	 *			set this monitor can notify you when file is changed/moved/renamed, etc.
+	 */
+	class CM_EXPORT FolderMonitor
+	{
+		struct Pimpl;
+		class FileNotifyInfo;
+		struct FolderWatchInfo;
+	public:
+		FolderMonitor();
+		~FolderMonitor();
+
+		/**
+		 * @brief	Starts monitoring a folder at the specified path.
+		 *
+		 * @param	folderPath		Absolute path to the folder you want to monitor.
+		 * @param	subdirectories	If true, provided folder and all of its subdirectories will be monitored
+		 *							for changes. Otherwise only the provided folder will be monitored.
+		 * @param	changeFilter	A set of flags you may OR together. Different notification events will
+		 *							trigger depending on which flags you set.
+		 */
+		void startMonitor(const Path& folderPath, bool subdirectories, FolderChange changeFilter);
+
+		/**
+		 * @brief	Stops monitoring the folder at the specified path.
+		 */
+		void stopMonitor(const Path& folderPath);
+
+		/**
+		 * @brief	Stops monitoring all folders that are currently being monitored.
+		 */
+		void stopMonitorAll();
+
+		/**
+		 * @brief	Callbacks will only get fired after update is called().
+		 * 			
+		 * @note	Internal method.
+		 */
+		void _update();
+
+		/**
+		 * @brief	Triggers when a file is modified. Provides
+		 *			full path to the file.
+		 */
+		Event<void(const Path&)> onModified;
+
+		/**
+		 * @brief	Triggers when a file/folder is adeed. Provides
+		 *			full path to the file/folder.
+		 */
+		Event<void(const Path&)> onAdded;
+
+		/**
+		 * @brief	Triggers when a file/folder is removed. Provides
+		 *			full path to the file/folder.
+		 */
+		Event<void(const Path&)> onRemoved;
+
+		/**
+		 * @brief	Triggers when a file/folder is renamed. Provides
+		 *			full path to the old and new name.
+		 */
+		Event<void(const Path&, const Path&)> onRenamed;
+
+	private:
+		Pimpl* mPimpl;
+
+		/**
+		 * @brief	Worker method that monitors the IO ports for any modification notifications.
+		 */
+		void workerThreadMain();
+
+		/**
+		 * @brief	Called by the worker thread whenever a modification notification is received.
+		 */
+		void handleNotifications(FileNotifyInfo& notifyInfo, FolderWatchInfo& watchInfo);
+	};
 }

+ 0 - 15
CamelotCore/Include/stdafx.h

@@ -1,15 +0,0 @@
-// stdafx.h : include file for standard system include files,
-// or project specific include files that are used frequently, but
-// are changed infrequently
-//
-
-#pragma once
-
-#include "targetver.h"
-
-#include <stdio.h>
-#include <tchar.h>
-
-
-
-// TODO: reference additional headers your program requires here

+ 0 - 8
CamelotCore/Include/targetver.h

@@ -1,8 +0,0 @@
-#pragma once
-
-// Including SDKDDKVer.h defines the highest available Windows platform.
-
-// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
-// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
-
-#include <SDKDDKVer.h>

+ 0 - 14
CamelotCore/Source/BsThreadPolicy.cpp

@@ -1,14 +0,0 @@
-#include "BsThreadPolicy.h"
-
-namespace BansheeEngine
-{
-	void ThreadBansheePolicy::onThreadStarted(const String& name) 
-	{
-		MemStack::beginThread();
-	}
-
-	void ThreadBansheePolicy::onThreadEnded(const String& name) 
-	{
-		MemStack::endThread();
-	}
-}

+ 0 - 14
CamelotCore/Source/CmApplication.cpp

@@ -33,7 +33,6 @@
 #include "CmProfiler.h"
 #include "CmQueryManager.h"
 #include "BsThreadPool.h"
-#include "BsThreadPolicy.h"
 #include "BsTaskScheduler.h"
 #include "CmUUID.h"
 
@@ -257,19 +256,6 @@ namespace BansheeEngine
 		gDynLibManager().unload(library);
 	}
 
-	UINT64 Application::getAppWindowId()
-	{
-		if(!mPrimaryWindow)
-		{
-			CM_EXCEPT(InternalErrorException, "Unable to get window handle. No active window exists!");
-		}
-
-		UINT64 windowId = 0;
-		mPrimaryWindow->getCustomAttribute("WINDOW", &windowId);
-
-		return windowId;
-	}
-
 	Application& gApplication()
 	{
 		static Application application;

+ 1 - 1
CamelotCore/Source/Win32/CmPlatformImpl.cpp

@@ -2,8 +2,8 @@
 #include "CmRenderWindow.h"
 #include "CmPixelUtil.h"
 #include "CmApplication.h"
-#include "CmWin32Defs.h"
 #include "CmDebug.h"
+#include "Win32/CmWin32Defs.h"
 #include "Win32/CmWin32DropTarget.h"
 #include <iphlpapi.h>
 

+ 544 - 544
CamelotCore/Source/CmPlatformWndProc.cpp → CamelotCore/Source/Win32/CmPlatformWndProc.cpp

@@ -1,545 +1,545 @@
-#include "CmPlatformWndProc.h"
-#include "CmRenderWindow.h"
-#include "CmApplication.h"
-#include "CmInput.h"
-#include "CmDebug.h"
-#include "CmRenderWindowManager.h"
-
-namespace BansheeEngine
-{
-	bool PlatformWndProc::isShiftPressed = false;
-	bool PlatformWndProc::isCtrlPressed = false;
-
-	LRESULT CALLBACK PlatformWndProc::_win32WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-	{
-		if (uMsg == WM_CREATE)
-		{	// Store pointer to Win32Window in user data area
-			SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)(((LPCREATESTRUCT)lParam)->lpCreateParams));
-
-			RenderWindow* newWindow = (RenderWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
-			if(newWindow->isModal())
-			{
-				if(!mModalWindowStack.empty())
-				{
-					RenderWindow* curModalWindow = mModalWindowStack.top();
-
-					HWND curHwnd;
-					curModalWindow->getCustomAttribute("WINDOW", &curHwnd);
-					EnableWindow(curHwnd, FALSE);
-				}
-				else
-				{
-					Vector<RenderWindow*> renderWindows = RenderWindowManager::instance().getRenderWindows();
-					for(auto& renderWindow : renderWindows)
-					{
-						if(renderWindow == newWindow)
-							continue;
-
-						HWND curHwnd;
-						renderWindow->getCustomAttribute("WINDOW", &curHwnd);
-						EnableWindow(curHwnd, FALSE);
-					}
-				}
-
-				mModalWindowStack.push(newWindow);
-			}
-
-			return 0;
-		}
-
-		// look up window instance
-		// note: it is possible to get a WM_SIZE before WM_CREATE
-		RenderWindow* win = (RenderWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
-		if (!win)
-			return DefWindowProc(hWnd, uMsg, wParam, lParam);
-
-		switch( uMsg )
-		{
-		case WM_ACTIVATE:
-			{
-				bool active = (LOWORD(wParam) != WA_INACTIVE);
-				if( active )
-					win->setActive(true);
-
-				break;
-			}
-		case WM_DESTROY:
-			{
-				bool reenableWindows = false;
-				if(!mModalWindowStack.empty())
-				{
-					if(mModalWindowStack.top() == win) // This is the most common case, top-most modal was closed
-					{
-						mModalWindowStack.pop();
-					}
-					else // Possibly some other window was closed somehow, see if it was modal and remove from stack if it is
-					{
-						Stack<RenderWindow*> newStack;
-
-						while(!mModalWindowStack.empty())
-						{
-							RenderWindow* curWindow = mModalWindowStack.top();
-							mModalWindowStack.pop();
-
-							if(curWindow == win)
-								continue;
-
-							newStack.push(curWindow);
-						}
-
-						mModalWindowStack = newStack;
-					}
-
-					if(!mModalWindowStack.empty()) // Enable next modal window
-					{
-						RenderWindow* curModalWindow = mModalWindowStack.top();
-
-						HWND curHwnd;
-						curModalWindow->getCustomAttribute("WINDOW", &curHwnd);
-						EnableWindow(curHwnd, TRUE);
-					}
-					else
-						reenableWindows = true; // No more modal windows, re-enable any remaining window
-				}
-
-				if(reenableWindows)
-				{
-					Vector<RenderWindow*> renderWindows = RenderWindowManager::instance().getRenderWindows();
-					for(auto& renderWindow : renderWindows)
-					{
-						HWND curHwnd;
-						renderWindow->getCustomAttribute("WINDOW", &curHwnd);
-						EnableWindow(curHwnd, TRUE);
-					}
-				}
-
-				break;
-			}
-		case WM_SETFOCUS:
-			{
-				if(!win->hasFocus())
-					windowFocusReceived(win);
-
-				break;
-			}
-		case WM_KILLFOCUS:
-			{
-				if(win->hasFocus())
-					windowFocusLost(win);
-
-				break;
-			}
-		case WM_SYSCHAR:
-			// return zero to bypass defProc and signal we processed the message, unless it's an ALT-space
-			if (wParam != VK_SPACE)
-				return 0;
-			break;
-		case WM_MOVE:
-			windowMovedOrResized(win);
-			break;
-		case WM_DISPLAYCHANGE:
-			windowMovedOrResized(win);
-			break;
-		case WM_SIZE:
-			windowMovedOrResized(win);
-			break;
-		case WM_SETCURSOR:
-			if(isCursorHidden())
-				win32HideCursor();
-			else
-			{
-				switch (LOWORD(lParam))
-				{
-				case HTTOPLEFT:
-					SetCursor(LoadCursor(0, IDC_SIZENWSE));
-					return 0;
-				case HTTOP:
-					SetCursor(LoadCursor(0, IDC_SIZENS));
-					return 0;
-				case HTTOPRIGHT:
-					SetCursor(LoadCursor(0, IDC_SIZENESW));
-					return 0;
-				case HTLEFT:
-					SetCursor(LoadCursor(0, IDC_SIZEWE));
-					return 0;
-				case HTRIGHT:
-					SetCursor(LoadCursor(0, IDC_SIZEWE));
-					return 0;
-				case HTBOTTOMLEFT:
-					SetCursor(LoadCursor(0, IDC_SIZENESW));
-					return 0;
-				case HTBOTTOM:
-					SetCursor(LoadCursor(0, IDC_SIZENS));
-					return 0;
-				case HTBOTTOMRIGHT:
-					SetCursor(LoadCursor(0, IDC_SIZENWSE));
-					return 0;
-				}
-
-				win32ShowCursor();
-			}
-			return true;
-		case WM_GETMINMAXINFO:
-			// Prevent the window from going smaller than some minimu size
-			((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
-			((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
-			break;
-		case WM_CLOSE:
-			{
-				// TODO - Only stop main loop if primary window is closed!!
-				gApplication().stopMainLoop();
-
-				return 0;
-			}
-		case WM_NCHITTEST:
-			{
-				auto iterFind = mNonClientAreas.find(win);
-				if(iterFind == mNonClientAreas.end())
-					break;
-
-				POINT mousePos;
-				mousePos.x = GET_X_LPARAM(lParam);
-				mousePos.y = GET_Y_LPARAM(lParam); 
-
-				ScreenToClient(hWnd, &mousePos);
-
-				Vector2I mousePosInt;
-				mousePosInt.x = mousePos.x;
-				mousePosInt.y = mousePos.y;
-
-				Vector<NonClientResizeArea>& resizeAreasPerWindow = iterFind->second.resizeAreas;
-				for(auto area : resizeAreasPerWindow)
-				{
-					if(area.area.contains(mousePosInt))
-						return translateNonClientAreaType(area.type);
-				}
-
-				Vector<RectI>& moveAreasPerWindow = iterFind->second.moveAreas;
-				for(auto area : moveAreasPerWindow)
-				{
-					if(area.contains(mousePosInt))
-						return HTCAPTION;
-				}
-
-				return HTCLIENT;
-			}
-		case WM_MOUSELEAVE:
-			{
-				// Note: Right now I track only mouse leaving client area. So it's possible for the "mouse left window" callback
-				// to trigger, while the mouse is still in the non-client area of the window.
-				mIsTrackingMouse = false; // TrackMouseEvent ends when this message is received and needs to be re-applied
-
-				CM_LOCK_MUTEX(mSync);
-
-				mMouseLeftWindows.push_back(win);
-			}
-			break;
-		case WM_LBUTTONUP:
-			{
-				ReleaseCapture();
-
-				Vector2I intMousePos;
-				OSPointerButtonStates btnStates;
-
-				getMouseData(hWnd, wParam, lParam, intMousePos, btnStates);
-
-				if(!onCursorButtonReleased.empty())
-					onCursorButtonReleased(intMousePos, OSMouseButton::Left, btnStates);
-			}
-			break;
-		case WM_MBUTTONUP:
-			{
-				ReleaseCapture();
-
-				Vector2I intMousePos;
-				OSPointerButtonStates btnStates;
-
-				getMouseData(hWnd, wParam, lParam, intMousePos, btnStates);
-
-				if(!onCursorButtonReleased.empty())
-					onCursorButtonReleased(intMousePos, OSMouseButton::Middle, btnStates);
-			}
-			break;
-		case WM_RBUTTONUP:
-			{
-				ReleaseCapture();
-
-				Vector2I intMousePos;
-				OSPointerButtonStates btnStates;
-
-				getMouseData(hWnd, wParam, lParam, intMousePos, btnStates);
-
-				if(!onCursorButtonReleased.empty())
-					onCursorButtonReleased(intMousePos, OSMouseButton::Right, btnStates);
-			}
-			break;
-		case WM_LBUTTONDOWN:
-			{
-				SetCapture(hWnd);
-
-				Vector2I intMousePos;
-				OSPointerButtonStates btnStates;
-
-				getMouseData(hWnd, wParam, lParam, intMousePos, btnStates);
-
-				if(!onCursorButtonPressed.empty())
-					onCursorButtonPressed(intMousePos, OSMouseButton::Left, btnStates);
-			}
-			break;
-		case WM_MBUTTONDOWN:
-			{
-				SetCapture(hWnd);
-
-				Vector2I intMousePos;
-				OSPointerButtonStates btnStates;
-
-				getMouseData(hWnd, wParam, lParam, intMousePos, btnStates);
-
-				if(!onCursorButtonPressed.empty())
-					onCursorButtonPressed(intMousePos, OSMouseButton::Middle, btnStates);
-			}
-			break;
-		case WM_RBUTTONDOWN:
-			{
-				SetCapture(hWnd);
-
-				Vector2I intMousePos;
-				OSPointerButtonStates btnStates;
-
-				getMouseData(hWnd, wParam, lParam, intMousePos, btnStates);
-
-				if(!onCursorButtonPressed.empty())
-					onCursorButtonPressed(intMousePos, OSMouseButton::Right, btnStates);
-			}
-			break;
-		case WM_LBUTTONDBLCLK:
-			{
-				Vector2I intMousePos;
-				OSPointerButtonStates btnStates;
-
-				getMouseData(hWnd, wParam, lParam, intMousePos, btnStates);
-
-				if(!onCursorDoubleClick.empty())
-					onCursorDoubleClick(intMousePos, btnStates);
-			}
-			break;
-		case WM_NCMOUSEMOVE:
-		case WM_MOUSEMOVE:
-			{
-				// Set up tracking so we get notified when mouse leaves the window
-				if(!mIsTrackingMouse)
-				{
-					TRACKMOUSEEVENT tme = { sizeof(tme) };
-					tme.dwFlags = TME_LEAVE;
-
-					tme.hwndTrack = hWnd;
-					TrackMouseEvent(&tme);
-
-					mIsTrackingMouse = true;
-				}
-
-				if(uMsg == WM_NCMOUSEMOVE)
-					return true;
-
-				Vector2I intMousePos;
-				OSPointerButtonStates btnStates;
-				
-				getMouseData(hWnd, wParam, lParam, intMousePos, btnStates);
-
-				if(!onCursorMoved.empty())
-					onCursorMoved(intMousePos, btnStates);
-
-				return true;
-			}
-		case WM_MOUSEWHEEL:
-			{
-				INT16 wheelDelta = GET_WHEEL_DELTA_WPARAM(wParam);
-
-				float wheelDeltaFlt = wheelDelta / (float)WHEEL_DELTA;
-				if(!onMouseWheelScrolled.empty())
-					onMouseWheelScrolled(wheelDeltaFlt);
-
-				return true;
-			}
-		case WM_SYSKEYDOWN:
-		case WM_KEYDOWN:
-			{
-				if(wParam == VK_SHIFT)
-				{
-					isShiftPressed = true;
-					break;
-				}
-
-				if(wParam == VK_CONTROL)
-				{
-					isCtrlPressed = true;
-					break;
-				}
-
-				InputCommandType command = InputCommandType::Backspace;
-				if(getCommand((unsigned int)wParam, command))
-				{
-					if(!onInputCommand.empty())
-						onInputCommand(command);
-
-					return 0;
-				}
-
-				break;
-			}
-		case WM_SYSKEYUP:
-		case WM_KEYUP:
-			{
-				if(wParam == VK_SHIFT)
-				{
-					isShiftPressed = false;
-				}
-
-				if(wParam == VK_CONTROL)
-				{
-					isCtrlPressed = false;
-				}
-
-				break;
-			}
-		case WM_CHAR:
-			{
-				// TODO - Not handling IME input
-
-				switch (wParam) 
-				{ 
-				case VK_BACK:
-				case 0x0A:  // linefeed 
-				case 0x0D:  // carriage return 
-				case VK_ESCAPE:
-				case VK_TAB: 
-					break; 
-				default:    // displayable character 
-					{
-						UINT8 scanCode = (lParam >> 16) & 0xFF;
-
-						BYTE keyState[256];
-						HKL layout = GetKeyboardLayout(0);
-						if(GetKeyboardState(keyState) == 0)
-							return 0;
-
-						unsigned int vk = MapVirtualKeyEx(scanCode, MAPVK_VSC_TO_VK_EX, layout);
-						if(vk == 0)
-							return 0;
-
-						InputCommandType command = InputCommandType::Backspace;
-						if(getCommand(vk, command)) // We ignore character combinations that are special commands
-							return 0;
-
-						UINT32 finalChar = (UINT32)wParam;
-
-						if(!onCharInput.empty())
-							onCharInput(finalChar);
-
-						return 0;
-					}
-				} 
-
-				break;
-			}
-		case WM_CM_SETCAPTURE:
-			SetCapture(hWnd);
-			break;
-		case WM_CM_RELEASECAPTURE:
-			ReleaseCapture();
-			break;
-		case WM_CAPTURECHANGED:
-			if(!onMouseCaptureChanged.empty())
-				onMouseCaptureChanged();
-			break;
-		}
-
-		return DefWindowProc( hWnd, uMsg, wParam, lParam );
-	}
-
-	LRESULT PlatformWndProc::translateNonClientAreaType(NonClientAreaBorderType type)
-	{
-		LRESULT dir = HTCLIENT;
-		switch(type)
-		{
-		case NonClientAreaBorderType::Left:
-			dir = HTLEFT;
-			break;
-		case NonClientAreaBorderType::TopLeft:
-			dir = HTTOPLEFT;
-			break;
-		case NonClientAreaBorderType::Top:
-			dir = HTTOP;
-			break;
-		case NonClientAreaBorderType::TopRight:
-			dir = HTTOPRIGHT;
-			break;
-		case NonClientAreaBorderType::Right:
-			dir = HTRIGHT;
-			break;
-		case NonClientAreaBorderType::BottomRight:
-			dir = HTBOTTOMRIGHT;
-			break;
-		case NonClientAreaBorderType::Bottom:
-			dir = HTBOTTOM;
-			break;
-		case NonClientAreaBorderType::BottomLeft:
-			dir = HTBOTTOMLEFT;
-			break;
-		}
-
-		return dir;
-	}
-
-	void PlatformWndProc::getMouseData(HWND hWnd, WPARAM wParam, LPARAM lParam, Vector2I& mousePos, OSPointerButtonStates& btnStates)
-	{
-		POINT clientPoint;
-
-		clientPoint.x = GET_X_LPARAM(lParam);
-		clientPoint.y = GET_Y_LPARAM(lParam); 
-
-		ClientToScreen(hWnd, &clientPoint);
-
-		mousePos.x = clientPoint.x;
-		mousePos.y = clientPoint.y;
-
-		btnStates.mouseButtons[0] = (wParam & MK_LBUTTON) != 0;
-		btnStates.mouseButtons[1] = (wParam & MK_MBUTTON) != 0;
-		btnStates.mouseButtons[2] = (wParam & MK_RBUTTON) != 0;
-		btnStates.shift = (wParam & MK_SHIFT) != 0;
-		btnStates.ctrl = (wParam & MK_CONTROL) != 0;
-	}
-
-	bool PlatformWndProc::getCommand(unsigned int virtualKeyCode, InputCommandType& command)
-	{
-		switch (virtualKeyCode) 
-		{ 
-		case VK_LEFT:
-			command = isShiftPressed ? InputCommandType::SelectLeft : InputCommandType::CursorMoveLeft;
-			return true;
-		case VK_RIGHT:
-			command = isShiftPressed ? InputCommandType::SelectRight : InputCommandType::CursorMoveRight;
-			return true;
-		case VK_UP:
-			command = isShiftPressed ? InputCommandType::SelectUp : InputCommandType::CursorMoveUp;
-			return true;
-		case VK_DOWN:
-			command = isShiftPressed ? InputCommandType::SelectDown : InputCommandType::CursorMoveDown;
-			return true;
-		case VK_ESCAPE:
-			command = InputCommandType::Escape;
-			return true;
-		case VK_RETURN:
-			command = InputCommandType::Return;
-			return true;
-		case VK_BACK:
-			command = InputCommandType::Backspace;
-			return true;
-		case VK_DELETE:
-			command = InputCommandType::Delete;
-			return true;
-		}
-
-		return false;
-	}
+#include "Win32/CmPlatformWndProc.h"
+#include "CmRenderWindow.h"
+#include "CmApplication.h"
+#include "CmInput.h"
+#include "CmDebug.h"
+#include "CmRenderWindowManager.h"
+
+namespace BansheeEngine
+{
+	bool PlatformWndProc::isShiftPressed = false;
+	bool PlatformWndProc::isCtrlPressed = false;
+
+	LRESULT CALLBACK PlatformWndProc::_win32WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+	{
+		if (uMsg == WM_CREATE)
+		{	// Store pointer to Win32Window in user data area
+			SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)(((LPCREATESTRUCT)lParam)->lpCreateParams));
+
+			RenderWindow* newWindow = (RenderWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+			if(newWindow->isModal())
+			{
+				if(!mModalWindowStack.empty())
+				{
+					RenderWindow* curModalWindow = mModalWindowStack.top();
+
+					HWND curHwnd;
+					curModalWindow->getCustomAttribute("WINDOW", &curHwnd);
+					EnableWindow(curHwnd, FALSE);
+				}
+				else
+				{
+					Vector<RenderWindow*> renderWindows = RenderWindowManager::instance().getRenderWindows();
+					for(auto& renderWindow : renderWindows)
+					{
+						if(renderWindow == newWindow)
+							continue;
+
+						HWND curHwnd;
+						renderWindow->getCustomAttribute("WINDOW", &curHwnd);
+						EnableWindow(curHwnd, FALSE);
+					}
+				}
+
+				mModalWindowStack.push(newWindow);
+			}
+
+			return 0;
+		}
+
+		// look up window instance
+		// note: it is possible to get a WM_SIZE before WM_CREATE
+		RenderWindow* win = (RenderWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+		if (!win)
+			return DefWindowProc(hWnd, uMsg, wParam, lParam);
+
+		switch( uMsg )
+		{
+		case WM_ACTIVATE:
+			{
+				bool active = (LOWORD(wParam) != WA_INACTIVE);
+				if( active )
+					win->setActive(true);
+
+				break;
+			}
+		case WM_DESTROY:
+			{
+				bool reenableWindows = false;
+				if(!mModalWindowStack.empty())
+				{
+					if(mModalWindowStack.top() == win) // This is the most common case, top-most modal was closed
+					{
+						mModalWindowStack.pop();
+					}
+					else // Possibly some other window was closed somehow, see if it was modal and remove from stack if it is
+					{
+						Stack<RenderWindow*> newStack;
+
+						while(!mModalWindowStack.empty())
+						{
+							RenderWindow* curWindow = mModalWindowStack.top();
+							mModalWindowStack.pop();
+
+							if(curWindow == win)
+								continue;
+
+							newStack.push(curWindow);
+						}
+
+						mModalWindowStack = newStack;
+					}
+
+					if(!mModalWindowStack.empty()) // Enable next modal window
+					{
+						RenderWindow* curModalWindow = mModalWindowStack.top();
+
+						HWND curHwnd;
+						curModalWindow->getCustomAttribute("WINDOW", &curHwnd);
+						EnableWindow(curHwnd, TRUE);
+					}
+					else
+						reenableWindows = true; // No more modal windows, re-enable any remaining window
+				}
+
+				if(reenableWindows)
+				{
+					Vector<RenderWindow*> renderWindows = RenderWindowManager::instance().getRenderWindows();
+					for(auto& renderWindow : renderWindows)
+					{
+						HWND curHwnd;
+						renderWindow->getCustomAttribute("WINDOW", &curHwnd);
+						EnableWindow(curHwnd, TRUE);
+					}
+				}
+
+				break;
+			}
+		case WM_SETFOCUS:
+			{
+				if(!win->hasFocus())
+					windowFocusReceived(win);
+
+				break;
+			}
+		case WM_KILLFOCUS:
+			{
+				if(win->hasFocus())
+					windowFocusLost(win);
+
+				break;
+			}
+		case WM_SYSCHAR:
+			// return zero to bypass defProc and signal we processed the message, unless it's an ALT-space
+			if (wParam != VK_SPACE)
+				return 0;
+			break;
+		case WM_MOVE:
+			windowMovedOrResized(win);
+			break;
+		case WM_DISPLAYCHANGE:
+			windowMovedOrResized(win);
+			break;
+		case WM_SIZE:
+			windowMovedOrResized(win);
+			break;
+		case WM_SETCURSOR:
+			if(isCursorHidden())
+				win32HideCursor();
+			else
+			{
+				switch (LOWORD(lParam))
+				{
+				case HTTOPLEFT:
+					SetCursor(LoadCursor(0, IDC_SIZENWSE));
+					return 0;
+				case HTTOP:
+					SetCursor(LoadCursor(0, IDC_SIZENS));
+					return 0;
+				case HTTOPRIGHT:
+					SetCursor(LoadCursor(0, IDC_SIZENESW));
+					return 0;
+				case HTLEFT:
+					SetCursor(LoadCursor(0, IDC_SIZEWE));
+					return 0;
+				case HTRIGHT:
+					SetCursor(LoadCursor(0, IDC_SIZEWE));
+					return 0;
+				case HTBOTTOMLEFT:
+					SetCursor(LoadCursor(0, IDC_SIZENESW));
+					return 0;
+				case HTBOTTOM:
+					SetCursor(LoadCursor(0, IDC_SIZENS));
+					return 0;
+				case HTBOTTOMRIGHT:
+					SetCursor(LoadCursor(0, IDC_SIZENWSE));
+					return 0;
+				}
+
+				win32ShowCursor();
+			}
+			return true;
+		case WM_GETMINMAXINFO:
+			// Prevent the window from going smaller than some minimu size
+			((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
+			((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
+			break;
+		case WM_CLOSE:
+			{
+				// TODO - Only stop main loop if primary window is closed!!
+				gApplication().stopMainLoop();
+
+				return 0;
+			}
+		case WM_NCHITTEST:
+			{
+				auto iterFind = mNonClientAreas.find(win);
+				if(iterFind == mNonClientAreas.end())
+					break;
+
+				POINT mousePos;
+				mousePos.x = GET_X_LPARAM(lParam);
+				mousePos.y = GET_Y_LPARAM(lParam); 
+
+				ScreenToClient(hWnd, &mousePos);
+
+				Vector2I mousePosInt;
+				mousePosInt.x = mousePos.x;
+				mousePosInt.y = mousePos.y;
+
+				Vector<NonClientResizeArea>& resizeAreasPerWindow = iterFind->second.resizeAreas;
+				for(auto area : resizeAreasPerWindow)
+				{
+					if(area.area.contains(mousePosInt))
+						return translateNonClientAreaType(area.type);
+				}
+
+				Vector<RectI>& moveAreasPerWindow = iterFind->second.moveAreas;
+				for(auto area : moveAreasPerWindow)
+				{
+					if(area.contains(mousePosInt))
+						return HTCAPTION;
+				}
+
+				return HTCLIENT;
+			}
+		case WM_MOUSELEAVE:
+			{
+				// Note: Right now I track only mouse leaving client area. So it's possible for the "mouse left window" callback
+				// to trigger, while the mouse is still in the non-client area of the window.
+				mIsTrackingMouse = false; // TrackMouseEvent ends when this message is received and needs to be re-applied
+
+				CM_LOCK_MUTEX(mSync);
+
+				mMouseLeftWindows.push_back(win);
+			}
+			break;
+		case WM_LBUTTONUP:
+			{
+				ReleaseCapture();
+
+				Vector2I intMousePos;
+				OSPointerButtonStates btnStates;
+
+				getMouseData(hWnd, wParam, lParam, intMousePos, btnStates);
+
+				if(!onCursorButtonReleased.empty())
+					onCursorButtonReleased(intMousePos, OSMouseButton::Left, btnStates);
+			}
+			break;
+		case WM_MBUTTONUP:
+			{
+				ReleaseCapture();
+
+				Vector2I intMousePos;
+				OSPointerButtonStates btnStates;
+
+				getMouseData(hWnd, wParam, lParam, intMousePos, btnStates);
+
+				if(!onCursorButtonReleased.empty())
+					onCursorButtonReleased(intMousePos, OSMouseButton::Middle, btnStates);
+			}
+			break;
+		case WM_RBUTTONUP:
+			{
+				ReleaseCapture();
+
+				Vector2I intMousePos;
+				OSPointerButtonStates btnStates;
+
+				getMouseData(hWnd, wParam, lParam, intMousePos, btnStates);
+
+				if(!onCursorButtonReleased.empty())
+					onCursorButtonReleased(intMousePos, OSMouseButton::Right, btnStates);
+			}
+			break;
+		case WM_LBUTTONDOWN:
+			{
+				SetCapture(hWnd);
+
+				Vector2I intMousePos;
+				OSPointerButtonStates btnStates;
+
+				getMouseData(hWnd, wParam, lParam, intMousePos, btnStates);
+
+				if(!onCursorButtonPressed.empty())
+					onCursorButtonPressed(intMousePos, OSMouseButton::Left, btnStates);
+			}
+			break;
+		case WM_MBUTTONDOWN:
+			{
+				SetCapture(hWnd);
+
+				Vector2I intMousePos;
+				OSPointerButtonStates btnStates;
+
+				getMouseData(hWnd, wParam, lParam, intMousePos, btnStates);
+
+				if(!onCursorButtonPressed.empty())
+					onCursorButtonPressed(intMousePos, OSMouseButton::Middle, btnStates);
+			}
+			break;
+		case WM_RBUTTONDOWN:
+			{
+				SetCapture(hWnd);
+
+				Vector2I intMousePos;
+				OSPointerButtonStates btnStates;
+
+				getMouseData(hWnd, wParam, lParam, intMousePos, btnStates);
+
+				if(!onCursorButtonPressed.empty())
+					onCursorButtonPressed(intMousePos, OSMouseButton::Right, btnStates);
+			}
+			break;
+		case WM_LBUTTONDBLCLK:
+			{
+				Vector2I intMousePos;
+				OSPointerButtonStates btnStates;
+
+				getMouseData(hWnd, wParam, lParam, intMousePos, btnStates);
+
+				if(!onCursorDoubleClick.empty())
+					onCursorDoubleClick(intMousePos, btnStates);
+			}
+			break;
+		case WM_NCMOUSEMOVE:
+		case WM_MOUSEMOVE:
+			{
+				// Set up tracking so we get notified when mouse leaves the window
+				if(!mIsTrackingMouse)
+				{
+					TRACKMOUSEEVENT tme = { sizeof(tme) };
+					tme.dwFlags = TME_LEAVE;
+
+					tme.hwndTrack = hWnd;
+					TrackMouseEvent(&tme);
+
+					mIsTrackingMouse = true;
+				}
+
+				if(uMsg == WM_NCMOUSEMOVE)
+					return true;
+
+				Vector2I intMousePos;
+				OSPointerButtonStates btnStates;
+				
+				getMouseData(hWnd, wParam, lParam, intMousePos, btnStates);
+
+				if(!onCursorMoved.empty())
+					onCursorMoved(intMousePos, btnStates);
+
+				return true;
+			}
+		case WM_MOUSEWHEEL:
+			{
+				INT16 wheelDelta = GET_WHEEL_DELTA_WPARAM(wParam);
+
+				float wheelDeltaFlt = wheelDelta / (float)WHEEL_DELTA;
+				if(!onMouseWheelScrolled.empty())
+					onMouseWheelScrolled(wheelDeltaFlt);
+
+				return true;
+			}
+		case WM_SYSKEYDOWN:
+		case WM_KEYDOWN:
+			{
+				if(wParam == VK_SHIFT)
+				{
+					isShiftPressed = true;
+					break;
+				}
+
+				if(wParam == VK_CONTROL)
+				{
+					isCtrlPressed = true;
+					break;
+				}
+
+				InputCommandType command = InputCommandType::Backspace;
+				if(getCommand((unsigned int)wParam, command))
+				{
+					if(!onInputCommand.empty())
+						onInputCommand(command);
+
+					return 0;
+				}
+
+				break;
+			}
+		case WM_SYSKEYUP:
+		case WM_KEYUP:
+			{
+				if(wParam == VK_SHIFT)
+				{
+					isShiftPressed = false;
+				}
+
+				if(wParam == VK_CONTROL)
+				{
+					isCtrlPressed = false;
+				}
+
+				break;
+			}
+		case WM_CHAR:
+			{
+				// TODO - Not handling IME input
+
+				switch (wParam) 
+				{ 
+				case VK_BACK:
+				case 0x0A:  // linefeed 
+				case 0x0D:  // carriage return 
+				case VK_ESCAPE:
+				case VK_TAB: 
+					break; 
+				default:    // displayable character 
+					{
+						UINT8 scanCode = (lParam >> 16) & 0xFF;
+
+						BYTE keyState[256];
+						HKL layout = GetKeyboardLayout(0);
+						if(GetKeyboardState(keyState) == 0)
+							return 0;
+
+						unsigned int vk = MapVirtualKeyEx(scanCode, MAPVK_VSC_TO_VK_EX, layout);
+						if(vk == 0)
+							return 0;
+
+						InputCommandType command = InputCommandType::Backspace;
+						if(getCommand(vk, command)) // We ignore character combinations that are special commands
+							return 0;
+
+						UINT32 finalChar = (UINT32)wParam;
+
+						if(!onCharInput.empty())
+							onCharInput(finalChar);
+
+						return 0;
+					}
+				} 
+
+				break;
+			}
+		case WM_CM_SETCAPTURE:
+			SetCapture(hWnd);
+			break;
+		case WM_CM_RELEASECAPTURE:
+			ReleaseCapture();
+			break;
+		case WM_CAPTURECHANGED:
+			if(!onMouseCaptureChanged.empty())
+				onMouseCaptureChanged();
+			break;
+		}
+
+		return DefWindowProc( hWnd, uMsg, wParam, lParam );
+	}
+
+	LRESULT PlatformWndProc::translateNonClientAreaType(NonClientAreaBorderType type)
+	{
+		LRESULT dir = HTCLIENT;
+		switch(type)
+		{
+		case NonClientAreaBorderType::Left:
+			dir = HTLEFT;
+			break;
+		case NonClientAreaBorderType::TopLeft:
+			dir = HTTOPLEFT;
+			break;
+		case NonClientAreaBorderType::Top:
+			dir = HTTOP;
+			break;
+		case NonClientAreaBorderType::TopRight:
+			dir = HTTOPRIGHT;
+			break;
+		case NonClientAreaBorderType::Right:
+			dir = HTRIGHT;
+			break;
+		case NonClientAreaBorderType::BottomRight:
+			dir = HTBOTTOMRIGHT;
+			break;
+		case NonClientAreaBorderType::Bottom:
+			dir = HTBOTTOM;
+			break;
+		case NonClientAreaBorderType::BottomLeft:
+			dir = HTBOTTOMLEFT;
+			break;
+		}
+
+		return dir;
+	}
+
+	void PlatformWndProc::getMouseData(HWND hWnd, WPARAM wParam, LPARAM lParam, Vector2I& mousePos, OSPointerButtonStates& btnStates)
+	{
+		POINT clientPoint;
+
+		clientPoint.x = GET_X_LPARAM(lParam);
+		clientPoint.y = GET_Y_LPARAM(lParam); 
+
+		ClientToScreen(hWnd, &clientPoint);
+
+		mousePos.x = clientPoint.x;
+		mousePos.y = clientPoint.y;
+
+		btnStates.mouseButtons[0] = (wParam & MK_LBUTTON) != 0;
+		btnStates.mouseButtons[1] = (wParam & MK_MBUTTON) != 0;
+		btnStates.mouseButtons[2] = (wParam & MK_RBUTTON) != 0;
+		btnStates.shift = (wParam & MK_SHIFT) != 0;
+		btnStates.ctrl = (wParam & MK_CONTROL) != 0;
+	}
+
+	bool PlatformWndProc::getCommand(unsigned int virtualKeyCode, InputCommandType& command)
+	{
+		switch (virtualKeyCode) 
+		{ 
+		case VK_LEFT:
+			command = isShiftPressed ? InputCommandType::SelectLeft : InputCommandType::CursorMoveLeft;
+			return true;
+		case VK_RIGHT:
+			command = isShiftPressed ? InputCommandType::SelectRight : InputCommandType::CursorMoveRight;
+			return true;
+		case VK_UP:
+			command = isShiftPressed ? InputCommandType::SelectUp : InputCommandType::CursorMoveUp;
+			return true;
+		case VK_DOWN:
+			command = isShiftPressed ? InputCommandType::SelectDown : InputCommandType::CursorMoveDown;
+			return true;
+		case VK_ESCAPE:
+			command = InputCommandType::Escape;
+			return true;
+		case VK_RETURN:
+			command = InputCommandType::Return;
+			return true;
+		case VK_BACK:
+			command = InputCommandType::Backspace;
+			return true;
+		case VK_DELETE:
+			command = InputCommandType::Delete;
+			return true;
+		}
+
+		return false;
+	}
 }

+ 665 - 665
CamelotCore/Source/CmWin32FolderMonitor.cpp → CamelotCore/Source/Win32/CmWin32FolderMonitor.cpp

@@ -1,666 +1,666 @@
-#include "CmWin32FolderMonitor.h"
-#include "CmFileSystem.h"
-#include "CmException.h"
-#include "CmPath.h"
-
-#include "CmDebug.h"
-
-#include <windows.h>
-
-namespace BansheeEngine
-{
-	enum class MonitorState
-	{
-		Inactive,
-		Starting,
-		Monitoring,
-		Shutdown,
-		Shutdown2
-	};
-
-	class WorkerFunc
-	{
-	public:
-		WorkerFunc(FolderMonitor* owner);
-
-		void operator()();
-
-	private:
-		FolderMonitor* mOwner;
-	};
-
-	struct FolderMonitor::FolderWatchInfo
-	{
-		FolderWatchInfo(const Path& folderToMonitor, HANDLE dirHandle, bool monitorSubdirectories, DWORD monitorFlags);
-		~FolderWatchInfo();
-
-		void startMonitor(HANDLE compPortHandle);
-		void stopMonitor(HANDLE compPortHandle);
-
-		static const UINT32 READ_BUFFER_SIZE = 65536;
-
-		Path mFolderToMonitor;
-		HANDLE mDirHandle;
-		OVERLAPPED mOverlapped;
-		MonitorState mState;
-		UINT8 mBuffer[READ_BUFFER_SIZE];
-		DWORD mBufferSize;
-		bool mMonitorSubdirectories;
-		DWORD mMonitorFlags;
-		DWORD mReadError;
-
-		WString mCachedOldFileName; // Used during rename notifications as they are handled in two steps
-
-		CM_MUTEX(mStatusMutex)
-		CM_THREAD_SYNCHRONISER(mStartStopEvent)
-	};
-
-	FolderMonitor::FolderWatchInfo::FolderWatchInfo(const Path& folderToMonitor, HANDLE dirHandle, bool monitorSubdirectories, DWORD monitorFlags)
-		:mFolderToMonitor(folderToMonitor), mDirHandle(dirHandle), mState(MonitorState::Inactive), mBufferSize(0),
-		mMonitorSubdirectories(monitorSubdirectories), mMonitorFlags(monitorFlags), mReadError(0)
-	{
-		memset(&mOverlapped, 0, sizeof(mOverlapped));
-	}
-
-	FolderMonitor::FolderWatchInfo::~FolderWatchInfo()
-	{
-		assert(mState == MonitorState::Inactive);
-
-		stopMonitor(0);
-	}
-
-	void FolderMonitor::FolderWatchInfo::startMonitor(HANDLE compPortHandle)
-	{
-		if(mState != MonitorState::Inactive)
-			return; // Already monitoring
-
-		{
-			CM_LOCK_MUTEX_NAMED(mStatusMutex, lock);
-
-			mState = MonitorState::Starting;
-			PostQueuedCompletionStatus(compPortHandle, sizeof(this), (DWORD)this, &mOverlapped);
-
-			while(mState != MonitorState::Monitoring)
-				CM_THREAD_WAIT(mStartStopEvent, mStatusMutex, lock);
-		}
-
-		if(mReadError != ERROR_SUCCESS)
-		{
-			{
-				CM_LOCK_MUTEX(mStatusMutex);
-				mState = MonitorState::Inactive;
-			}
-
-			CM_EXCEPT(InternalErrorException, "Failed to start folder monitor on folder \"" + 
-				mFolderToMonitor.toString() + "\" because ReadDirectoryChangesW failed.");
-		}
-	}
-
-	void FolderMonitor::FolderWatchInfo::stopMonitor(HANDLE compPortHandle)
-	{
-		if(mState != MonitorState::Inactive)
-		{
-			CM_LOCK_MUTEX_NAMED(mStatusMutex, lock);
-
-			mState = MonitorState::Shutdown;
-			PostQueuedCompletionStatus(compPortHandle, sizeof(this), (DWORD)this, &mOverlapped);
-
-			while(mState != MonitorState::Inactive)
-				CM_THREAD_WAIT(mStartStopEvent, mStatusMutex, lock);
-		}
-
-		if(mDirHandle != INVALID_HANDLE_VALUE)
-		{			
-			CloseHandle(mDirHandle);
-			mDirHandle = INVALID_HANDLE_VALUE;
-		}
-	}
-
-	class FolderMonitor::FileNotifyInfo
-	{
-	public:
-		FileNotifyInfo(UINT8* notifyBuffer, DWORD bufferSize)
-		:mBuffer(notifyBuffer), mBufferSize(bufferSize)
-		{
-			mCurrentRecord = (PFILE_NOTIFY_INFORMATION)mBuffer;
-		}
-
-		bool getNext();
-	
-		DWORD	getAction() const;
-		WString getFileName() const;
-		WString getFileNameWithPath(const Path& rootPath) const;
-
-	
-	protected:
-		UINT8* mBuffer;
-		DWORD mBufferSize;
-		PFILE_NOTIFY_INFORMATION mCurrentRecord;
-	};
-
-	bool FolderMonitor::FileNotifyInfo::getNext()
-	{
-		if(mCurrentRecord && mCurrentRecord->NextEntryOffset != 0)
-		{
-			PFILE_NOTIFY_INFORMATION oldRecord = mCurrentRecord;
-			mCurrentRecord = (PFILE_NOTIFY_INFORMATION) ((UINT8*)mCurrentRecord + mCurrentRecord->NextEntryOffset);
-
-			if((DWORD)((UINT8*)mCurrentRecord - mBuffer) > mBufferSize)
-			{
-				// Gone out of range, something bad happened
-				assert(false);
-
-				mCurrentRecord = oldRecord;
-			}
-					
-			return (mCurrentRecord != oldRecord);
-		}
-
-		return false;
-	}
-
-	DWORD FolderMonitor::FileNotifyInfo::getAction() const
-	{ 
-		assert(mCurrentRecord != nullptr);
-
-		if(mCurrentRecord)
-			return mCurrentRecord->Action;
-
-		return 0;
-	}
-
-	WString FolderMonitor::FileNotifyInfo::getFileName() const
-	{
-		if(mCurrentRecord)
-		{
-			wchar_t fileNameBuffer[32768 + 1] = {0};
-
-			memcpy(fileNameBuffer, mCurrentRecord->FileName, 
-					std::min(DWORD(32768 * sizeof(wchar_t)), mCurrentRecord->FileNameLength));
-		
-			return WString(fileNameBuffer);
-		}
-
-		return WString();
-	}		
-
-	WString FolderMonitor::FileNotifyInfo::getFileNameWithPath(const Path& rootPath) const
-	{
-		Path fullPath = rootPath;
-		return fullPath.append(getFileName()).toWString();
-	}
-
-	enum class FileActionType
-	{
-		Added,
-		Removed,
-		Modified,
-		Renamed
-	};
-
-	struct FileAction
-	{
-		static FileAction* createAdded(const WString& fileName)
-		{
-			UINT8* bytes = (UINT8*)cm_alloc((UINT32)(sizeof(FileAction) + (fileName.size() + 1) * sizeof(WString::value_type)));
-
-			FileAction* action = (FileAction*)bytes;
-			bytes += sizeof(FileAction);
-
-			action->oldName = nullptr;
-			action->newName = (WString::value_type*)bytes;
-			action->type = FileActionType::Added;
-
-			memcpy(action->newName, fileName.data(), fileName.size() * sizeof(WString::value_type));
-			action->newName[fileName.size()] = L'\0';
-
-			return action;
-		}
-
-		static FileAction* createRemoved(const WString& fileName)
-		{
-			UINT8* bytes = (UINT8*)cm_alloc((UINT32)(sizeof(FileAction) + (fileName.size() + 1) * sizeof(WString::value_type)));
-
-			FileAction* action = (FileAction*)bytes;
-			bytes += sizeof(FileAction);
-
-			action->oldName = nullptr;
-			action->newName = (WString::value_type*)bytes;
-			action->type = FileActionType::Removed;
-
-			memcpy(action->newName, fileName.data(), fileName.size() * sizeof(WString::value_type));
-			action->newName[fileName.size()] = L'\0';
-
-			return action;
-		}
-
-		static FileAction* createModified(const WString& fileName)
-		{
-			UINT8* bytes = (UINT8*)cm_alloc((UINT32)(sizeof(FileAction) + (fileName.size() + 1) * sizeof(WString::value_type)));
-
-			FileAction* action = (FileAction*)bytes;
-			bytes += sizeof(FileAction);
-
-			action->oldName = nullptr;
-			action->newName = (WString::value_type*)bytes;
-			action->type = FileActionType::Modified;
-
-			memcpy(action->newName, fileName.data(), fileName.size() * sizeof(WString::value_type));
-			action->newName[fileName.size()] = L'\0';
-
-			return action;
-		}
-
-		static FileAction* createRenamed(const WString& oldFilename, const WString& newfileName)
-		{
-			UINT8* bytes = (UINT8*)cm_alloc((UINT32)(sizeof(FileAction) + 
-				(oldFilename.size() + newfileName.size() + 2) * sizeof(WString::value_type)));
-
-			FileAction* action = (FileAction*)bytes;
-			bytes += sizeof(FileAction);
-
-			action->oldName = (WString::value_type*)bytes;
-			bytes += (oldFilename.size() + 1) * sizeof(WString::value_type);
-
-			action->newName = (WString::value_type*)bytes;
-			action->type = FileActionType::Modified;
-
-			memcpy(action->oldName, oldFilename.data(), oldFilename.size() * sizeof(WString::value_type));
-			action->oldName[oldFilename.size()] = L'\0';
-
-			memcpy(action->newName, newfileName.data(), newfileName.size() * sizeof(WString::value_type));
-			action->newName[newfileName.size()] = L'\0';
-
-			return action;
-		}
-
-		static void destroy(FileAction* action)
-		{
-			cm_free(action);
-		}
-
-		WString::value_type* oldName;
-		WString::value_type* newName;
-		FileActionType type;
-	};
-
-	struct FolderMonitor::Pimpl
-	{
-		Vector<FolderWatchInfo*> mFoldersToWatch;
-		HANDLE mCompPortHandle;
-
-		Queue<FileAction*> mFileActions;
-		Queue<FileAction*> mActiveFileActions;
-
-		CM_MUTEX(mMainMutex);
-		CM_THREAD_TYPE* mWorkerThread;
-	};
-
-	FolderMonitor::FolderMonitor()
-	{
-		mPimpl = cm_new<Pimpl>();
-		mPimpl->mWorkerThread = nullptr;
-		mPimpl->mCompPortHandle = nullptr;
-	}
-
-	FolderMonitor::~FolderMonitor()
-	{
-		stopMonitorAll();
-
-		// No need for mutex since we know worker thread is shut down by now
-		while(!mPimpl->mFileActions.empty())
-		{
-			FileAction* action = mPimpl->mFileActions.front();
-			mPimpl->mFileActions.pop();
-
-			FileAction::destroy(action);
-		}
-
-		cm_delete(mPimpl);
-	}
-
-	void FolderMonitor::startMonitor(const Path& folderPath, bool subdirectories, FolderChange changeFilter)
-	{
-		if(!FileSystem::isDirectory(folderPath))
-		{
-			CM_EXCEPT(InvalidParametersException, "Provided path \"" + folderPath.toString() + "\" is not a directory");
-		}
-
-		WString extendedFolderPath = L"\\\\?\\" + folderPath.toWString(Path::PathType::Windows);
-		HANDLE dirHandle = CreateFileW(extendedFolderPath.c_str(), FILE_LIST_DIRECTORY,
-			FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING,
-			FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, nullptr);
-
-		if(dirHandle == INVALID_HANDLE_VALUE)
-		{
-			CM_EXCEPT(InternalErrorException, "Failed to open folder \"" + folderPath.toString() + "\" for monitoring. Error code: " + toString((UINT64)GetLastError()));
-		}
-
-		DWORD filterFlags = 0;
-
-		if((((UINT32)changeFilter) & (UINT32)BansheeEngine::FolderChange::FileName) != 0)
-			filterFlags |= FILE_NOTIFY_CHANGE_FILE_NAME;
-
-		if((((UINT32)changeFilter) & (UINT32)BansheeEngine::FolderChange::DirName) != 0)
-			filterFlags |= FILE_NOTIFY_CHANGE_DIR_NAME;
-
-		if((((UINT32)changeFilter) & (UINT32)BansheeEngine::FolderChange::Attributes) != 0)
-			filterFlags |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
-
-		if((((UINT32)changeFilter) & (UINT32)BansheeEngine::FolderChange::Size) != 0)
-			filterFlags |= FILE_NOTIFY_CHANGE_SIZE;
-
-		if((((UINT32)changeFilter) & (UINT32)BansheeEngine::FolderChange::LastWrite) != 0)
-			filterFlags |= FILE_NOTIFY_CHANGE_LAST_WRITE;
-
-		if((((UINT32)changeFilter) & (UINT32)BansheeEngine::FolderChange::LastAccess) != 0)
-			filterFlags |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
-
-		if((((UINT32)changeFilter) & (UINT32)BansheeEngine::FolderChange::Creation) != 0)
-			filterFlags |= FILE_NOTIFY_CHANGE_CREATION;
-
-		if((((UINT32)changeFilter) & (UINT32)BansheeEngine::FolderChange::Security) != 0)
-			filterFlags |= FILE_NOTIFY_CHANGE_SECURITY;
-
-		mPimpl->mFoldersToWatch.push_back(cm_new<FolderWatchInfo>(folderPath, dirHandle, subdirectories, filterFlags));
-		FolderWatchInfo* watchInfo = mPimpl->mFoldersToWatch.back();
-
-		mPimpl->mCompPortHandle = CreateIoCompletionPort(dirHandle, mPimpl->mCompPortHandle, (DWORD)watchInfo, 0);
-
-		if(mPimpl->mCompPortHandle == nullptr)
-		{
-			mPimpl->mFoldersToWatch.erase(mPimpl->mFoldersToWatch.end() - 1);
-			cm_delete(watchInfo);
-			CM_EXCEPT(InternalErrorException, "Failed to open completition port for folder monitoring. Error code: " + toString((UINT64)GetLastError()));
-		}
-
-		if(mPimpl->mWorkerThread == nullptr)
-		{
-			CM_THREAD_CREATE(t, (std::bind(&FolderMonitor::workerThreadMain, this)));
-			mPimpl->mWorkerThread = t;
-
-			if(mPimpl->mWorkerThread == nullptr)
-			{
-				mPimpl->mFoldersToWatch.erase(mPimpl->mFoldersToWatch.end() - 1);
-				cm_delete(watchInfo);
-				CM_EXCEPT(InternalErrorException, "Failed to create a new worker thread for folder monitoring");
-			}
-		}
-
-		if(mPimpl->mWorkerThread != nullptr)
-		{
-			try
-			{
-				watchInfo->startMonitor(mPimpl->mCompPortHandle);
-			}
-			catch (Exception* e)
-			{
-				mPimpl->mFoldersToWatch.erase(mPimpl->mFoldersToWatch.end() - 1);
-				cm_delete(watchInfo);
-				throw(e);
-			}
-		}
-		else
-		{
-			mPimpl->mFoldersToWatch.erase(mPimpl->mFoldersToWatch.end() - 1);
-			cm_delete(watchInfo);
-			CM_EXCEPT(InternalErrorException, "Failed to create a new worker thread for folder monitoring");
-		}
-	}
-
-	void FolderMonitor::stopMonitor(const Path& folderPath)
-	{
-		auto findIter = std::find_if(mPimpl->mFoldersToWatch.begin(), mPimpl->mFoldersToWatch.end(), 
-			[&](const FolderWatchInfo* x) { return x->mFolderToMonitor == folderPath; });
-
-		if(findIter != mPimpl->mFoldersToWatch.end())
-		{
-			FolderWatchInfo* watchInfo = *findIter;
-
-			watchInfo->stopMonitor(mPimpl->mCompPortHandle);
-			cm_delete(watchInfo);
-
-			mPimpl->mFoldersToWatch.erase(findIter);
-		}
-
-		if(mPimpl->mFoldersToWatch.size() == 0)
-			stopMonitorAll();
-	}
-
-	void FolderMonitor::stopMonitorAll()
-	{
-		for(auto& watchInfo : mPimpl->mFoldersToWatch)
-		{
-			watchInfo->stopMonitor(mPimpl->mCompPortHandle);
-
-			{
-				// Note: Need this mutex to ensure worker thread is done with watchInfo.
-				// Even though we wait for a condition variable from the worker thread in stopMonitor,
-				// that doesn't mean the worker thread is done with the condition variable
-				// (which is stored inside watchInfo)
-				CM_LOCK_MUTEX(mPimpl->mMainMutex); 
-				cm_delete(watchInfo);
-			}
-		}
-
-		mPimpl->mFoldersToWatch.clear();
-
-		if(mPimpl->mWorkerThread != nullptr)
-		{
-			PostQueuedCompletionStatus(mPimpl->mCompPortHandle, 0, 0, nullptr);
-
-			mPimpl->mWorkerThread->join();
-			CM_THREAD_DESTROY(mPimpl->mWorkerThread);
-			mPimpl->mWorkerThread = nullptr;
-		}
-
-		if(mPimpl->mCompPortHandle != nullptr)
-		{
-			CloseHandle(mPimpl->mCompPortHandle);
-			mPimpl->mCompPortHandle = nullptr;
-		}
-	}
-
-	void FolderMonitor::workerThreadMain()
-	{
-		FolderWatchInfo* watchInfo = nullptr;
-
-		do 
-		{
-			DWORD numBytes;
-			LPOVERLAPPED overlapped;
-
-			if(!GetQueuedCompletionStatus(mPimpl->mCompPortHandle, &numBytes, (PULONG_PTR) &watchInfo, &overlapped, INFINITE))
-			{
-				assert(false);
-				// TODO: Folder handle was lost most likely. Not sure how to deal with that. Shutdown watch on this folder and cleanup?
-			}
-
-			if(watchInfo != nullptr)
-			{
-				MonitorState state;
-
-				{
-					CM_LOCK_MUTEX(watchInfo->mStatusMutex);
-					state = watchInfo->mState;
-				}
-
-				switch(state)
-				{
-				case MonitorState::Starting:
-					if(!ReadDirectoryChangesW(watchInfo->mDirHandle, watchInfo->mBuffer, FolderWatchInfo::READ_BUFFER_SIZE,
-						watchInfo->mMonitorSubdirectories, watchInfo->mMonitorFlags, &watchInfo->mBufferSize, &watchInfo->mOverlapped, nullptr))
-					{
-						assert(false); // TODO - Possibly the buffer was too small?
-						watchInfo->mReadError = GetLastError();
-					}
-					else
-					{
-						watchInfo->mReadError = ERROR_SUCCESS;
-
-						{
-							CM_LOCK_MUTEX(watchInfo->mStatusMutex);
-							watchInfo->mState = MonitorState::Monitoring;
-						}
-					}
-
-					CM_THREAD_NOTIFY_ONE(watchInfo->mStartStopEvent);
-
-					break;
-				case MonitorState::Monitoring:
-					{
-						FileNotifyInfo info(watchInfo->mBuffer, FolderWatchInfo::READ_BUFFER_SIZE);
-						handleNotifications(info, *watchInfo);
-
-						if(!ReadDirectoryChangesW(watchInfo->mDirHandle, watchInfo->mBuffer, FolderWatchInfo::READ_BUFFER_SIZE,
-							watchInfo->mMonitorSubdirectories, watchInfo->mMonitorFlags, &watchInfo->mBufferSize, &watchInfo->mOverlapped, nullptr))
-						{
-							assert(false); // TODO: Failed during normal operation, possibly the buffer was too small. Shutdown watch on this folder and cleanup?
-							watchInfo->mReadError = GetLastError();
-						}
-						else
-						{
-							watchInfo->mReadError = ERROR_SUCCESS;
-						}
-					}
-					break;
-				case MonitorState::Shutdown:
-					if(watchInfo->mDirHandle != INVALID_HANDLE_VALUE)
-					{
-						CloseHandle(watchInfo->mDirHandle);
-						watchInfo->mDirHandle = INVALID_HANDLE_VALUE;
-
-						{
-							CM_LOCK_MUTEX(watchInfo->mStatusMutex);
-							watchInfo->mState = MonitorState::Shutdown2;
-						}
-					}
-					else
-					{
-						{
-							CM_LOCK_MUTEX(watchInfo->mStatusMutex);
-							watchInfo->mState = MonitorState::Inactive;
-						}
-
-						{
-							CM_LOCK_MUTEX(mPimpl->mMainMutex); // Ensures that we don't delete "watchInfo" before this thread is done with mStartStopEvent
-							CM_THREAD_NOTIFY_ONE(watchInfo->mStartStopEvent);
-						}
-					}
-
-					break;
-				case MonitorState::Shutdown2:
-					if(watchInfo->mDirHandle != INVALID_HANDLE_VALUE)
-					{
-						// Handle is still open? Try again.
-						CloseHandle(watchInfo->mDirHandle);
-						watchInfo->mDirHandle = INVALID_HANDLE_VALUE;
-					}
-					else
-					{
-						{
-							CM_LOCK_MUTEX(watchInfo->mStatusMutex);
-							watchInfo->mState = MonitorState::Inactive;
-						}
-
-						{
-							CM_LOCK_MUTEX(mPimpl->mMainMutex); // Ensures that we don't delete "watchInfo" before this thread is done with mStartStopEvent
-							CM_THREAD_NOTIFY_ONE(watchInfo->mStartStopEvent);
-						}
-					}
-
-					break;
-				}
-			}
-
-		} while (watchInfo != nullptr);
-	}
-
-	void FolderMonitor::handleNotifications(FileNotifyInfo& notifyInfo, FolderWatchInfo& watchInfo)
-	{
-		Vector<FileAction*> mActions;
-
-		do
-		{
-			switch(notifyInfo.getAction())
-			{
-			case FILE_ACTION_ADDED:
-				{
-					WString fileName = notifyInfo.getFileNameWithPath(watchInfo.mFolderToMonitor); 
-					mActions.push_back(FileAction::createAdded(fileName));
-				}
-				break;
-			case FILE_ACTION_REMOVED:
-				{
-					WString fileName = notifyInfo.getFileNameWithPath(watchInfo.mFolderToMonitor); 
-					mActions.push_back(FileAction::createRemoved(fileName));
-				}
-				break;
-			case FILE_ACTION_MODIFIED:
-				{
-					WString fileName = notifyInfo.getFileNameWithPath(watchInfo.mFolderToMonitor); 
-					mActions.push_back(FileAction::createModified(fileName));
-				}
-				break;
-			case FILE_ACTION_RENAMED_OLD_NAME:
-				{
-					WString fileName = notifyInfo.getFileNameWithPath(watchInfo.mFolderToMonitor);
-					watchInfo.mCachedOldFileName = fileName;
-				}
-				break;
-			case FILE_ACTION_RENAMED_NEW_NAME:
-				{
-					WString fileName = notifyInfo.getFileNameWithPath(watchInfo.mFolderToMonitor);
-					mActions.push_back(FileAction::createRenamed(watchInfo.mCachedOldFileName, fileName));
-				}
-				break;
-
-			}
-    
-		} while(notifyInfo.getNext());
-
-		{
-			CM_LOCK_MUTEX(mPimpl->mMainMutex);
-
-			for(auto& action : mActions)
-				mPimpl->mFileActions.push(action);
-		}
-	}
-
-	void FolderMonitor::_update()
-	{
-		{
-			CM_LOCK_MUTEX(mPimpl->mMainMutex);
-
-			mPimpl->mActiveFileActions.swap(mPimpl->mFileActions);
-		}
-
-		while(!mPimpl->mActiveFileActions.empty())
-		{
-			FileAction* action = mPimpl->mActiveFileActions.front();
-			mPimpl->mActiveFileActions.pop();
-
-			switch(action->type)
-			{
-			case FileActionType::Added:
-				if(!onAdded.empty())
-					onAdded(Path(action->newName));
-				break;
-			case FileActionType::Removed:
-				if(!onRemoved.empty())
-					onRemoved(Path(action->newName));
-				break;
-			case FileActionType::Modified:
-				if(!onModified.empty())
-					onModified(Path(action->newName));
-				break;
-			case FileActionType::Renamed:
-				if(!onRenamed.empty())
-					onRenamed(Path(action->oldName), Path(action->newName));
-				break;
-			}
-
-			FileAction::destroy(action);
-		}
-	}
+#include "Win32/CmWin32FolderMonitor.h"
+#include "CmFileSystem.h"
+#include "CmException.h"
+#include "CmPath.h"
+
+#include "CmDebug.h"
+
+#include <windows.h>
+
+namespace BansheeEngine
+{
+	enum class MonitorState
+	{
+		Inactive,
+		Starting,
+		Monitoring,
+		Shutdown,
+		Shutdown2
+	};
+
+	class WorkerFunc
+	{
+	public:
+		WorkerFunc(FolderMonitor* owner);
+
+		void operator()();
+
+	private:
+		FolderMonitor* mOwner;
+	};
+
+	struct FolderMonitor::FolderWatchInfo
+	{
+		FolderWatchInfo(const Path& folderToMonitor, HANDLE dirHandle, bool monitorSubdirectories, DWORD monitorFlags);
+		~FolderWatchInfo();
+
+		void startMonitor(HANDLE compPortHandle);
+		void stopMonitor(HANDLE compPortHandle);
+
+		static const UINT32 READ_BUFFER_SIZE = 65536;
+
+		Path mFolderToMonitor;
+		HANDLE mDirHandle;
+		OVERLAPPED mOverlapped;
+		MonitorState mState;
+		UINT8 mBuffer[READ_BUFFER_SIZE];
+		DWORD mBufferSize;
+		bool mMonitorSubdirectories;
+		DWORD mMonitorFlags;
+		DWORD mReadError;
+
+		WString mCachedOldFileName; // Used during rename notifications as they are handled in two steps
+
+		CM_MUTEX(mStatusMutex)
+		CM_THREAD_SYNCHRONISER(mStartStopEvent)
+	};
+
+	FolderMonitor::FolderWatchInfo::FolderWatchInfo(const Path& folderToMonitor, HANDLE dirHandle, bool monitorSubdirectories, DWORD monitorFlags)
+		:mFolderToMonitor(folderToMonitor), mDirHandle(dirHandle), mState(MonitorState::Inactive), mBufferSize(0),
+		mMonitorSubdirectories(monitorSubdirectories), mMonitorFlags(monitorFlags), mReadError(0)
+	{
+		memset(&mOverlapped, 0, sizeof(mOverlapped));
+	}
+
+	FolderMonitor::FolderWatchInfo::~FolderWatchInfo()
+	{
+		assert(mState == MonitorState::Inactive);
+
+		stopMonitor(0);
+	}
+
+	void FolderMonitor::FolderWatchInfo::startMonitor(HANDLE compPortHandle)
+	{
+		if(mState != MonitorState::Inactive)
+			return; // Already monitoring
+
+		{
+			CM_LOCK_MUTEX_NAMED(mStatusMutex, lock);
+
+			mState = MonitorState::Starting;
+			PostQueuedCompletionStatus(compPortHandle, sizeof(this), (DWORD)this, &mOverlapped);
+
+			while(mState != MonitorState::Monitoring)
+				CM_THREAD_WAIT(mStartStopEvent, mStatusMutex, lock);
+		}
+
+		if(mReadError != ERROR_SUCCESS)
+		{
+			{
+				CM_LOCK_MUTEX(mStatusMutex);
+				mState = MonitorState::Inactive;
+			}
+
+			CM_EXCEPT(InternalErrorException, "Failed to start folder monitor on folder \"" + 
+				mFolderToMonitor.toString() + "\" because ReadDirectoryChangesW failed.");
+		}
+	}
+
+	void FolderMonitor::FolderWatchInfo::stopMonitor(HANDLE compPortHandle)
+	{
+		if(mState != MonitorState::Inactive)
+		{
+			CM_LOCK_MUTEX_NAMED(mStatusMutex, lock);
+
+			mState = MonitorState::Shutdown;
+			PostQueuedCompletionStatus(compPortHandle, sizeof(this), (DWORD)this, &mOverlapped);
+
+			while(mState != MonitorState::Inactive)
+				CM_THREAD_WAIT(mStartStopEvent, mStatusMutex, lock);
+		}
+
+		if(mDirHandle != INVALID_HANDLE_VALUE)
+		{			
+			CloseHandle(mDirHandle);
+			mDirHandle = INVALID_HANDLE_VALUE;
+		}
+	}
+
+	class FolderMonitor::FileNotifyInfo
+	{
+	public:
+		FileNotifyInfo(UINT8* notifyBuffer, DWORD bufferSize)
+		:mBuffer(notifyBuffer), mBufferSize(bufferSize)
+		{
+			mCurrentRecord = (PFILE_NOTIFY_INFORMATION)mBuffer;
+		}
+
+		bool getNext();
+	
+		DWORD	getAction() const;
+		WString getFileName() const;
+		WString getFileNameWithPath(const Path& rootPath) const;
+
+	
+	protected:
+		UINT8* mBuffer;
+		DWORD mBufferSize;
+		PFILE_NOTIFY_INFORMATION mCurrentRecord;
+	};
+
+	bool FolderMonitor::FileNotifyInfo::getNext()
+	{
+		if(mCurrentRecord && mCurrentRecord->NextEntryOffset != 0)
+		{
+			PFILE_NOTIFY_INFORMATION oldRecord = mCurrentRecord;
+			mCurrentRecord = (PFILE_NOTIFY_INFORMATION) ((UINT8*)mCurrentRecord + mCurrentRecord->NextEntryOffset);
+
+			if((DWORD)((UINT8*)mCurrentRecord - mBuffer) > mBufferSize)
+			{
+				// Gone out of range, something bad happened
+				assert(false);
+
+				mCurrentRecord = oldRecord;
+			}
+					
+			return (mCurrentRecord != oldRecord);
+		}
+
+		return false;
+	}
+
+	DWORD FolderMonitor::FileNotifyInfo::getAction() const
+	{ 
+		assert(mCurrentRecord != nullptr);
+
+		if(mCurrentRecord)
+			return mCurrentRecord->Action;
+
+		return 0;
+	}
+
+	WString FolderMonitor::FileNotifyInfo::getFileName() const
+	{
+		if(mCurrentRecord)
+		{
+			wchar_t fileNameBuffer[32768 + 1] = {0};
+
+			memcpy(fileNameBuffer, mCurrentRecord->FileName, 
+					std::min(DWORD(32768 * sizeof(wchar_t)), mCurrentRecord->FileNameLength));
+		
+			return WString(fileNameBuffer);
+		}
+
+		return WString();
+	}		
+
+	WString FolderMonitor::FileNotifyInfo::getFileNameWithPath(const Path& rootPath) const
+	{
+		Path fullPath = rootPath;
+		return fullPath.append(getFileName()).toWString();
+	}
+
+	enum class FileActionType
+	{
+		Added,
+		Removed,
+		Modified,
+		Renamed
+	};
+
+	struct FileAction
+	{
+		static FileAction* createAdded(const WString& fileName)
+		{
+			UINT8* bytes = (UINT8*)cm_alloc((UINT32)(sizeof(FileAction) + (fileName.size() + 1) * sizeof(WString::value_type)));
+
+			FileAction* action = (FileAction*)bytes;
+			bytes += sizeof(FileAction);
+
+			action->oldName = nullptr;
+			action->newName = (WString::value_type*)bytes;
+			action->type = FileActionType::Added;
+
+			memcpy(action->newName, fileName.data(), fileName.size() * sizeof(WString::value_type));
+			action->newName[fileName.size()] = L'\0';
+
+			return action;
+		}
+
+		static FileAction* createRemoved(const WString& fileName)
+		{
+			UINT8* bytes = (UINT8*)cm_alloc((UINT32)(sizeof(FileAction) + (fileName.size() + 1) * sizeof(WString::value_type)));
+
+			FileAction* action = (FileAction*)bytes;
+			bytes += sizeof(FileAction);
+
+			action->oldName = nullptr;
+			action->newName = (WString::value_type*)bytes;
+			action->type = FileActionType::Removed;
+
+			memcpy(action->newName, fileName.data(), fileName.size() * sizeof(WString::value_type));
+			action->newName[fileName.size()] = L'\0';
+
+			return action;
+		}
+
+		static FileAction* createModified(const WString& fileName)
+		{
+			UINT8* bytes = (UINT8*)cm_alloc((UINT32)(sizeof(FileAction) + (fileName.size() + 1) * sizeof(WString::value_type)));
+
+			FileAction* action = (FileAction*)bytes;
+			bytes += sizeof(FileAction);
+
+			action->oldName = nullptr;
+			action->newName = (WString::value_type*)bytes;
+			action->type = FileActionType::Modified;
+
+			memcpy(action->newName, fileName.data(), fileName.size() * sizeof(WString::value_type));
+			action->newName[fileName.size()] = L'\0';
+
+			return action;
+		}
+
+		static FileAction* createRenamed(const WString& oldFilename, const WString& newfileName)
+		{
+			UINT8* bytes = (UINT8*)cm_alloc((UINT32)(sizeof(FileAction) + 
+				(oldFilename.size() + newfileName.size() + 2) * sizeof(WString::value_type)));
+
+			FileAction* action = (FileAction*)bytes;
+			bytes += sizeof(FileAction);
+
+			action->oldName = (WString::value_type*)bytes;
+			bytes += (oldFilename.size() + 1) * sizeof(WString::value_type);
+
+			action->newName = (WString::value_type*)bytes;
+			action->type = FileActionType::Modified;
+
+			memcpy(action->oldName, oldFilename.data(), oldFilename.size() * sizeof(WString::value_type));
+			action->oldName[oldFilename.size()] = L'\0';
+
+			memcpy(action->newName, newfileName.data(), newfileName.size() * sizeof(WString::value_type));
+			action->newName[newfileName.size()] = L'\0';
+
+			return action;
+		}
+
+		static void destroy(FileAction* action)
+		{
+			cm_free(action);
+		}
+
+		WString::value_type* oldName;
+		WString::value_type* newName;
+		FileActionType type;
+	};
+
+	struct FolderMonitor::Pimpl
+	{
+		Vector<FolderWatchInfo*> mFoldersToWatch;
+		HANDLE mCompPortHandle;
+
+		Queue<FileAction*> mFileActions;
+		Queue<FileAction*> mActiveFileActions;
+
+		CM_MUTEX(mMainMutex);
+		CM_THREAD_TYPE* mWorkerThread;
+	};
+
+	FolderMonitor::FolderMonitor()
+	{
+		mPimpl = cm_new<Pimpl>();
+		mPimpl->mWorkerThread = nullptr;
+		mPimpl->mCompPortHandle = nullptr;
+	}
+
+	FolderMonitor::~FolderMonitor()
+	{
+		stopMonitorAll();
+
+		// No need for mutex since we know worker thread is shut down by now
+		while(!mPimpl->mFileActions.empty())
+		{
+			FileAction* action = mPimpl->mFileActions.front();
+			mPimpl->mFileActions.pop();
+
+			FileAction::destroy(action);
+		}
+
+		cm_delete(mPimpl);
+	}
+
+	void FolderMonitor::startMonitor(const Path& folderPath, bool subdirectories, FolderChange changeFilter)
+	{
+		if(!FileSystem::isDirectory(folderPath))
+		{
+			CM_EXCEPT(InvalidParametersException, "Provided path \"" + folderPath.toString() + "\" is not a directory");
+		}
+
+		WString extendedFolderPath = L"\\\\?\\" + folderPath.toWString(Path::PathType::Windows);
+		HANDLE dirHandle = CreateFileW(extendedFolderPath.c_str(), FILE_LIST_DIRECTORY,
+			FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING,
+			FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, nullptr);
+
+		if(dirHandle == INVALID_HANDLE_VALUE)
+		{
+			CM_EXCEPT(InternalErrorException, "Failed to open folder \"" + folderPath.toString() + "\" for monitoring. Error code: " + toString((UINT64)GetLastError()));
+		}
+
+		DWORD filterFlags = 0;
+
+		if((((UINT32)changeFilter) & (UINT32)BansheeEngine::FolderChange::FileName) != 0)
+			filterFlags |= FILE_NOTIFY_CHANGE_FILE_NAME;
+
+		if((((UINT32)changeFilter) & (UINT32)BansheeEngine::FolderChange::DirName) != 0)
+			filterFlags |= FILE_NOTIFY_CHANGE_DIR_NAME;
+
+		if((((UINT32)changeFilter) & (UINT32)BansheeEngine::FolderChange::Attributes) != 0)
+			filterFlags |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
+
+		if((((UINT32)changeFilter) & (UINT32)BansheeEngine::FolderChange::Size) != 0)
+			filterFlags |= FILE_NOTIFY_CHANGE_SIZE;
+
+		if((((UINT32)changeFilter) & (UINT32)BansheeEngine::FolderChange::LastWrite) != 0)
+			filterFlags |= FILE_NOTIFY_CHANGE_LAST_WRITE;
+
+		if((((UINT32)changeFilter) & (UINT32)BansheeEngine::FolderChange::LastAccess) != 0)
+			filterFlags |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
+
+		if((((UINT32)changeFilter) & (UINT32)BansheeEngine::FolderChange::Creation) != 0)
+			filterFlags |= FILE_NOTIFY_CHANGE_CREATION;
+
+		if((((UINT32)changeFilter) & (UINT32)BansheeEngine::FolderChange::Security) != 0)
+			filterFlags |= FILE_NOTIFY_CHANGE_SECURITY;
+
+		mPimpl->mFoldersToWatch.push_back(cm_new<FolderWatchInfo>(folderPath, dirHandle, subdirectories, filterFlags));
+		FolderWatchInfo* watchInfo = mPimpl->mFoldersToWatch.back();
+
+		mPimpl->mCompPortHandle = CreateIoCompletionPort(dirHandle, mPimpl->mCompPortHandle, (DWORD)watchInfo, 0);
+
+		if(mPimpl->mCompPortHandle == nullptr)
+		{
+			mPimpl->mFoldersToWatch.erase(mPimpl->mFoldersToWatch.end() - 1);
+			cm_delete(watchInfo);
+			CM_EXCEPT(InternalErrorException, "Failed to open completition port for folder monitoring. Error code: " + toString((UINT64)GetLastError()));
+		}
+
+		if(mPimpl->mWorkerThread == nullptr)
+		{
+			CM_THREAD_CREATE(t, (std::bind(&FolderMonitor::workerThreadMain, this)));
+			mPimpl->mWorkerThread = t;
+
+			if(mPimpl->mWorkerThread == nullptr)
+			{
+				mPimpl->mFoldersToWatch.erase(mPimpl->mFoldersToWatch.end() - 1);
+				cm_delete(watchInfo);
+				CM_EXCEPT(InternalErrorException, "Failed to create a new worker thread for folder monitoring");
+			}
+		}
+
+		if(mPimpl->mWorkerThread != nullptr)
+		{
+			try
+			{
+				watchInfo->startMonitor(mPimpl->mCompPortHandle);
+			}
+			catch (Exception* e)
+			{
+				mPimpl->mFoldersToWatch.erase(mPimpl->mFoldersToWatch.end() - 1);
+				cm_delete(watchInfo);
+				throw(e);
+			}
+		}
+		else
+		{
+			mPimpl->mFoldersToWatch.erase(mPimpl->mFoldersToWatch.end() - 1);
+			cm_delete(watchInfo);
+			CM_EXCEPT(InternalErrorException, "Failed to create a new worker thread for folder monitoring");
+		}
+	}
+
+	void FolderMonitor::stopMonitor(const Path& folderPath)
+	{
+		auto findIter = std::find_if(mPimpl->mFoldersToWatch.begin(), mPimpl->mFoldersToWatch.end(), 
+			[&](const FolderWatchInfo* x) { return x->mFolderToMonitor == folderPath; });
+
+		if(findIter != mPimpl->mFoldersToWatch.end())
+		{
+			FolderWatchInfo* watchInfo = *findIter;
+
+			watchInfo->stopMonitor(mPimpl->mCompPortHandle);
+			cm_delete(watchInfo);
+
+			mPimpl->mFoldersToWatch.erase(findIter);
+		}
+
+		if(mPimpl->mFoldersToWatch.size() == 0)
+			stopMonitorAll();
+	}
+
+	void FolderMonitor::stopMonitorAll()
+	{
+		for(auto& watchInfo : mPimpl->mFoldersToWatch)
+		{
+			watchInfo->stopMonitor(mPimpl->mCompPortHandle);
+
+			{
+				// Note: Need this mutex to ensure worker thread is done with watchInfo.
+				// Even though we wait for a condition variable from the worker thread in stopMonitor,
+				// that doesn't mean the worker thread is done with the condition variable
+				// (which is stored inside watchInfo)
+				CM_LOCK_MUTEX(mPimpl->mMainMutex); 
+				cm_delete(watchInfo);
+			}
+		}
+
+		mPimpl->mFoldersToWatch.clear();
+
+		if(mPimpl->mWorkerThread != nullptr)
+		{
+			PostQueuedCompletionStatus(mPimpl->mCompPortHandle, 0, 0, nullptr);
+
+			mPimpl->mWorkerThread->join();
+			CM_THREAD_DESTROY(mPimpl->mWorkerThread);
+			mPimpl->mWorkerThread = nullptr;
+		}
+
+		if(mPimpl->mCompPortHandle != nullptr)
+		{
+			CloseHandle(mPimpl->mCompPortHandle);
+			mPimpl->mCompPortHandle = nullptr;
+		}
+	}
+
+	void FolderMonitor::workerThreadMain()
+	{
+		FolderWatchInfo* watchInfo = nullptr;
+
+		do 
+		{
+			DWORD numBytes;
+			LPOVERLAPPED overlapped;
+
+			if(!GetQueuedCompletionStatus(mPimpl->mCompPortHandle, &numBytes, (PULONG_PTR) &watchInfo, &overlapped, INFINITE))
+			{
+				assert(false);
+				// TODO: Folder handle was lost most likely. Not sure how to deal with that. Shutdown watch on this folder and cleanup?
+			}
+
+			if(watchInfo != nullptr)
+			{
+				MonitorState state;
+
+				{
+					CM_LOCK_MUTEX(watchInfo->mStatusMutex);
+					state = watchInfo->mState;
+				}
+
+				switch(state)
+				{
+				case MonitorState::Starting:
+					if(!ReadDirectoryChangesW(watchInfo->mDirHandle, watchInfo->mBuffer, FolderWatchInfo::READ_BUFFER_SIZE,
+						watchInfo->mMonitorSubdirectories, watchInfo->mMonitorFlags, &watchInfo->mBufferSize, &watchInfo->mOverlapped, nullptr))
+					{
+						assert(false); // TODO - Possibly the buffer was too small?
+						watchInfo->mReadError = GetLastError();
+					}
+					else
+					{
+						watchInfo->mReadError = ERROR_SUCCESS;
+
+						{
+							CM_LOCK_MUTEX(watchInfo->mStatusMutex);
+							watchInfo->mState = MonitorState::Monitoring;
+						}
+					}
+
+					CM_THREAD_NOTIFY_ONE(watchInfo->mStartStopEvent);
+
+					break;
+				case MonitorState::Monitoring:
+					{
+						FileNotifyInfo info(watchInfo->mBuffer, FolderWatchInfo::READ_BUFFER_SIZE);
+						handleNotifications(info, *watchInfo);
+
+						if(!ReadDirectoryChangesW(watchInfo->mDirHandle, watchInfo->mBuffer, FolderWatchInfo::READ_BUFFER_SIZE,
+							watchInfo->mMonitorSubdirectories, watchInfo->mMonitorFlags, &watchInfo->mBufferSize, &watchInfo->mOverlapped, nullptr))
+						{
+							assert(false); // TODO: Failed during normal operation, possibly the buffer was too small. Shutdown watch on this folder and cleanup?
+							watchInfo->mReadError = GetLastError();
+						}
+						else
+						{
+							watchInfo->mReadError = ERROR_SUCCESS;
+						}
+					}
+					break;
+				case MonitorState::Shutdown:
+					if(watchInfo->mDirHandle != INVALID_HANDLE_VALUE)
+					{
+						CloseHandle(watchInfo->mDirHandle);
+						watchInfo->mDirHandle = INVALID_HANDLE_VALUE;
+
+						{
+							CM_LOCK_MUTEX(watchInfo->mStatusMutex);
+							watchInfo->mState = MonitorState::Shutdown2;
+						}
+					}
+					else
+					{
+						{
+							CM_LOCK_MUTEX(watchInfo->mStatusMutex);
+							watchInfo->mState = MonitorState::Inactive;
+						}
+
+						{
+							CM_LOCK_MUTEX(mPimpl->mMainMutex); // Ensures that we don't delete "watchInfo" before this thread is done with mStartStopEvent
+							CM_THREAD_NOTIFY_ONE(watchInfo->mStartStopEvent);
+						}
+					}
+
+					break;
+				case MonitorState::Shutdown2:
+					if(watchInfo->mDirHandle != INVALID_HANDLE_VALUE)
+					{
+						// Handle is still open? Try again.
+						CloseHandle(watchInfo->mDirHandle);
+						watchInfo->mDirHandle = INVALID_HANDLE_VALUE;
+					}
+					else
+					{
+						{
+							CM_LOCK_MUTEX(watchInfo->mStatusMutex);
+							watchInfo->mState = MonitorState::Inactive;
+						}
+
+						{
+							CM_LOCK_MUTEX(mPimpl->mMainMutex); // Ensures that we don't delete "watchInfo" before this thread is done with mStartStopEvent
+							CM_THREAD_NOTIFY_ONE(watchInfo->mStartStopEvent);
+						}
+					}
+
+					break;
+				}
+			}
+
+		} while (watchInfo != nullptr);
+	}
+
+	void FolderMonitor::handleNotifications(FileNotifyInfo& notifyInfo, FolderWatchInfo& watchInfo)
+	{
+		Vector<FileAction*> mActions;
+
+		do
+		{
+			switch(notifyInfo.getAction())
+			{
+			case FILE_ACTION_ADDED:
+				{
+					WString fileName = notifyInfo.getFileNameWithPath(watchInfo.mFolderToMonitor); 
+					mActions.push_back(FileAction::createAdded(fileName));
+				}
+				break;
+			case FILE_ACTION_REMOVED:
+				{
+					WString fileName = notifyInfo.getFileNameWithPath(watchInfo.mFolderToMonitor); 
+					mActions.push_back(FileAction::createRemoved(fileName));
+				}
+				break;
+			case FILE_ACTION_MODIFIED:
+				{
+					WString fileName = notifyInfo.getFileNameWithPath(watchInfo.mFolderToMonitor); 
+					mActions.push_back(FileAction::createModified(fileName));
+				}
+				break;
+			case FILE_ACTION_RENAMED_OLD_NAME:
+				{
+					WString fileName = notifyInfo.getFileNameWithPath(watchInfo.mFolderToMonitor);
+					watchInfo.mCachedOldFileName = fileName;
+				}
+				break;
+			case FILE_ACTION_RENAMED_NEW_NAME:
+				{
+					WString fileName = notifyInfo.getFileNameWithPath(watchInfo.mFolderToMonitor);
+					mActions.push_back(FileAction::createRenamed(watchInfo.mCachedOldFileName, fileName));
+				}
+				break;
+
+			}
+    
+		} while(notifyInfo.getNext());
+
+		{
+			CM_LOCK_MUTEX(mPimpl->mMainMutex);
+
+			for(auto& action : mActions)
+				mPimpl->mFileActions.push(action);
+		}
+	}
+
+	void FolderMonitor::_update()
+	{
+		{
+			CM_LOCK_MUTEX(mPimpl->mMainMutex);
+
+			mPimpl->mActiveFileActions.swap(mPimpl->mFileActions);
+		}
+
+		while(!mPimpl->mActiveFileActions.empty())
+		{
+			FileAction* action = mPimpl->mActiveFileActions.front();
+			mPimpl->mActiveFileActions.pop();
+
+			switch(action->type)
+			{
+			case FileActionType::Added:
+				if(!onAdded.empty())
+					onAdded(Path(action->newName));
+				break;
+			case FileActionType::Removed:
+				if(!onRemoved.empty())
+					onRemoved(Path(action->newName));
+				break;
+			case FileActionType::Modified:
+				if(!onModified.empty())
+					onModified(Path(action->newName));
+				break;
+			case FileActionType::Renamed:
+				if(!onRenamed.empty())
+					onRenamed(Path(action->oldName), Path(action->newName));
+				break;
+			}
+
+			FileAction::destroy(action);
+		}
+	}
 }

+ 0 - 8
CamelotCore/Source/stdafx.cpp

@@ -1,8 +0,0 @@
-// stdafx.cpp : source file that includes just the standard includes
-// CamelotRenderer.pch will be the pre-compiled header
-// stdafx.obj will contain the pre-compiled type information
-
-#include "stdafx.h"
-
-// TODO: reference any additional headers you need in STDAFX.H
-// and not in this file

+ 0 - 1
CamelotD3D11RenderSystem/Include/CmD3D11GpuBuffer.h

@@ -2,7 +2,6 @@
 
 #include "CmD3D11Prerequisites.h"
 #include "CmGpuBuffer.h"
-#include "CmCommonEnums.h"
 
 namespace BansheeEngine 
 {

+ 0 - 1
CamelotD3D11RenderSystem/Include/CmD3D11Mappings.h

@@ -1,7 +1,6 @@
 #pragma once
 
 #include "CmD3D11Prerequisites.h"
-#include "CmCommonEnums.h"
 #include "CmTexture.h"
 #include "CmPixelData.h"
 #include "CmIndexBuffer.h"

+ 1 - 1
CamelotD3D11RenderSystem/Source/CmD3D11RenderWindow.cpp

@@ -1,6 +1,6 @@
 #include "CmD3D11RenderWindow.h"
 #include "CmCoreThread.h"
-#include "CmPlatformWndProc.h"
+#include "Win32/CmPlatformWndProc.h"
 #include "CmD3D11RenderSystem.h"
 #include "CmD3D11Device.h"
 #include "CmD3D11RenderTexture.h"

+ 2 - 31
CamelotD3D9Renderer/Include/CmD3D9Mappings.h

@@ -1,35 +1,7 @@
-/*
------------------------------------------------------------------------------
-This source file is part of OGRE
-    (Object-oriented Graphics Rendering Engine)
-For the latest info, see http://www.ogre3d.org/
 
-Copyright (c) 2000-2011 Torus Knot Software Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
-#ifndef __D3D9MAPPINGS_H__
-#define __D3D9MAPPINGS_H__
+#pragma once
 
 #include "CmD3D9Prerequisites.h"
-#include "CmCommonEnums.h"
 #include "CmRenderSystem.h"
 #include "CmHardwareBuffer.h"
 #include "CmIndexBuffer.h"
@@ -107,5 +79,4 @@ namespace BansheeEngine
 		static PixelFormat _getClosestSupportedRenderTargetPF(PixelFormat enginePF);
 		static PixelFormat _getClosestSupportedDepthStencilPF(PixelFormat enginePF);
 	};
-}
-#endif
+}

+ 1 - 1
CamelotD3D9Renderer/Source/CmD3D9RenderWindow.cpp

@@ -6,7 +6,7 @@
 #include "CmD3D9RenderSystem.h"
 #include "CmRenderSystem.h"
 #include "CmBitwise.h"
-#include "CmPlatformWndProc.h"
+#include "Win32/CmPlatformWndProc.h"
 #include "CmD3D9DeviceManager.h"
 
 namespace BansheeEngine

+ 0 - 1
CamelotGLRenderer/Include/CmGLGpuParamBlockBuffer.h

@@ -2,7 +2,6 @@
 
 #include "CmGLPrerequisites.h"
 #include "CmGpuParamBlockBuffer.h"
-#include "CmCommonEnums.h"
 
 namespace BansheeEngine
 {

+ 1 - 1
CamelotGLRenderer/Source/CmWin32Window.cpp

@@ -9,7 +9,7 @@
 #include "CmException.h"
 #include "CmWin32GLSupport.h"
 #include "CmWin32Context.h"
-#include "CmPlatformWndProc.h"
+#include "Win32/CmPlatformWndProc.h"
 #include "CmGLPixelFormat.h"
 
 GLenum GLEWAPIENTRY wglewContextInit(BansheeEngine::GLSupport *glSupport);

+ 10 - 3
CamelotOISInput/Source/CmOISPlugin.cpp

@@ -1,5 +1,6 @@
 #include "CmOISPrerequisites.h"
 #include "CmInputHandlerOIS.h"
+#include "CmRenderWindow.h"
 #include "CmApplication.h"
 #include "CmInput.h"
 
@@ -13,10 +14,16 @@ namespace BansheeEngine
 
 	extern "C" CM_OIS_EXPORT void* loadPlugin()
 	{
-		// TODO - Window handles in Windows are 64 bits when compiled as x64, but OIS only accepts a 32bit value. Is this okay?
-		UINT32 windowId = (UINT32)gApplication().getAppWindowId();
+		RenderWindowPtr primaryWindow = gApplication().getPrimaryWindow();
+
+		if (primaryWindow == nullptr)
+			assert(false && "Unable to get window handle. No active window exists!");
 
-		std::shared_ptr<RawInputHandler> inputHandler = cm_shared_ptr<InputHandlerOIS>(windowId);
+		UINT64 windowId = 0;
+		primaryWindow->getCustomAttribute("WINDOW", &windowId);
+
+		// TODO - Window handles in Windows are 64 bits when compiled as x64, but OIS only accepts a 32bit value. Is this okay?
+		std::shared_ptr<RawInputHandler> inputHandler = cm_shared_ptr<InputHandlerOIS>((UINT32)windowId);
 
 		gInput()._registerRawInputHandler(inputHandler);