Browse Source

Merge pull request #364 from AtomicGameEngine/JME-ATOMIC-SHARP

Atomic C# branch sync (WIP)
JoshEngebretson 10 years ago
parent
commit
f3a2604901
100 changed files with 7155 additions and 176 deletions
  1. 2 0
      .gitignore
  2. 75 0
      Attic/AtomicNETTest/MyClass.cs
  3. 38 0
      Attic/AtomicSharp/AtomicEditor/AtomicEditor.csproj
  4. 6 0
      Attic/AtomicSharp/AtomicEditor/MyClass.cs
  5. 27 0
      Attic/AtomicSharp/AtomicEditor/Properties/AssemblyInfo.cs
  6. 223 0
      Attic/AtomicSharp/AtomicEngine.cs
  7. 55 0
      Attic/AtomicSharp/AtomicInterop.cs
  8. 100 0
      Attic/AtomicSharp/AtomicSharp.csproj
  9. 35 0
      Attic/AtomicSharp/AtomicSharp.sln
  10. 44 0
      Attic/AtomicSharp/AtomicSharpTest/AtomicSharpTest.csproj
  11. 265 0
      Attic/AtomicSharp/AtomicSharpTest/Program.cs
  12. 27 0
      Attic/AtomicSharp/AtomicSharpTest/Properties/AssemblyInfo.cs
  13. 47 0
      Attic/AtomicSharp/AtomicSharpTool/AtomicSharpTool.csproj
  14. 51 0
      Attic/AtomicSharp/AtomicSharpTool/Program.cs
  15. 27 0
      Attic/AtomicSharp/AtomicSharpTool/Properties/AssemblyInfo.cs
  16. 48 0
      Attic/AtomicSharp/CSComponent.cs
  17. 105 0
      Attic/AtomicSharp/ComponentCore.cs
  18. 161 0
      Attic/AtomicSharp/EventCore.cs
  19. 138 0
      Attic/AtomicSharp/Math.cs
  20. 124 0
      Attic/AtomicSharp/NativeCore.cs
  21. 27 0
      Attic/AtomicSharp/Properties/AssemblyInfo.cs
  22. 635 0
      Attic/AtomicSharp/SDLConsts.cs
  23. 33 0
      Attic/AtomicSharp/ScriptObject.cs
  24. 0 0
      Attic/NETNative/AtomicSharpAPI.cpp
  25. 34 0
      Attic/NETNative/AtomicSharpAPI.h
  26. 295 0
      Attic/NETNative/AtomicSharpApp.cpp
  27. 72 0
      Attic/NETNative/AtomicSharpApp.h
  28. 33 0
      Attic/NETNative/CMakeLists.txt
  29. 3 3
      Build/Windows/Compile.bat
  30. 3 3
      Build/Windows/CompileAtomicTool.bat
  31. 3 2
      CMake/Modules/AtomicDesktop.cmake
  32. 4 1
      CMake/Modules/AtomicMac.cmake
  33. 55 0
      CMake/Modules/AtomicNET.cmake
  34. 3 4
      CMake/Modules/AtomicWindows.cmake
  35. 12 6
      Jakefile
  36. 1 1
      Resources/EditorData/AtomicEditor/editor/ui/inspectorframe.tb.txt
  37. 1 0
      Script/AtomicEditor/main.ts
  38. 2 0
      Script/AtomicEditor/ui/EditorStrings.ts
  39. 8 0
      Script/AtomicEditor/ui/Shortcuts.ts
  40. 68 0
      Script/AtomicEditor/ui/frames/inspector/AssemblyInspector.ts
  41. 86 0
      Script/AtomicEditor/ui/frames/inspector/CSComponentClassSelector.ts
  42. 217 69
      Script/AtomicEditor/ui/frames/inspector/ComponentInspector.ts
  43. 1 0
      Script/AtomicEditor/ui/frames/inspector/CreateComponentButton.ts
  44. 10 1
      Script/AtomicEditor/ui/frames/inspector/InspectorFrame.ts
  45. 7 1
      Script/AtomicEditor/ui/frames/menus/MainFrameMenu.ts
  46. 77 0
      Script/AtomicNET/AtomicNET/AtomicNETBootstrap/AssemblyLoaderCache.cs
  47. 91 0
      Script/AtomicNET/AtomicNET/AtomicNETBootstrap/Bootstrap.cs
  48. 34 0
      Script/AtomicNET/AtomicNET/AtomicNETBootstrap/IAssemblyLoadContext.cs
  49. 98 0
      Script/AtomicNET/AtomicNET/AtomicNETBootstrap/LoadContext.cs
  50. 96 0
      Script/AtomicNET/AtomicNET/AtomicNETEngine/AtomicNET.cs
  51. 27 0
      Script/AtomicNET/AtomicNET/AtomicNETEngine/CSComponent.cs
  52. 163 0
      Script/AtomicNET/AtomicNET/AtomicNETEngine/ComponentCore.cs
  53. 14 0
      Script/AtomicNET/AtomicNET/AtomicNETEngine/Constants.cs
  54. 20 0
      Script/AtomicNET/AtomicNET/AtomicNETEngine/InspectorAttribute.cs
  55. 146 0
      Script/AtomicNET/AtomicNET/AtomicNETEngine/Math.cs
  56. 147 0
      Script/AtomicNET/AtomicNET/AtomicNETEngine/NativeCore.cs
  57. 30 0
      Script/AtomicNET/AtomicNET/AtomicNETEngine/RefCounted.cs
  58. 635 0
      Script/AtomicNET/AtomicNET/AtomicNETEngine/SDLConsts.cs
  59. 224 0
      Script/AtomicNET/AtomicNET/AtomicNETTools/AssemblyInspector.cs
  60. 41 0
      Script/AtomicNET/AtomicNET/AtomicNETTools/AtomicTools.cs
  61. 808 0
      Script/AtomicNET/AtomicNET/AtomicNETTools/CSComponentInspector.cs
  62. 549 0
      Script/AtomicNET/AtomicNET/AtomicNETTools/MiniJSON.cs
  63. 44 0
      Script/AtomicNET/AtomicNET/build.cmd
  64. 29 0
      Script/AtomicNET/AtomicNET/build.sh
  65. 54 0
      Script/AtomicNET/AtomicNETProjects.json
  66. 1 2
      Script/Packages/Atomic/Package.json
  67. 3 2
      Script/Packages/Atomic/Scene.json
  68. 5 0
      Script/Packages/Atomic/Script.json
  69. 6 0
      Script/Packages/AtomicNET/NETCore.json
  70. 6 0
      Script/Packages/AtomicNET/NETScript.json
  71. 7 0
      Script/Packages/AtomicNET/Package.json
  72. 2 1
      Script/Packages/ToolCore/ToolCore.json
  73. 11 0
      Script/TypeScript/AtomicWork.d.ts
  74. 18 18
      Script/tsconfig.json
  75. 2 2
      Source/Atomic/Atomic2D/TmxFile2D.h
  76. 1 1
      Source/Atomic/Atomic3D/BillboardSet.h
  77. 3 1
      Source/Atomic/CMakeLists.txt
  78. 7 0
      Source/Atomic/Container/RefCounted.cpp
  79. 11 0
      Source/Atomic/Container/RefCounted.h
  80. 1 2
      Source/Atomic/Core/Context.cpp
  81. 13 4
      Source/Atomic/Core/Context.h
  82. 1 1
      Source/Atomic/Graphics/Drawable.h
  83. 15 0
      Source/Atomic/Resource/JSONFile.cpp
  84. 6 0
      Source/Atomic/Resource/JSONFile.h
  85. 25 0
      Source/Atomic/Script/ScriptComponent.cpp
  86. 37 0
      Source/Atomic/Script/ScriptComponent.h
  87. 131 0
      Source/Atomic/Script/ScriptComponentFile.cpp
  88. 69 0
      Source/Atomic/Script/ScriptComponentFile.h
  89. 26 0
      Source/Atomic/Script/ScriptSystem.cpp
  90. 20 0
      Source/Atomic/Script/ScriptSystem.h
  91. 2 2
      Source/Atomic/UI/UISelectList.cpp
  92. 1 1
      Source/Atomic/UI/UISelectList.h
  93. 27 0
      Source/Atomic/UI/UIWidget.cpp
  94. 5 1
      Source/Atomic/UI/UIWidget.h
  95. 2 26
      Source/AtomicEditor/Application/AEEditorApp.cpp
  96. 93 7
      Source/AtomicEditor/Application/AEEditorCommon.cpp
  97. 35 4
      Source/AtomicEditor/Application/AEPlayerApp.cpp
  98. 2 0
      Source/AtomicEditor/Application/AEPlayerApp.h
  99. 14 9
      Source/AtomicEditor/CMakeLists.txt
  100. 9 1
      Source/AtomicEditor/EditorMode/AEEditorMode.cpp

+ 2 - 0
.gitignore

@@ -22,3 +22,5 @@ node_modules/*
 Script/TypeScript/*
 !Script/TypeScript/AtomicWork.d.ts
 Script/Haxe/*
+
+Submodules/*

+ 75 - 0
Attic/AtomicNETTest/MyClass.cs

@@ -0,0 +1,75 @@
+
+using AtomicEngine;
+using System;
+
+namespace AtomicNETTest
+{
+    public enum BehaviorState
+    {
+      Friendly,
+      Aggressive,
+      Neutral
+    }
+
+
+    public class Spinner : CSComponent
+    {
+
+        [Inspector]
+        float speed = 1.0f;
+
+        [Inspector]
+        float pitchSpeed = 0.0f;
+
+        public override void Update(float timeStep)
+        {
+          Node.Yaw(timeStep * speed * 75.0f);
+          Node.Pitch(timeStep * pitchSpeed * 75.0f);
+
+          //Console.WriteLine("TICK! : {0}", speed);
+        }
+    }
+
+    public class MyComponent : CSComponent
+    {
+
+        public override void Update(float timeStep)
+        {
+            //Node.Yaw(timeStep * 75);
+
+        }
+
+        [Inspector]
+        public bool MyBoolValue = true;
+
+        [Inspector]
+        public int MyIntValue = 5;
+
+        [Inspector]
+        public int MyOtherIntValue = 101;
+
+        [Inspector]
+        public Vector3 MyVector3Value = new Vector3(1, 1, 1);
+
+        [Inspector]
+        public Quaternion MyQuaternionValue = new Quaternion(1, 0, 0, 0);
+
+        [Inspector()]
+        public float MyFloatValue = 42.0f;
+
+        [Inspector]
+        public string MyStringValue = "Hey!";
+
+        [Inspector]
+        public BehaviorState State = BehaviorState.Neutral;
+
+        [Inspector("Textures/chest.png")]
+        public Sprite2D MySprite2DValue;
+
+        [Inspector(DefaultValue = "Textures/chest.png")]
+        public Sprite2D MyOtherSprite2DValue;
+
+
+    }
+
+}

+ 38 - 0
Attic/AtomicSharp/AtomicEditor/AtomicEditor.csproj

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{91790BBE-7726-4B21-A746-0A4998F5BC7B}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>AtomicEditor</RootNamespace>
+    <AssemblyName>AtomicEditor</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>full</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="MyClass.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+</Project>

+ 6 - 0
Attic/AtomicSharp/AtomicEditor/MyClass.cs

@@ -0,0 +1,6 @@
+using System;
+
+namespace AtomicEditor
+{
+}
+

+ 27 - 0
Attic/AtomicSharp/AtomicEditor/Properties/AssemblyInfo.cs

@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle ("AtomicEditor")]
+[assembly: AssemblyDescription ("")]
+[assembly: AssemblyConfiguration ("")]
+[assembly: AssemblyCompany ("")]
+[assembly: AssemblyProduct ("")]
+[assembly: AssemblyCopyright ("josh")]
+[assembly: AssemblyTrademark ("")]
+[assembly: AssemblyCulture ("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion ("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+

+ 223 - 0
Attic/AtomicSharp/AtomicEngine.cs

@@ -0,0 +1,223 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+using AtomicPlayer;
+
+namespace AtomicEngine
+{
+	public static class Atomic
+	{
+		[DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl)]
+		private static extern int atomicsharp_initialize ();
+
+		[DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl)]
+		private static extern bool atomicsharp_runframe ();
+
+		[DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		private static extern IntPtr csb_AtomicEngine_GetSubsystem(string name);
+
+		[DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		private static extern uint csb_Atomic_StringToStringHash(string name);
+					
+		public static uint StringToStringHash(string value)
+		{
+			return csb_Atomic_StringToStringHash (value);
+		}
+
+		static Atomic()
+		{
+            try { 
+			    Initialize ();
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine(e.ToString());
+                throw;
+            }
+        }
+
+		public static void Run()
+		{
+			
+			while (Atomic.RunFrame ()) {
+
+
+			}
+
+		}
+
+		public static bool RunFrame()
+		{
+			GC.Collect();
+			GC.WaitForPendingFinalizers();
+			GC.Collect();				
+			NativeCore.ReleaseExpiredNativeReferences ();
+
+			return atomicsharp_runframe ();
+		}
+
+		public static void RegisterAssemblyComponents(Assembly assembly)
+		{
+			ComponentCore.RegisterAssemblyComponents (assembly);
+		}
+
+		public static void Initialize()
+		{
+			ContainerModule.Initialize ();
+			CoreModule.Initialize ();
+			MathModule.Initialize ();
+			EngineModule.Initialize ();
+			InputModule.Initialize ();
+			IOModule.Initialize ();
+			ResourceModule.Initialize ();
+			AudioModule.Initialize ();
+			GraphicsModule.Initialize ();
+			SceneModule.Initialize ();	
+			Atomic2DModule.Initialize ();
+			Atomic3DModule.Initialize ();
+			NavigationModule.Initialize ();
+			NetworkModule.Initialize ();
+			PhysicsModule.Initialize ();
+			EnvironmentModule.Initialize ();
+			UIModule.Initialize ();
+
+			AtomicPlayer.PlayerModule.Initialize ();
+
+			AtomicInterop.Initialize ();
+
+			atomicsharp_initialize ();
+
+			initSubsystems ();
+		}
+
+		static Dictionary<Type, RefCounted> subSystems = new Dictionary<Type, RefCounted>();
+
+		static private void registerSubsystem (RefCounted subsystem)
+		{
+			subSystems[subsystem.GetType()] = subsystem;
+		}
+
+		static public T GetSubsystem<T>() where T : RefCounted
+		{
+			return (T) subSystems [typeof(T)];
+		}
+
+		static private void initSubsystems()
+		{
+			registerSubsystem (NativeCore.WrapNative<Player> (csb_AtomicEngine_GetSubsystem("Player")));	
+			registerSubsystem (NativeCore.WrapNative<Graphics> (csb_AtomicEngine_GetSubsystem("Graphics")));	
+			registerSubsystem (NativeCore.WrapNative<Renderer> (csb_AtomicEngine_GetSubsystem("Renderer")));	
+			registerSubsystem (NativeCore.WrapNative<ResourceCache> (csb_AtomicEngine_GetSubsystem("ResourceCache")));	
+		}
+
+	}
+
+	public static partial class Constants
+	{
+		public const string LIBNAME = "/Users/josh/Dev/atomic/AtomicGameEngineSharp-build/Source/AtomicSharp/AtomicSharp";
+	}
+		
+	public partial class RefCounted
+	{		
+		public RefCounted()
+		{
+
+		}
+
+		public void AllocGCHandle()
+		{
+			// if we're not a native type, we need to not be kept alive
+			// as we need to save managed state, native types don't 
+			// save managed state and can be trivially regenerated
+			// by creating a GCHandle this managed instance will
+			// be used whenever we get a native ptr back from engine
+
+			if (!handle.IsAllocated)
+			{
+				handle = GCHandle.Alloc (this);
+			}
+		}
+
+
+		public void FreeGCHandle()
+		{
+			if (handle.IsAllocated)
+			{
+				handle.Free();
+			}
+		}
+
+		protected RefCounted (IntPtr native)
+		{
+			nativeInstance = native;
+		}
+			
+		public IntPtr nativeInstance;
+
+
+		public static void SafeAddRef(uint id)
+		{
+			csb_Atomic_RefCounted_SafeAddRef (id);
+		}
+
+		public static void SafeReleaseRef(uint id)
+		{
+			csb_Atomic_RefCounted_SafeReleaseRef (id);
+		}
+
+		[DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		public static extern void csb_Atomic_RefCounted_SafeAddRef (uint id);
+
+		[DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		public static extern void csb_Atomic_RefCounted_SafeReleaseRef (uint id);
+
+		[DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		public static extern IntPtr csb_Atomic_RefCounted_GetClassID (IntPtr self);
+
+		GCHandle handle;
+
+	}
+
+
+	public partial class Component : Animatable
+	{
+		public void Destroy()
+		{
+			if (Node != null)
+				Node.RemoveComponent (this);
+
+			// if we're a CSComponent notify ComponentCore
+			ComponentCore.DestroyComponent (this);
+
+		}
+	}
+
+	public partial class Node : Animatable
+	{
+		public T GetComponent<T> (bool recursive  = false) where T:Component
+		{
+			return (T) GetComponent (typeof(T).Name, recursive);
+		}
+
+		public T AddComponent<T> () where T:Component, new()
+		{
+			T component = new T ();
+			AddComponent( component, 0, CreateMode.REPLICATED);
+			return component;
+		}
+
+		
+	}
+
+	public class InspectorAttribute : Attribute
+	{
+		public InspectorAttribute(string defaultValue = "")
+		{
+			DefaultValue = defaultValue;
+		}
+
+		public string DefaultValue;
+	}		
+}

+ 55 - 0
Attic/AtomicSharp/AtomicInterop.cs

@@ -0,0 +1,55 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace AtomicEngine
+{
+	internal static class AtomicInterop
+	{
+		[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		delegate IntPtr CSComponentCreateDelegate (string name);
+
+		static IntPtr CSComponentCreate(string name)
+		{
+			return ComponentCore.CreateCSComponent (name);
+		}
+
+		[DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		private static extern void csb_AtomicEngine_AtomicInterop_Set_CSComponentCreate(CSComponentCreateDelegate method);
+
+
+		// ----
+
+		[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		delegate void CSComponentCallMethodDelegate (uint componentID, CSComponentMethod method, float value);
+
+		[DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		private static extern void csb_AtomicEngine_AtomicInterop_Set_CSComponentCallMethod(CSComponentCallMethodDelegate method);	
+
+		static void CSComponentCallMethod(uint componentID, CSComponentMethod method, float value)
+		{
+			ComponentCore.CallComponentMethod (componentID, method, value);
+		}
+
+		// Events
+
+		[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		delegate void CSBeginSendEventDelegate (uint senderRefId, uint eventType, IntPtr eventData);
+
+		[DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		private static extern void csb_AtomicEngine_AtomicInterop_Set_CSBeginSendEvent(CSBeginSendEventDelegate method);	
+
+		static void CSBeginSendEvent(uint senderRefId, uint eventType, IntPtr eventData)
+		{
+			EventCore.BeginSendEvent (senderRefId, eventType, eventData);
+		}
+
+		public static void Initialize()
+		{
+			csb_AtomicEngine_AtomicInterop_Set_CSComponentCreate (CSComponentCreate);	
+			csb_AtomicEngine_AtomicInterop_Set_CSComponentCallMethod (CSComponentCallMethod);
+			csb_AtomicEngine_AtomicInterop_Set_CSBeginSendEvent (CSBeginSendEvent);
+		}
+
+	}
+}
+

+ 100 - 0
Attic/AtomicSharp/AtomicSharp.csproj

@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{3A4C776B-61D6-412E-B1E9-7A1C84CD6B5B}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>AtomicEngine</RootNamespace>
+    <AssemblyName>AtomicSharp</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>full</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="..\Source\Generated\MACOSX\CSharp\Packages\Atomic\Managed\CSModuleContainer.cs">
+      <Link>CSModuleContainer.cs</Link>
+    </Compile>
+    <Compile Include="..\Source\Generated\MACOSX\CSharp\Packages\Atomic\Managed\CSModuleCore.cs">
+      <Link>CSModuleCore.cs</Link>
+    </Compile>
+    <Compile Include="..\Source\Generated\MACOSX\CSharp\Packages\Atomic\Managed\CSModuleScene.cs">
+      <Link>CSModuleScene.cs</Link>
+    </Compile>
+    <Compile Include="..\Source\Generated\MACOSX\CSharp\Packages\Atomic\Managed\CSModuleResource.cs">
+      <Link>CSModuleResource.cs</Link>
+    </Compile>
+    <Compile Include="..\Source\Generated\MACOSX\CSharp\Packages\Atomic\Managed\CSModuleGraphics.cs">
+      <Link>CSModuleGraphics.cs</Link>
+    </Compile>
+    <Compile Include="..\Source\Generated\MACOSX\CSharp\Packages\Atomic\Managed\CSModuleIO.cs">
+      <Link>CSModuleIO.cs</Link>
+    </Compile>
+    <Compile Include="..\Source\Generated\MACOSX\CSharp\Packages\AtomicPlayer\Managed\CSModulePlayer.cs">
+      <Link>CSModulePlayer.cs</Link>
+    </Compile>
+    <Compile Include="AtomicEngine.cs" />
+    <Compile Include="ComponentCore.cs" />
+    <Compile Include="Math.cs" />
+    <Compile Include="CSComponent.cs" />
+    <Compile Include="AtomicInterop.cs" />
+    <Compile Include="NativeCore.cs" />
+    <Compile Include="EventCore.cs" />
+    <Compile Include="ScriptObject.cs" />
+    <Compile Include="..\Source\Generated\MACOSX\CSharp\Packages\Atomic\Managed\CSModuleInput.cs">
+      <Link>CSModuleInput.cs</Link>
+    </Compile>
+    <Compile Include="SDLConsts.cs" />
+    <Compile Include="..\Source\Generated\MACOSX\CSharp\Packages\Atomic\Managed\CSModuleAtomic2D.cs">
+      <Link>CSModuleAtomic2D.cs</Link>
+    </Compile>
+    <Compile Include="..\Source\Generated\MACOSX\CSharp\Packages\Atomic\Managed\CSModuleAtomic3D.cs">
+      <Link>CSModuleAtomic3D.cs</Link>
+    </Compile>
+    <Compile Include="..\Source\Generated\MACOSX\CSharp\Packages\Atomic\Managed\CSModuleAudio.cs">
+      <Link>CSModuleAudio.cs</Link>
+    </Compile>
+    <Compile Include="..\Source\Generated\MACOSX\CSharp\Packages\Atomic\Managed\CSModuleEngine.cs">
+      <Link>CSModuleEngine.cs</Link>
+    </Compile>
+    <Compile Include="..\Source\Generated\MACOSX\CSharp\Packages\Atomic\Managed\CSModuleEnvironment.cs">
+      <Link>CSModuleEnvironment.cs</Link>
+    </Compile>
+    <Compile Include="..\Source\Generated\MACOSX\CSharp\Packages\Atomic\Managed\CSModuleMath.cs">
+      <Link>CSModuleMath.cs</Link>
+    </Compile>
+    <Compile Include="..\Source\Generated\MACOSX\CSharp\Packages\Atomic\Managed\CSModuleNavigation.cs">
+      <Link>CSModuleNavigation.cs</Link>
+    </Compile>
+    <Compile Include="..\Source\Generated\MACOSX\CSharp\Packages\Atomic\Managed\CSModuleNetwork.cs">
+      <Link>CSModuleNetwork.cs</Link>
+    </Compile>
+    <Compile Include="..\Source\Generated\MACOSX\CSharp\Packages\Atomic\Managed\CSModulePhysics.cs">
+      <Link>CSModulePhysics.cs</Link>
+    </Compile>
+    <Compile Include="..\Source\Generated\MACOSX\CSharp\Packages\Atomic\Managed\CSModuleUI.cs">
+      <Link>CSModuleUI.cs</Link>
+    </Compile>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+</Project>

+ 35 - 0
Attic/AtomicSharp/AtomicSharp.sln

@@ -0,0 +1,35 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomicSharp", "AtomicSharp.csproj", "{3A4C776B-61D6-412E-B1E9-7A1C84CD6B5B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomicSharpTest", "AtomicSharpTest\AtomicSharpTest.csproj", "{DBD98CE5-11DE-47F8-BF9A-83BF8576794E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomicSharpTool", "AtomicSharpTool\AtomicSharpTool.csproj", "{BA7825F5-7175-4486-8B06-BB88167246F2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomicEditor", "AtomicEditor\AtomicEditor.csproj", "{91790BBE-7726-4B21-A746-0A4998F5BC7B}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{3A4C776B-61D6-412E-B1E9-7A1C84CD6B5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{3A4C776B-61D6-412E-B1E9-7A1C84CD6B5B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{3A4C776B-61D6-412E-B1E9-7A1C84CD6B5B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{3A4C776B-61D6-412E-B1E9-7A1C84CD6B5B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{91790BBE-7726-4B21-A746-0A4998F5BC7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{91790BBE-7726-4B21-A746-0A4998F5BC7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{91790BBE-7726-4B21-A746-0A4998F5BC7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{91790BBE-7726-4B21-A746-0A4998F5BC7B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{BA7825F5-7175-4486-8B06-BB88167246F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{BA7825F5-7175-4486-8B06-BB88167246F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{BA7825F5-7175-4486-8B06-BB88167246F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{BA7825F5-7175-4486-8B06-BB88167246F2}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DBD98CE5-11DE-47F8-BF9A-83BF8576794E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DBD98CE5-11DE-47F8-BF9A-83BF8576794E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DBD98CE5-11DE-47F8-BF9A-83BF8576794E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DBD98CE5-11DE-47F8-BF9A-83BF8576794E}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+EndGlobal

+ 44 - 0
Attic/AtomicSharp/AtomicSharpTest/AtomicSharpTest.csproj

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{DBD98CE5-11DE-47F8-BF9A-83BF8576794E}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>AtomicSharpTest</RootNamespace>
+    <AssemblyName>AtomicSharpTest</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Externalconsole>true</Externalconsole>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>full</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Externalconsole>true</Externalconsole>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <ItemGroup>
+    <ProjectReference Include="..\AtomicSharp.csproj">
+      <Project>{3A4C776B-61D6-412E-B1E9-7A1C84CD6B5B}</Project>
+      <Name>AtomicSharp</Name>
+    </ProjectReference>
+  </ItemGroup>
+</Project>

+ 265 - 0
Attic/AtomicSharp/AtomicSharpTest/Program.cs

@@ -0,0 +1,265 @@
+
+using System;
+using System.Collections.Generic;
+using AtomicEngine;
+using AtomicPlayer;
+
+class BunnyMark : ScriptObject
+{
+	class Bunny
+	{
+		public Node node;
+		public Vector2 position = new Vector2 ();
+		public Vector2 speed = new Vector2 ();
+	}
+
+	public BunnyMark ()
+	{
+		var player = Atomic.GetSubsystem<Player> ();
+
+		player.LoadScene ("Scenes/Scene.scene");	
+		scene = player.CurrentScene;
+
+		SubscribeToEvent ("Update", handleUpdate);
+		SubscribeToEvent ("MouseButtonDown", handleMouseButtonDown);
+		SubscribeToEvent ("MouseButtonUp", handleMouseButtonUp);
+
+		var graphics = Atomic.GetSubsystem<Graphics> ();
+		var cache = Atomic.GetSubsystem<ResourceCache> ();
+
+		halfWidth = graphics.Width * pixelSize * 0.5f;
+		halfHeight = graphics.Height * pixelSize * 0.5f;
+
+		maxX = halfWidth;
+		minX = -halfWidth;
+		maxY = halfHeight;
+		minY = -halfHeight;
+
+		// TODO: generic version of this
+		var sheet = (SpriteSheet2D)cache.GetResource ("SpriteSheet2D", "Sprites/bunnys_sheet.xml");
+
+		var bunny1 = sheet.GetSprite ("bunny1");
+		var bunny2 = sheet.GetSprite ("bunny2");
+		var bunny3 = sheet.GetSprite ("bunny3");
+		var bunny4 = sheet.GetSprite ("bunny4");
+		var bunny5 = sheet.GetSprite ("bunny5");
+
+		bunnyTextures = new Sprite2D[] { bunny1, bunny2, bunny3, bunny4, bunny5 };
+
+		bunnyType = 2;
+		currentTexture = bunnyTextures [bunnyType];
+
+	}
+
+	void handleMouseButtonDown (VariantMap eventData)
+	{
+		isAdding = true;
+	}
+
+	void handleMouseButtonUp (VariantMap eventData)
+	{
+		isAdding = false;
+		bunnyType++;
+		bunnyType %= 5;
+		currentTexture = bunnyTextures [bunnyType];
+
+	}
+
+	void handleUpdate (VariantMap eventData)
+	{
+
+		if (isAdding) {
+
+			var scale = new Vector2 ();
+			var initPos = new Vector2 (minX, maxY);
+
+
+			for (var i = 0; i < amount; i++) {
+
+				var bunny = new Bunny ();
+				bunnies.Add (bunny);
+
+				var node = scene.CreateChild ();
+				bunny.node = node;
+
+				var sprite = (StaticSprite2D)node.CreateComponent ("StaticSprite2D");
+				sprite.BlendMode = BlendMode.BLEND_ALPHA;
+				sprite.Sprite = currentTexture;
+
+				node.Position2D = bunny.position = initPos;
+				bunny.speed.x = (float)(random.NextDouble () * 10);
+				bunny.speed.y = (float)(random.NextDouble () * 10) - 5;
+
+
+				scale.x = scale.y = (0.5f + ((float)random.NextDouble ()) * 0.5f);
+				node.Scale2D = scale;
+
+				node.Rotation2D = (((float)random.NextDouble ()) - 0.5f);
+			}
+		}
+
+		foreach (var bunny in bunnies) {
+
+			var px = bunny.position.x;
+			var py = bunny.position.y;
+
+			var speedX = bunny.speed.x;
+			var speedY = bunny.speed.y;
+
+			px += speedX * .002f;
+			py += speedY * .002f;
+
+			if (px > maxX) {
+				speedX *= -1;
+				px = maxX;
+			} else if (px < minX) {
+				speedX *= -1;
+				px = minX;
+			}
+
+			if (py > maxY) {
+				speedY = 0;
+				py = maxY;
+
+			} else if (py < minY) {
+
+				speedY *= -0.95f;
+
+				if (((float)random.NextDouble ()) > 0.5f) {
+					speedY -= ((float)random.NextDouble ()) * 6f;
+				}
+
+				py = minY;
+			}
+
+			bunny.speed.x = speedX;
+			bunny.speed.y = speedY + gravity;
+
+			bunny.position.x = px;
+			bunny.position.y = py;
+			bunny.node.Position2D = bunny.position;
+			;
+
+		}
+				
+	}
+
+	Random random = new Random ();
+
+	List<Bunny> bunnies = new List<Bunny> ();
+
+	int amount = 3;
+	float gravity = -0.5f;
+	Scene scene;
+
+	Sprite2D[] bunnyTextures;
+
+	bool isAdding = false;
+
+	int bunnyType = 2;
+	Sprite2D currentTexture;
+
+
+	float pixelSize = 0.01f;
+
+	float halfWidth;
+	float halfHeight;
+
+	float maxX;
+	float minX;
+	float maxY;
+	float minY;
+
+}
+	
+enum MyEnum
+{
+	Peaceful,
+	Friendly,
+	Aggressive
+}
+
+class Spinner : CSComponent
+{
+	[Inspector]
+	public int MyField = 42;
+
+	[Inspector("Sprites/star.png")]
+	public Sprite2D MySprite;
+
+	[Inspector]
+	public Vector3 Vector3Field = new Vector3(1, 2, 3);
+
+	[Inspector]
+	public MyEnum Attitude = MyEnum.Friendly;
+
+	[Inspector]
+	public Sprite2D[] SpritesField;
+
+}
+
+/*
+class Spinner : CSComponent
+{
+	public float Speed = 1.0f;
+
+	override public void Start()
+	{
+		myObject = new MyObject ();
+
+		SubscribeToEvent (myObject, "MyEvent", handleMyObjectEvent);
+
+		var renderer = Atomic.GetSubsystem<Renderer> ();
+		SubscribeToEvent (renderer, "BeginViewUpdate", handleEvent);
+
+		SubscribeToEvent (this, "SelfEvent", handleSelfEvent);
+
+		SendEvent ("SelfEvent");
+	}
+
+	void handleSelfEvent(VariantMap eventData)
+	{
+		Console.WriteLine ("Got Self Event");		
+	}
+		
+	void handleMyObjectEvent(VariantMap eventData)
+	{
+		//Console.WriteLine ("Got My Event");		
+	}
+
+	void handleEvent(VariantMap eventData)
+	{
+		View view = eventData.Get<View> ("view");
+		view.Camera.Zoom = zoom;
+		zoom += .01f;
+
+		myObject.SendEvent ("MyEvent");
+	}
+
+	override public void Update(float timeStep)
+	{
+		Node.Yaw (timeStep * 75 * Speed);
+	}
+
+	float zoom = 1.0f;
+
+	MyObject myObject;
+
+}
+*/
+	
+class MyGame
+{
+	public static void Main (string[] args)
+	{		
+
+		Atomic.RegisterAssemblyComponents (typeof(MyGame).Assembly);
+
+		var bunnyMark = new BunnyMark ();
+
+		Atomic.Run ();
+
+	}
+}
+
+

+ 27 - 0
Attic/AtomicSharp/AtomicSharpTest/Properties/AssemblyInfo.cs

@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle ("AtomicSharpTest")]
+[assembly: AssemblyDescription ("")]
+[assembly: AssemblyConfiguration ("")]
+[assembly: AssemblyCompany ("")]
+[assembly: AssemblyProduct ("")]
+[assembly: AssemblyCopyright ("josh")]
+[assembly: AssemblyTrademark ("")]
+[assembly: AssemblyCulture ("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion ("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+

+ 47 - 0
Attic/AtomicSharp/AtomicSharpTool/AtomicSharpTool.csproj

@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{BA7825F5-7175-4486-8B06-BB88167246F2}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>AtomicSharpTool</RootNamespace>
+    <AssemblyName>AtomicSharpTool</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Externalconsole>true</Externalconsole>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>full</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Externalconsole>true</Externalconsole>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="Newtonsoft.Json">
+      <HintPath>bin\Debug\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <ItemGroup>
+    <ProjectReference Include="..\AtomicSharp.csproj">
+      <Project>{3A4C776B-61D6-412E-B1E9-7A1C84CD6B5B}</Project>
+      <Name>AtomicSharp</Name>
+    </ProjectReference>
+  </ItemGroup>
+</Project>

+ 51 - 0
Attic/AtomicSharp/AtomicSharpTool/Program.cs

@@ -0,0 +1,51 @@
+using System;
+using System.Reflection;
+using AtomicEngine;
+
+namespace AtomicSharpTool
+{
+	class MainClass
+	{
+		public static void Main (string[] args)
+		{
+			Assembly assembly = Assembly.LoadFrom("/Users/josh/Dev/atomic/AtomicGameEngineSharp/Build/AtomicSharp/AtomicSharpTest/bin/Debug/AtomicSharpTest.exe");
+
+			Type[] types = assembly.GetTypes ();
+
+			foreach (var type in types) 
+			{
+				if (type.BaseType.Name == "CSComponent") {
+
+					FieldInfo[] fields = type.GetFields ();
+
+					Console.WriteLine (type.Name);
+
+					object instance = null;
+
+					foreach (var field in fields)
+					{
+						foreach (var attribute in field.GetCustomAttributes(true)) {
+
+							if (attribute is InspectorAttribute) {
+
+								if (instance == null)
+									instance = Activator.CreateInstance (type);
+
+								var attr = attribute as InspectorAttribute;
+
+								string defaultValue = attr.DefaultValue;
+								if (defaultValue.Length == 0 && field.GetValue (instance) != null)
+									defaultValue = field.GetValue (instance).ToString ();
+
+							
+								Console.WriteLine ("Inspector Field: {0}, {1}, {2}", field.Name, 
+									field.FieldType.Name, defaultValue);
+								
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+}

+ 27 - 0
Attic/AtomicSharp/AtomicSharpTool/Properties/AssemblyInfo.cs

@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle ("AtomicSharpTool")]
+[assembly: AssemblyDescription ("")]
+[assembly: AssemblyConfiguration ("")]
+[assembly: AssemblyCompany ("")]
+[assembly: AssemblyProduct ("")]
+[assembly: AssemblyCopyright ("josh")]
+[assembly: AssemblyTrademark ("")]
+[assembly: AssemblyCulture ("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion ("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+

+ 48 - 0
Attic/AtomicSharp/CSComponent.cs

@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace AtomicEngine
+{
+	public delegate void AtomicEventDelegate (VariantMap eventData);
+
+	public partial class CSComponent : Component
+	{
+		public uint ManagedID;
+
+		//public CSComponent ()
+		//{
+		//	nativeInstance = NativeCore.RegisterNative (csb_Atomic_CSComponent_Constructor(), this);
+//			ComponentCore.RegisterCSComponent (this);
+	//	}
+
+		virtual public void Start()
+		{
+
+		}
+
+		virtual public void Update(float timeStep)
+		{
+
+		}
+
+		public void SendEvent(string eventType, Dictionary<string, object> eventData = null)
+		{
+			EventCore.SendEvent (this, eventType);
+		}
+
+		public void SubscribeToEvent(AObject sender, string eventType, AtomicEventDelegate function)
+		{
+			EventCore.SubscribeToEvent (this, sender, eventType, function);
+		}
+
+		public void SubscribeToEvent(string eventType, AtomicEventDelegate function)
+		{
+			EventCore.SubscribeToEvent (this, null, eventType, function);
+		}
+
+		//[DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		//private static extern IntPtr csb_Atomic_CSComponent_Constructor();
+
+	}
+}

+ 105 - 0
Attic/AtomicSharp/ComponentCore.cs

@@ -0,0 +1,105 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Reflection;
+
+namespace AtomicEngine
+{
+	static internal class ComponentCore
+	{
+		static Dictionary<String, Type> componentTypes = new Dictionary<String, Type>();
+
+		// holds a reference
+		static Dictionary<uint, CSComponent> liveComponents = new Dictionary<uint, CSComponent>();
+
+		public static IntPtr CurrentCSComponentNativeInstance = default(IntPtr);
+
+		public static void CallComponentMethod(uint componentID, CSComponentMethod method, float value)
+		{
+			CSComponent component;
+
+			if (liveComponents.TryGetValue (componentID, out component)) {
+
+				switch (method) {
+
+				//case CSComponentMethod.Start:
+				//	component.Start ();
+				//	break;
+
+				//case CSComponentMethod.Update:
+				//	component.Update (value);
+				//	break;
+				}
+
+			}
+
+		}
+
+		public static void RegisterCSComponent(CSComponent component)
+		{
+			// register (holds a reference)
+			liveComponents [component.RefID] = component;
+		}
+
+		public static void DestroyComponent(Component component)
+		{
+			var c = component as CSComponent;
+
+			if (c != null) {
+
+				liveComponents.Remove (c.RefID);
+			}
+		}
+
+		// native create CSComponent
+		public static IntPtr CreateCSComponent(string name)
+		{
+			Type type;
+
+			if (componentTypes.TryGetValue (name, out type)) {
+
+				// create an instance of the component type
+				var component = (CSComponent) Activator.CreateInstance(type);
+
+				return component.nativeInstance;
+
+			}
+
+			return IntPtr.Zero;
+
+		}
+
+		static void RegisterComponentType(Type componentType)
+		{
+			// TODO: Check for name clash, we don't want to use assembly qualified names, etc to keep it simple
+			componentTypes [componentType.Name] = componentType;
+		}
+
+		public static void RegisterAssemblyComponents(Assembly assembly)
+		{
+			Type csComponentType = typeof(CSComponent);
+			Type[] types = assembly.GetTypes ();
+
+			List<Type> componentTypes = new List<Type> ();
+
+			foreach (Type type in types)
+			{
+				for (var current = type.BaseType; current != null; current = current.BaseType) {
+
+					if (current == csComponentType) {
+						componentTypes.Add(type);
+						break;
+					}
+				}
+			}
+
+			foreach (Type type in componentTypes) {
+
+				RegisterComponentType (type);
+
+			}
+
+		}
+
+	}
+}

+ 161 - 0
Attic/AtomicSharp/EventCore.cs

@@ -0,0 +1,161 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace AtomicEngine
+{
+
+	public class VariantMap
+	{		
+		public VariantMap(IntPtr native)
+		{
+			this.native = native;
+		}
+
+		public void Invalidate()
+		{
+			native = IntPtr.Zero;
+		}
+
+		void checkValid()
+		{
+			if (native == IntPtr.Zero)
+				throw new System.AccessViolationException("Event data only valid during event");
+
+		}
+
+		public T Get<T>(string key) where T:RefCounted
+		{
+			checkValid ();
+
+			// TODO: safe case
+
+			IntPtr r = csb_Atomic_VariantMap_GetInstance (native, key);
+							
+			return r == IntPtr.Zero ? null :  NativeCore.WrapNative<T> (r);
+		}
+
+		public int GetInt(string key)
+		{
+			checkValid ();
+
+			return 0;
+		}
+
+		~VariantMap()
+		{
+
+		}
+
+		IntPtr native = default(IntPtr);
+
+		[DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		private static extern IntPtr csb_Atomic_VariantMap_GetInstance(IntPtr native, string key);
+
+
+	}
+
+	public static class EventCore
+	{
+		class Subscription
+		{
+			public uint SenderRefID;
+			public AtomicEventDelegate Handler;			
+		}
+
+		// event type -> subscribers
+		static Dictionary<uint, List<uint> > eventSubscribers = new Dictionary<uint, List<uint>>();
+
+		static Dictionary<uint, Dictionary<uint, Subscription> > subscriptions = new Dictionary<uint, Dictionary<uint, Subscription> >();
+
+
+		public static void SendEvent(AObject sender, string eventType)
+		{
+			csb_Atomic_AObject_SendEvent (sender.nativeInstance, eventType);	
+		}
+
+		public static void SubscribeToEvent(AObject subscriber, AObject sender, string eventType, AtomicEventDelegate function)
+		{
+			var eventTypeID = Atomic.StringToStringHash (eventType);			
+
+			Dictionary<uint, Subscription> subs;
+
+			if (!subscriptions.TryGetValue (subscriber.RefID, out subs)) {
+
+				subs = new Dictionary<uint, Subscription> ();
+				subscriptions [subscriber.RefID] = subs;
+
+			}
+
+			Subscription sub;
+
+			if (!subs.TryGetValue (eventTypeID, out sub)) {
+
+				sub = new Subscription ();
+				subs [eventTypeID] = sub;				
+			}
+
+			sub.SenderRefID = sender == null ? 0 : sender.RefID;
+			sub.Handler = function;
+
+			List<uint> subscribers;
+
+			if (!eventSubscribers.TryGetValue (eventTypeID, out subscribers)) {
+
+				subscribers = new List<uint> ();
+				eventSubscribers [eventTypeID] = subscribers;
+			}
+
+			if (!subscribers.Contains (subscriber.RefID)) {
+
+				subscribers.Add (subscriber.RefID);
+			}
+									
+		}
+
+		public static void BeginSendEvent(uint senderRefId, uint eventType, IntPtr eventData)
+		{
+			List<uint> subscribers;
+
+			if (!eventSubscribers.TryGetValue (eventType, out subscribers)) {				
+				return;			
+			}
+
+			if (subscribers.Count == 0) {
+				return;
+			}
+
+			VariantMap vmap = new VariantMap (eventData);
+
+			foreach (var id in subscribers) {
+
+				Dictionary<uint, Subscription> subs;
+
+				if (subscriptions.TryGetValue (id, out subs)) {
+
+					Subscription sub;
+
+					if (subs.TryGetValue (eventType, out sub)) {
+
+						if (sub.SenderRefID == 0 || sub.SenderRefID == senderRefId) {
+
+							sub.Handler (vmap);
+							
+						}
+
+					}
+
+				}
+
+			}
+
+			vmap.Invalidate ();
+
+		}
+
+		[DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		private static extern void csb_Atomic_AObject_SendEvent(IntPtr self, string eventType);
+
+	}
+}
+

+ 138 - 0
Attic/AtomicSharp/Math.cs

@@ -0,0 +1,138 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace AtomicEngine
+{
+	[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct Vector3
+	{
+		public Vector3 (float x, float y, float z)
+		{
+			this.x = x;
+			this.y = y;
+			this.z = z;
+		}
+
+		public override string ToString()
+		{
+			return x + ", " + y + ", " + z;
+		}
+
+		public float x;
+		public float y;
+		public float z;
+
+
+		/// Zero vector.
+		static public readonly Vector3 Zero = new Vector3(0, 0, 0);
+		/// (-1,0,0) vector.
+		static public readonly Vector3 Left = new Vector3(-1, 0, 0);
+		/// (1,0,0) vector.
+		static public readonly Vector3 Right = new Vector3(1, 0, 0);
+		/// (0,1,0) vector.
+		static public readonly Vector3 Up = new Vector3(0, 1, 0);
+		/// (0,-1,0) vector.
+		static public readonly Vector3 Down = new Vector3(0, -1, 0);
+		/// (0,0,1) vector.
+		static public readonly Vector3 Forward = new Vector3(0, 0, 1);
+		/// (0,0,-1) vector.
+		static public readonly Vector3 Back = new Vector3(0, 0, -1);
+		/// (1,1,1) vector.
+		static public readonly Vector3 One = new Vector3(1, 1, 1);
+
+	}
+
+	[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct Vector4
+	{
+	}
+
+	[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct Vector2
+	{
+		public Vector2 (float x, float y)
+		{
+			this.x = x;
+			this.y = y;
+		}
+			
+		public float x;
+		public float y;
+
+	}
+
+	[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct Quaternion
+	{
+		public Quaternion (float w = 1.0f, float x = 0.0f, float y = 0.0f, float z = 0.0f)
+		{
+			this.w = w;
+			this.x = x;
+			this.y = y;
+			this.z = z;
+		}
+
+		public override string ToString()
+		{
+			return x + ", " + y + ", " + z;
+		}
+
+		public float w;
+		public float x;
+		public float y;
+		public float z;
+			
+		static public readonly Quaternion Identity = new Quaternion();
+
+	}
+
+	[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct Color
+	{
+		public Color (float r, float g, float b, float a = 1.0f)
+		{
+			this.r = r;
+			this.g = g;
+			this.b = b;
+			this.a = a;
+		}
+
+		public float r;
+		public float g;
+		public float b;
+		public float a;
+
+	}
+
+	[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct IntRect
+	{
+	}
+
+	[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct IntVector2
+	{
+		public int x;
+		public int y;
+
+		public IntVector2 (int x, int y)
+		{
+			this.x = x;
+			this.y = y;
+		}
+
+
+		static public readonly IntVector2 Zero = new IntVector2(0, 0);
+
+	}
+
+	[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct BoundingBox
+	{
+	}
+
+	[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct Rect
+	{
+	}}
+

+ 124 - 0
Attic/AtomicSharp/NativeCore.cs

@@ -0,0 +1,124 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace AtomicEngine
+{
+	// Want to be able to inherit from CSComponent, ScriptObject, and the various UI classes
+	// This means that the managed side needs to be kept alive as will have object state
+	// and we might get these back from native code in a variety of ways
+
+	// a inherited instance must have a GCHandle to keep it alive
+	// it must also at some point along constructor chain create the backing native
+
+	// can we detect a native class?  
+
+	// we shouldn't go off IntPtr here, as a pointer could be reused native before recycles
+
+	static class NativeCore
+	{
+		// given an existing instance classID, construct the managed instance, with downcast support (ask for Component, get StaticModel for example)
+		public static Dictionary<IntPtr, Func<IntPtr, RefCounted>> nativeClassIDToManagedConstructor = new Dictionary<IntPtr, Func<IntPtr, RefCounted>>();
+
+		// native engine types, instances of these types can be trivially recreated managed side
+		private static Dictionary<Type, Type> nativeTypes = new Dictionary<Type, Type> ();
+
+		// RefID -> WeakReference of managed instance
+		public static Dictionary<uint, WeakReference> nativeLookup = new Dictionary<uint, WeakReference> ();
+
+
+		public static bool GetNativeType (Type type)
+		{
+			return nativeTypes.ContainsKey (type);
+		}
+			
+		public static void RegisterNativeType (Type type)
+		{
+			nativeTypes.Add (type, type);		
+		}
+
+		public static IntPtr RegisterNative (IntPtr native, RefCounted r)
+		{
+			r.nativeInstance = native;
+
+			var w = new WeakReference (r);
+			NativeCore.nativeLookup [r.RefID] = w;
+			r.AddRef();
+
+			return native;
+		}
+
+		public static void ReleaseExpiredNativeReferences()
+		{
+			List<uint> released = new List<uint> ();
+
+			foreach(KeyValuePair<uint, WeakReference> entry in nativeLookup)
+			{
+
+				if (entry.Value.Target == null || !entry.Value.IsAlive) {										
+					released.Add (entry.Key);
+
+				} else {
+
+				}
+
+			}
+
+			foreach (uint id in released) {
+
+				// use safe release
+				RefCounted.SafeReleaseRef (id);
+				nativeLookup.Remove (id);
+			}
+
+		}
+
+		// wraps an existing native instance, with downcast support
+		public static T WrapNative<T> (IntPtr native) where T:RefCounted
+		{
+			if (native == IntPtr.Zero)
+				return null;
+
+			// instance id
+			uint id = csb_Atomic_RefCounted_GetRefID (native);
+
+			WeakReference w;
+
+			// first see if we're already available
+			if (nativeLookup.TryGetValue (id, out w)) {
+
+				if (w.IsAlive) {
+
+					// we're alive!
+					return (T)w.Target; 
+
+				} else {
+
+					// we were seen before, but have since been GC'd, remove!
+					nativeLookup.Remove (id);
+				}
+			}
+
+			IntPtr classID = RefCounted.csb_Atomic_RefCounted_GetClassID (native);
+
+			// and store, with downcast support for instance Component -> StaticModel
+			// we never want to hit this path for script inherited natives
+
+			RefCounted r = nativeClassIDToManagedConstructor[classID](native);
+			w = new WeakReference (r);
+			NativeCore.nativeLookup [id] = w;
+
+			// store a ref, so native side will not be released while we still have a reference in managed code
+			r.AddRef();
+
+			return (T) r;
+
+		}
+
+		[DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		private static extern uint csb_Atomic_RefCounted_GetRefID(IntPtr self);
+
+	}
+
+}
+

+ 27 - 0
Attic/AtomicSharp/Properties/AssemblyInfo.cs

@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle ("AtomicSharp")]
+[assembly: AssemblyDescription ("")]
+[assembly: AssemblyConfiguration ("")]
+[assembly: AssemblyCompany ("")]
+[assembly: AssemblyProduct ("")]
+[assembly: AssemblyCopyright ("josh")]
+[assembly: AssemblyTrademark ("")]
+[assembly: AssemblyCulture ("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion ("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+

+ 635 - 0
Attic/AtomicSharp/SDLConsts.cs

@@ -0,0 +1,635 @@
+#region License
+/* SDL2# - C# Wrapper for SDL2
+ *
+ * Copyright (c) 2013-2015 Ethan Lee.
+ *
+ * This software is provided 'as-is', without any express or implied warranty.
+ * In no event will the authors be held liable for any damages arising from
+ * the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software in a
+ * product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ * Ethan "flibitijibibo" Lee <[email protected]>
+ *
+ */
+#endregion
+
+namespace AtomicEngine
+{
+
+	public static class SDL
+	{
+
+
+		public const int SDL_BUTTON_LEFT =	1;
+		public const int SDL_BUTTON_MIDDLE =	2;
+		public const int SDL_BUTTON_RIGHT =	3;
+		public const int SDL_BUTTON_X1 =	4;
+		public const int SDL_BUTTON_X2 =	5;
+		public const int SDL_BUTTON_LMASK =	(1 << ((int)SDL_BUTTON_LEFT - 1));
+		public const int SDL_BUTTON_MMASK =	(1 << ((int)SDL_BUTTON_MIDDLE - 1));
+		public const int SDL_BUTTON_RMASK =	(1 << ((int)SDL_BUTTON_RIGHT - 1));
+		public const int SDL_BUTTON_X1MASK = (1 << ((int)SDL_BUTTON_X1 - 1));
+		public const int SDL_BUTTON_X2MASK = (1 << ((int)SDL_BUTTON_X2 - 1));
+
+		public const byte SDL_HAT_CENTERED =	0x00;
+		public const byte SDL_HAT_UP =		0x01;
+		public const byte SDL_HAT_RIGHT =	0x02;
+		public const byte SDL_HAT_DOWN =	0x04;
+		public const byte SDL_HAT_LEFT =	0x08;
+		public const byte SDL_HAT_RIGHTUP =	SDL_HAT_RIGHT | SDL_HAT_UP;
+		public const byte SDL_HAT_RIGHTDOWN =	SDL_HAT_RIGHT | SDL_HAT_DOWN;
+		public const byte SDL_HAT_LEFTUP =	SDL_HAT_LEFT | SDL_HAT_UP;
+		public const byte SDL_HAT_LEFTDOWN =	SDL_HAT_LEFT | SDL_HAT_DOWN;
+
+		public enum SDL_GameControllerButton
+		{
+			SDL_CONTROLLER_BUTTON_INVALID = -1,
+			SDL_CONTROLLER_BUTTON_A,
+			SDL_CONTROLLER_BUTTON_B,
+			SDL_CONTROLLER_BUTTON_X,
+			SDL_CONTROLLER_BUTTON_Y,
+			SDL_CONTROLLER_BUTTON_BACK,
+			SDL_CONTROLLER_BUTTON_GUIDE,
+			SDL_CONTROLLER_BUTTON_START,
+			SDL_CONTROLLER_BUTTON_LEFTSTICK,
+			SDL_CONTROLLER_BUTTON_RIGHTSTICK,
+			SDL_CONTROLLER_BUTTON_LEFTSHOULDER,
+			SDL_CONTROLLER_BUTTON_RIGHTSHOULDER,
+			SDL_CONTROLLER_BUTTON_DPAD_UP,
+			SDL_CONTROLLER_BUTTON_DPAD_DOWN,
+			SDL_CONTROLLER_BUTTON_DPAD_LEFT,
+			SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
+			SDL_CONTROLLER_BUTTON_MAX,
+		}
+
+		public enum SDL_GameControllerAxis
+		{
+			SDL_CONTROLLER_AXIS_INVALID = -1,
+			SDL_CONTROLLER_AXIS_LEFTX,
+			SDL_CONTROLLER_AXIS_LEFTY,
+			SDL_CONTROLLER_AXIS_RIGHTX,
+			SDL_CONTROLLER_AXIS_RIGHTY,
+			SDL_CONTROLLER_AXIS_TRIGGERLEFT,
+			SDL_CONTROLLER_AXIS_TRIGGERRIGHT,
+			SDL_CONTROLLER_AXIS_MAX
+		}
+
+
+		/* Scancodes based off USB keyboard page (0x07) */
+		public enum SDL_Scancode
+		{
+			SDL_SCANCODE_UNKNOWN = 0,
+
+			SDL_SCANCODE_A = 4,
+			SDL_SCANCODE_B = 5,
+			SDL_SCANCODE_C = 6,
+			SDL_SCANCODE_D = 7,
+			SDL_SCANCODE_E = 8,
+			SDL_SCANCODE_F = 9,
+			SDL_SCANCODE_G = 10,
+			SDL_SCANCODE_H = 11,
+			SDL_SCANCODE_I = 12,
+			SDL_SCANCODE_J = 13,
+			SDL_SCANCODE_K = 14,
+			SDL_SCANCODE_L = 15,
+			SDL_SCANCODE_M = 16,
+			SDL_SCANCODE_N = 17,
+			SDL_SCANCODE_O = 18,
+			SDL_SCANCODE_P = 19,
+			SDL_SCANCODE_Q = 20,
+			SDL_SCANCODE_R = 21,
+			SDL_SCANCODE_S = 22,
+			SDL_SCANCODE_T = 23,
+			SDL_SCANCODE_U = 24,
+			SDL_SCANCODE_V = 25,
+			SDL_SCANCODE_W = 26,
+			SDL_SCANCODE_X = 27,
+			SDL_SCANCODE_Y = 28,
+			SDL_SCANCODE_Z = 29,
+
+			SDL_SCANCODE_1 = 30,
+			SDL_SCANCODE_2 = 31,
+			SDL_SCANCODE_3 = 32,
+			SDL_SCANCODE_4 = 33,
+			SDL_SCANCODE_5 = 34,
+			SDL_SCANCODE_6 = 35,
+			SDL_SCANCODE_7 = 36,
+			SDL_SCANCODE_8 = 37,
+			SDL_SCANCODE_9 = 38,
+			SDL_SCANCODE_0 = 39,
+
+			SDL_SCANCODE_RETURN = 40,
+			SDL_SCANCODE_ESCAPE = 41,
+			SDL_SCANCODE_BACKSPACE = 42,
+			SDL_SCANCODE_TAB = 43,
+			SDL_SCANCODE_SPACE = 44,
+
+			SDL_SCANCODE_MINUS = 45,
+			SDL_SCANCODE_EQUALS = 46,
+			SDL_SCANCODE_LEFTBRACKET = 47,
+			SDL_SCANCODE_RIGHTBRACKET = 48,
+			SDL_SCANCODE_BACKSLASH = 49,
+			SDL_SCANCODE_NONUSHASH = 50,
+			SDL_SCANCODE_SEMICOLON = 51,
+			SDL_SCANCODE_APOSTROPHE = 52,
+			SDL_SCANCODE_GRAVE = 53,
+			SDL_SCANCODE_COMMA = 54,
+			SDL_SCANCODE_PERIOD = 55,
+			SDL_SCANCODE_SLASH = 56,
+
+			SDL_SCANCODE_CAPSLOCK = 57,
+
+			SDL_SCANCODE_F1 = 58,
+			SDL_SCANCODE_F2 = 59,
+			SDL_SCANCODE_F3 = 60,
+			SDL_SCANCODE_F4 = 61,
+			SDL_SCANCODE_F5 = 62,
+			SDL_SCANCODE_F6 = 63,
+			SDL_SCANCODE_F7 = 64,
+			SDL_SCANCODE_F8 = 65,
+			SDL_SCANCODE_F9 = 66,
+			SDL_SCANCODE_F10 = 67,
+			SDL_SCANCODE_F11 = 68,
+			SDL_SCANCODE_F12 = 69,
+
+			SDL_SCANCODE_PRINTSCREEN = 70,
+			SDL_SCANCODE_SCROLLLOCK = 71,
+			SDL_SCANCODE_PAUSE = 72,
+			SDL_SCANCODE_INSERT = 73,
+			SDL_SCANCODE_HOME = 74,
+			SDL_SCANCODE_PAGEUP = 75,
+			SDL_SCANCODE_DELETE = 76,
+			SDL_SCANCODE_END = 77,
+			SDL_SCANCODE_PAGEDOWN = 78,
+			SDL_SCANCODE_RIGHT = 79,
+			SDL_SCANCODE_LEFT = 80,
+			SDL_SCANCODE_DOWN = 81,
+			SDL_SCANCODE_UP = 82,
+
+			SDL_SCANCODE_NUMLOCKCLEAR = 83,
+			SDL_SCANCODE_KP_DIVIDE = 84,
+			SDL_SCANCODE_KP_MULTIPLY = 85,
+			SDL_SCANCODE_KP_MINUS = 86,
+			SDL_SCANCODE_KP_PLUS = 87,
+			SDL_SCANCODE_KP_ENTER = 88,
+			SDL_SCANCODE_KP_1 = 89,
+			SDL_SCANCODE_KP_2 = 90,
+			SDL_SCANCODE_KP_3 = 91,
+			SDL_SCANCODE_KP_4 = 92,
+			SDL_SCANCODE_KP_5 = 93,
+			SDL_SCANCODE_KP_6 = 94,
+			SDL_SCANCODE_KP_7 = 95,
+			SDL_SCANCODE_KP_8 = 96,
+			SDL_SCANCODE_KP_9 = 97,
+			SDL_SCANCODE_KP_0 = 98,
+			SDL_SCANCODE_KP_PERIOD = 99,
+
+			SDL_SCANCODE_NONUSBACKSLASH = 100,
+			SDL_SCANCODE_APPLICATION = 101,
+			SDL_SCANCODE_POWER = 102,
+			SDL_SCANCODE_KP_EQUALS = 103,
+			SDL_SCANCODE_F13 = 104,
+			SDL_SCANCODE_F14 = 105,
+			SDL_SCANCODE_F15 = 106,
+			SDL_SCANCODE_F16 = 107,
+			SDL_SCANCODE_F17 = 108,
+			SDL_SCANCODE_F18 = 109,
+			SDL_SCANCODE_F19 = 110,
+			SDL_SCANCODE_F20 = 111,
+			SDL_SCANCODE_F21 = 112,
+			SDL_SCANCODE_F22 = 113,
+			SDL_SCANCODE_F23 = 114,
+			SDL_SCANCODE_F24 = 115,
+			SDL_SCANCODE_EXECUTE = 116,
+			SDL_SCANCODE_HELP = 117,
+			SDL_SCANCODE_MENU = 118,
+			SDL_SCANCODE_SELECT = 119,
+			SDL_SCANCODE_STOP = 120,
+			SDL_SCANCODE_AGAIN = 121,
+			SDL_SCANCODE_UNDO = 122,
+			SDL_SCANCODE_CUT = 123,
+			SDL_SCANCODE_COPY = 124,
+			SDL_SCANCODE_PASTE = 125,
+			SDL_SCANCODE_FIND = 126,
+			SDL_SCANCODE_MUTE = 127,
+			SDL_SCANCODE_VOLUMEUP = 128,
+			SDL_SCANCODE_VOLUMEDOWN = 129,
+			/* not sure whether there's a reason to enable these */
+			/*	SDL_SCANCODE_LOCKINGCAPSLOCK = 130,  */
+			/*	SDL_SCANCODE_LOCKINGNUMLOCK = 131, */
+			/*	SDL_SCANCODE_LOCKINGSCROLLLOCK = 132, */
+			SDL_SCANCODE_KP_COMMA = 133,
+			SDL_SCANCODE_KP_EQUALSAS400 = 134,
+
+			SDL_SCANCODE_INTERNATIONAL1 = 135,
+			SDL_SCANCODE_INTERNATIONAL2 = 136,
+			SDL_SCANCODE_INTERNATIONAL3 = 137,
+			SDL_SCANCODE_INTERNATIONAL4 = 138,
+			SDL_SCANCODE_INTERNATIONAL5 = 139,
+			SDL_SCANCODE_INTERNATIONAL6 = 140,
+			SDL_SCANCODE_INTERNATIONAL7 = 141,
+			SDL_SCANCODE_INTERNATIONAL8 = 142,
+			SDL_SCANCODE_INTERNATIONAL9 = 143,
+			SDL_SCANCODE_LANG1 = 144,
+			SDL_SCANCODE_LANG2 = 145,
+			SDL_SCANCODE_LANG3 = 146,
+			SDL_SCANCODE_LANG4 = 147,
+			SDL_SCANCODE_LANG5 = 148,
+			SDL_SCANCODE_LANG6 = 149,
+			SDL_SCANCODE_LANG7 = 150,
+			SDL_SCANCODE_LANG8 = 151,
+			SDL_SCANCODE_LANG9 = 152,
+
+			SDL_SCANCODE_ALTERASE = 153,
+			SDL_SCANCODE_SYSREQ = 154,
+			SDL_SCANCODE_CANCEL = 155,
+			SDL_SCANCODE_CLEAR = 156,
+			SDL_SCANCODE_PRIOR = 157,
+			SDL_SCANCODE_RETURN2 = 158,
+			SDL_SCANCODE_SEPARATOR = 159,
+			SDL_SCANCODE_OUT = 160,
+			SDL_SCANCODE_OPER = 161,
+			SDL_SCANCODE_CLEARAGAIN = 162,
+			SDL_SCANCODE_CRSEL = 163,
+			SDL_SCANCODE_EXSEL = 164,
+
+			SDL_SCANCODE_KP_00 = 176,
+			SDL_SCANCODE_KP_000 = 177,
+			SDL_SCANCODE_THOUSANDSSEPARATOR = 178,
+			SDL_SCANCODE_DECIMALSEPARATOR = 179,
+			SDL_SCANCODE_CURRENCYUNIT = 180,
+			SDL_SCANCODE_CURRENCYSUBUNIT = 181,
+			SDL_SCANCODE_KP_LEFTPAREN = 182,
+			SDL_SCANCODE_KP_RIGHTPAREN = 183,
+			SDL_SCANCODE_KP_LEFTBRACE = 184,
+			SDL_SCANCODE_KP_RIGHTBRACE = 185,
+			SDL_SCANCODE_KP_TAB = 186,
+			SDL_SCANCODE_KP_BACKSPACE = 187,
+			SDL_SCANCODE_KP_A = 188,
+			SDL_SCANCODE_KP_B = 189,
+			SDL_SCANCODE_KP_C = 190,
+			SDL_SCANCODE_KP_D = 191,
+			SDL_SCANCODE_KP_E = 192,
+			SDL_SCANCODE_KP_F = 193,
+			SDL_SCANCODE_KP_XOR = 194,
+			SDL_SCANCODE_KP_POWER = 195,
+			SDL_SCANCODE_KP_PERCENT = 196,
+			SDL_SCANCODE_KP_LESS = 197,
+			SDL_SCANCODE_KP_GREATER = 198,
+			SDL_SCANCODE_KP_AMPERSAND = 199,
+			SDL_SCANCODE_KP_DBLAMPERSAND = 200,
+			SDL_SCANCODE_KP_VERTICALBAR = 201,
+			SDL_SCANCODE_KP_DBLVERTICALBAR = 202,
+			SDL_SCANCODE_KP_COLON = 203,
+			SDL_SCANCODE_KP_HASH = 204,
+			SDL_SCANCODE_KP_SPACE = 205,
+			SDL_SCANCODE_KP_AT = 206,
+			SDL_SCANCODE_KP_EXCLAM = 207,
+			SDL_SCANCODE_KP_MEMSTORE = 208,
+			SDL_SCANCODE_KP_MEMRECALL = 209,
+			SDL_SCANCODE_KP_MEMCLEAR = 210,
+			SDL_SCANCODE_KP_MEMADD = 211,
+			SDL_SCANCODE_KP_MEMSUBTRACT = 212,
+			SDL_SCANCODE_KP_MEMMULTIPLY = 213,
+			SDL_SCANCODE_KP_MEMDIVIDE = 214,
+			SDL_SCANCODE_KP_PLUSMINUS = 215,
+			SDL_SCANCODE_KP_CLEAR = 216,
+			SDL_SCANCODE_KP_CLEARENTRY = 217,
+			SDL_SCANCODE_KP_BINARY = 218,
+			SDL_SCANCODE_KP_OCTAL = 219,
+			SDL_SCANCODE_KP_DECIMAL = 220,
+			SDL_SCANCODE_KP_HEXADECIMAL = 221,
+
+			SDL_SCANCODE_LCTRL = 224,
+			SDL_SCANCODE_LSHIFT = 225,
+			SDL_SCANCODE_LALT = 226,
+			SDL_SCANCODE_LGUI = 227,
+			SDL_SCANCODE_RCTRL = 228,
+			SDL_SCANCODE_RSHIFT = 229,
+			SDL_SCANCODE_RALT = 230,
+			SDL_SCANCODE_RGUI = 231,
+
+			SDL_SCANCODE_MODE = 257,
+
+			/* These come from the USB consumer page (0x0C) */
+			SDL_SCANCODE_AUDIONEXT = 258,
+			SDL_SCANCODE_AUDIOPREV = 259,
+			SDL_SCANCODE_AUDIOSTOP = 260,
+			SDL_SCANCODE_AUDIOPLAY = 261,
+			SDL_SCANCODE_AUDIOMUTE = 262,
+			SDL_SCANCODE_MEDIASELECT = 263,
+			SDL_SCANCODE_WWW = 264,
+			SDL_SCANCODE_MAIL = 265,
+			SDL_SCANCODE_CALCULATOR = 266,
+			SDL_SCANCODE_COMPUTER = 267,
+			SDL_SCANCODE_AC_SEARCH = 268,
+			SDL_SCANCODE_AC_HOME = 269,
+			SDL_SCANCODE_AC_BACK = 270,
+			SDL_SCANCODE_AC_FORWARD = 271,
+			SDL_SCANCODE_AC_STOP = 272,
+			SDL_SCANCODE_AC_REFRESH = 273,
+			SDL_SCANCODE_AC_BOOKMARKS = 274,
+
+			/* These come from other sources, and are mostly mac related */
+			SDL_SCANCODE_BRIGHTNESSDOWN = 275,
+			SDL_SCANCODE_BRIGHTNESSUP = 276,
+			SDL_SCANCODE_DISPLAYSWITCH = 277,
+			SDL_SCANCODE_KBDILLUMTOGGLE = 278,
+			SDL_SCANCODE_KBDILLUMDOWN = 279,
+			SDL_SCANCODE_KBDILLUMUP = 280,
+			SDL_SCANCODE_EJECT = 281,
+			SDL_SCANCODE_SLEEP = 282,
+
+			SDL_SCANCODE_APP1 = 283,
+			SDL_SCANCODE_APP2 = 284,
+
+			/* This is not a key, simply marks the number of scancodes
+			 * so that you know how big to make your arrays. */
+			SDL_NUM_SCANCODES = 512
+		}
+
+		public const int SDLK_SCANCODE_MASK = (1 << 30);
+
+		public enum SDL_Keycode
+		{
+			SDLK_UNKNOWN = 0,
+
+			SDLK_RETURN = '\r',
+			SDLK_ESCAPE = 27,
+			// '\033'
+			SDLK_BACKSPACE = '\b',
+			SDLK_TAB = '\t',
+			SDLK_SPACE = ' ',
+			SDLK_EXCLAIM = '!',
+			SDLK_QUOTEDBL = '"',
+			SDLK_HASH = '#',
+			SDLK_PERCENT = '%',
+			SDLK_DOLLAR = '$',
+			SDLK_AMPERSAND = '&',
+			SDLK_QUOTE = '\'',
+			SDLK_LEFTPAREN = '(',
+			SDLK_RIGHTPAREN = ')',
+			SDLK_ASTERISK = '*',
+			SDLK_PLUS = '+',
+			SDLK_COMMA = ',',
+			SDLK_MINUS = '-',
+			SDLK_PERIOD = '.',
+			SDLK_SLASH = '/',
+			SDLK_0 = '0',
+			SDLK_1 = '1',
+			SDLK_2 = '2',
+			SDLK_3 = '3',
+			SDLK_4 = '4',
+			SDLK_5 = '5',
+			SDLK_6 = '6',
+			SDLK_7 = '7',
+			SDLK_8 = '8',
+			SDLK_9 = '9',
+			SDLK_COLON = ':',
+			SDLK_SEMICOLON = ';',
+			SDLK_LESS = '<',
+			SDLK_EQUALS = '=',
+			SDLK_GREATER = '>',
+			SDLK_QUESTION = '?',
+			SDLK_AT = '@',
+			/*
+			Skip uppercase letters
+			*/
+			SDLK_LEFTBRACKET = '[',
+			SDLK_BACKSLASH = '\\',
+			SDLK_RIGHTBRACKET = ']',
+			SDLK_CARET = '^',
+			SDLK_UNDERSCORE = '_',
+			SDLK_BACKQUOTE = '`',
+			SDLK_a = 'a',
+			SDLK_b = 'b',
+			SDLK_c = 'c',
+			SDLK_d = 'd',
+			SDLK_e = 'e',
+			SDLK_f = 'f',
+			SDLK_g = 'g',
+			SDLK_h = 'h',
+			SDLK_i = 'i',
+			SDLK_j = 'j',
+			SDLK_k = 'k',
+			SDLK_l = 'l',
+			SDLK_m = 'm',
+			SDLK_n = 'n',
+			SDLK_o = 'o',
+			SDLK_p = 'p',
+			SDLK_q = 'q',
+			SDLK_r = 'r',
+			SDLK_s = 's',
+			SDLK_t = 't',
+			SDLK_u = 'u',
+			SDLK_v = 'v',
+			SDLK_w = 'w',
+			SDLK_x = 'x',
+			SDLK_y = 'y',
+			SDLK_z = 'z',
+
+			SDLK_CAPSLOCK = (int)SDL_Scancode.SDL_SCANCODE_CAPSLOCK | SDLK_SCANCODE_MASK,
+
+			SDLK_F1 = (int)SDL_Scancode.SDL_SCANCODE_F1 | SDLK_SCANCODE_MASK,
+			SDLK_F2 = (int)SDL_Scancode.SDL_SCANCODE_F2 | SDLK_SCANCODE_MASK,
+			SDLK_F3 = (int)SDL_Scancode.SDL_SCANCODE_F3 | SDLK_SCANCODE_MASK,
+			SDLK_F4 = (int)SDL_Scancode.SDL_SCANCODE_F4 | SDLK_SCANCODE_MASK,
+			SDLK_F5 = (int)SDL_Scancode.SDL_SCANCODE_F5 | SDLK_SCANCODE_MASK,
+			SDLK_F6 = (int)SDL_Scancode.SDL_SCANCODE_F6 | SDLK_SCANCODE_MASK,
+			SDLK_F7 = (int)SDL_Scancode.SDL_SCANCODE_F7 | SDLK_SCANCODE_MASK,
+			SDLK_F8 = (int)SDL_Scancode.SDL_SCANCODE_F8 | SDLK_SCANCODE_MASK,
+			SDLK_F9 = (int)SDL_Scancode.SDL_SCANCODE_F9 | SDLK_SCANCODE_MASK,
+			SDLK_F10 = (int)SDL_Scancode.SDL_SCANCODE_F10 | SDLK_SCANCODE_MASK,
+			SDLK_F11 = (int)SDL_Scancode.SDL_SCANCODE_F11 | SDLK_SCANCODE_MASK,
+			SDLK_F12 = (int)SDL_Scancode.SDL_SCANCODE_F12 | SDLK_SCANCODE_MASK,
+
+			SDLK_PRINTSCREEN = (int)SDL_Scancode.SDL_SCANCODE_PRINTSCREEN | SDLK_SCANCODE_MASK,
+			SDLK_SCROLLLOCK = (int)SDL_Scancode.SDL_SCANCODE_SCROLLLOCK | SDLK_SCANCODE_MASK,
+			SDLK_PAUSE = (int)SDL_Scancode.SDL_SCANCODE_PAUSE | SDLK_SCANCODE_MASK,
+			SDLK_INSERT = (int)SDL_Scancode.SDL_SCANCODE_INSERT | SDLK_SCANCODE_MASK,
+			SDLK_HOME = (int)SDL_Scancode.SDL_SCANCODE_HOME | SDLK_SCANCODE_MASK,
+			SDLK_PAGEUP = (int)SDL_Scancode.SDL_SCANCODE_PAGEUP | SDLK_SCANCODE_MASK,
+			SDLK_DELETE = 127,
+			SDLK_END = (int)SDL_Scancode.SDL_SCANCODE_END | SDLK_SCANCODE_MASK,
+			SDLK_PAGEDOWN = (int)SDL_Scancode.SDL_SCANCODE_PAGEDOWN | SDLK_SCANCODE_MASK,
+			SDLK_RIGHT = (int)SDL_Scancode.SDL_SCANCODE_RIGHT | SDLK_SCANCODE_MASK,
+			SDLK_LEFT = (int)SDL_Scancode.SDL_SCANCODE_LEFT | SDLK_SCANCODE_MASK,
+			SDLK_DOWN = (int)SDL_Scancode.SDL_SCANCODE_DOWN | SDLK_SCANCODE_MASK,
+			SDLK_UP = (int)SDL_Scancode.SDL_SCANCODE_UP | SDLK_SCANCODE_MASK,
+
+			SDLK_NUMLOCKCLEAR = (int)SDL_Scancode.SDL_SCANCODE_NUMLOCKCLEAR | SDLK_SCANCODE_MASK,
+			SDLK_KP_DIVIDE = (int)SDL_Scancode.SDL_SCANCODE_KP_DIVIDE | SDLK_SCANCODE_MASK,
+			SDLK_KP_MULTIPLY = (int)SDL_Scancode.SDL_SCANCODE_KP_MULTIPLY | SDLK_SCANCODE_MASK,
+			SDLK_KP_MINUS = (int)SDL_Scancode.SDL_SCANCODE_KP_MINUS | SDLK_SCANCODE_MASK,
+			SDLK_KP_PLUS = (int)SDL_Scancode.SDL_SCANCODE_KP_PLUS | SDLK_SCANCODE_MASK,
+			SDLK_KP_ENTER = (int)SDL_Scancode.SDL_SCANCODE_KP_ENTER | SDLK_SCANCODE_MASK,
+			SDLK_KP_1 = (int)SDL_Scancode.SDL_SCANCODE_KP_1 | SDLK_SCANCODE_MASK,
+			SDLK_KP_2 = (int)SDL_Scancode.SDL_SCANCODE_KP_2 | SDLK_SCANCODE_MASK,
+			SDLK_KP_3 = (int)SDL_Scancode.SDL_SCANCODE_KP_3 | SDLK_SCANCODE_MASK,
+			SDLK_KP_4 = (int)SDL_Scancode.SDL_SCANCODE_KP_4 | SDLK_SCANCODE_MASK,
+			SDLK_KP_5 = (int)SDL_Scancode.SDL_SCANCODE_KP_5 | SDLK_SCANCODE_MASK,
+			SDLK_KP_6 = (int)SDL_Scancode.SDL_SCANCODE_KP_6 | SDLK_SCANCODE_MASK,
+			SDLK_KP_7 = (int)SDL_Scancode.SDL_SCANCODE_KP_7 | SDLK_SCANCODE_MASK,
+			SDLK_KP_8 = (int)SDL_Scancode.SDL_SCANCODE_KP_8 | SDLK_SCANCODE_MASK,
+			SDLK_KP_9 = (int)SDL_Scancode.SDL_SCANCODE_KP_9 | SDLK_SCANCODE_MASK,
+			SDLK_KP_0 = (int)SDL_Scancode.SDL_SCANCODE_KP_0 | SDLK_SCANCODE_MASK,
+			SDLK_KP_PERIOD = (int)SDL_Scancode.SDL_SCANCODE_KP_PERIOD | SDLK_SCANCODE_MASK,
+
+			SDLK_APPLICATION = (int)SDL_Scancode.SDL_SCANCODE_APPLICATION | SDLK_SCANCODE_MASK,
+			SDLK_POWER = (int)SDL_Scancode.SDL_SCANCODE_POWER | SDLK_SCANCODE_MASK,
+			SDLK_KP_EQUALS = (int)SDL_Scancode.SDL_SCANCODE_KP_EQUALS | SDLK_SCANCODE_MASK,
+			SDLK_F13 = (int)SDL_Scancode.SDL_SCANCODE_F13 | SDLK_SCANCODE_MASK,
+			SDLK_F14 = (int)SDL_Scancode.SDL_SCANCODE_F14 | SDLK_SCANCODE_MASK,
+			SDLK_F15 = (int)SDL_Scancode.SDL_SCANCODE_F15 | SDLK_SCANCODE_MASK,
+			SDLK_F16 = (int)SDL_Scancode.SDL_SCANCODE_F16 | SDLK_SCANCODE_MASK,
+			SDLK_F17 = (int)SDL_Scancode.SDL_SCANCODE_F17 | SDLK_SCANCODE_MASK,
+			SDLK_F18 = (int)SDL_Scancode.SDL_SCANCODE_F18 | SDLK_SCANCODE_MASK,
+			SDLK_F19 = (int)SDL_Scancode.SDL_SCANCODE_F19 | SDLK_SCANCODE_MASK,
+			SDLK_F20 = (int)SDL_Scancode.SDL_SCANCODE_F20 | SDLK_SCANCODE_MASK,
+			SDLK_F21 = (int)SDL_Scancode.SDL_SCANCODE_F21 | SDLK_SCANCODE_MASK,
+			SDLK_F22 = (int)SDL_Scancode.SDL_SCANCODE_F22 | SDLK_SCANCODE_MASK,
+			SDLK_F23 = (int)SDL_Scancode.SDL_SCANCODE_F23 | SDLK_SCANCODE_MASK,
+			SDLK_F24 = (int)SDL_Scancode.SDL_SCANCODE_F24 | SDLK_SCANCODE_MASK,
+			SDLK_EXECUTE = (int)SDL_Scancode.SDL_SCANCODE_EXECUTE | SDLK_SCANCODE_MASK,
+			SDLK_HELP = (int)SDL_Scancode.SDL_SCANCODE_HELP | SDLK_SCANCODE_MASK,
+			SDLK_MENU = (int)SDL_Scancode.SDL_SCANCODE_MENU | SDLK_SCANCODE_MASK,
+			SDLK_SELECT = (int)SDL_Scancode.SDL_SCANCODE_SELECT | SDLK_SCANCODE_MASK,
+			SDLK_STOP = (int)SDL_Scancode.SDL_SCANCODE_STOP | SDLK_SCANCODE_MASK,
+			SDLK_AGAIN = (int)SDL_Scancode.SDL_SCANCODE_AGAIN | SDLK_SCANCODE_MASK,
+			SDLK_UNDO = (int)SDL_Scancode.SDL_SCANCODE_UNDO | SDLK_SCANCODE_MASK,
+			SDLK_CUT = (int)SDL_Scancode.SDL_SCANCODE_CUT | SDLK_SCANCODE_MASK,
+			SDLK_COPY = (int)SDL_Scancode.SDL_SCANCODE_COPY | SDLK_SCANCODE_MASK,
+			SDLK_PASTE = (int)SDL_Scancode.SDL_SCANCODE_PASTE | SDLK_SCANCODE_MASK,
+			SDLK_FIND = (int)SDL_Scancode.SDL_SCANCODE_FIND | SDLK_SCANCODE_MASK,
+			SDLK_MUTE = (int)SDL_Scancode.SDL_SCANCODE_MUTE | SDLK_SCANCODE_MASK,
+			SDLK_VOLUMEUP = (int)SDL_Scancode.SDL_SCANCODE_VOLUMEUP | SDLK_SCANCODE_MASK,
+			SDLK_VOLUMEDOWN = (int)SDL_Scancode.SDL_SCANCODE_VOLUMEDOWN | SDLK_SCANCODE_MASK,
+			SDLK_KP_COMMA = (int)SDL_Scancode.SDL_SCANCODE_KP_COMMA | SDLK_SCANCODE_MASK,
+			SDLK_KP_EQUALSAS400 =
+			(int)SDL_Scancode.SDL_SCANCODE_KP_EQUALSAS400 | SDLK_SCANCODE_MASK,
+
+			SDLK_ALTERASE = (int)SDL_Scancode.SDL_SCANCODE_ALTERASE | SDLK_SCANCODE_MASK,
+			SDLK_SYSREQ = (int)SDL_Scancode.SDL_SCANCODE_SYSREQ | SDLK_SCANCODE_MASK,
+			SDLK_CANCEL = (int)SDL_Scancode.SDL_SCANCODE_CANCEL | SDLK_SCANCODE_MASK,
+			SDLK_CLEAR = (int)SDL_Scancode.SDL_SCANCODE_CLEAR | SDLK_SCANCODE_MASK,
+			SDLK_PRIOR = (int)SDL_Scancode.SDL_SCANCODE_PRIOR | SDLK_SCANCODE_MASK,
+			SDLK_RETURN2 = (int)SDL_Scancode.SDL_SCANCODE_RETURN2 | SDLK_SCANCODE_MASK,
+			SDLK_SEPARATOR = (int)SDL_Scancode.SDL_SCANCODE_SEPARATOR | SDLK_SCANCODE_MASK,
+			SDLK_OUT = (int)SDL_Scancode.SDL_SCANCODE_OUT | SDLK_SCANCODE_MASK,
+			SDLK_OPER = (int)SDL_Scancode.SDL_SCANCODE_OPER | SDLK_SCANCODE_MASK,
+			SDLK_CLEARAGAIN = (int)SDL_Scancode.SDL_SCANCODE_CLEARAGAIN | SDLK_SCANCODE_MASK,
+			SDLK_CRSEL = (int)SDL_Scancode.SDL_SCANCODE_CRSEL | SDLK_SCANCODE_MASK,
+			SDLK_EXSEL = (int)SDL_Scancode.SDL_SCANCODE_EXSEL | SDLK_SCANCODE_MASK,
+
+			SDLK_KP_00 = (int)SDL_Scancode.SDL_SCANCODE_KP_00 | SDLK_SCANCODE_MASK,
+			SDLK_KP_000 = (int)SDL_Scancode.SDL_SCANCODE_KP_000 | SDLK_SCANCODE_MASK,
+			SDLK_THOUSANDSSEPARATOR =
+			(int)SDL_Scancode.SDL_SCANCODE_THOUSANDSSEPARATOR | SDLK_SCANCODE_MASK,
+			SDLK_DECIMALSEPARATOR =
+			(int)SDL_Scancode.SDL_SCANCODE_DECIMALSEPARATOR | SDLK_SCANCODE_MASK,
+			SDLK_CURRENCYUNIT = (int)SDL_Scancode.SDL_SCANCODE_CURRENCYUNIT | SDLK_SCANCODE_MASK,
+			SDLK_CURRENCYSUBUNIT =
+			(int)SDL_Scancode.SDL_SCANCODE_CURRENCYSUBUNIT | SDLK_SCANCODE_MASK,
+			SDLK_KP_LEFTPAREN = (int)SDL_Scancode.SDL_SCANCODE_KP_LEFTPAREN | SDLK_SCANCODE_MASK,
+			SDLK_KP_RIGHTPAREN = (int)SDL_Scancode.SDL_SCANCODE_KP_RIGHTPAREN | SDLK_SCANCODE_MASK,
+			SDLK_KP_LEFTBRACE = (int)SDL_Scancode.SDL_SCANCODE_KP_LEFTBRACE | SDLK_SCANCODE_MASK,
+			SDLK_KP_RIGHTBRACE = (int)SDL_Scancode.SDL_SCANCODE_KP_RIGHTBRACE | SDLK_SCANCODE_MASK,
+			SDLK_KP_TAB = (int)SDL_Scancode.SDL_SCANCODE_KP_TAB | SDLK_SCANCODE_MASK,
+			SDLK_KP_BACKSPACE = (int)SDL_Scancode.SDL_SCANCODE_KP_BACKSPACE | SDLK_SCANCODE_MASK,
+			SDLK_KP_A = (int)SDL_Scancode.SDL_SCANCODE_KP_A | SDLK_SCANCODE_MASK,
+			SDLK_KP_B = (int)SDL_Scancode.SDL_SCANCODE_KP_B | SDLK_SCANCODE_MASK,
+			SDLK_KP_C = (int)SDL_Scancode.SDL_SCANCODE_KP_C | SDLK_SCANCODE_MASK,
+			SDLK_KP_D = (int)SDL_Scancode.SDL_SCANCODE_KP_D | SDLK_SCANCODE_MASK,
+			SDLK_KP_E = (int)SDL_Scancode.SDL_SCANCODE_KP_E | SDLK_SCANCODE_MASK,
+			SDLK_KP_F = (int)SDL_Scancode.SDL_SCANCODE_KP_F | SDLK_SCANCODE_MASK,
+			SDLK_KP_XOR = (int)SDL_Scancode.SDL_SCANCODE_KP_XOR | SDLK_SCANCODE_MASK,
+			SDLK_KP_POWER = (int)SDL_Scancode.SDL_SCANCODE_KP_POWER | SDLK_SCANCODE_MASK,
+			SDLK_KP_PERCENT = (int)SDL_Scancode.SDL_SCANCODE_KP_PERCENT | SDLK_SCANCODE_MASK,
+			SDLK_KP_LESS = (int)SDL_Scancode.SDL_SCANCODE_KP_LESS | SDLK_SCANCODE_MASK,
+			SDLK_KP_GREATER = (int)SDL_Scancode.SDL_SCANCODE_KP_GREATER | SDLK_SCANCODE_MASK,
+			SDLK_KP_AMPERSAND = (int)SDL_Scancode.SDL_SCANCODE_KP_AMPERSAND | SDLK_SCANCODE_MASK,
+			SDLK_KP_DBLAMPERSAND =
+			(int)SDL_Scancode.SDL_SCANCODE_KP_DBLAMPERSAND | SDLK_SCANCODE_MASK,
+			SDLK_KP_VERTICALBAR =
+			(int)SDL_Scancode.SDL_SCANCODE_KP_VERTICALBAR | SDLK_SCANCODE_MASK,
+			SDLK_KP_DBLVERTICALBAR =
+			(int)SDL_Scancode.SDL_SCANCODE_KP_DBLVERTICALBAR | SDLK_SCANCODE_MASK,
+			SDLK_KP_COLON = (int)SDL_Scancode.SDL_SCANCODE_KP_COLON | SDLK_SCANCODE_MASK,
+			SDLK_KP_HASH = (int)SDL_Scancode.SDL_SCANCODE_KP_HASH | SDLK_SCANCODE_MASK,
+			SDLK_KP_SPACE = (int)SDL_Scancode.SDL_SCANCODE_KP_SPACE | SDLK_SCANCODE_MASK,
+			SDLK_KP_AT = (int)SDL_Scancode.SDL_SCANCODE_KP_AT | SDLK_SCANCODE_MASK,
+			SDLK_KP_EXCLAM = (int)SDL_Scancode.SDL_SCANCODE_KP_EXCLAM | SDLK_SCANCODE_MASK,
+			SDLK_KP_MEMSTORE = (int)SDL_Scancode.SDL_SCANCODE_KP_MEMSTORE | SDLK_SCANCODE_MASK,
+			SDLK_KP_MEMRECALL = (int)SDL_Scancode.SDL_SCANCODE_KP_MEMRECALL | SDLK_SCANCODE_MASK,
+			SDLK_KP_MEMCLEAR = (int)SDL_Scancode.SDL_SCANCODE_KP_MEMCLEAR | SDLK_SCANCODE_MASK,
+			SDLK_KP_MEMADD = (int)SDL_Scancode.SDL_SCANCODE_KP_MEMADD | SDLK_SCANCODE_MASK,
+			SDLK_KP_MEMSUBTRACT =
+			(int)SDL_Scancode.SDL_SCANCODE_KP_MEMSUBTRACT | SDLK_SCANCODE_MASK,
+			SDLK_KP_MEMMULTIPLY =
+			(int)SDL_Scancode.SDL_SCANCODE_KP_MEMMULTIPLY | SDLK_SCANCODE_MASK,
+			SDLK_KP_MEMDIVIDE = (int)SDL_Scancode.SDL_SCANCODE_KP_MEMDIVIDE | SDLK_SCANCODE_MASK,
+			SDLK_KP_PLUSMINUS = (int)SDL_Scancode.SDL_SCANCODE_KP_PLUSMINUS | SDLK_SCANCODE_MASK,
+			SDLK_KP_CLEAR = (int)SDL_Scancode.SDL_SCANCODE_KP_CLEAR | SDLK_SCANCODE_MASK,
+			SDLK_KP_CLEARENTRY = (int)SDL_Scancode.SDL_SCANCODE_KP_CLEARENTRY | SDLK_SCANCODE_MASK,
+			SDLK_KP_BINARY = (int)SDL_Scancode.SDL_SCANCODE_KP_BINARY | SDLK_SCANCODE_MASK,
+			SDLK_KP_OCTAL = (int)SDL_Scancode.SDL_SCANCODE_KP_OCTAL | SDLK_SCANCODE_MASK,
+			SDLK_KP_DECIMAL = (int)SDL_Scancode.SDL_SCANCODE_KP_DECIMAL | SDLK_SCANCODE_MASK,
+			SDLK_KP_HEXADECIMAL =
+			(int)SDL_Scancode.SDL_SCANCODE_KP_HEXADECIMAL | SDLK_SCANCODE_MASK,
+
+			SDLK_LCTRL = (int)SDL_Scancode.SDL_SCANCODE_LCTRL | SDLK_SCANCODE_MASK,
+			SDLK_LSHIFT = (int)SDL_Scancode.SDL_SCANCODE_LSHIFT | SDLK_SCANCODE_MASK,
+			SDLK_LALT = (int)SDL_Scancode.SDL_SCANCODE_LALT | SDLK_SCANCODE_MASK,
+			SDLK_LGUI = (int)SDL_Scancode.SDL_SCANCODE_LGUI | SDLK_SCANCODE_MASK,
+			SDLK_RCTRL = (int)SDL_Scancode.SDL_SCANCODE_RCTRL | SDLK_SCANCODE_MASK,
+			SDLK_RSHIFT = (int)SDL_Scancode.SDL_SCANCODE_RSHIFT | SDLK_SCANCODE_MASK,
+			SDLK_RALT = (int)SDL_Scancode.SDL_SCANCODE_RALT | SDLK_SCANCODE_MASK,
+			SDLK_RGUI = (int)SDL_Scancode.SDL_SCANCODE_RGUI | SDLK_SCANCODE_MASK,
+
+			SDLK_MODE = (int)SDL_Scancode.SDL_SCANCODE_MODE | SDLK_SCANCODE_MASK,
+
+			SDLK_AUDIONEXT = (int)SDL_Scancode.SDL_SCANCODE_AUDIONEXT | SDLK_SCANCODE_MASK,
+			SDLK_AUDIOPREV = (int)SDL_Scancode.SDL_SCANCODE_AUDIOPREV | SDLK_SCANCODE_MASK,
+			SDLK_AUDIOSTOP = (int)SDL_Scancode.SDL_SCANCODE_AUDIOSTOP | SDLK_SCANCODE_MASK,
+			SDLK_AUDIOPLAY = (int)SDL_Scancode.SDL_SCANCODE_AUDIOPLAY | SDLK_SCANCODE_MASK,
+			SDLK_AUDIOMUTE = (int)SDL_Scancode.SDL_SCANCODE_AUDIOMUTE | SDLK_SCANCODE_MASK,
+			SDLK_MEDIASELECT = (int)SDL_Scancode.SDL_SCANCODE_MEDIASELECT | SDLK_SCANCODE_MASK,
+			SDLK_WWW = (int)SDL_Scancode.SDL_SCANCODE_WWW | SDLK_SCANCODE_MASK,
+			SDLK_MAIL = (int)SDL_Scancode.SDL_SCANCODE_MAIL | SDLK_SCANCODE_MASK,
+			SDLK_CALCULATOR = (int)SDL_Scancode.SDL_SCANCODE_CALCULATOR | SDLK_SCANCODE_MASK,
+			SDLK_COMPUTER = (int)SDL_Scancode.SDL_SCANCODE_COMPUTER | SDLK_SCANCODE_MASK,
+			SDLK_AC_SEARCH = (int)SDL_Scancode.SDL_SCANCODE_AC_SEARCH | SDLK_SCANCODE_MASK,
+			SDLK_AC_HOME = (int)SDL_Scancode.SDL_SCANCODE_AC_HOME | SDLK_SCANCODE_MASK,
+			SDLK_AC_BACK = (int)SDL_Scancode.SDL_SCANCODE_AC_BACK | SDLK_SCANCODE_MASK,
+			SDLK_AC_FORWARD = (int)SDL_Scancode.SDL_SCANCODE_AC_FORWARD | SDLK_SCANCODE_MASK,
+			SDLK_AC_STOP = (int)SDL_Scancode.SDL_SCANCODE_AC_STOP | SDLK_SCANCODE_MASK,
+			SDLK_AC_REFRESH = (int)SDL_Scancode.SDL_SCANCODE_AC_REFRESH | SDLK_SCANCODE_MASK,
+			SDLK_AC_BOOKMARKS = (int)SDL_Scancode.SDL_SCANCODE_AC_BOOKMARKS | SDLK_SCANCODE_MASK,
+
+			SDLK_BRIGHTNESSDOWN =
+			(int)SDL_Scancode.SDL_SCANCODE_BRIGHTNESSDOWN | SDLK_SCANCODE_MASK,
+			SDLK_BRIGHTNESSUP = (int)SDL_Scancode.SDL_SCANCODE_BRIGHTNESSUP | SDLK_SCANCODE_MASK,
+			SDLK_DISPLAYSWITCH = (int)SDL_Scancode.SDL_SCANCODE_DISPLAYSWITCH | SDLK_SCANCODE_MASK,
+			SDLK_KBDILLUMTOGGLE =
+			(int)SDL_Scancode.SDL_SCANCODE_KBDILLUMTOGGLE | SDLK_SCANCODE_MASK,
+			SDLK_KBDILLUMDOWN = (int)SDL_Scancode.SDL_SCANCODE_KBDILLUMDOWN | SDLK_SCANCODE_MASK,
+			SDLK_KBDILLUMUP = (int)SDL_Scancode.SDL_SCANCODE_KBDILLUMUP | SDLK_SCANCODE_MASK,
+			SDLK_EJECT = (int)SDL_Scancode.SDL_SCANCODE_EJECT | SDLK_SCANCODE_MASK,
+			SDLK_SLEEP = (int)SDL_Scancode.SDL_SCANCODE_SLEEP | SDLK_SCANCODE_MASK
+		}
+	}
+
+}

+ 33 - 0
Attic/AtomicSharp/ScriptObject.cs

@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace AtomicEngine
+{
+	public class ScriptObject : AObject
+	{
+		public ScriptObject ()
+		{
+			nativeInstance = NativeCore.RegisterNative (csb_Atomic_CSScriptObject_Constructor(), this);	
+		}
+
+		public void SendEvent(string eventType, Dictionary<string, object> eventData = null)
+		{
+			EventCore.SendEvent (this, eventType);
+		}
+
+		public void SubscribeToEvent(AObject sender, string eventType, AtomicEventDelegate function)
+		{
+			EventCore.SubscribeToEvent (this, sender, eventType, function);
+		}
+
+		public void SubscribeToEvent(string eventType, AtomicEventDelegate function)
+		{
+			EventCore.SubscribeToEvent (this, null, eventType, function);
+		}
+
+		[DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		private static extern IntPtr csb_Atomic_CSScriptObject_Constructor();
+	}
+}
+

+ 0 - 0
Attic/NETNative/AtomicSharpAPI.cpp


+ 34 - 0
Attic/NETNative/AtomicSharpAPI.h

@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+#pragma once
+
+#include <AtomicNET/NETCore/CSComponent.h>
+
+namespace Atomic
+{
+
+extern "C"
+{
+
+CSComponent* CSComponentCreate(String name);
+
+void CSComponentCallMethod(unsigned id, CSComponentMethod methodID, float value = 0.0f);
+
+void CSBeginSendEvent(unsigned senderRefID, unsigned eventType, VariantMap* eventData);
+
+void CSEndSendEvent(unsigned senderRefID, unsigned eventType, VariantMap* eventData);
+
+}
+
+}

+ 295 - 0
Attic/NETNative/AtomicSharpApp.cpp

@@ -0,0 +1,295 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+//
+// 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.
+//
+
+#include <Atomic/Atomic.h>
+#include <Atomic/Engine/Engine.h>
+#include <Atomic/IO/FileSystem.h>
+#include <Atomic/IO/Log.h>
+#include <Atomic/IO/IOEvents.h>
+#include <Atomic/Input/InputEvents.h>
+#include <Atomic/Input/Input.h>
+#include <Atomic/Core/Main.h>
+#include <Atomic/Core/ProcessUtils.h>
+#include <Atomic/Resource/ResourceCache.h>
+#include <Atomic/Resource/ResourceEvents.h>
+#include <Atomic/UI/UI.h>
+
+// Move me
+#include <Atomic/Environment/Environment.h>
+
+#include <AtomicJS/Javascript/Javascript.h>
+
+#include <AtomicPlayer/Player.h>
+
+#include <AtomicNET/NETCore/NETCore.h>
+#include "AtomicSharpApp.h"
+
+#include <Atomic/DebugNew.h>
+
+#ifdef __APPLE__
+#include <unistd.h>
+#endif
+
+DEFINE_APPLICATION_MAIN(AtomicPlayer::AtomicPlayerApp)
+
+namespace AtomicPlayer
+{
+
+    extern void jsapi_init_atomicplayer(JSVM* vm);
+
+    AtomicPlayerApp::AtomicPlayerApp(Context* context) :
+        Application(context)
+    {
+    }
+
+    void AtomicPlayerApp::Setup()
+    {
+
+#ifdef ATOMIC_3D
+        RegisterEnvironmentLibrary(context_);
+#endif
+
+        FileSystem* filesystem = GetSubsystem<FileSystem>();
+
+        engineParameters_["WindowTitle"] = "AtomicPlayer";
+
+#if (ATOMIC_PLATFORM_ANDROID)
+        engineParameters_["FullScreen"] = true;
+        engineParameters_["ResourcePaths"] = "CoreData;PlayerData;Cache;AtomicResources";
+#elif ATOMIC_PLATFORM_WEB
+        engineParameters_["FullScreen"] = false;
+        engineParameters_["ResourcePaths"] = "AtomicResources";
+        // engineParameters_["WindowWidth"] = 1280;
+        // engineParameters_["WindowHeight"] = 720;
+#elif ATOMIC_PLATFORM_IOS
+        engineParameters_["FullScreen"] = false;
+        engineParameters_["ResourcePaths"] = "AtomicResources";
+#else
+        engineParameters_["FullScreen"] = false;
+        engineParameters_["WindowWidth"] = 1280 * .55f;
+        engineParameters_["WindowHeight"] = 720 * .55f;
+        engineParameters_["ResourcePaths"] = "/Users/josh/Dev/atomic/AtomicGameEngineSharp/Resources/CoreData;/Users/josh/Dev/atomic/AtomicGameEngineSharp/Resources/PlayerData;/Users/josh/Dev/atomic/AtomicExamples/BunnyMark/Resources;/Users/josh/Dev/atomic/AtomicExamples/BunnyMark/";
+#endif
+
+#if ATOMIC_PLATFORM_WINDOWS
+        engineParameters_["WindowIcon"] = "Images/AtomicLogo32.png";
+        engineParameters_["ResourcePrefixPath"] = "AtomicPlayer_Resources";
+#elif ATOMIC_PLATFORM_ANDROID
+        //engineParameters_["ResourcePrefixPath"] = "assets";
+#elif ATOMIC_PLATFORM_OSX
+        engineParameters_["ResourcePrefixPath"] = "../Resources";
+#endif
+
+        const Vector<String>& arguments = GetArguments();
+
+        for (unsigned i = 0; i < arguments.Size(); ++i)
+        {
+            if (arguments[i].Length() > 1)
+            {
+                String argument = arguments[i].ToLower();
+                String value = i + 1 < arguments.Size() ? arguments[i + 1] : String::EMPTY;
+
+                if (argument == "--log-std")
+                {
+                    SubscribeToEvent(E_LOGMESSAGE, HANDLER(AtomicPlayerApp, HandleLogMessage));
+                }
+            }
+        }
+
+        // Use the script file name as the base name for the log file
+        engineParameters_["LogName"] = filesystem->GetAppPreferencesDir("AtomicPlayer", "Logs") + "AtomicPlayer.log";
+    }
+
+    void AtomicPlayerApp::Start()
+    {
+        Application::Start();
+
+        // Instantiate and register NETCore subsystem
+        context_->RegisterSubsystem(new NETCore(context_));
+
+        // Instantiate and register the Javascript subsystem
+        Javascript* javascript = new Javascript(context_);
+        context_->RegisterSubsystem(javascript);
+
+        vm_ = javascript->InstantiateVM("MainVM");
+        vm_->InitJSContext();
+
+        UI* ui = GetSubsystem<UI>();
+        ui->Initialize("DefaultUI/language/lng_en.tb.txt");
+        ui->LoadDefaultPlayerSkin();
+
+        vm_->SetModuleSearchPaths("Modules");
+
+        // Instantiate and register the Player subsystem
+        context_->RegisterSubsystem(new AtomicPlayer::Player(context_));
+        AtomicPlayer::jsapi_init_atomicplayer(vm_);
+
+        JSVM* vm = JSVM::GetJSVM(0);
+
+        if (!vm->ExecuteMain())
+        {
+            SendEvent(E_EXITREQUESTED);
+        }
+
+
+        return;
+    }
+
+    void AtomicPlayerApp::Stop()
+    {
+
+        vm_ = 0;
+        context_->RemoveSubsystem<Javascript>();
+        // make sure JSVM is really down and no outstanding refs
+        // as if not, will hold on engine subsystems, which is bad
+        assert(!JSVM::GetJSVM(0));
+
+        context_->RemoveSubsystem<NETCore>();
+
+        Application::Stop();
+
+    }
+
+    void AtomicPlayerApp::HandleScriptReloadStarted(StringHash eventType, VariantMap& eventData)
+    {
+    }
+
+    void AtomicPlayerApp::HandleScriptReloadFinished(StringHash eventType, VariantMap& eventData)
+    {
+    }
+
+    void AtomicPlayerApp::HandleScriptReloadFailed(StringHash eventType, VariantMap& eventData)
+    {
+        ErrorExit();
+    }
+
+    void AtomicPlayerApp::HandleLogMessage(StringHash eventType, VariantMap& eventData)
+    {
+        using namespace LogMessage;
+
+        int level = eventData[P_LEVEL].GetInt();
+        // The message may be multi-line, so split to rows in that case
+        Vector<String> rows = eventData[P_MESSAGE].GetString().Split('\n');
+
+        for (unsigned i = 0; i < rows.Size(); ++i)
+        {
+            if (level == LOG_ERROR)
+            {
+                fprintf(stderr, "%s\n", rows[i].CString());
+            }
+            else
+            {
+                fprintf(stdout, "%s\n", rows[i].CString());
+            }
+        }
+
+    }
+
+    int AtomicPlayerApp::Initialize()
+    {
+        try
+        {
+            Setup();
+            if (exitCode_)
+                return exitCode_;
+
+            if (!engine_->Initialize(engineParameters_))
+            {
+                ErrorExit();
+                return exitCode_;
+            }
+
+            Start();
+
+            return exitCode_;
+
+        }
+        catch (std::bad_alloc&)
+        {
+            ErrorDialog(GetTypeName(), "An out-of-memory error occurred. The application will now exit.");
+            return EXIT_FAILURE;
+        }
+    }
+
+    bool AtomicPlayerApp::RunFrame()
+    {
+        try
+        {
+            if (!engine_->IsExiting())
+            {
+                engine_->RunFrame();
+                return true;
+            }
+            else
+                return false;
+        }
+        catch (std::bad_alloc&)
+        {
+            ErrorDialog(GetTypeName(), "An out-of-memory error occurred. The application will now exit.");
+            return EXIT_FAILURE;
+        }
+    }
+
+    int AtomicPlayerApp::Shutdown()
+    {
+        Stop();
+
+        return exitCode_;
+    }
+
+}
+
+static SharedPtr<Atomic::Context> sContext;
+static SharedPtr<AtomicPlayer::AtomicPlayerApp> sApplication;
+
+extern "C" {
+
+#ifdef ATOMIC_PLATFORM_WINDOWS
+#pragma warning(disable: 4244) // possible loss of data
+#define ATOMIC_EXPORT_API __declspec(dllexport)
+#else
+#define ATOMIC_EXPORT_API
+#endif
+
+ATOMIC_EXPORT_API int atomicsharp_initialize()
+{
+    sContext = new Atomic::Context();
+    sApplication = new AtomicPlayer::AtomicPlayerApp(sContext);
+    return sApplication->Initialize();
+}
+
+ATOMIC_EXPORT_API bool atomicsharp_runframe()
+{
+    if (!sApplication->RunFrame())
+    {
+        sApplication->Shutdown();
+
+        sApplication = 0;
+        sContext = 0;
+        return false;
+    }
+
+    return true;
+}
+
+}

+ 72 - 0
Attic/NETNative/AtomicSharpApp.h

@@ -0,0 +1,72 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+//
+// 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.
+//
+
+#pragma once
+
+#include <Atomic/Engine/Application.h>
+
+namespace Atomic
+{
+    class JSVM;
+}
+
+using namespace Atomic;
+
+namespace AtomicPlayer
+{
+
+class AtomicPlayerApp : public Application
+{
+    OBJECT(AtomicPlayerApp);
+
+public:
+    /// Construct.
+    AtomicPlayerApp(Context* context);
+
+    /// Setup before engine initialization. Verify that a script file has been specified.
+    virtual void Setup();
+    /// Setup after engine initialization. Load the script and execute its start function.
+    virtual void Start();
+    /// Cleanup after the main loop. Run the script's stop function if it exists.
+    virtual void Stop();
+
+    int Initialize();
+    bool RunFrame();
+    int Shutdown();
+
+private:
+
+    SharedPtr<JSVM> vm_;
+
+    /// Handle reload start of the script file.
+    void HandleScriptReloadStarted(StringHash eventType, VariantMap& eventData);
+    /// Handle reload success of the script file.
+    void HandleScriptReloadFinished(StringHash eventType, VariantMap& eventData);
+    /// Handle reload failure of the script file.
+    void HandleScriptReloadFailed(StringHash eventType, VariantMap& eventData);
+
+    void HandleLogMessage(StringHash eventType, VariantMap& eventData);
+
+};
+
+}

+ 33 - 0
Attic/NETNative/CMakeLists.txt

@@ -0,0 +1,33 @@
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}
+                    ${CMAKE_SOURCE_DIR}/Source/ThirdParty
+                    ${CMAKE_SOURCE_DIR}/Source/ThirdParty/rapidjson/include
+                    ${CMAKE_SOURCE_DIR}/Source/ThirdParty/kNet/include
+                    ${CMAKE_SOURCE_DIR}/Source/ThirdParty/FreeType/include
+                    ${CMAKE_SOURCE_DIR}/Source/ThirdParty/Box2D )
+
+
+# ${CMAKE_SOURCE_DIR}/Build/Source/Generated/${JAVASCRIPT_BINDINGS_PLATFORM}/CSharp/Packages/Atomic/Native)                    
+
+file (GLOB CSHARP_SOURCES *.cpp *.h)
+
+if (NOT MSVC)
+    # for kNet
+    add_definitions (-DUNIX)
+endif()
+
+set (SOURCE_FILES ${CSHARP_SOURCES} ${CSHARP_BINDINGS_SOURCE} ${CSHARPATOMICPLAYER_BINDINGS_SOURCE})
+
+add_library(AtomicNETNative SHARED ${SOURCE_FILES})
+
+target_link_libraries(AtomicNETNative AtomicJS AtomicPlayerLib AtomicPlayerJS NETCore ${ATOMIC_LINK_LIBRARIES})
+
+if (APPLE)
+
+target_link_libraries(AtomicNETNative "-framework AudioUnit -framework Carbon -framework Cocoa -framework CoreAudio -framework ForceFeedback -framework IOKit -framework OpenGL -framework CoreServices -framework Security")
+
+endif()
+
+if (NOT IOS AND NOT ANDROID AND NOT EMSCRIPTEN)
+    add_dependencies(AtomicNETNative AtomicTool)
+endif()

+ 3 - 3
Build/Windows/Compile.bat

@@ -1,3 +1,3 @@
-call "%VS140COMNTOOLS%..\..\VC\bin\vcvars32.bat"
-cmake ..\\..\\  -DATOMIC_DEV_BUILD=0 -G "Visual Studio 14 2015"
-msbuild /m Atomic.sln /p:Configuration=Release /p:Platform=Win32
+call "%VS140COMNTOOLS%..\..\VC\bin\amd64\vcvars64.bat"
+cmake ..\\..\\  -DATOMIC_DEV_BUILD=0 -G "Visual Studio 14 2015 Win64"
+msbuild /m Atomic.sln /p:Configuration=Release /p:Platform=x64

+ 3 - 3
Build/Windows/CompileAtomicTool.bat

@@ -1,3 +1,3 @@
-call "%VS140COMNTOOLS%..\..\VC\bin\vcvars32.bat"
-cmake ..\\..\\  -DATOMIC_DEV_BUILD=1 -G "Visual Studio 14 2015"
-msbuild /m Atomic.sln /t:AtomicTool /p:Configuration=Release /p:Platform=Win32
+call "%VS140COMNTOOLS%..\..\VC\bin\amd64\vcvars64.bat"
+cmake ..\\..\\  -DATOMIC_DEV_BUILD=1 -G "Visual Studio 14 2015 Win64"
+msbuild /m Atomic.sln /t:AtomicTool /p:Configuration=Release /p:Platform=x64

+ 3 - 2
CMake/Modules/AtomicDesktop.cmake

@@ -1,6 +1,7 @@
-
 include_directories(${CMAKE_SOURCE_DIR}/Source/ThirdParty/Poco/Foundation/include)
 
-add_definitions( -DATOMIC_TBUI -DATOMIC_FILEWATCHER -DPOCO_NO_AUTOMATIC_LIBS)
+add_definitions( -DATOMIC_TBUI -DATOMIC_FILEWATCHER -DPOCO_NO_AUTOMATIC_LIBS -DPOCO_STATIC )
 
 set (ATOMIC_LINK_LIBRARIES ${ATOMIC_LINK_LIBRARIES} LibCpuId SQLite)
+
+include(AtomicNET)

+ 4 - 1
CMake/Modules/AtomicMac.cmake

@@ -1,8 +1,11 @@
 
+set (JAVASCRIPT_BINDINGS_PLATFORM "MACOSX")
+
 include (BundleUtilities)
 include(AtomicDesktop)
 
-set (JAVASCRIPT_BINDINGS_PLATFORM "MACOSX")
+# only have 32 bit mono installed, fix this
+# set (CMAKE_OSX_ARCHITECTURES i386)
 
 add_definitions(-DATOMIC_PLATFORM_OSX -DATOMIC_OPENGL -DKNET_UNIX)
 

+ 55 - 0
CMake/Modules/AtomicNET.cmake

@@ -0,0 +1,55 @@
+
+if (ATOMIC_DOTNET_DEV)
+add_definitions ( -DATOMIC_DOTNET )
+endif ()
+
+set (CSATOMICNATIVEDIR "${CMAKE_SOURCE_DIR}/Build/Source/Generated/${JAVASCRIPT_BINDINGS_PLATFORM}/CSharp/Packages/Atomic/Native")
+set (CSATOMICPLAYERNATIVEDIR "${CMAKE_SOURCE_DIR}/Build/Source/Generated/${JAVASCRIPT_BINDINGS_PLATFORM}/CSharp/Packages/AtomicPlayer/Native")
+set (CSATOMICNETNATIVEDIR "${CMAKE_SOURCE_DIR}/Build/Source/Generated/${JAVASCRIPT_BINDINGS_PLATFORM}/CSharp/Packages/AtomicNET/Native")
+
+# Create the binding files ahead of time, so they are picked up with glob
+
+set (CSFILES CSModuleAtomic2D.cpp;CSModuleAtomic3D.cpp;CSModuleAudio.cpp;CSModuleContainer.cpp;CSModuleCore.cpp;
+             CSModuleEngine.cpp;CSModuleEnvironment.cpp;CSModuleGraphics.cpp;CSModuleInput.cpp;
+             CSModuleIO.cpp;CSModuleJavascript.cpp;CSModuleMath.cpp;CSModuleNavigation.cpp;
+             CSModuleNetwork.cpp;CSModulePhysics.cpp;CSModuleResource.cpp;CSPackageAtomic.cpp;
+             CSModuleScene.cpp;CSModuleUI.cpp;CSPackageAtomic.h;CSModuleAtomicNET.cpp)
+
+set (CSATOMICPLAYERFILES CSModulePlayer.cpp;CSPackageAtomicPlayer.cpp;CSPackageAtomicPlayer.h)
+
+set (CSATOMICNETFILES CSModuleNETCore.cpp;CSModuleNETScript.cpp;CSPackageAtomicNET.cpp;CSPackageAtomicNET.h)
+
+foreach(CSFILE ${CSFILES})
+
+  set (CSFILEPATH "${CSATOMICNATIVEDIR}/${CSFILE}")
+
+  if (NOT EXISTS ${CSFILEPATH})
+    file(WRITE "${CSFILEPATH}" "// will be created by AtomicTool")
+  endif()
+
+endforeach()
+
+foreach(CSFILE ${CSATOMICPLAYERFILES})
+
+  set (CSFILEPATH "${CSATOMICPLAYERNATIVEDIR}/${CSFILE}")
+
+  if (NOT EXISTS ${CSFILEPATH})
+    file(WRITE "${CSFILEPATH}" "// will be created by AtomicTool")
+  endif()
+
+endforeach()
+
+foreach(CSFILE ${CSATOMICNETFILES})
+
+  set (CSFILEPATH "${CSATOMICNETNATIVEDIR}/${CSFILE}")
+
+  if (NOT EXISTS ${CSFILEPATH})
+    file(WRITE "${CSFILEPATH}" "// will be created by AtomicTool")
+  endif()
+
+endforeach()
+
+
+file (GLOB CSHARP_BINDINGS_SOURCE ${CSATOMICNATIVEDIR}/*.cpp ${CSATOMICNATIVEDIR}/*.h)
+file (GLOB CSHARPATOMICPLAYER_BINDINGS_SOURCE ${CSATOMICPLAYERNATIVEDIR}/*.cpp ${CSATOMICPLAYERNATIVEDIR}/*.h)
+file (GLOB CSHARPATOMICNET_BINDINGS_SOURCE ${CSATOMICNETNATIVEDIR}/*.cpp ${CSATOMICNETNATIVEDIR}/*.h)

+ 3 - 4
CMake/Modules/AtomicWindows.cmake

@@ -1,10 +1,9 @@
 
-include(AtomicDesktop)
-
 set (JAVASCRIPT_BINDINGS_PLATFORM "WINDOWS")
 
-#set (CMAKE_DEBUG_POSTFIX _d)
+include(AtomicDesktop)
 
+#set (CMAKE_DEBUG_POSTFIX _d)
 
 if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
     set (D3DCOMPILER_47_DLL ${CMAKE_SOURCE_DIR}/Build/Windows/Binaries/x64/D3DCompiler_47.dll)
@@ -12,7 +11,7 @@ else()
     set (D3DCOMPILER_47_DLL ${CMAKE_SOURCE_DIR}/Build/Windows/Binaries/x86/D3DCompiler_47.dll)
 endif()
 
-add_definitions(-DATOMIC_PLATFORM_WINDOWS -D_CRT_SECURE_NO_WARNINGS -DATOMIC_TBUI)
+add_definitions(-DATOMIC_PLATFORM_WINDOWS -D_CRT_SECURE_NO_WARNINGS -DATOMIC_TBUI )
 
 list (APPEND ATOMIC_LINK_LIBRARIES MojoShader user32 gdi32 winmm imm32 ole32 oleaut32 version uuid Ws2_32)
 

+ 12 - 6
Jakefile

@@ -35,6 +35,7 @@ var iosDeployBuildFolder = artifactsFolder + "/ios-deploy";
 var webBuildFolder = artifactsFolder + "/Web_Build";
 var linuxBuildFolder = artifactsFolder + "/Linux_Build";
 var jsDocFolder = artifactsFolder + "/JSDoc";
+var atomicNETFolder = artifactsFolder + "/AtomicNET";
 
 // binaries
 
@@ -62,7 +63,8 @@ var allBuildFolders = [
   iosDeployBuildFolder,
   webBuildFolder,
   linuxBuildFolder,
-  jsDocFolder
+  jsDocFolder,
+  atomicNETFolder
 ];
 
 // packaging
@@ -217,7 +219,7 @@ namespace('build', function() {
     } else if (host == "win32") {
 
       if (deployments.windows) {
-        fs.copySync(platformBinariesFolder + "/Win32/AtomicPlayer.exe", deployRoot + "/Windows/x86/AtomicPlayer.exe");
+        fs.copySync(platformBinariesFolder + "/Win32/AtomicPlayer.exe", deployRoot + "/Windows/x64/AtomicPlayer.exe");
       }
 
     }
@@ -496,7 +498,7 @@ namespace('package', function() {
 
   });
 
-  task('windows', ['clean:all', 'build:windows'], function() {
+  task('windows', ['clean:all','build:windows'], function() {
 
     if (!fs.existsSync(distFolder)) {
       jake.mkdirP(distFolder);
@@ -508,9 +510,9 @@ namespace('package', function() {
 
     fs.copySync(windowsBuildFolder + "/Source/AtomicEditor/Release/AtomicEditor.exe", windowsPackageFolder + "/AtomicEditor.exe")
 
-    // 32 bit build for packaging!
+    // 64 bit build for packaging!
 
-    fs.copySync(jakeRoot + "/Build/Windows/Binaries/x86/D3DCompiler_47.dll", windowsPackageFolder + "/D3DCompiler_47.dll")
+    fs.copySync(jakeRoot + "/Build/Windows/Binaries/x64/D3DCompiler_47.dll", windowsPackageFolder + "/D3DCompiler_47.dll")
 
     // copy resources
 
@@ -519,8 +521,12 @@ namespace('package', function() {
     fs.copySync(jakeRoot + "/Resources/PlayerData", windowsPackageFolder + "/Resources/PlayerData");
     fs.copySync(jakeRoot + "/Data/AtomicEditor/", windowsPackageFolder + "/Resources/ToolData");
 
-    // 32 bit!
+    // AtomicNET
+    fs.copySync(jakeRoot + "/Submodules/CoreCLR/Windows/Release", windowsPackageFolder + "/Resources/AtomicNET/Windows/");
+    fs.copySync(jakeRoot + "/Artifacts/AtomicNET", windowsPackageFolder + "/Resources/AtomicNET/Windows/Atomic");
+
     fs.copySync(jakeRoot + "/Build/Windows/Binaries/x86/D3DCompiler_47.dll", windowsPackageFolder + "/Resources/ToolData/Deployment/Windows/x86/D3DCompiler_47.dll");
+    fs.copySync(jakeRoot + "/Build/Windows/Binaries/x64/D3DCompiler_47.dll", windowsPackageFolder + "/Resources/ToolData/Deployment/Windows/x64/D3DCompiler_47.dll");
 
     if (jenkinsBuild) {
 

+ 1 - 1
Resources/EditorData/AtomicEditor/editor/ui/inspectorframe.tb.txt

@@ -1,4 +1,4 @@
 TBContainer: skin: AEContainer, gravity: all, id: mainframecontainer
-	lp: min-width: 310
+	lp: min-width: 318
 	TBScrollContainer: scroll-mode: y, id: inspectorcontainerscroll, gravity: all
 		TBLayout: distribution: gravity, id: inspectorcontainer, gravity: all

+ 1 - 0
Script/AtomicEditor/main.ts

@@ -6,6 +6,7 @@
 //
 
 /// <reference path="../TypeScript/Atomic.d.ts" />
+/// <reference path="../TypeScript/AtomicNET.d.ts" />
 /// <reference path="../TypeScript/ToolCore.d.ts" />
 /// <reference path="../TypeScript/Editor.d.ts" />
 /// <reference path="../TypeScript/AtomicWork.d.ts" />

+ 2 - 0
Script/AtomicEditor/ui/EditorStrings.ts

@@ -21,6 +21,7 @@ export enum StringID {
     ShortcutCloseFile,
     ShortcutSaveFile,
     ShortcutPlay,
+    ShortcutPlayDebug,
     ShortcutBuild,
     ShortcutBuildSettings
 }
@@ -71,6 +72,7 @@ export class EditorString {
         lookup[StringID.ShortcutCloseFile] = shortcutKey + "W";
 
         lookup[StringID.ShortcutPlay] = shortcutKey + "P";
+        lookup[StringID.ShortcutPlayDebug] = "⇧" + shortcutKey + "P";
 
         lookup[StringID.ShortcutBuild] = shortcutKey + "B";
 

+ 8 - 0
Script/AtomicEditor/ui/Shortcuts.ts

@@ -26,6 +26,14 @@ class Shortcuts extends Atomic.ScriptObject {
 
     }
 
+    invokePlayDebug() {
+
+        this.sendEvent(EditorEvents.SaveAllResources);
+        Atomic.editorMode.playProjectDebug();
+
+    }
+
+
     invokeFormatCode() {
 
         var editor = EditorUI.getMainFrame().resourceframe.currentResourceEditor;

+ 68 - 0
Script/AtomicEditor/ui/frames/inspector/AssemblyInspector.ts

@@ -0,0 +1,68 @@
+//
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+// LICENSE: Atomic Game Engine Editor and Tools EULA
+// Please see LICENSE_ATOMIC_EDITOR_AND_TOOLS.md in repository root for
+// license information: https://github.com/AtomicGameEngine/AtomicGameEngine
+//
+
+import InspectorWidget = require("./InspectorWidget");
+import ArrayEditWidget = require("./ArrayEditWidget");
+import InspectorUtils = require("./InspectorUtils");
+
+class AssemblyInspector extends InspectorWidget {
+
+    constructor() {
+
+        super();
+
+        this.subscribeToEvent(this, "WidgetEvent", (data) => this.handleWidgetEvent(data));
+
+    }
+
+    handleWidgetEvent(ev: Atomic.UIWidgetEvent) {
+
+    }
+
+    inspect(asset: ToolCore.Asset) {
+
+        this.asset = asset;
+        this.importer = <ToolCore.NETAssemblyImporter> asset.importer;
+
+        // node attr layout
+        var rootLayout = this.rootLayout;
+
+        // Assembly Section
+        var assemblyLayout = this.createSection(rootLayout, "NETAssembly", 1);
+
+        var assemblyFile = <AtomicNET.CSComponentAssembly> asset.importer.getResource();
+
+        var container = InspectorUtils.createContainer();
+        container.gravity = Atomic.UI_GRAVITY_ALL;
+        assemblyLayout.addChild(container);
+
+        var panel = new Atomic.UILayout();
+        panel.axis = Atomic.UI_AXIS_Y;
+        panel.layoutSize = Atomic.UI_LAYOUT_SIZE_PREFERRED;
+        panel.layoutPosition = Atomic.UI_LAYOUT_POSITION_LEFT_TOP;
+        container.addChild(panel);
+
+        var label = InspectorUtils.createAttrName("CSComponents:");
+        panel.addChild(label);
+
+        for (var index in assemblyFile.classNames)
+        {
+            var classname = assemblyFile.classNames[index];
+
+            label = InspectorUtils.createAttrName(classname);
+            panel.addChild(label);
+        }
+
+    }
+
+
+    asset: ToolCore.Asset;
+    importer:ToolCore.NETAssemblyImporter;
+
+}
+
+export = AssemblyInspector;

+ 86 - 0
Script/AtomicEditor/ui/frames/inspector/CSComponentClassSelector.ts

@@ -0,0 +1,86 @@
+//
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+// LICENSE: Atomic Game Engine Editor and Tools EULA
+// Please see LICENSE_ATOMIC_EDITOR_AND_TOOLS.md in repository root for
+// license information: https://github.com/AtomicGameEngine/AtomicGameEngine
+//
+
+import EditorUI = require("ui/EditorUI");
+
+class CSComponentClassSelector extends Atomic.UIWindow {
+
+    constructor(editField: Atomic.UIEditField, component: AtomicNET.CSComponent) {
+
+        super();
+
+        var assemblyFile = component.assemblyFile;
+
+        this.text = "Select Class: " + assemblyFile.name;
+
+        this.rect = [0, 0, 400, 512];
+
+        var mainLayout = new Atomic.UILayout();
+        mainLayout.gravity = Atomic.UI_GRAVITY_ALL;
+        mainLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_AVAILABLE;
+        mainLayout.axis = Atomic.UI_AXIS_Y;
+        this.contentRoot.addChild(mainLayout);
+
+        // really want a grid container
+        var scrollContainer = new Atomic.UIScrollContainer();
+        scrollContainer.gravity = Atomic.UI_GRAVITY_ALL;
+        scrollContainer.scrollMode = Atomic.UI_SCROLL_MODE_Y_AUTO;
+        scrollContainer.adaptContentSize = true;
+
+        var scrollLayout = new Atomic.UILayout();
+        scrollLayout.layoutPosition = Atomic.UI_LAYOUT_POSITION_LEFT_TOP;
+        scrollLayout.layoutDistributionPosition = Atomic.UI_LAYOUT_DISTRIBUTION_POSITION_LEFT_TOP;
+        scrollLayout.axis = Atomic.UI_AXIS_Y;
+
+        scrollContainer.contentRoot.addChild(scrollLayout);
+
+        var window = this;
+
+        for (var i in assemblyFile.classNames) {
+
+            var classname = assemblyFile.classNames[i];
+            var button = new Atomic.UIButton();
+            button.text = classname;
+
+            button.onClick = function() {
+                editField.text = this.text;
+                component.componentClassName = this.text;
+                window.close();
+            }.bind(button);
+
+            scrollLayout.addChild(button);
+        }
+
+        mainLayout.addChild(scrollContainer);
+
+        EditorUI.getMainFrame().addChild(this);
+
+        this.center();
+
+        this.subscribeToEvent("WidgetEvent", (data) => this.handleWidgetEvent(data));
+
+    }
+
+    handleWidgetEvent(ev: Atomic.UIWidgetEvent) {
+
+        if (ev.type == Atomic.UI_EVENT_TYPE_CLICK) {
+
+            if (ev.target != this && !this.isAncestorOf(ev.target)) {
+
+                //this.close();
+
+            }
+
+        }
+
+        return false;
+
+    }
+
+}
+
+export = CSComponentClassSelector;

+ 217 - 69
Script/AtomicEditor/ui/frames/inspector/ComponentInspector.ts

@@ -9,6 +9,7 @@ import ScriptWidget = require("ui/ScriptWidget");
 import DataBinding = require("./DataBinding");
 import InspectorUtils = require("./InspectorUtils");
 import EditorUI = require("ui/EditorUI");
+import CSComponentClassSelector = require("./CSComponentClassSelector");
 
 class ComponentInspector extends Atomic.UISection {
 
@@ -39,6 +40,57 @@ class ComponentInspector extends Atomic.UISection {
 
     }
 
+    addAttr(attr: Atomic.AttributeInfo, before: Atomic.UIWidget = null, after: Atomic.UIWidget = null): Atomic.UILayout {
+
+        if (attr.mode & Atomic.AM_NOEDIT)
+            return null;
+
+        var binding = DataBinding.createBinding(this.component, attr);
+
+        if (!binding)
+            return null;
+
+        var attrLayout = new Atomic.UILayout();
+
+        attrLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_GRAVITY;
+
+        var name = new Atomic.UITextField();
+        name.textAlign = Atomic.UI_TEXT_ALIGN_LEFT;
+        name.skinBg = "InspectorTextAttrName";
+        name.layoutParams = this.atlp;
+
+        if (attr.type == Atomic.VAR_VECTOR3 || attr.type == Atomic.VAR_COLOR ||
+            attr.type == Atomic.VAR_QUATERNION) {
+            attrLayout.axis = Atomic.UI_AXIS_Y;
+            attrLayout.layoutPosition = Atomic.UI_LAYOUT_POSITION_LEFT_TOP;
+            attrLayout.skinBg = "InspectorVectorAttrLayout";
+        }
+
+        var bname = attr.name;
+
+        if (bname == "Is Enabled")
+            bname = "Enabled";
+
+        name.text = bname;
+        name.fontDescription = this.fd;
+
+        attrLayout.addChild(name);
+
+        attrLayout.addChild(binding.widget);
+
+        if (before)
+            this.attrsVerticalLayout.addChildBefore(attrLayout, before);
+        else if (after)
+            this.attrsVerticalLayout.addChildAfter(attrLayout, after);
+        else
+            this.attrsVerticalLayout.addChild(attrLayout);
+
+
+        this.bindings.push(binding);
+
+        return attrLayout;
+    }
+
     inspect(component: Atomic.Component) {
 
         this.component = component;
@@ -47,31 +99,41 @@ class ComponentInspector extends Atomic.UISection {
         // For JSComponents append the filename
         if (component.typeName == "JSComponent") {
 
-            var jsc = <Atomic.JSComponent> component;
+            var jsc = <Atomic.JSComponent>component;
 
             if (jsc.componentFile) {
-              var pathInfo = Atomic.splitPath( jsc.componentFile.name);
-              this.text = "JS - " + pathInfo.fileName;
+                var pathInfo = Atomic.splitPath(jsc.componentFile.name);
+                this.text = "JS - " + pathInfo.fileName;
             }
 
         }
 
+        // For CSComponents append the classname
+        if (component.typeName == "CSComponent") {
+
+            var csc = <AtomicNET.CSComponent>component;
+
+            if (csc.componentClassName) {
+                this.text = "CS - " + csc.componentClassName;
+            }
+        }
+
         // don't expand by default
         this.value = 0;
 
-        var fd = new Atomic.UIFontDescription();
+        var fd = this.fd = new Atomic.UIFontDescription();
         fd.id = "Vera";
         fd.size = 11;
 
-        var nlp = new Atomic.UILayoutParams();
+        var nlp = this.nlp = new Atomic.UILayoutParams();
         nlp.width = 304;
 
         // atttribute name layout param
-        var atlp = new Atomic.UILayoutParams();
+        var atlp = this.atlp = new Atomic.UILayoutParams();
         atlp.width = 100;
 
 
-        var attrsVerticalLayout = new Atomic.UILayout(Atomic.UI_AXIS_Y);
+        var attrsVerticalLayout = this.attrsVerticalLayout = new Atomic.UILayout(Atomic.UI_AXIS_Y);
         attrsVerticalLayout.spacing = 3;
         attrsVerticalLayout.layoutPosition = Atomic.UI_LAYOUT_POSITION_LEFT_TOP;
         attrsVerticalLayout.layoutSize = Atomic.UI_LAYOUT_SIZE_AVAILABLE;
@@ -81,49 +143,7 @@ class ComponentInspector extends Atomic.UISection {
         var attrs = component.getAttributes();
 
         for (var i in attrs) {
-
-            var attr = <Atomic.AttributeInfo> attrs[i];
-
-            if (attr.mode & Atomic.AM_NOEDIT)
-                continue;
-
-            var binding = DataBinding.createBinding(component, attr);
-
-            if (!binding)
-                continue;
-
-            var attrLayout = new Atomic.UILayout();
-
-            attrLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_GRAVITY;
-
-            var name = new Atomic.UITextField();
-            name.textAlign = Atomic.UI_TEXT_ALIGN_LEFT;
-            name.skinBg = "InspectorTextAttrName";
-            name.layoutParams = atlp;
-
-            if (attr.type == Atomic.VAR_VECTOR3 || attr.type == Atomic.VAR_COLOR ||
-                attr.type == Atomic.VAR_QUATERNION) {
-                attrLayout.axis = Atomic.UI_AXIS_Y;
-                attrLayout.layoutPosition = Atomic.UI_LAYOUT_POSITION_LEFT_TOP;
-                attrLayout.skinBg = "InspectorVectorAttrLayout";
-            }
-
-            var bname = attr.name;
-
-            if (bname == "Is Enabled")
-                bname = "Enabled";
-
-            name.text = bname;
-            name.fontDescription = fd;
-
-            attrLayout.addChild(name);
-
-            attrLayout.addChild(binding.widget);
-
-            attrsVerticalLayout.addChild(attrLayout);
-
-            this.bindings.push(binding);
-
+            this.addAttr(attrs[i]);
         }
 
         // custom component UI
@@ -145,6 +165,27 @@ class ComponentInspector extends Atomic.UISection {
             this.value = 1;
         }
 
+        if (component.typeName == "CSComponent") {
+            // auto expand CSComponents
+            this.value = 1;
+            this.addCSComponentUI(attrsVerticalLayout);
+
+            var csc = <AtomicNET.CSComponent>this.component;
+            var currentClassName = csc.componentClassName;
+
+            this.subscribeToEvent(component, "CSComponentClassChanged", (ev: AtomicNET.CSComponentClassChangedEvent) => {
+
+                if (currentClassName != ev.classname) {
+                    //console.log("CSComponent Class Name Changed ", currentClassName, " ", ev.classname);
+                    this.text = "CS - " + ev.classname;
+                    currentClassName = ev.classname;
+                    this.updateDataBindings();
+                }
+
+            });
+        }
+
+
         if (component.typeName == "TileMap2D") {
             this.addTilemap2DUI(attrsVerticalLayout);
         }
@@ -159,7 +200,7 @@ class ComponentInspector extends Atomic.UISection {
         }
 
 
-        var deleteButton = new Atomic.UIButton();
+        var deleteButton = this.deleteButton = new Atomic.UIButton();
         deleteButton.text = "Delete Component";
         deleteButton.fontDescription = fd;
 
@@ -184,6 +225,74 @@ class ComponentInspector extends Atomic.UISection {
 
     }
 
+    updateDataBindings() {
+
+        var newBindings: Array<DataBinding> = new Array();
+        var foundAttr: Array<Atomic.AttributeInfo> = new Array();
+
+        var attrs = this.component.getAttributes();
+
+        // run through current attr bindings looking for ones to preserve
+        for (var i in this.bindings) {
+
+            var binding = this.bindings[i];
+
+            for (var j in attrs) {
+
+                var attr = <Atomic.AttributeInfo>attrs[j];
+
+                if (attr.name == binding.attrInfo.name && attr.type == binding.attrInfo.type) {
+
+                    newBindings.push(binding);
+                    foundAttr.push(attr);
+                    break;
+
+                }
+
+            }
+
+        }
+
+        // remove bindings that no longer exist
+        for (var i in this.bindings) {
+
+            var binding = this.bindings[i];
+
+            if (newBindings.indexOf(binding) == -1) {
+
+                binding.widget.parent.remove();
+
+            }
+
+        }
+
+        // set new bindings, additional bindings may be added below
+        this.bindings = newBindings;
+
+        // add new attr
+        var curAttrLayout:Atomic.UILayout = null;
+        for (var i in attrs) {
+
+            var attr = attrs[i];
+
+            if (foundAttr.indexOf(attr) == -1) {
+
+                if (!curAttrLayout)
+                  curAttrLayout = this.addAttr(attr, this.deleteButton);
+                else
+                  curAttrLayout = this.addAttr(attr, null, curAttrLayout);
+
+            }
+
+        }
+
+        for (var i in this.bindings) {
+            this.bindings[i].setWidgetValueFromObject();
+            this.bindings[i].objectLocked = false;
+        }
+
+    }
+
     // Move these to a mixing class
 
     addPrefabUI(layout: Atomic.UILayout) {
@@ -196,7 +305,7 @@ class ComponentInspector extends Atomic.UISection {
 
         if (dragObject.object && dragObject.object.typeName == "Asset") {
 
-            var asset = <ToolCore.Asset> dragObject.object;
+            var asset = <ToolCore.Asset>dragObject.object;
 
             if (asset.importerTypeName == importerTypeName) {
                 return asset.importer;
@@ -220,7 +329,7 @@ class ComponentInspector extends Atomic.UISection {
 
             EditorUI.getModelOps().showResourceSelection("Select Material", "MaterialImporter", function(asset: ToolCore.Asset) {
 
-                staticModel.setMaterialIndex(index, <Atomic.Material> Atomic.cache.getResource("Material", asset.path));
+                staticModel.setMaterialIndex(index, <Atomic.Material>Atomic.cache.getResource("Material", asset.path));
 
                 if (staticModel.getMaterial())
                     materialField.text = staticModel.getMaterial().name;
@@ -248,10 +357,10 @@ class ComponentInspector extends Atomic.UISection {
 
                 if (importer) {
 
-                    var materialImporter = <ToolCore.MaterialImporter> importer;
+                    var materialImporter = <ToolCore.MaterialImporter>importer;
                     var asset = materialImporter.asset;
 
-                    var material = <Atomic.Material> Atomic.cache.getResource("Material", asset.path);
+                    var material = <Atomic.Material>Atomic.cache.getResource("Material", asset.path);
 
                     if (material) {
 
@@ -269,7 +378,7 @@ class ComponentInspector extends Atomic.UISection {
 
     addModelUI(layout: Atomic.UILayout, typeName: string) {
 
-        var staticModel = <Atomic.StaticModel> this.component;
+        var staticModel = <Atomic.StaticModel>this.component;
 
         var numGeometries = staticModel.numGeometries;
         if (typeName == "Skybox") {
@@ -288,7 +397,7 @@ class ComponentInspector extends Atomic.UISection {
 
     addSpriteUI(layout: Atomic.UILayout, typeName: string) {
 
-        var spriteComponent = <Atomic.StaticSprite2D> this.component;
+        var spriteComponent = <Atomic.StaticSprite2D>this.component;
 
         var o = InspectorUtils.createAttrEditFieldWithSelectButton("Sprite", layout);
         var field = o.editField;
@@ -302,7 +411,7 @@ class ComponentInspector extends Atomic.UISection {
             // this should allow selecting of sprite sheets as well
             EditorUI.getModelOps().showResourceSelection("Select Sprite", "TextureImporter", function(asset: ToolCore.Asset) {
 
-                spriteComponent.sprite = <Atomic.Sprite2D> Atomic.cache.getResource("Sprite2D", asset.path);
+                spriteComponent.sprite = <Atomic.Sprite2D>Atomic.cache.getResource("Sprite2D", asset.path);
                 if (spriteComponent.sprite)
                     field.text = spriteComponent.sprite.name;
 
@@ -319,9 +428,9 @@ class ComponentInspector extends Atomic.UISection {
 
                 if (importer) {
 
-                  spriteComponent.sprite = <Atomic.Sprite2D> Atomic.cache.getResource("Sprite2D", importer.asset.path);
-                  if (spriteComponent.sprite)
-                      field.text = spriteComponent.sprite.name;
+                    spriteComponent.sprite = <Atomic.Sprite2D>Atomic.cache.getResource("Sprite2D", importer.asset.path);
+                    if (spriteComponent.sprite)
+                        field.text = spriteComponent.sprite.name;
 
                 }
             }
@@ -333,7 +442,7 @@ class ComponentInspector extends Atomic.UISection {
 
     addTilemap2DUI(layout: Atomic.UILayout) {
 
-        var tilemap = <Atomic.TileMap2D> this.component;
+        var tilemap = <Atomic.TileMap2D>this.component;
 
         var o = InspectorUtils.createAttrEditFieldWithSelectButton("TMX File", layout);
         var field = o.editField;
@@ -347,7 +456,7 @@ class ComponentInspector extends Atomic.UISection {
             // this should allow selecting of sprite sheets as well
             EditorUI.getModelOps().showResourceSelection("Select TMX File", "TMXImporter", function(asset: ToolCore.Asset) {
 
-                tilemap.tmxFile = <Atomic.TmxFile2D> Atomic.cache.getResource("TmxFile2D", asset.path);
+                tilemap.tmxFile = <Atomic.TmxFile2D>Atomic.cache.getResource("TmxFile2D", asset.path);
                 if (tilemap.tmxFile)
                     field.text = tilemap.tmxFile.name;
             });
@@ -363,9 +472,9 @@ class ComponentInspector extends Atomic.UISection {
 
                 if (importer) {
 
-                  tilemap.tmxFile = <Atomic.TmxFile2D> Atomic.cache.getResource("TmxFile2D", importer.asset.path);
-                  if (tilemap.tmxFile)
-                      field.text = tilemap.tmxFile.name;
+                    tilemap.tmxFile = <Atomic.TmxFile2D>Atomic.cache.getResource("TmxFile2D", importer.asset.path);
+                    if (tilemap.tmxFile)
+                        field.text = tilemap.tmxFile.name;
 
                 }
             }
@@ -376,7 +485,7 @@ class ComponentInspector extends Atomic.UISection {
 
     addLightCascadeParametersUI(layout: Atomic.UILayout) {
 
-        var light = <Atomic.Light> this.component;
+        var light = <Atomic.Light>this.component;
 
         var cascadeInfo = light.getShadowCascade();
 
@@ -428,7 +537,7 @@ class ComponentInspector extends Atomic.UISection {
 
     addCollisionShapeUI(layout: Atomic.UILayout) {
 
-        var shape = <Atomic.CollisionShape> this.component;
+        var shape = <Atomic.CollisionShape>this.component;
 
         var button = new Atomic.UIButton();
         button.fontDescription = InspectorUtils.attrFontDesc;
@@ -437,7 +546,7 @@ class ComponentInspector extends Atomic.UISection {
 
         button.onClick = () => {
 
-            var model = <Atomic.Drawable> shape.node.getComponent("StaticModel");
+            var model = <Atomic.Drawable>shape.node.getComponent("StaticModel");
             if (model) {
                 var box = model.boundingBox;
                 shape.setBox([box[3] - box[0], box[4] - box[1], box[5] - box[2]]);
@@ -449,10 +558,49 @@ class ComponentInspector extends Atomic.UISection {
 
     }
 
+    addCSComponentUI(layout: Atomic.UILayout) {
+
+        for (var i in this.bindings) {
+
+            var binding = this.bindings[i];
+
+            // replace the Class widget with a editfield + select button
+            if (binding.attrInfo.name == "Class") {
+
+                var parent = binding.widget.parent;
+                var text = binding.widget.text;
+                binding.widget.parent.removeChild(binding.widget);
+                var o = InspectorUtils.createAttrEditFieldWithSelectButton("", parent);
+                o.editField.text = text;
+                binding.widget = o.editField;
+
+                o.selectButton.onClick = () => {
+
+                    var cscomponent = <AtomicNET.CSComponent>this.component;
+                    if (cscomponent.assemblyFile) {
+                        var selector = new CSComponentClassSelector(o.editField, cscomponent);
+                    }
+                }
+
+                break;
+            }
+        }
+    }
 
     component: Atomic.Component;
     bindings: Array<DataBinding> = new Array();
 
+    fd: Atomic.UIFontDescription;
+
+    nlp: Atomic.UILayoutParams;
+
+    // atttribute name layout param
+    atlp: Atomic.UILayoutParams;
+
+    attrsVerticalLayout: Atomic.UILayout;
+
+    deleteButton: Atomic.UIButton;
+
 
 }
 

+ 1 - 0
Script/AtomicEditor/ui/frames/inspector/CreateComponentButton.ts

@@ -42,6 +42,7 @@ geometryCreateSource.addItem(new Atomic.UIMenuItem("Water", "create component"))
 var logicCreateSource = new Atomic.UIMenuItemSource();
 
 logicCreateSource.addItem(new Atomic.UIMenuItem("JSComponent", "JSComponent"));
+logicCreateSource.addItem(new Atomic.UIMenuItem("CSComponent", "CSComponent"));
 logicCreateSource.addItem(new Atomic.UIMenuItem("AnimationController", "create component"));
 logicCreateSource.addItem(new Atomic.UIMenuItem("SplinePath", "create component"));
 

+ 10 - 1
Script/AtomicEditor/ui/frames/inspector/InspectorFrame.ts

@@ -14,6 +14,7 @@ import DataBinding = require("./DataBinding");
 import MaterialInspector = require("./MaterialInspector");
 import ModelInspector = require("./ModelInspector");
 import NodeInspector = require("./NodeInspector");
+import AssemblyInspector = require("./AssemblyInspector");
 
 class InspectorFrame extends ScriptWidget {
 
@@ -96,7 +97,6 @@ class InspectorFrame extends ScriptWidget {
 
             inspector.inspect(asset);
 
-
         }
 
         if (asset.importerTypeName == "MaterialImporter") {
@@ -113,9 +113,18 @@ class InspectorFrame extends ScriptWidget {
             container.addChild(materialInspector);
 
             materialInspector.inspect(asset, material);
+        }
+
+        if (asset.importerTypeName == "NETAssemblyImporter") {
+
+            var assemblyInspector = new AssemblyInspector();
+            container.addChild(assemblyInspector);
+
+            assemblyInspector.inspect(asset);
 
         }
 
+
     }
 
     handleNodeRemoved(ev: Atomic.NodeRemovedEvent) {

+ 7 - 1
Script/AtomicEditor/ui/frames/menus/MainFrameMenu.ts

@@ -58,6 +58,11 @@ class MainFrameMenu extends Atomic.ScriptObject {
                 return true;
             }
 
+            if (refid == "edit play debug") {
+                EditorUI.getShortcuts().invokePlayDebug();
+                return true;
+            }
+
             if (refid == "edit format code") {
                 EditorUI.getShortcuts().invokeFormatCode();
                 return true;
@@ -244,7 +249,8 @@ var editItems = {
     "-3": null,
     "Format Code": ["edit format code", StringID.ShortcutBeautify],
     "-4": null,
-    "Play": ["edit play", StringID.ShortcutPlay]
+    "Play": ["edit play", StringID.ShortcutPlay],
+    "Debug (C# Project)": ["edit play debug", StringID.ShortcutPlayDebug]
 
 };
 

+ 77 - 0
Script/AtomicNET/AtomicNET/AtomicNETBootstrap/AssemblyLoaderCache.cs

@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace Atomic.Bootstrap
+{
+    internal class AssemblyLoaderCache
+    {
+        private readonly ConcurrentDictionary<AssemblyName, object> _assemblyLoadLocks = new ConcurrentDictionary<AssemblyName, object>(AssemblyNameComparer.Ordinal);
+        private readonly ConcurrentDictionary<AssemblyName, Assembly> _assemblyCache = new ConcurrentDictionary<AssemblyName, Assembly>(AssemblyNameComparer.Ordinal);
+
+        public Assembly GetOrAdd(AssemblyName name, Func<AssemblyName, Assembly> factory)
+        {
+            // If the assembly was already loaded use it
+            Assembly assembly;
+            if (_assemblyCache.TryGetValue(name, out assembly))
+            {
+                return assembly;
+            }
+
+            var loadLock = _assemblyLoadLocks.GetOrAdd(name, new object());
+
+            try
+            {
+                // Concurrently loading the assembly might result in two distinct instances of the same assembly
+                // being loaded. This was observed when loading via Assembly.LoadStream. Prevent this by locking on the name.
+                lock (loadLock)
+                {
+                    if (_assemblyCache.TryGetValue(name, out assembly))
+                    {
+                        // This would succeed in case the thread was previously waiting on the lock when assembly
+                        // load was in progress
+                        return assembly;
+                    }
+
+                    assembly = factory(name);
+
+                    if (assembly != null)
+                    {
+                        _assemblyCache[name] = assembly;
+                    }
+                }
+            }
+            finally
+            {
+                _assemblyLoadLocks.TryRemove(name, out loadLock);
+            }
+
+            return assembly;
+        }
+
+        private class AssemblyNameComparer : IEqualityComparer<AssemblyName>
+        {
+            public static IEqualityComparer<AssemblyName> Ordinal = new AssemblyNameComparer();
+
+            public bool Equals(AssemblyName x, AssemblyName y)
+            {
+                return
+                    string.Equals(x.Name, y.Name, StringComparison.Ordinal) &&
+                    string.Equals(x.CultureName ?? "", y.CultureName ?? "", StringComparison.Ordinal);
+            }
+
+            public int GetHashCode(AssemblyName obj)
+            {
+                var hashCode = 0;
+                if (obj.Name != null)
+                {
+                    hashCode ^= obj.Name.GetHashCode();
+                }
+
+                hashCode ^= (obj.CultureName ?? "").GetHashCode();
+                return hashCode;
+            }
+        }
+    }
+}

+ 91 - 0
Script/AtomicNET/AtomicNET/AtomicNETBootstrap/Bootstrap.cs

@@ -0,0 +1,91 @@
+
+using System;
+using System.Linq;
+using System.Reflection;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Runtime.Loader;
+
+namespace Atomic.Bootstrap
+{
+
+// This must be in TPA list
+public class AtomicLoadContext : LoadContext
+{
+
+    static List<string> assemblyLoadPaths = new List<string>();
+
+    public static void Startup(string _assemblyLoadPaths)
+    {
+      LoadContext.InitializeDefaultContext(new AtomicLoadContext());
+      assemblyLoadPaths = _assemblyLoadPaths.Split(';').ToList();
+      //Console.WriteLine("Bootstrap Startup paths: {0}", _assemblyLoadPaths);
+    }
+
+    public static void AddAssemblyLoadPath(string path)
+    {
+      assemblyLoadPaths.Add(path);
+    }
+
+    [DllImport("kernel32.dll")]
+    public static extern IntPtr GetModuleHandle(string lpModuleName);
+
+    [DllImport("dl")]
+    protected static extern IntPtr dlopen(string filename, int flags);
+
+    protected override IntPtr LoadUnmanagedDll(String unmanagedDllName)
+    {
+
+      /*
+      if (unmanagedDllName == "__Internal")
+      {
+        IntPtr result = GetModuleHandle(null);
+        return result;
+      }
+
+      // do we need to walk paths here?
+      Console.WriteLine("LoadUnmanagedDll: " + unmanagedDllName);
+      return GetModuleHandle(unmanagedDllName); //RTLD_LAZY
+      */
+
+
+      if (unmanagedDllName == "__Internal")
+      {
+        IntPtr result = dlopen(null, 1); //RTLD_LAZY
+        return result;
+      }
+
+      // do we need to walk paths here?
+      Console.WriteLine("LoadUnmanagedDll: " + unmanagedDllName);
+      return dlopen(unmanagedDllName, 1 ); //RTLD_LAZY
+
+    }
+
+    public override Assembly LoadAssembly(AssemblyName assemblyName)
+    {
+
+      Assembly assembly = null;
+
+      foreach (var path in assemblyLoadPaths)
+      {
+        try
+        {
+            //Console.WriteLine("Assembly Load Attempt: {0}", path + assemblyName.Name + ".dll");
+            assembly = LoadFromAssemblyPath(path + assemblyName.Name + ".dll");
+            break;
+        }
+        catch //(Exception e)
+        {
+          //Console.WriteLine(e.Message);
+        }
+
+      }
+
+      return assembly;
+
+    }
+
+
+}
+
+}

+ 34 - 0
Script/AtomicNET/AtomicNET/AtomicNETBootstrap/IAssemblyLoadContext.cs

@@ -0,0 +1,34 @@
+using System;
+using System.IO;
+using System.Reflection;
+
+namespace Atomic.Bootstrap
+{
+    /// <summary>
+    /// A context in which assemblies can be loaded.
+    /// </summary>
+    public interface IAssemblyLoadContext : IDisposable
+    {
+        /// <summary>
+        /// Load an assembly by name.
+        /// </summary>
+        /// <param name="assemblyName">The name of the assembly.</param>
+        /// <returns>The loaded assembly.</returns>
+        Assembly Load(AssemblyName assemblyName);
+
+        /// <summary>
+        /// Loads the assembly located at the provided file system path.
+        /// </summary>
+        /// <param name="path">The fully qualified path of the file to load.</param>
+        /// <returns>The loaded assembly.</returns>
+        Assembly LoadFile(string path);
+
+        /// <summary>
+        /// Loads the assembly with a common object file format (COFF)-based image containing an emitted assembly, optionally including symbols for the assembly.
+        /// </summary>
+        /// <param name="assemblyStream">The stream representing the assembly.</param>
+        /// <param name="assemblySymbols">The stream representing the symbols.</param>
+        /// <returns>The loaded assembly.</returns>
+        Assembly LoadStream(Stream assemblyStream, Stream assemblySymbols);
+    }
+}

+ 98 - 0
Script/AtomicNET/AtomicNET/AtomicNETBootstrap/LoadContext.cs

@@ -0,0 +1,98 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Threading;
+//#if DNXCORE50
+using System.Runtime.Loader;
+//#endif
+
+namespace Atomic.Bootstrap
+{
+    public abstract class LoadContext : AssemblyLoadContext, IAssemblyLoadContext
+    {
+        private readonly AssemblyLoaderCache _cache = new AssemblyLoaderCache();
+        //private readonly string _friendlyName;
+
+        public LoadContext()
+        {
+        }
+
+        public LoadContext(string friendlyName)
+        {
+            //_friendlyName = friendlyName;
+        }
+
+        protected override Assembly Load(AssemblyName assemblyName)
+        {
+            return _cache.GetOrAdd(assemblyName, LoadAssembly);
+        }
+
+        Assembly IAssemblyLoadContext.Load(AssemblyName assemblyName)
+        {
+            return LoadFromAssemblyName(assemblyName);
+        }
+
+        public abstract Assembly LoadAssembly(AssemblyName assemblyName);
+
+        public Assembly LoadFile(string path)
+        {
+            // Look for platform specific native image
+            string nativeImagePath = GetNativeImagePath(path);
+
+            if (nativeImagePath != null)
+            {
+                return LoadFromNativeImagePath(nativeImagePath, path);
+            }
+
+            return LoadFromAssemblyPath(path);
+        }
+
+        public Assembly LoadStream(Stream assembly, Stream assemblySymbols)
+        {
+            if (assemblySymbols == null)
+            {
+                return LoadFromStream(assembly);
+            }
+
+            return LoadFromStream(assembly, assemblySymbols);
+        }
+
+        public static void InitializeDefaultContext(LoadContext loadContext)
+        {
+            AssemblyLoadContext.InitializeDefaultContext(loadContext);
+        }
+
+        private string GetNativeImagePath(string ilPath)
+        {
+            var directory = Path.GetDirectoryName(ilPath);
+            var arch = IntPtr.Size == 4 ? "x86" : "AMD64";
+
+            var nativeImageName = Path.GetFileNameWithoutExtension(ilPath) + ".ni.dll";
+            var nativePath = Path.Combine(directory, arch, nativeImageName);
+
+            if (File.Exists(nativePath))
+            {
+                return nativePath;
+            }
+            else
+            {
+                // Runtime is arch sensitive so the ni is in the same folder as IL
+                nativePath = Path.Combine(directory, nativeImageName);
+                if (File.Exists(nativePath))
+                {
+                    return nativePath;
+                }
+            }
+
+            return null;
+        }
+
+        public virtual void Dispose()
+        {
+
+        }
+    }
+
+}

+ 96 - 0
Script/AtomicNET/AtomicNET/AtomicNETEngine/AtomicNET.cs

@@ -0,0 +1,96 @@
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace AtomicEngine
+{
+
+public static class Atomic
+{
+
+  static public void Initialize()
+  {
+    ContainerModule.Initialize ();
+    CoreModule.Initialize ();
+    MathModule.Initialize ();
+    EngineModule.Initialize ();
+    InputModule.Initialize ();
+    IOModule.Initialize ();
+    ResourceModule.Initialize ();
+    AudioModule.Initialize ();
+    GraphicsModule.Initialize ();
+    SceneModule.Initialize ();
+    Atomic2DModule.Initialize ();
+    Atomic3DModule.Initialize ();
+    NavigationModule.Initialize ();
+    NetworkModule.Initialize ();
+    PhysicsModule.Initialize ();
+    EnvironmentModule.Initialize ();
+    UIModule.Initialize ();
+    NETCoreModule.Initialize();
+    NETScriptModule.Initialize();
+    AtomicPlayer.PlayerModule.Initialize ();
+  }
+
+  static public void Start()
+  {
+    initSubsystems();
+  }
+
+  static public void ExecMainAssembly()
+  {
+      Assembly assembly = null;
+
+      try
+      {
+        assembly = Assembly.Load("Main");
+      }
+      catch (Exception e)
+      {
+          Console.WriteLine("Failed to exec main assembly {0}", e.Message );
+          return;
+      }
+
+      if (assembly == null)
+        return;
+
+      // a project assembly may define an AtomicMain which will be run
+      foreach (var type in assembly.GetTypes())
+      {
+        MethodInfo main = type.GetMethod("Main", BindingFlags.Public | BindingFlags.Static);
+
+        if (main == null || main.GetParameters().Length != 0)
+          continue;
+
+        main.Invoke(null, null);
+
+      }
+  }
+
+  static Dictionary<Type, RefCounted> subSystems = new Dictionary<Type, RefCounted>();
+
+  static private void registerSubsystem (RefCounted subsystem)
+  {
+    subSystems[subsystem.GetType()] = subsystem;
+  }
+
+  static public T GetSubsystem<T>() where T : RefCounted
+  {
+    return (T) subSystems [typeof(T)];
+  }
+
+  static private void initSubsystems()
+  {
+    registerSubsystem (NativeCore.WrapNative<Graphics> (csb_AtomicEngine_GetSubsystem("Graphics")));
+    registerSubsystem (NativeCore.WrapNative<Renderer> (csb_AtomicEngine_GetSubsystem("Renderer")));
+    registerSubsystem (NativeCore.WrapNative<ResourceCache> (csb_AtomicEngine_GetSubsystem("ResourceCache")));
+  }
+
+  [DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+  private static extern IntPtr csb_AtomicEngine_GetSubsystem(string name);
+
+}
+				
+
+}

+ 27 - 0
Script/AtomicNET/AtomicNET/AtomicNETEngine/CSComponent.cs

@@ -0,0 +1,27 @@
+
+
+namespace AtomicEngine
+{
+
+	public partial class CSComponent : ScriptComponent
+	{
+		public virtual void Start()
+		{
+
+		}
+
+
+		public virtual void Update(float timeStep)
+		{
+
+		}
+
+		internal void StartInternal()
+		{
+			ApplyFieldValues();
+			Start();
+		}
+			
+	}
+
+}

+ 163 - 0
Script/AtomicNET/AtomicNET/AtomicNETEngine/ComponentCore.cs

@@ -0,0 +1,163 @@
+using System;
+using System.Reflection;
+using System.Collections.Generic;
+using System.Runtime.Loader;
+using System.Runtime.InteropServices;
+using System.Linq;
+
+namespace AtomicEngine
+{
+
+  public static class ComponentCore
+  {
+
+    static List<CSComponent> startQueue = new List<CSComponent>();
+
+    // holds a reference
+    static Dictionary<IntPtr, CSComponent> liveComponents = new Dictionary<IntPtr, CSComponent>();
+
+    public static void Update (float timeStep)
+    {
+
+      List<CSComponent> _startQueue = new List<CSComponent>(startQueue);
+      startQueue.Clear();
+
+      foreach (var c in _startQueue)
+      {
+        c.StartInternal();
+      }
+
+      foreach (var c in liveComponents.Values)
+      {
+        c.Update(timeStep);
+      }
+    }
+
+    // This will need to be optimized
+    public static void CSComponentApplyFields(IntPtr componentPtr, IntPtr fieldMapPtr)
+    {
+      NETVariantMap fieldMap = NativeCore.WrapNative<NETVariantMap>(fieldMapPtr);;
+      CSComponent component = NativeCore.WrapNative<CSComponent>(componentPtr);;
+
+      if (fieldMap == null || component == null)
+      return;
+
+      FieldInfo[] fields = componentClassFields[component.GetType()];
+
+      foreach (var field in fields)
+      {
+        if (fieldMap.Contains(field.Name))
+        {
+          //Console.WriteLine("Applying: {0} {1}", field.Name, field.FieldType.Name);
+
+          var fieldType = field.FieldType;
+
+          if (fieldType.IsEnum)
+          {
+            field.SetValue(component, fieldMap.GetInt(field.Name));
+            continue;
+          }
+
+          switch (Type.GetTypeCode(fieldType))
+          {
+            case TypeCode.Boolean:
+            field.SetValue(component, fieldMap.GetBool(field.Name));
+            break;
+
+            case TypeCode.Int32:
+            field.SetValue(component, fieldMap.GetInt(field.Name));
+            break;
+
+            case TypeCode.Single:
+            field.SetValue(component, fieldMap.GetFloat(field.Name));
+            break;
+
+            case TypeCode.String:
+            field.SetValue(component, fieldMap.GetString(field.Name));
+            break;
+
+            default:
+
+            if (fieldType == typeof(Vector3))
+            {
+              field.SetValue(component, fieldMap.GetVector3(field.Name));
+            }
+            else if (fieldType == typeof(Quaternion))
+            {
+              field.SetValue(component, fieldMap.GetQuaternion(field.Name));
+            }
+            else if (fieldType.IsSubclassOf(typeof(Resource)))
+            {
+              field.SetValue(component, fieldMap.GetResourceFromRef(field.Name));
+            }
+            else if (fieldType.IsSubclassOf(typeof(RefCounted)))
+            {
+              field.SetValue(component, fieldMap.GetPtr(field.Name));
+            }
+
+            break;
+          }
+        }
+      }
+    }
+
+    static Dictionary<Type, FieldInfo[] > componentClassFields = new Dictionary<Type, FieldInfo[]>();
+
+    static Dictionary<string, Dictionary<string, Type>> componentTypeLookup = new Dictionary<string, Dictionary<string, Type>>();
+
+    public static IntPtr CSComponentCreate(string assemblyName, string classTypeName)
+    {
+
+      Assembly assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(assemblyName));
+
+      string classNamespace = "";
+      if (!componentTypeLookup.ContainsKey(assemblyName))
+      {
+        componentTypeLookup[assemblyName] = new Dictionary<string, Type>();
+      }
+
+      var lookup = componentTypeLookup[assemblyName];
+
+      Type type = null;
+
+      if (!lookup.TryGetValue(classTypeName, out type))
+      {
+        var types = assembly.GetTypes();
+        foreach (var atype in types)
+        {
+          if (atype.Name == classTypeName)
+          {
+            lookup[classTypeName] = atype;
+            type = atype;
+            break;
+          }
+        }
+      }
+
+      if (type == null)
+      return IntPtr.Zero;
+
+      // TODO: check type is derived from CSComponent
+
+      var component = (CSComponent) Activator.CreateInstance(type);
+
+      if (!componentClassFields.ContainsKey(type))
+      {
+        var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
+        .Where(field => field.IsDefined(typeof(InspectorAttribute), true));
+
+        componentClassFields[type] = fields.ToArray<FieldInfo>();
+
+      }
+
+      startQueue.Add(component);
+
+      liveComponents[component.nativeInstance] = component;
+
+      return component.nativeInstance;
+
+    }
+
+  }
+
+}

+ 14 - 0
Script/AtomicNET/AtomicNET/AtomicNETEngine/Constants.cs

@@ -0,0 +1,14 @@
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace AtomicEngine
+{
+
+	public static partial class Constants
+	{
+		public const string LIBNAME = "__Internal";
+	}
+
+}

+ 20 - 0
Script/AtomicNET/AtomicNET/AtomicNETEngine/InspectorAttribute.cs

@@ -0,0 +1,20 @@
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace AtomicEngine
+{
+
+
+	public class InspectorAttribute : Attribute
+	{
+		public InspectorAttribute(string DefaultValue = "")
+		{
+		}
+
+		public string DefaultValue;
+	}
+
+
+}

+ 146 - 0
Script/AtomicNET/AtomicNET/AtomicNETEngine/Math.cs

@@ -0,0 +1,146 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace AtomicEngine
+{
+	[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct Vector3
+	{
+		public Vector3 (float x, float y, float z)
+		{
+			this.x = x;
+			this.y = y;
+			this.z = z;
+		}
+
+		public override string ToString()
+		{
+			return x + ", " + y + ", " + z;
+		}
+
+		public float x;
+		public float y;
+		public float z;
+
+
+		/// Zero vector.
+		static public readonly Vector3 Zero = new Vector3(0, 0, 0);
+		/// (-1,0,0) vector.
+		static public readonly Vector3 Left = new Vector3(-1, 0, 0);
+		/// (1,0,0) vector.
+		static public readonly Vector3 Right = new Vector3(1, 0, 0);
+		/// (0,1,0) vector.
+		static public readonly Vector3 Up = new Vector3(0, 1, 0);
+		/// (0,-1,0) vector.
+		static public readonly Vector3 Down = new Vector3(0, -1, 0);
+		/// (0,0,1) vector.
+		static public readonly Vector3 Forward = new Vector3(0, 0, 1);
+		/// (0,0,-1) vector.
+		static public readonly Vector3 Back = new Vector3(0, 0, -1);
+		/// (1,1,1) vector.
+		static public readonly Vector3 One = new Vector3(1, 1, 1);
+
+	}
+
+	[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct Vector4
+	{
+	}
+
+	[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct Vector2
+	{
+		public Vector2 (float x, float y)
+		{
+			this.x = x;
+			this.y = y;
+		}
+
+		public float x;
+		public float y;
+
+	}
+
+	[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct Quaternion
+	{
+		public Quaternion (float w = 1.0f, float x = 0.0f, float y = 0.0f, float z = 0.0f)
+		{
+			this.w = w;
+			this.x = x;
+			this.y = y;
+			this.z = z;
+		}
+
+		public override string ToString()
+		{
+			return x + ", " + y + ", " + z;
+		}
+
+		public float w;
+		public float x;
+		public float y;
+		public float z;
+
+		static public readonly Quaternion Identity = new Quaternion();
+
+	}
+
+	[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct Color
+	{
+		public Color (float r, float g, float b, float a = 1.0f)
+		{
+			this.r = r;
+			this.g = g;
+			this.b = b;
+			this.a = a;
+		}
+
+		public float r;
+		public float g;
+		public float b;
+		public float a;
+
+	}
+
+	[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct IntRect
+	{
+		/// Left coordinate.
+    int left;
+    /// Top coordinate.
+    int top;
+    /// Right coordinate.
+    int right;
+    /// Bottom coordinate.
+    int bottom;
+
+	}
+
+	[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct IntVector2
+	{
+		public int x;
+		public int y;
+
+		public IntVector2 (int x, int y)
+		{
+			this.x = x;
+			this.y = y;
+		}
+
+
+		static public readonly IntVector2 Zero = new IntVector2(0, 0);
+
+	}
+
+	[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct BoundingBox
+	{
+	}
+
+	[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct Rect
+	{
+	}}

+ 147 - 0
Script/AtomicNET/AtomicNET/AtomicNETEngine/NativeCore.cs

@@ -0,0 +1,147 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace AtomicEngine
+{
+
+  static class NativeCore
+  {
+    [DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+    private static extern void csb_AtomicEngine_ReleaseRef (IntPtr refCounted);
+
+    // given an existing instance classID, construct the managed instance, with downcast support (ask for Component, get StaticModel for example)
+    public static Dictionary<IntPtr, Func<IntPtr, RefCounted>> nativeClassIDToManagedConstructor = new Dictionary<IntPtr, Func<IntPtr, RefCounted>>();
+
+    // weak references here, hold a ref native side
+    public static Dictionary<IntPtr, WeakReference> nativeLookup = new Dictionary<IntPtr, WeakReference> ();
+
+    // native engine types, instances of these types can be trivially recreated managed side
+    private static Dictionary<Type, Type> nativeTypes = new Dictionary<Type, Type> ();
+
+    public static bool GetNativeType (Type type)
+    {
+      return nativeTypes.ContainsKey (type);
+    }
+
+    public static void RegisterNativeType (Type type)
+    {
+      nativeTypes.Add (type, type);
+    }
+
+    public static void ReleaseExpiredNativeReferences()
+    {
+      List<IntPtr> released = null;
+
+      foreach(KeyValuePair<IntPtr, WeakReference> entry in nativeLookup)
+      {
+
+        if (entry.Value.Target == null || !entry.Value.IsAlive)
+        {
+          if (released == null)
+            released = new List<IntPtr> ();
+
+          released.Add (entry.Key);
+        }
+
+      }
+
+      if (released == null)
+        return;
+
+      foreach (IntPtr native in released) {
+        nativeLookup.Remove (native);
+        csb_AtomicEngine_ReleaseRef(native);
+        //Console.WriteLine("Released: " + test);
+      }
+
+    }
+
+    static IntPtr test = IntPtr.Zero;
+
+    // called by native code
+    public static void NETUpdate (float timeStep)
+    {
+
+      GC.Collect();
+      GC.WaitForPendingFinalizers();
+      GC.Collect();
+      ReleaseExpiredNativeReferences();
+
+      ComponentCore.Update(timeStep);
+
+    }
+
+    // called by native code for every refcounted deleted
+    public static void RefCountedDeleted (IntPtr native)
+    {
+      // native side deleted, immediate remove, if we have a script reference still this is an error
+
+      WeakReference w;
+
+      if (nativeLookup.TryGetValue (native, out w)) {
+
+          if ( w != null && w.IsAlive) {
+            throw new System.InvalidOperationException("Native Refcounted was deleted with live managed instance");
+          }
+      }
+
+      nativeLookup.Remove(native);
+    }
+
+    // register a newly created native
+    public static IntPtr RegisterNative (IntPtr native, RefCounted r)
+    {
+      r.nativeInstance = native;
+
+      var w = new WeakReference (r);
+      NativeCore.nativeLookup [native] = w;
+      // keep native side alive
+      r.AddRef();
+
+      return native;
+    }
+
+    // wraps an existing native instance, with downcast support
+    public static T WrapNative<T> (IntPtr native) where T:RefCounted
+    {
+      if (native == IntPtr.Zero)
+        return null;
+
+      WeakReference w;
+
+      // first see if we're already available
+      if (nativeLookup.TryGetValue (native, out w)) {
+
+        if (w.IsAlive) {
+
+          // we're alive!
+          return (T)w.Target;
+
+        } else {
+
+          // we were seen before, but have since been GC'd, remove!
+          nativeLookup.Remove (native);
+          csb_AtomicEngine_ReleaseRef(native);
+        }
+      }
+
+      IntPtr classID = RefCounted.csb_Atomic_RefCounted_GetClassID (native);
+
+      // and store, with downcast support for instance Component -> StaticModel
+      // we never want to hit this path for script inherited natives
+
+      RefCounted r = nativeClassIDToManagedConstructor[classID](native);
+      w = new WeakReference (r);
+      NativeCore.nativeLookup [native] = w;
+
+      // store a ref, so native side will not be released while we still have a reference in managed code
+      r.AddRef();
+
+      return (T) r;
+
+    }
+
+  }
+
+}

+ 30 - 0
Script/AtomicNET/AtomicNET/AtomicNETEngine/RefCounted.cs

@@ -0,0 +1,30 @@
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace AtomicEngine
+{
+
+	public partial class RefCounted
+	{
+
+		public RefCounted ()
+		{
+		}
+
+		protected RefCounted (IntPtr native)
+		{
+			nativeInstance = native;
+		}
+
+		public IntPtr nativeInstance = IntPtr.Zero;
+
+		[DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		public static extern IntPtr csb_Atomic_RefCounted_GetClassID (IntPtr self);
+
+	}
+
+
+}

+ 635 - 0
Script/AtomicNET/AtomicNET/AtomicNETEngine/SDLConsts.cs

@@ -0,0 +1,635 @@
+#region License
+/* SDL2# - C# Wrapper for SDL2
+ *
+ * Copyright (c) 2013-2015 Ethan Lee.
+ *
+ * This software is provided 'as-is', without any express or implied warranty.
+ * In no event will the authors be held liable for any damages arising from
+ * the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software in a
+ * product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ * Ethan "flibitijibibo" Lee <[email protected]>
+ *
+ */
+#endregion
+
+namespace AtomicEngine
+{
+
+	public static class SDL
+	{
+
+
+		public const int SDL_BUTTON_LEFT =	1;
+		public const int SDL_BUTTON_MIDDLE =	2;
+		public const int SDL_BUTTON_RIGHT =	3;
+		public const int SDL_BUTTON_X1 =	4;
+		public const int SDL_BUTTON_X2 =	5;
+		public const int SDL_BUTTON_LMASK =	(1 << ((int)SDL_BUTTON_LEFT - 1));
+		public const int SDL_BUTTON_MMASK =	(1 << ((int)SDL_BUTTON_MIDDLE - 1));
+		public const int SDL_BUTTON_RMASK =	(1 << ((int)SDL_BUTTON_RIGHT - 1));
+		public const int SDL_BUTTON_X1MASK = (1 << ((int)SDL_BUTTON_X1 - 1));
+		public const int SDL_BUTTON_X2MASK = (1 << ((int)SDL_BUTTON_X2 - 1));
+
+		public const byte SDL_HAT_CENTERED =	0x00;
+		public const byte SDL_HAT_UP =		0x01;
+		public const byte SDL_HAT_RIGHT =	0x02;
+		public const byte SDL_HAT_DOWN =	0x04;
+		public const byte SDL_HAT_LEFT =	0x08;
+		public const byte SDL_HAT_RIGHTUP =	SDL_HAT_RIGHT | SDL_HAT_UP;
+		public const byte SDL_HAT_RIGHTDOWN =	SDL_HAT_RIGHT | SDL_HAT_DOWN;
+		public const byte SDL_HAT_LEFTUP =	SDL_HAT_LEFT | SDL_HAT_UP;
+		public const byte SDL_HAT_LEFTDOWN =	SDL_HAT_LEFT | SDL_HAT_DOWN;
+
+		public enum SDL_GameControllerButton
+		{
+			SDL_CONTROLLER_BUTTON_INVALID = -1,
+			SDL_CONTROLLER_BUTTON_A,
+			SDL_CONTROLLER_BUTTON_B,
+			SDL_CONTROLLER_BUTTON_X,
+			SDL_CONTROLLER_BUTTON_Y,
+			SDL_CONTROLLER_BUTTON_BACK,
+			SDL_CONTROLLER_BUTTON_GUIDE,
+			SDL_CONTROLLER_BUTTON_START,
+			SDL_CONTROLLER_BUTTON_LEFTSTICK,
+			SDL_CONTROLLER_BUTTON_RIGHTSTICK,
+			SDL_CONTROLLER_BUTTON_LEFTSHOULDER,
+			SDL_CONTROLLER_BUTTON_RIGHTSHOULDER,
+			SDL_CONTROLLER_BUTTON_DPAD_UP,
+			SDL_CONTROLLER_BUTTON_DPAD_DOWN,
+			SDL_CONTROLLER_BUTTON_DPAD_LEFT,
+			SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
+			SDL_CONTROLLER_BUTTON_MAX,
+		}
+
+		public enum SDL_GameControllerAxis
+		{
+			SDL_CONTROLLER_AXIS_INVALID = -1,
+			SDL_CONTROLLER_AXIS_LEFTX,
+			SDL_CONTROLLER_AXIS_LEFTY,
+			SDL_CONTROLLER_AXIS_RIGHTX,
+			SDL_CONTROLLER_AXIS_RIGHTY,
+			SDL_CONTROLLER_AXIS_TRIGGERLEFT,
+			SDL_CONTROLLER_AXIS_TRIGGERRIGHT,
+			SDL_CONTROLLER_AXIS_MAX
+		}
+
+
+		/* Scancodes based off USB keyboard page (0x07) */
+		public enum SDL_Scancode
+		{
+			SDL_SCANCODE_UNKNOWN = 0,
+
+			SDL_SCANCODE_A = 4,
+			SDL_SCANCODE_B = 5,
+			SDL_SCANCODE_C = 6,
+			SDL_SCANCODE_D = 7,
+			SDL_SCANCODE_E = 8,
+			SDL_SCANCODE_F = 9,
+			SDL_SCANCODE_G = 10,
+			SDL_SCANCODE_H = 11,
+			SDL_SCANCODE_I = 12,
+			SDL_SCANCODE_J = 13,
+			SDL_SCANCODE_K = 14,
+			SDL_SCANCODE_L = 15,
+			SDL_SCANCODE_M = 16,
+			SDL_SCANCODE_N = 17,
+			SDL_SCANCODE_O = 18,
+			SDL_SCANCODE_P = 19,
+			SDL_SCANCODE_Q = 20,
+			SDL_SCANCODE_R = 21,
+			SDL_SCANCODE_S = 22,
+			SDL_SCANCODE_T = 23,
+			SDL_SCANCODE_U = 24,
+			SDL_SCANCODE_V = 25,
+			SDL_SCANCODE_W = 26,
+			SDL_SCANCODE_X = 27,
+			SDL_SCANCODE_Y = 28,
+			SDL_SCANCODE_Z = 29,
+
+			SDL_SCANCODE_1 = 30,
+			SDL_SCANCODE_2 = 31,
+			SDL_SCANCODE_3 = 32,
+			SDL_SCANCODE_4 = 33,
+			SDL_SCANCODE_5 = 34,
+			SDL_SCANCODE_6 = 35,
+			SDL_SCANCODE_7 = 36,
+			SDL_SCANCODE_8 = 37,
+			SDL_SCANCODE_9 = 38,
+			SDL_SCANCODE_0 = 39,
+
+			SDL_SCANCODE_RETURN = 40,
+			SDL_SCANCODE_ESCAPE = 41,
+			SDL_SCANCODE_BACKSPACE = 42,
+			SDL_SCANCODE_TAB = 43,
+			SDL_SCANCODE_SPACE = 44,
+
+			SDL_SCANCODE_MINUS = 45,
+			SDL_SCANCODE_EQUALS = 46,
+			SDL_SCANCODE_LEFTBRACKET = 47,
+			SDL_SCANCODE_RIGHTBRACKET = 48,
+			SDL_SCANCODE_BACKSLASH = 49,
+			SDL_SCANCODE_NONUSHASH = 50,
+			SDL_SCANCODE_SEMICOLON = 51,
+			SDL_SCANCODE_APOSTROPHE = 52,
+			SDL_SCANCODE_GRAVE = 53,
+			SDL_SCANCODE_COMMA = 54,
+			SDL_SCANCODE_PERIOD = 55,
+			SDL_SCANCODE_SLASH = 56,
+
+			SDL_SCANCODE_CAPSLOCK = 57,
+
+			SDL_SCANCODE_F1 = 58,
+			SDL_SCANCODE_F2 = 59,
+			SDL_SCANCODE_F3 = 60,
+			SDL_SCANCODE_F4 = 61,
+			SDL_SCANCODE_F5 = 62,
+			SDL_SCANCODE_F6 = 63,
+			SDL_SCANCODE_F7 = 64,
+			SDL_SCANCODE_F8 = 65,
+			SDL_SCANCODE_F9 = 66,
+			SDL_SCANCODE_F10 = 67,
+			SDL_SCANCODE_F11 = 68,
+			SDL_SCANCODE_F12 = 69,
+
+			SDL_SCANCODE_PRINTSCREEN = 70,
+			SDL_SCANCODE_SCROLLLOCK = 71,
+			SDL_SCANCODE_PAUSE = 72,
+			SDL_SCANCODE_INSERT = 73,
+			SDL_SCANCODE_HOME = 74,
+			SDL_SCANCODE_PAGEUP = 75,
+			SDL_SCANCODE_DELETE = 76,
+			SDL_SCANCODE_END = 77,
+			SDL_SCANCODE_PAGEDOWN = 78,
+			SDL_SCANCODE_RIGHT = 79,
+			SDL_SCANCODE_LEFT = 80,
+			SDL_SCANCODE_DOWN = 81,
+			SDL_SCANCODE_UP = 82,
+
+			SDL_SCANCODE_NUMLOCKCLEAR = 83,
+			SDL_SCANCODE_KP_DIVIDE = 84,
+			SDL_SCANCODE_KP_MULTIPLY = 85,
+			SDL_SCANCODE_KP_MINUS = 86,
+			SDL_SCANCODE_KP_PLUS = 87,
+			SDL_SCANCODE_KP_ENTER = 88,
+			SDL_SCANCODE_KP_1 = 89,
+			SDL_SCANCODE_KP_2 = 90,
+			SDL_SCANCODE_KP_3 = 91,
+			SDL_SCANCODE_KP_4 = 92,
+			SDL_SCANCODE_KP_5 = 93,
+			SDL_SCANCODE_KP_6 = 94,
+			SDL_SCANCODE_KP_7 = 95,
+			SDL_SCANCODE_KP_8 = 96,
+			SDL_SCANCODE_KP_9 = 97,
+			SDL_SCANCODE_KP_0 = 98,
+			SDL_SCANCODE_KP_PERIOD = 99,
+
+			SDL_SCANCODE_NONUSBACKSLASH = 100,
+			SDL_SCANCODE_APPLICATION = 101,
+			SDL_SCANCODE_POWER = 102,
+			SDL_SCANCODE_KP_EQUALS = 103,
+			SDL_SCANCODE_F13 = 104,
+			SDL_SCANCODE_F14 = 105,
+			SDL_SCANCODE_F15 = 106,
+			SDL_SCANCODE_F16 = 107,
+			SDL_SCANCODE_F17 = 108,
+			SDL_SCANCODE_F18 = 109,
+			SDL_SCANCODE_F19 = 110,
+			SDL_SCANCODE_F20 = 111,
+			SDL_SCANCODE_F21 = 112,
+			SDL_SCANCODE_F22 = 113,
+			SDL_SCANCODE_F23 = 114,
+			SDL_SCANCODE_F24 = 115,
+			SDL_SCANCODE_EXECUTE = 116,
+			SDL_SCANCODE_HELP = 117,
+			SDL_SCANCODE_MENU = 118,
+			SDL_SCANCODE_SELECT = 119,
+			SDL_SCANCODE_STOP = 120,
+			SDL_SCANCODE_AGAIN = 121,
+			SDL_SCANCODE_UNDO = 122,
+			SDL_SCANCODE_CUT = 123,
+			SDL_SCANCODE_COPY = 124,
+			SDL_SCANCODE_PASTE = 125,
+			SDL_SCANCODE_FIND = 126,
+			SDL_SCANCODE_MUTE = 127,
+			SDL_SCANCODE_VOLUMEUP = 128,
+			SDL_SCANCODE_VOLUMEDOWN = 129,
+			/* not sure whether there's a reason to enable these */
+			/*	SDL_SCANCODE_LOCKINGCAPSLOCK = 130,  */
+			/*	SDL_SCANCODE_LOCKINGNUMLOCK = 131, */
+			/*	SDL_SCANCODE_LOCKINGSCROLLLOCK = 132, */
+			SDL_SCANCODE_KP_COMMA = 133,
+			SDL_SCANCODE_KP_EQUALSAS400 = 134,
+
+			SDL_SCANCODE_INTERNATIONAL1 = 135,
+			SDL_SCANCODE_INTERNATIONAL2 = 136,
+			SDL_SCANCODE_INTERNATIONAL3 = 137,
+			SDL_SCANCODE_INTERNATIONAL4 = 138,
+			SDL_SCANCODE_INTERNATIONAL5 = 139,
+			SDL_SCANCODE_INTERNATIONAL6 = 140,
+			SDL_SCANCODE_INTERNATIONAL7 = 141,
+			SDL_SCANCODE_INTERNATIONAL8 = 142,
+			SDL_SCANCODE_INTERNATIONAL9 = 143,
+			SDL_SCANCODE_LANG1 = 144,
+			SDL_SCANCODE_LANG2 = 145,
+			SDL_SCANCODE_LANG3 = 146,
+			SDL_SCANCODE_LANG4 = 147,
+			SDL_SCANCODE_LANG5 = 148,
+			SDL_SCANCODE_LANG6 = 149,
+			SDL_SCANCODE_LANG7 = 150,
+			SDL_SCANCODE_LANG8 = 151,
+			SDL_SCANCODE_LANG9 = 152,
+
+			SDL_SCANCODE_ALTERASE = 153,
+			SDL_SCANCODE_SYSREQ = 154,
+			SDL_SCANCODE_CANCEL = 155,
+			SDL_SCANCODE_CLEAR = 156,
+			SDL_SCANCODE_PRIOR = 157,
+			SDL_SCANCODE_RETURN2 = 158,
+			SDL_SCANCODE_SEPARATOR = 159,
+			SDL_SCANCODE_OUT = 160,
+			SDL_SCANCODE_OPER = 161,
+			SDL_SCANCODE_CLEARAGAIN = 162,
+			SDL_SCANCODE_CRSEL = 163,
+			SDL_SCANCODE_EXSEL = 164,
+
+			SDL_SCANCODE_KP_00 = 176,
+			SDL_SCANCODE_KP_000 = 177,
+			SDL_SCANCODE_THOUSANDSSEPARATOR = 178,
+			SDL_SCANCODE_DECIMALSEPARATOR = 179,
+			SDL_SCANCODE_CURRENCYUNIT = 180,
+			SDL_SCANCODE_CURRENCYSUBUNIT = 181,
+			SDL_SCANCODE_KP_LEFTPAREN = 182,
+			SDL_SCANCODE_KP_RIGHTPAREN = 183,
+			SDL_SCANCODE_KP_LEFTBRACE = 184,
+			SDL_SCANCODE_KP_RIGHTBRACE = 185,
+			SDL_SCANCODE_KP_TAB = 186,
+			SDL_SCANCODE_KP_BACKSPACE = 187,
+			SDL_SCANCODE_KP_A = 188,
+			SDL_SCANCODE_KP_B = 189,
+			SDL_SCANCODE_KP_C = 190,
+			SDL_SCANCODE_KP_D = 191,
+			SDL_SCANCODE_KP_E = 192,
+			SDL_SCANCODE_KP_F = 193,
+			SDL_SCANCODE_KP_XOR = 194,
+			SDL_SCANCODE_KP_POWER = 195,
+			SDL_SCANCODE_KP_PERCENT = 196,
+			SDL_SCANCODE_KP_LESS = 197,
+			SDL_SCANCODE_KP_GREATER = 198,
+			SDL_SCANCODE_KP_AMPERSAND = 199,
+			SDL_SCANCODE_KP_DBLAMPERSAND = 200,
+			SDL_SCANCODE_KP_VERTICALBAR = 201,
+			SDL_SCANCODE_KP_DBLVERTICALBAR = 202,
+			SDL_SCANCODE_KP_COLON = 203,
+			SDL_SCANCODE_KP_HASH = 204,
+			SDL_SCANCODE_KP_SPACE = 205,
+			SDL_SCANCODE_KP_AT = 206,
+			SDL_SCANCODE_KP_EXCLAM = 207,
+			SDL_SCANCODE_KP_MEMSTORE = 208,
+			SDL_SCANCODE_KP_MEMRECALL = 209,
+			SDL_SCANCODE_KP_MEMCLEAR = 210,
+			SDL_SCANCODE_KP_MEMADD = 211,
+			SDL_SCANCODE_KP_MEMSUBTRACT = 212,
+			SDL_SCANCODE_KP_MEMMULTIPLY = 213,
+			SDL_SCANCODE_KP_MEMDIVIDE = 214,
+			SDL_SCANCODE_KP_PLUSMINUS = 215,
+			SDL_SCANCODE_KP_CLEAR = 216,
+			SDL_SCANCODE_KP_CLEARENTRY = 217,
+			SDL_SCANCODE_KP_BINARY = 218,
+			SDL_SCANCODE_KP_OCTAL = 219,
+			SDL_SCANCODE_KP_DECIMAL = 220,
+			SDL_SCANCODE_KP_HEXADECIMAL = 221,
+
+			SDL_SCANCODE_LCTRL = 224,
+			SDL_SCANCODE_LSHIFT = 225,
+			SDL_SCANCODE_LALT = 226,
+			SDL_SCANCODE_LGUI = 227,
+			SDL_SCANCODE_RCTRL = 228,
+			SDL_SCANCODE_RSHIFT = 229,
+			SDL_SCANCODE_RALT = 230,
+			SDL_SCANCODE_RGUI = 231,
+
+			SDL_SCANCODE_MODE = 257,
+
+			/* These come from the USB consumer page (0x0C) */
+			SDL_SCANCODE_AUDIONEXT = 258,
+			SDL_SCANCODE_AUDIOPREV = 259,
+			SDL_SCANCODE_AUDIOSTOP = 260,
+			SDL_SCANCODE_AUDIOPLAY = 261,
+			SDL_SCANCODE_AUDIOMUTE = 262,
+			SDL_SCANCODE_MEDIASELECT = 263,
+			SDL_SCANCODE_WWW = 264,
+			SDL_SCANCODE_MAIL = 265,
+			SDL_SCANCODE_CALCULATOR = 266,
+			SDL_SCANCODE_COMPUTER = 267,
+			SDL_SCANCODE_AC_SEARCH = 268,
+			SDL_SCANCODE_AC_HOME = 269,
+			SDL_SCANCODE_AC_BACK = 270,
+			SDL_SCANCODE_AC_FORWARD = 271,
+			SDL_SCANCODE_AC_STOP = 272,
+			SDL_SCANCODE_AC_REFRESH = 273,
+			SDL_SCANCODE_AC_BOOKMARKS = 274,
+
+			/* These come from other sources, and are mostly mac related */
+			SDL_SCANCODE_BRIGHTNESSDOWN = 275,
+			SDL_SCANCODE_BRIGHTNESSUP = 276,
+			SDL_SCANCODE_DISPLAYSWITCH = 277,
+			SDL_SCANCODE_KBDILLUMTOGGLE = 278,
+			SDL_SCANCODE_KBDILLUMDOWN = 279,
+			SDL_SCANCODE_KBDILLUMUP = 280,
+			SDL_SCANCODE_EJECT = 281,
+			SDL_SCANCODE_SLEEP = 282,
+
+			SDL_SCANCODE_APP1 = 283,
+			SDL_SCANCODE_APP2 = 284,
+
+			/* This is not a key, simply marks the number of scancodes
+			 * so that you know how big to make your arrays. */
+			SDL_NUM_SCANCODES = 512
+		}
+
+		public const int SDLK_SCANCODE_MASK = (1 << 30);
+
+		public enum SDL_Keycode
+		{
+			SDLK_UNKNOWN = 0,
+
+			SDLK_RETURN = '\r',
+			SDLK_ESCAPE = 27,
+			// '\033'
+			SDLK_BACKSPACE = '\b',
+			SDLK_TAB = '\t',
+			SDLK_SPACE = ' ',
+			SDLK_EXCLAIM = '!',
+			SDLK_QUOTEDBL = '"',
+			SDLK_HASH = '#',
+			SDLK_PERCENT = '%',
+			SDLK_DOLLAR = '$',
+			SDLK_AMPERSAND = '&',
+			SDLK_QUOTE = '\'',
+			SDLK_LEFTPAREN = '(',
+			SDLK_RIGHTPAREN = ')',
+			SDLK_ASTERISK = '*',
+			SDLK_PLUS = '+',
+			SDLK_COMMA = ',',
+			SDLK_MINUS = '-',
+			SDLK_PERIOD = '.',
+			SDLK_SLASH = '/',
+			SDLK_0 = '0',
+			SDLK_1 = '1',
+			SDLK_2 = '2',
+			SDLK_3 = '3',
+			SDLK_4 = '4',
+			SDLK_5 = '5',
+			SDLK_6 = '6',
+			SDLK_7 = '7',
+			SDLK_8 = '8',
+			SDLK_9 = '9',
+			SDLK_COLON = ':',
+			SDLK_SEMICOLON = ';',
+			SDLK_LESS = '<',
+			SDLK_EQUALS = '=',
+			SDLK_GREATER = '>',
+			SDLK_QUESTION = '?',
+			SDLK_AT = '@',
+			/*
+			Skip uppercase letters
+			*/
+			SDLK_LEFTBRACKET = '[',
+			SDLK_BACKSLASH = '\\',
+			SDLK_RIGHTBRACKET = ']',
+			SDLK_CARET = '^',
+			SDLK_UNDERSCORE = '_',
+			SDLK_BACKQUOTE = '`',
+			SDLK_a = 'a',
+			SDLK_b = 'b',
+			SDLK_c = 'c',
+			SDLK_d = 'd',
+			SDLK_e = 'e',
+			SDLK_f = 'f',
+			SDLK_g = 'g',
+			SDLK_h = 'h',
+			SDLK_i = 'i',
+			SDLK_j = 'j',
+			SDLK_k = 'k',
+			SDLK_l = 'l',
+			SDLK_m = 'm',
+			SDLK_n = 'n',
+			SDLK_o = 'o',
+			SDLK_p = 'p',
+			SDLK_q = 'q',
+			SDLK_r = 'r',
+			SDLK_s = 's',
+			SDLK_t = 't',
+			SDLK_u = 'u',
+			SDLK_v = 'v',
+			SDLK_w = 'w',
+			SDLK_x = 'x',
+			SDLK_y = 'y',
+			SDLK_z = 'z',
+
+			SDLK_CAPSLOCK = (int)SDL_Scancode.SDL_SCANCODE_CAPSLOCK | SDLK_SCANCODE_MASK,
+
+			SDLK_F1 = (int)SDL_Scancode.SDL_SCANCODE_F1 | SDLK_SCANCODE_MASK,
+			SDLK_F2 = (int)SDL_Scancode.SDL_SCANCODE_F2 | SDLK_SCANCODE_MASK,
+			SDLK_F3 = (int)SDL_Scancode.SDL_SCANCODE_F3 | SDLK_SCANCODE_MASK,
+			SDLK_F4 = (int)SDL_Scancode.SDL_SCANCODE_F4 | SDLK_SCANCODE_MASK,
+			SDLK_F5 = (int)SDL_Scancode.SDL_SCANCODE_F5 | SDLK_SCANCODE_MASK,
+			SDLK_F6 = (int)SDL_Scancode.SDL_SCANCODE_F6 | SDLK_SCANCODE_MASK,
+			SDLK_F7 = (int)SDL_Scancode.SDL_SCANCODE_F7 | SDLK_SCANCODE_MASK,
+			SDLK_F8 = (int)SDL_Scancode.SDL_SCANCODE_F8 | SDLK_SCANCODE_MASK,
+			SDLK_F9 = (int)SDL_Scancode.SDL_SCANCODE_F9 | SDLK_SCANCODE_MASK,
+			SDLK_F10 = (int)SDL_Scancode.SDL_SCANCODE_F10 | SDLK_SCANCODE_MASK,
+			SDLK_F11 = (int)SDL_Scancode.SDL_SCANCODE_F11 | SDLK_SCANCODE_MASK,
+			SDLK_F12 = (int)SDL_Scancode.SDL_SCANCODE_F12 | SDLK_SCANCODE_MASK,
+
+			SDLK_PRINTSCREEN = (int)SDL_Scancode.SDL_SCANCODE_PRINTSCREEN | SDLK_SCANCODE_MASK,
+			SDLK_SCROLLLOCK = (int)SDL_Scancode.SDL_SCANCODE_SCROLLLOCK | SDLK_SCANCODE_MASK,
+			SDLK_PAUSE = (int)SDL_Scancode.SDL_SCANCODE_PAUSE | SDLK_SCANCODE_MASK,
+			SDLK_INSERT = (int)SDL_Scancode.SDL_SCANCODE_INSERT | SDLK_SCANCODE_MASK,
+			SDLK_HOME = (int)SDL_Scancode.SDL_SCANCODE_HOME | SDLK_SCANCODE_MASK,
+			SDLK_PAGEUP = (int)SDL_Scancode.SDL_SCANCODE_PAGEUP | SDLK_SCANCODE_MASK,
+			SDLK_DELETE = 127,
+			SDLK_END = (int)SDL_Scancode.SDL_SCANCODE_END | SDLK_SCANCODE_MASK,
+			SDLK_PAGEDOWN = (int)SDL_Scancode.SDL_SCANCODE_PAGEDOWN | SDLK_SCANCODE_MASK,
+			SDLK_RIGHT = (int)SDL_Scancode.SDL_SCANCODE_RIGHT | SDLK_SCANCODE_MASK,
+			SDLK_LEFT = (int)SDL_Scancode.SDL_SCANCODE_LEFT | SDLK_SCANCODE_MASK,
+			SDLK_DOWN = (int)SDL_Scancode.SDL_SCANCODE_DOWN | SDLK_SCANCODE_MASK,
+			SDLK_UP = (int)SDL_Scancode.SDL_SCANCODE_UP | SDLK_SCANCODE_MASK,
+
+			SDLK_NUMLOCKCLEAR = (int)SDL_Scancode.SDL_SCANCODE_NUMLOCKCLEAR | SDLK_SCANCODE_MASK,
+			SDLK_KP_DIVIDE = (int)SDL_Scancode.SDL_SCANCODE_KP_DIVIDE | SDLK_SCANCODE_MASK,
+			SDLK_KP_MULTIPLY = (int)SDL_Scancode.SDL_SCANCODE_KP_MULTIPLY | SDLK_SCANCODE_MASK,
+			SDLK_KP_MINUS = (int)SDL_Scancode.SDL_SCANCODE_KP_MINUS | SDLK_SCANCODE_MASK,
+			SDLK_KP_PLUS = (int)SDL_Scancode.SDL_SCANCODE_KP_PLUS | SDLK_SCANCODE_MASK,
+			SDLK_KP_ENTER = (int)SDL_Scancode.SDL_SCANCODE_KP_ENTER | SDLK_SCANCODE_MASK,
+			SDLK_KP_1 = (int)SDL_Scancode.SDL_SCANCODE_KP_1 | SDLK_SCANCODE_MASK,
+			SDLK_KP_2 = (int)SDL_Scancode.SDL_SCANCODE_KP_2 | SDLK_SCANCODE_MASK,
+			SDLK_KP_3 = (int)SDL_Scancode.SDL_SCANCODE_KP_3 | SDLK_SCANCODE_MASK,
+			SDLK_KP_4 = (int)SDL_Scancode.SDL_SCANCODE_KP_4 | SDLK_SCANCODE_MASK,
+			SDLK_KP_5 = (int)SDL_Scancode.SDL_SCANCODE_KP_5 | SDLK_SCANCODE_MASK,
+			SDLK_KP_6 = (int)SDL_Scancode.SDL_SCANCODE_KP_6 | SDLK_SCANCODE_MASK,
+			SDLK_KP_7 = (int)SDL_Scancode.SDL_SCANCODE_KP_7 | SDLK_SCANCODE_MASK,
+			SDLK_KP_8 = (int)SDL_Scancode.SDL_SCANCODE_KP_8 | SDLK_SCANCODE_MASK,
+			SDLK_KP_9 = (int)SDL_Scancode.SDL_SCANCODE_KP_9 | SDLK_SCANCODE_MASK,
+			SDLK_KP_0 = (int)SDL_Scancode.SDL_SCANCODE_KP_0 | SDLK_SCANCODE_MASK,
+			SDLK_KP_PERIOD = (int)SDL_Scancode.SDL_SCANCODE_KP_PERIOD | SDLK_SCANCODE_MASK,
+
+			SDLK_APPLICATION = (int)SDL_Scancode.SDL_SCANCODE_APPLICATION | SDLK_SCANCODE_MASK,
+			SDLK_POWER = (int)SDL_Scancode.SDL_SCANCODE_POWER | SDLK_SCANCODE_MASK,
+			SDLK_KP_EQUALS = (int)SDL_Scancode.SDL_SCANCODE_KP_EQUALS | SDLK_SCANCODE_MASK,
+			SDLK_F13 = (int)SDL_Scancode.SDL_SCANCODE_F13 | SDLK_SCANCODE_MASK,
+			SDLK_F14 = (int)SDL_Scancode.SDL_SCANCODE_F14 | SDLK_SCANCODE_MASK,
+			SDLK_F15 = (int)SDL_Scancode.SDL_SCANCODE_F15 | SDLK_SCANCODE_MASK,
+			SDLK_F16 = (int)SDL_Scancode.SDL_SCANCODE_F16 | SDLK_SCANCODE_MASK,
+			SDLK_F17 = (int)SDL_Scancode.SDL_SCANCODE_F17 | SDLK_SCANCODE_MASK,
+			SDLK_F18 = (int)SDL_Scancode.SDL_SCANCODE_F18 | SDLK_SCANCODE_MASK,
+			SDLK_F19 = (int)SDL_Scancode.SDL_SCANCODE_F19 | SDLK_SCANCODE_MASK,
+			SDLK_F20 = (int)SDL_Scancode.SDL_SCANCODE_F20 | SDLK_SCANCODE_MASK,
+			SDLK_F21 = (int)SDL_Scancode.SDL_SCANCODE_F21 | SDLK_SCANCODE_MASK,
+			SDLK_F22 = (int)SDL_Scancode.SDL_SCANCODE_F22 | SDLK_SCANCODE_MASK,
+			SDLK_F23 = (int)SDL_Scancode.SDL_SCANCODE_F23 | SDLK_SCANCODE_MASK,
+			SDLK_F24 = (int)SDL_Scancode.SDL_SCANCODE_F24 | SDLK_SCANCODE_MASK,
+			SDLK_EXECUTE = (int)SDL_Scancode.SDL_SCANCODE_EXECUTE | SDLK_SCANCODE_MASK,
+			SDLK_HELP = (int)SDL_Scancode.SDL_SCANCODE_HELP | SDLK_SCANCODE_MASK,
+			SDLK_MENU = (int)SDL_Scancode.SDL_SCANCODE_MENU | SDLK_SCANCODE_MASK,
+			SDLK_SELECT = (int)SDL_Scancode.SDL_SCANCODE_SELECT | SDLK_SCANCODE_MASK,
+			SDLK_STOP = (int)SDL_Scancode.SDL_SCANCODE_STOP | SDLK_SCANCODE_MASK,
+			SDLK_AGAIN = (int)SDL_Scancode.SDL_SCANCODE_AGAIN | SDLK_SCANCODE_MASK,
+			SDLK_UNDO = (int)SDL_Scancode.SDL_SCANCODE_UNDO | SDLK_SCANCODE_MASK,
+			SDLK_CUT = (int)SDL_Scancode.SDL_SCANCODE_CUT | SDLK_SCANCODE_MASK,
+			SDLK_COPY = (int)SDL_Scancode.SDL_SCANCODE_COPY | SDLK_SCANCODE_MASK,
+			SDLK_PASTE = (int)SDL_Scancode.SDL_SCANCODE_PASTE | SDLK_SCANCODE_MASK,
+			SDLK_FIND = (int)SDL_Scancode.SDL_SCANCODE_FIND | SDLK_SCANCODE_MASK,
+			SDLK_MUTE = (int)SDL_Scancode.SDL_SCANCODE_MUTE | SDLK_SCANCODE_MASK,
+			SDLK_VOLUMEUP = (int)SDL_Scancode.SDL_SCANCODE_VOLUMEUP | SDLK_SCANCODE_MASK,
+			SDLK_VOLUMEDOWN = (int)SDL_Scancode.SDL_SCANCODE_VOLUMEDOWN | SDLK_SCANCODE_MASK,
+			SDLK_KP_COMMA = (int)SDL_Scancode.SDL_SCANCODE_KP_COMMA | SDLK_SCANCODE_MASK,
+			SDLK_KP_EQUALSAS400 =
+			(int)SDL_Scancode.SDL_SCANCODE_KP_EQUALSAS400 | SDLK_SCANCODE_MASK,
+
+			SDLK_ALTERASE = (int)SDL_Scancode.SDL_SCANCODE_ALTERASE | SDLK_SCANCODE_MASK,
+			SDLK_SYSREQ = (int)SDL_Scancode.SDL_SCANCODE_SYSREQ | SDLK_SCANCODE_MASK,
+			SDLK_CANCEL = (int)SDL_Scancode.SDL_SCANCODE_CANCEL | SDLK_SCANCODE_MASK,
+			SDLK_CLEAR = (int)SDL_Scancode.SDL_SCANCODE_CLEAR | SDLK_SCANCODE_MASK,
+			SDLK_PRIOR = (int)SDL_Scancode.SDL_SCANCODE_PRIOR | SDLK_SCANCODE_MASK,
+			SDLK_RETURN2 = (int)SDL_Scancode.SDL_SCANCODE_RETURN2 | SDLK_SCANCODE_MASK,
+			SDLK_SEPARATOR = (int)SDL_Scancode.SDL_SCANCODE_SEPARATOR | SDLK_SCANCODE_MASK,
+			SDLK_OUT = (int)SDL_Scancode.SDL_SCANCODE_OUT | SDLK_SCANCODE_MASK,
+			SDLK_OPER = (int)SDL_Scancode.SDL_SCANCODE_OPER | SDLK_SCANCODE_MASK,
+			SDLK_CLEARAGAIN = (int)SDL_Scancode.SDL_SCANCODE_CLEARAGAIN | SDLK_SCANCODE_MASK,
+			SDLK_CRSEL = (int)SDL_Scancode.SDL_SCANCODE_CRSEL | SDLK_SCANCODE_MASK,
+			SDLK_EXSEL = (int)SDL_Scancode.SDL_SCANCODE_EXSEL | SDLK_SCANCODE_MASK,
+
+			SDLK_KP_00 = (int)SDL_Scancode.SDL_SCANCODE_KP_00 | SDLK_SCANCODE_MASK,
+			SDLK_KP_000 = (int)SDL_Scancode.SDL_SCANCODE_KP_000 | SDLK_SCANCODE_MASK,
+			SDLK_THOUSANDSSEPARATOR =
+			(int)SDL_Scancode.SDL_SCANCODE_THOUSANDSSEPARATOR | SDLK_SCANCODE_MASK,
+			SDLK_DECIMALSEPARATOR =
+			(int)SDL_Scancode.SDL_SCANCODE_DECIMALSEPARATOR | SDLK_SCANCODE_MASK,
+			SDLK_CURRENCYUNIT = (int)SDL_Scancode.SDL_SCANCODE_CURRENCYUNIT | SDLK_SCANCODE_MASK,
+			SDLK_CURRENCYSUBUNIT =
+			(int)SDL_Scancode.SDL_SCANCODE_CURRENCYSUBUNIT | SDLK_SCANCODE_MASK,
+			SDLK_KP_LEFTPAREN = (int)SDL_Scancode.SDL_SCANCODE_KP_LEFTPAREN | SDLK_SCANCODE_MASK,
+			SDLK_KP_RIGHTPAREN = (int)SDL_Scancode.SDL_SCANCODE_KP_RIGHTPAREN | SDLK_SCANCODE_MASK,
+			SDLK_KP_LEFTBRACE = (int)SDL_Scancode.SDL_SCANCODE_KP_LEFTBRACE | SDLK_SCANCODE_MASK,
+			SDLK_KP_RIGHTBRACE = (int)SDL_Scancode.SDL_SCANCODE_KP_RIGHTBRACE | SDLK_SCANCODE_MASK,
+			SDLK_KP_TAB = (int)SDL_Scancode.SDL_SCANCODE_KP_TAB | SDLK_SCANCODE_MASK,
+			SDLK_KP_BACKSPACE = (int)SDL_Scancode.SDL_SCANCODE_KP_BACKSPACE | SDLK_SCANCODE_MASK,
+			SDLK_KP_A = (int)SDL_Scancode.SDL_SCANCODE_KP_A | SDLK_SCANCODE_MASK,
+			SDLK_KP_B = (int)SDL_Scancode.SDL_SCANCODE_KP_B | SDLK_SCANCODE_MASK,
+			SDLK_KP_C = (int)SDL_Scancode.SDL_SCANCODE_KP_C | SDLK_SCANCODE_MASK,
+			SDLK_KP_D = (int)SDL_Scancode.SDL_SCANCODE_KP_D | SDLK_SCANCODE_MASK,
+			SDLK_KP_E = (int)SDL_Scancode.SDL_SCANCODE_KP_E | SDLK_SCANCODE_MASK,
+			SDLK_KP_F = (int)SDL_Scancode.SDL_SCANCODE_KP_F | SDLK_SCANCODE_MASK,
+			SDLK_KP_XOR = (int)SDL_Scancode.SDL_SCANCODE_KP_XOR | SDLK_SCANCODE_MASK,
+			SDLK_KP_POWER = (int)SDL_Scancode.SDL_SCANCODE_KP_POWER | SDLK_SCANCODE_MASK,
+			SDLK_KP_PERCENT = (int)SDL_Scancode.SDL_SCANCODE_KP_PERCENT | SDLK_SCANCODE_MASK,
+			SDLK_KP_LESS = (int)SDL_Scancode.SDL_SCANCODE_KP_LESS | SDLK_SCANCODE_MASK,
+			SDLK_KP_GREATER = (int)SDL_Scancode.SDL_SCANCODE_KP_GREATER | SDLK_SCANCODE_MASK,
+			SDLK_KP_AMPERSAND = (int)SDL_Scancode.SDL_SCANCODE_KP_AMPERSAND | SDLK_SCANCODE_MASK,
+			SDLK_KP_DBLAMPERSAND =
+			(int)SDL_Scancode.SDL_SCANCODE_KP_DBLAMPERSAND | SDLK_SCANCODE_MASK,
+			SDLK_KP_VERTICALBAR =
+			(int)SDL_Scancode.SDL_SCANCODE_KP_VERTICALBAR | SDLK_SCANCODE_MASK,
+			SDLK_KP_DBLVERTICALBAR =
+			(int)SDL_Scancode.SDL_SCANCODE_KP_DBLVERTICALBAR | SDLK_SCANCODE_MASK,
+			SDLK_KP_COLON = (int)SDL_Scancode.SDL_SCANCODE_KP_COLON | SDLK_SCANCODE_MASK,
+			SDLK_KP_HASH = (int)SDL_Scancode.SDL_SCANCODE_KP_HASH | SDLK_SCANCODE_MASK,
+			SDLK_KP_SPACE = (int)SDL_Scancode.SDL_SCANCODE_KP_SPACE | SDLK_SCANCODE_MASK,
+			SDLK_KP_AT = (int)SDL_Scancode.SDL_SCANCODE_KP_AT | SDLK_SCANCODE_MASK,
+			SDLK_KP_EXCLAM = (int)SDL_Scancode.SDL_SCANCODE_KP_EXCLAM | SDLK_SCANCODE_MASK,
+			SDLK_KP_MEMSTORE = (int)SDL_Scancode.SDL_SCANCODE_KP_MEMSTORE | SDLK_SCANCODE_MASK,
+			SDLK_KP_MEMRECALL = (int)SDL_Scancode.SDL_SCANCODE_KP_MEMRECALL | SDLK_SCANCODE_MASK,
+			SDLK_KP_MEMCLEAR = (int)SDL_Scancode.SDL_SCANCODE_KP_MEMCLEAR | SDLK_SCANCODE_MASK,
+			SDLK_KP_MEMADD = (int)SDL_Scancode.SDL_SCANCODE_KP_MEMADD | SDLK_SCANCODE_MASK,
+			SDLK_KP_MEMSUBTRACT =
+			(int)SDL_Scancode.SDL_SCANCODE_KP_MEMSUBTRACT | SDLK_SCANCODE_MASK,
+			SDLK_KP_MEMMULTIPLY =
+			(int)SDL_Scancode.SDL_SCANCODE_KP_MEMMULTIPLY | SDLK_SCANCODE_MASK,
+			SDLK_KP_MEMDIVIDE = (int)SDL_Scancode.SDL_SCANCODE_KP_MEMDIVIDE | SDLK_SCANCODE_MASK,
+			SDLK_KP_PLUSMINUS = (int)SDL_Scancode.SDL_SCANCODE_KP_PLUSMINUS | SDLK_SCANCODE_MASK,
+			SDLK_KP_CLEAR = (int)SDL_Scancode.SDL_SCANCODE_KP_CLEAR | SDLK_SCANCODE_MASK,
+			SDLK_KP_CLEARENTRY = (int)SDL_Scancode.SDL_SCANCODE_KP_CLEARENTRY | SDLK_SCANCODE_MASK,
+			SDLK_KP_BINARY = (int)SDL_Scancode.SDL_SCANCODE_KP_BINARY | SDLK_SCANCODE_MASK,
+			SDLK_KP_OCTAL = (int)SDL_Scancode.SDL_SCANCODE_KP_OCTAL | SDLK_SCANCODE_MASK,
+			SDLK_KP_DECIMAL = (int)SDL_Scancode.SDL_SCANCODE_KP_DECIMAL | SDLK_SCANCODE_MASK,
+			SDLK_KP_HEXADECIMAL =
+			(int)SDL_Scancode.SDL_SCANCODE_KP_HEXADECIMAL | SDLK_SCANCODE_MASK,
+
+			SDLK_LCTRL = (int)SDL_Scancode.SDL_SCANCODE_LCTRL | SDLK_SCANCODE_MASK,
+			SDLK_LSHIFT = (int)SDL_Scancode.SDL_SCANCODE_LSHIFT | SDLK_SCANCODE_MASK,
+			SDLK_LALT = (int)SDL_Scancode.SDL_SCANCODE_LALT | SDLK_SCANCODE_MASK,
+			SDLK_LGUI = (int)SDL_Scancode.SDL_SCANCODE_LGUI | SDLK_SCANCODE_MASK,
+			SDLK_RCTRL = (int)SDL_Scancode.SDL_SCANCODE_RCTRL | SDLK_SCANCODE_MASK,
+			SDLK_RSHIFT = (int)SDL_Scancode.SDL_SCANCODE_RSHIFT | SDLK_SCANCODE_MASK,
+			SDLK_RALT = (int)SDL_Scancode.SDL_SCANCODE_RALT | SDLK_SCANCODE_MASK,
+			SDLK_RGUI = (int)SDL_Scancode.SDL_SCANCODE_RGUI | SDLK_SCANCODE_MASK,
+
+			SDLK_MODE = (int)SDL_Scancode.SDL_SCANCODE_MODE | SDLK_SCANCODE_MASK,
+
+			SDLK_AUDIONEXT = (int)SDL_Scancode.SDL_SCANCODE_AUDIONEXT | SDLK_SCANCODE_MASK,
+			SDLK_AUDIOPREV = (int)SDL_Scancode.SDL_SCANCODE_AUDIOPREV | SDLK_SCANCODE_MASK,
+			SDLK_AUDIOSTOP = (int)SDL_Scancode.SDL_SCANCODE_AUDIOSTOP | SDLK_SCANCODE_MASK,
+			SDLK_AUDIOPLAY = (int)SDL_Scancode.SDL_SCANCODE_AUDIOPLAY | SDLK_SCANCODE_MASK,
+			SDLK_AUDIOMUTE = (int)SDL_Scancode.SDL_SCANCODE_AUDIOMUTE | SDLK_SCANCODE_MASK,
+			SDLK_MEDIASELECT = (int)SDL_Scancode.SDL_SCANCODE_MEDIASELECT | SDLK_SCANCODE_MASK,
+			SDLK_WWW = (int)SDL_Scancode.SDL_SCANCODE_WWW | SDLK_SCANCODE_MASK,
+			SDLK_MAIL = (int)SDL_Scancode.SDL_SCANCODE_MAIL | SDLK_SCANCODE_MASK,
+			SDLK_CALCULATOR = (int)SDL_Scancode.SDL_SCANCODE_CALCULATOR | SDLK_SCANCODE_MASK,
+			SDLK_COMPUTER = (int)SDL_Scancode.SDL_SCANCODE_COMPUTER | SDLK_SCANCODE_MASK,
+			SDLK_AC_SEARCH = (int)SDL_Scancode.SDL_SCANCODE_AC_SEARCH | SDLK_SCANCODE_MASK,
+			SDLK_AC_HOME = (int)SDL_Scancode.SDL_SCANCODE_AC_HOME | SDLK_SCANCODE_MASK,
+			SDLK_AC_BACK = (int)SDL_Scancode.SDL_SCANCODE_AC_BACK | SDLK_SCANCODE_MASK,
+			SDLK_AC_FORWARD = (int)SDL_Scancode.SDL_SCANCODE_AC_FORWARD | SDLK_SCANCODE_MASK,
+			SDLK_AC_STOP = (int)SDL_Scancode.SDL_SCANCODE_AC_STOP | SDLK_SCANCODE_MASK,
+			SDLK_AC_REFRESH = (int)SDL_Scancode.SDL_SCANCODE_AC_REFRESH | SDLK_SCANCODE_MASK,
+			SDLK_AC_BOOKMARKS = (int)SDL_Scancode.SDL_SCANCODE_AC_BOOKMARKS | SDLK_SCANCODE_MASK,
+
+			SDLK_BRIGHTNESSDOWN =
+			(int)SDL_Scancode.SDL_SCANCODE_BRIGHTNESSDOWN | SDLK_SCANCODE_MASK,
+			SDLK_BRIGHTNESSUP = (int)SDL_Scancode.SDL_SCANCODE_BRIGHTNESSUP | SDLK_SCANCODE_MASK,
+			SDLK_DISPLAYSWITCH = (int)SDL_Scancode.SDL_SCANCODE_DISPLAYSWITCH | SDLK_SCANCODE_MASK,
+			SDLK_KBDILLUMTOGGLE =
+			(int)SDL_Scancode.SDL_SCANCODE_KBDILLUMTOGGLE | SDLK_SCANCODE_MASK,
+			SDLK_KBDILLUMDOWN = (int)SDL_Scancode.SDL_SCANCODE_KBDILLUMDOWN | SDLK_SCANCODE_MASK,
+			SDLK_KBDILLUMUP = (int)SDL_Scancode.SDL_SCANCODE_KBDILLUMUP | SDLK_SCANCODE_MASK,
+			SDLK_EJECT = (int)SDL_Scancode.SDL_SCANCODE_EJECT | SDLK_SCANCODE_MASK,
+			SDLK_SLEEP = (int)SDL_Scancode.SDL_SCANCODE_SLEEP | SDLK_SCANCODE_MASK
+		}
+	}
+
+}

+ 224 - 0
Script/AtomicNET/AtomicNET/AtomicNETTools/AssemblyInspector.cs

@@ -0,0 +1,224 @@
+using System;
+using System.IO;
+using System.Diagnostics;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Reflection;
+using System.Reflection.Metadata;
+using System.Reflection.PortableExecutable;
+using System.Reflection.Metadata.Ecma335;
+using System.Text;
+
+using AtomicEngine;
+
+using File = System.IO.File;
+
+namespace AtomicTools
+{
+
+	class AssemblyInspector
+	{
+
+		Dictionary<string, InspectorEnum> InspectorEnums = new Dictionary<string, InspectorEnum> ();
+		Dictionary<string, InspectorComponent> InspectorComponents = new Dictionary<string, InspectorComponent> ();
+
+		PEReader peFile;
+		MetadataReader metaReader;
+
+		public AssemblyInspector ()
+		{
+
+		}
+
+		public string DumpToJSON ()
+		{
+			var dict = new Dictionary<string, object> ();
+
+			var enumList = new List<object> ();
+			var componentList = new List<object> ();
+
+			foreach (var entry in InspectorEnums) {
+				enumList.Add (entry.Value.GetJSONDict ());
+			}
+
+			foreach (var entry in InspectorComponents) {
+				componentList.Add (entry.Value.GetJSONDict ());
+			}
+
+			dict ["enums"] = enumList;
+			dict ["components"] = componentList;
+
+			return MiniJSON.Json.Serialize (dict);
+
+		}
+
+		public void Inspect (String pathToAssembly)
+		{
+
+			using (var stream = File.OpenRead (pathToAssembly))
+			using (peFile = new PEReader (stream)) {
+
+				metaReader = peFile.GetMetadataReader ();
+
+				ParseEnums ();
+				ParseComponents ();
+			}
+
+		}
+
+		void ParseComponents ()
+		{
+
+			foreach (var handle in metaReader.TypeDefinitions) {
+
+				var typeDef = metaReader.GetTypeDefinition (handle);
+
+				var baseTypeHandle = typeDef.BaseType;
+
+				if (baseTypeHandle.Kind == HandleKind.TypeReference) {
+
+					var typeRef = metaReader.GetTypeReference ((TypeReferenceHandle)baseTypeHandle);
+
+					if (metaReader.GetString (typeRef.Name) != "CSComponent")
+						continue;
+
+					var inspector = new CSComponentInspector (typeDef, peFile, metaReader);
+
+					var icomponent = inspector.Inspect ();
+
+					if (icomponent != null)
+						InspectorComponents [icomponent.Name] = icomponent;
+				}
+			}
+		}
+
+
+		void ParseEnums ()
+		{
+			foreach (var handle in metaReader.TypeDefinitions) {
+
+				var typeDef = metaReader.GetTypeDefinition (handle);
+
+				var baseTypeHandle = typeDef.BaseType;
+
+				if (baseTypeHandle.Kind == HandleKind.TypeReference) {
+					var typeRef = metaReader.GetTypeReference ((TypeReferenceHandle)baseTypeHandle);
+
+					if (metaReader.GetString (typeRef.Name) == "Enum") {
+						ParseEnum (typeDef);
+					}
+				}
+			}
+		}
+
+		void ParseEnum (TypeDefinition enumTypeDef)
+		{
+
+			// TODO: verify that int32 is the enums storage type for constant read below
+
+			InspectorEnum ienum = new InspectorEnum ();
+
+			ienum.Name = metaReader.GetString (enumTypeDef.Name);
+
+			InspectorEnums [ienum.Name] = ienum;
+
+			var fields = enumTypeDef.GetFields ();
+
+			foreach (var fieldHandle in fields) {
+
+				var inspectorField = new InspectorField ();
+
+				var fieldDef = metaReader.GetFieldDefinition (fieldHandle);
+
+				if ((fieldDef.Attributes & FieldAttributes.HasDefault) != 0) {
+
+					var constantHandle = fieldDef.GetDefaultValue ();
+					var constant = metaReader.GetConstant (constantHandle);
+
+					BlobReader constantReader = metaReader.GetBlobReader (constant.Value);
+
+					ienum.Values [metaReader.GetString (fieldDef.Name)] = constantReader.ReadInt32 ();
+
+				}
+			}
+
+			return;
+
+		}
+	}
+
+	internal class InspectorEnum
+	{
+		public String Name;
+		public Dictionary<string, int> Values = new Dictionary<string, int> ();
+
+		public Dictionary<string, object> GetJSONDict ()
+		{
+			var dict = new Dictionary<string,object> ();
+			dict ["name"] = Name;
+			dict ["values"] = Values;
+			return dict;
+		}
+	}
+
+	internal class InspectorComponent
+	{
+		public String Name;
+		public String Namespace;
+		public Dictionary<string, InspectorField> Fields = new Dictionary<string, InspectorField> ();
+
+		public Dictionary<string, object> GetJSONDict ()
+		{
+			var dict = new Dictionary<string,object> ();
+
+			dict ["name"] = Name;
+			dict ["namespace"] = Namespace;
+
+			var fieldList = new List<object> ();
+
+			foreach (var entry in Fields) {
+				fieldList.Add (entry.Value.GetJSONDict ());
+			}
+
+			dict ["fields"] = fieldList;
+
+			return dict;
+		}
+	}
+
+	internal class InspectorField
+	{
+
+		public Dictionary<string, object> GetJSONDict ()
+		{
+
+			var dict = new Dictionary<string,object> ();
+
+			dict ["isEnum"] = IsEnum;
+			dict ["typeName"] = TypeName;
+			dict ["name"] = Name;
+			dict ["defaultValue"] = DefaultValue;
+
+			dict ["caPos"] = CustomAttrPositionalArgs;
+			dict ["caNamed"] = CustomAttrNamedArgs;
+
+			return dict;
+
+		}
+
+		public bool IsEnum = false;
+
+		public string TypeName;
+
+		// the Name of the InspectorField
+		public string Name;
+		// The DefaultValue if supplied
+		public string DefaultValue;
+
+		// custom attributes, positional and named
+		public List<string> CustomAttrPositionalArgs = new List<string> ();
+		public Dictionary<string, string> CustomAttrNamedArgs = new Dictionary<string, string> ();
+	}
+
+}

+ 41 - 0
Script/AtomicNET/AtomicNET/AtomicNETTools/AtomicTools.cs

@@ -0,0 +1,41 @@
+using System;
+using System.IO;
+using System.Diagnostics;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Reflection;
+using System.Reflection.Metadata;
+using System.Reflection.PortableExecutable;
+using System.Reflection.Metadata.Ecma335;
+using System.Text;
+
+using AtomicEngine;
+
+using File = System.IO.File;
+
+namespace AtomicTools
+{
+	class AtomicTools
+	{
+
+		public static String InspectAssembly (String pathToAssembly)
+		{
+
+			try {
+
+				var inspector = new AssemblyInspector ();
+				inspector.Inspect (pathToAssembly);
+				return inspector.DumpToJSON();
+
+			} catch (Exception ex) {
+				Console.WriteLine (ex.Message);
+			}
+
+			return "";
+
+		}
+
+	}
+
+}

+ 808 - 0
Script/AtomicNET/AtomicNET/AtomicNETTools/CSComponentInspector.cs

@@ -0,0 +1,808 @@
+// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System.Collections.Immutable;
+
+//using Roslyn.Utilities;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.Text;
+using System.Reflection.Emit;
+using System.Reflection;
+using System.Reflection.Metadata;
+using System.Reflection.Metadata.Ecma335;
+using System.Reflection.PortableExecutable;
+
+// References
+
+//https://github.com/Microsoft/dotnetsamples/tree/master/System.Reflection.Metadata
+//https://github.com/dotnet/corefx/tree/master/src/System.Reflection.Metadata/tests
+//http://www.cnetion.com/getting-field-values-using-mono-cecil-qq-AUvBjRFgivICeoL1jxJy.php
+
+// https://github.com/Reactive-Extensions/IL2JS/blob/master/CCI2/PeReader/ILReader.cs
+
+// https://github.com/Reactive-Extensions/IL2JS
+
+// custom attr loading: https://github.com/Reactive-Extensions/IL2JS/blob/a4570f9c69b6c40d001e7539b952266d67609ca9/CST/PELoader.cs#L2352
+// custom attr: https://www.simple-talk.com/blogs/2011/06/03/anatomy-of-a-net-assembly-custom-attribute-encoding/
+// custom attr: https://github.com/jbevain/cecil/blob/67a2569688a13a6cb487f9af5c3418f7a8f43e3c/Mono.Cecil/AssemblyReader.cs
+
+// https://github.com/dotnet/roslyn/tree/master/src/Compilers/Core/Portable/MetadataReader
+
+
+namespace AtomicTools
+{
+
+	public class CSComponentInspector
+	{
+
+		InspectorComponent _inspectorComponent;
+
+		public CSComponentInspector (TypeDefinition typeDef, PEReader peFile, MetadataReader metaReader)
+		{
+			this.typeDef = typeDef;
+			this.peFile = peFile;
+			this.metaReader = metaReader;
+
+			this._inspectorComponent = new InspectorComponent ();
+			this._inspectorComponent.Name = metaReader.GetString (typeDef.Name);
+			this._inspectorComponent.Namespace = metaReader.GetString (typeDef.Namespace);
+		}
+
+		// Inspect a CSComponent derived class
+		internal InspectorComponent Inspect ()
+		{
+
+			var fields = typeDef.GetFields ();
+
+			foreach (var fieldHandle in fields) {
+
+				var inspectorField = new InspectorField ();
+
+				var fieldDef = metaReader.GetFieldDefinition (fieldHandle);
+
+				var customAttr = fieldDef.GetCustomAttributes ();
+
+				foreach (var caHandle in customAttr) {
+
+					// Look for InspectorAttribute
+					if (DecodeCustomAttribute (caHandle, inspectorField)) {
+
+						BlobReader sigReader = metaReader.GetBlobReader (fieldDef.Signature);
+						SignatureHeader header = sigReader.ReadSignatureHeader ();
+
+						if (header.Kind != SignatureKind.Field)
+							continue;
+
+						var typeCode = sigReader.ReadSignatureTypeCode ();
+
+						string typeName = typeCode.ToString ();
+
+						if (typeCode == SignatureTypeCode.TypeHandle) {
+
+							EntityHandle token = sigReader.ReadTypeHandle ();
+							HandleKind tokenType = token.Kind;
+
+							if (tokenType == HandleKind.TypeDefinition) {
+
+								// can store local enum typedefs
+								// enum initializers are stored as constant value in the IL
+
+								var typeDef = metaReader.GetTypeDefinition ((TypeDefinitionHandle)token);
+
+								var baseTypeToken = typeDef.BaseType;
+
+								if (baseTypeToken.Kind != HandleKind.TypeReference)
+									continue;
+
+								var baseTypeRef = metaReader.GetTypeReference ((TypeReferenceHandle)baseTypeToken);
+
+								if (metaReader.GetString (baseTypeRef.Name) != "Enum")
+									continue;
+
+								inspectorField.IsEnum = true;
+								typeName = metaReader.GetString (typeDef.Name);
+
+							} else if (tokenType == HandleKind.TypeReference) {
+
+								// TypeReference, ok
+								var typeRef = metaReader.GetTypeReference ((TypeReferenceHandle)token);
+
+								typeName = metaReader.GetString (typeRef.Name);
+
+							} else {
+								// ???
+								continue;
+							}
+
+						}
+
+						inspectorField.TypeName = typeName;
+						inspectorField.Name = metaReader.GetString (fieldDef.Name);
+						_inspectorComponent.Fields [inspectorField.Name] = inspectorField;
+
+						break;
+					}
+				}
+			}
+
+			// There is no way to get the initializer value of a field
+			// other than to inspect the IL code of the constructor
+			var methods = typeDef.GetMethods ();
+
+			foreach (var methodHandle in methods) {
+
+				var methodDef = metaReader.GetMethodDefinition (methodHandle);
+
+				if (metaReader.GetString (methodDef.Name) == ".ctor") {
+
+					var body = peFile.GetMethodBody (methodDef.RelativeVirtualAddress);
+					var ilBytes = body.GetILContent ();
+
+					InspectILBlock (ilBytes, ilBytes.Length);
+				}
+
+			}
+
+			//Dump ();
+
+			return _inspectorComponent;
+
+		}
+
+		private bool DecodeCustomAttribute (CustomAttributeHandle caHandle, InspectorField inspectorField)
+		{
+
+			// GetCustomAttribute: https://github.com/dotnet/roslyn/blob/master/src/Compilers/Core/Portable/MetadataReader/MetadataDecoder.cs#L1370
+
+			// Custom Attribute
+			var ca = metaReader.GetCustomAttribute (caHandle);
+
+			// MethodDefinitionHandle or MemberReferenceHandle
+			if (ca.Constructor.Kind != HandleKind.MemberReference) {
+				Console.WriteLine ("ca.Constructor.Kind != HandleKind.MemberReference");
+				return false;
+			}
+
+			// constructor of the custom attr which contains the signature
+			var memberRef = metaReader.GetMemberReference ((MemberReferenceHandle)ca.Constructor);
+
+			// parent of the constructor is the TypeReference
+			var parent = memberRef.Parent;
+
+			if (parent.Kind != HandleKind.TypeReference) {
+				Console.WriteLine ("parent.Kind != HandleKind.TypeReference");
+				return false;
+			}
+
+			var parentTypeRef = metaReader.GetTypeReference ((TypeReferenceHandle)parent);
+
+			// check whether we have an InspectorAttribute
+			if (metaReader.GetString (parentTypeRef.Name) != "InspectorAttribute") {
+				Console.WriteLine ("parentTypeRef != InspectorAttribute");
+				return false;
+			}
+
+			// args
+			var argsReader = metaReader.GetBlobReader ((BlobHandle)ca.Value);
+
+			uint prolog = argsReader.ReadUInt16 ();
+
+			if (prolog != 1) {
+				Console.WriteLine ("prolog != 1");
+				return false;
+			}
+
+			// sig reader is on constructor
+			BlobReader sigReader = metaReader.GetBlobReader (memberRef.Signature);
+			SignatureHeader header = sigReader.ReadSignatureHeader ();
+
+			// Get the type parameter count.
+			if (header.IsGeneric && sigReader.ReadCompressedInteger () != 0) {
+				Console.WriteLine ("header.IsGeneric && sigReader.ReadCompressedInteger() != 0");
+				return false;
+			}
+
+			// Get the parameter count
+			int paramCount = sigReader.ReadCompressedInteger ();
+
+			// Get the type return type.
+			var returnTypeCode = sigReader.ReadSignatureTypeCode ();
+
+			if (returnTypeCode != SignatureTypeCode.Void) {
+				Console.WriteLine ("returnTypeCode != SignatureTypeCode.Void");
+				return false;
+			}
+
+			List<SignatureTypeCode> sigTypeCodes = new List<SignatureTypeCode> ();
+
+			// position args
+			for (int i = 0; i < paramCount; i++) {
+
+				SignatureTypeCode paramTypeCode = sigReader.ReadSignatureTypeCode ();
+
+				// support string custom attr for now to simplify things
+				if (paramTypeCode != SignatureTypeCode.String)
+					return false;
+
+				string value;
+
+				if (CrackStringInAttributeValue (out value, ref argsReader)) {
+					inspectorField.CustomAttrPositionalArgs.Add (value);
+				}
+
+				sigTypeCodes.Add (paramTypeCode);
+			}
+
+			// named args
+
+			short namedParamCount = argsReader.ReadInt16 ();
+
+			for (short i = 0; i < namedParamCount; i++) {
+
+				// Ecma-335 23.3 - A NamedArg is simply a FixedArg preceded by information to identify which field or
+				// property it represents. [Note: Recall that the CLI allows fields and properties to have the same name; so
+				// we require a means to disambiguate such situations. end note] FIELD is the single byte 0x53. PROPERTY is
+				// the single byte 0x54.
+
+				// https://github.com/dotnet/roslyn/blob/master/src/Compilers/Core/Portable/MetadataReader/MetadataDecoder.cs#L1305
+
+				var kind = (CustomAttributeNamedArgumentKind)argsReader.ReadCompressedInteger ();
+
+				if (kind != CustomAttributeNamedArgumentKind.Field && kind != CustomAttributeNamedArgumentKind.Property) {
+					return false;
+				}
+
+				var typeCode = argsReader.ReadSerializationTypeCode ();
+
+				// support string custom attr for now to simplify things
+				if (typeCode != SerializationTypeCode.String)
+					return false;
+
+				string name;
+
+				if (!CrackStringInAttributeValue (out name, ref argsReader))
+					return false;
+
+				string value;
+
+				if (!CrackStringInAttributeValue (out value, ref argsReader))
+					return false;
+
+				inspectorField.CustomAttrNamedArgs [name] = value;
+
+			}
+
+			return true;
+
+		}
+
+		internal static bool CrackStringInAttributeValue (out string value, ref BlobReader sig)
+		{
+			try {
+				int strLen;
+				if (sig.TryReadCompressedInteger (out strLen) && sig.RemainingBytes >= strLen) {
+					value = sig.ReadUTF8 (strLen);
+
+					// Trim null characters at the end to mimic native compiler behavior.
+					// There are libraries that have them and leaving them in breaks tests.
+					value = value.TrimEnd ('\0');
+
+					return true;
+				}
+
+				value = null;
+
+				// Strings are stored as UTF8, but 0xFF means NULL string.
+				return sig.RemainingBytes >= 1 && sig.ReadByte () == 0xFF;
+			} catch (BadImageFormatException) {
+				value = null;
+				return false;
+			}
+		}
+
+		public void InspectILBlock (
+			ImmutableArray<byte> ilBytes,
+			int length,
+			IReadOnlyList<HandlerSpan> spans = null,
+			int blockOffset = 0,
+			IReadOnlyDictionary<int, string> markers = null)
+		{
+			if (ilBytes == null) {
+				return;
+			}
+
+			int spanIndex = 0;
+			int curIndex = InspectILBlock (ilBytes, length, spans, blockOffset, 0, spanIndex, markers, out spanIndex);
+		}
+
+		private int InspectILBlock (
+			ImmutableArray<byte> ilBytes,
+			int length,
+			IReadOnlyList<HandlerSpan> spans,
+			int blockOffset,
+			int curIndex,
+			int spanIndex,
+			IReadOnlyDictionary<int, string> markers,
+			out int nextSpanIndex)
+		{
+			int lastSpanIndex = spanIndex - 1;
+
+			List<string> loadedValues = new List<string> ();
+
+			while (curIndex < length) {
+
+				if (lastSpanIndex > 0 && StartsFilterHandler (spans, lastSpanIndex, curIndex + blockOffset)) {
+
+				}
+
+				if (StartsSpan (spans, spanIndex, curIndex + blockOffset)) {
+					curIndex = InspectILBlock (ilBytes, length, spans, blockOffset, curIndex, spanIndex + 1, markers, out spanIndex);
+				} else {
+
+					int ilOffset = curIndex + blockOffset;
+					string marker;
+					if (markers != null && markers.TryGetValue (ilOffset, out marker)) {
+					} else {
+					}
+
+					OpCode opCode;
+					int expectedSize;
+
+					byte op1 = ilBytes [curIndex++];
+					if (op1 == 0xfe && curIndex < length) {
+						byte op2 = ilBytes [curIndex++];
+						opCode = s_twoByteOpCodes [op2];
+						expectedSize = 2;
+					} else {
+						opCode = s_oneByteOpCodes [op1];
+						expectedSize = 1;
+					}
+
+					if (opCode.Size != expectedSize) {
+						//sb.AppendLine(string.Format("  <unknown 0x{0}{1:X2}>", expectedSize == 2 ? "fe" : "", op1));
+						continue;
+					}
+
+					//sb.Append("  ");
+
+					// Console.WriteLine (opCode.OperandType == OperandType.InlineNone ? "{0} {1}" : "{0,-10} {1}", opCode, opCode.OperandType);
+
+					switch (opCode.OperandType) {
+
+					case OperandType.InlineField:
+
+						// read token
+						uint fieldToken = ReadUInt32 (ilBytes, ref curIndex);
+						// get the kind
+						uint tokenKind = fieldToken & TokenTypeIds.TokenTypeMask;
+						// and the rowId
+						uint rowId = fieldToken & TokenTypeIds.RIDMask;
+
+						var fieldHandle = MetadataTokens.FieldDefinitionHandle ((int)rowId);
+
+						var fieldDef = metaReader.GetFieldDefinition (fieldHandle);
+
+						var fieldName = metaReader.GetString (fieldDef.Name);
+
+						if (opCode.ToString () == "stfld") {
+
+							InspectorField inspectorField;
+
+							if (_inspectorComponent.Fields.TryGetValue (fieldName, out inspectorField)) {
+								inspectorField.DefaultValue = String.Join (" ", loadedValues.ToArray ());
+							}
+
+						}
+
+						loadedValues.Clear ();
+
+						break;
+					case OperandType.InlineMethod:
+
+						// new Vector3, etc
+						if (opCode.ToString () == "newobj") {
+
+						} else
+							loadedValues.Clear ();
+
+						break;
+					case OperandType.InlineTok:
+					case OperandType.InlineType:
+						ReadUInt32 (ilBytes, ref curIndex);
+						loadedValues.Clear ();
+						break;
+
+					case OperandType.InlineSig: // signature (calli), not emitted by C#/VB
+						ReadUInt32 (ilBytes, ref curIndex);
+						loadedValues.Clear ();
+						break;
+
+					case OperandType.InlineString:
+							//sb.Append(" 391 ");
+							//sb.Append(VisualizeUserString());
+
+						uint stringToken = ReadUInt32 (ilBytes, ref curIndex);
+
+							// get the kind
+							//uint tokenKind = stringToken & TokenTypeIds.TokenTypeMask;
+							// and the rowId
+							//uint rowId = stringToken & TokenTypeIds.RIDMask;
+
+
+						UserStringHandle handle = MetadataTokens.UserStringHandle ((int)stringToken);
+						loadedValues.Add (metaReader.GetUserString (handle));
+
+						break;
+
+					case OperandType.InlineNone:
+
+						if (opCode == OpCodes.Ldc_I4_0)
+							loadedValues.Add ("0");
+						else if (opCode == OpCodes.Ldc_I4_1)
+							loadedValues.Add ("1");
+						else if (opCode == OpCodes.Ldc_I4_2)
+							loadedValues.Add ("2");
+						else if (opCode == OpCodes.Ldc_I4_3)
+							loadedValues.Add ("3");
+						else if (opCode == OpCodes.Ldc_I4_4)
+							loadedValues.Add ("4");
+						else if (opCode == OpCodes.Ldc_I4_5)
+							loadedValues.Add ("5");
+						else if (opCode == OpCodes.Ldc_I4_6)
+							loadedValues.Add ("6");
+						else if (opCode == OpCodes.Ldc_I4_7)
+							loadedValues.Add ("7");
+						else if (opCode == OpCodes.Ldc_I4_8)
+							loadedValues.Add ("8");
+						else if (opCode == OpCodes.Ldc_I4_M1)
+							loadedValues.Add ("-1");
+
+						break;
+
+					case OperandType.ShortInlineI:
+						loadedValues.Add (ReadSByte (ilBytes, ref curIndex).ToString ());
+						break;
+
+					case OperandType.ShortInlineVar:
+						loadedValues.Add (ReadByte (ilBytes, ref curIndex).ToString ());
+						break;
+
+					case OperandType.InlineVar:
+						loadedValues.Add (ReadUInt16 (ilBytes, ref curIndex).ToString ());
+						break;
+
+					case OperandType.InlineI:
+						loadedValues.Add (ReadUInt32 (ilBytes, ref curIndex).ToString ());
+						break;
+
+					case OperandType.InlineI8:
+						loadedValues.Add (ReadUInt64 (ilBytes, ref curIndex).ToString ());
+						break;
+
+					case OperandType.ShortInlineR:
+						{
+							loadedValues.Add (ReadSingle (ilBytes, ref curIndex).ToString ());
+						}
+						break;
+
+					case OperandType.InlineR:
+						{
+							loadedValues.Add (ReadDouble (ilBytes, ref curIndex).ToString ());
+						}
+						break;
+
+					case OperandType.ShortInlineBrTarget:
+						loadedValues.Clear ();
+						var sbyteValue = ReadSByte (ilBytes, ref curIndex) + curIndex + blockOffset;
+						break;
+
+					case OperandType.InlineBrTarget:
+						loadedValues.Clear ();
+						var int32value = ReadInt32 (ilBytes, ref curIndex) + curIndex + blockOffset;
+						break;
+
+					case OperandType.InlineSwitch:
+						loadedValues.Clear ();
+						int labelCount = ReadInt32 (ilBytes, ref curIndex);
+						int instrEnd = curIndex + labelCount * 4;
+						for (int i = 0; i < labelCount; i++) {
+							var int32LabelValue = ReadInt32 (ilBytes, ref curIndex) + instrEnd + blockOffset;
+							//sb.AppendLine((i == labelCount - 1) ? ")" : ",");
+						}
+						break;
+
+					default:
+						throw new InvalidOperationException ();
+					//throw ExceptionUtilities.UnexpectedValue(opCode.OperandType);
+					}
+
+					//sb.AppendLine();
+				}
+
+				if (EndsSpan (spans, lastSpanIndex, curIndex + blockOffset)) {
+					break;
+				}
+			}
+
+			nextSpanIndex = spanIndex;
+			return curIndex;
+		}
+
+		TypeDefinition typeDef;
+		PEReader peFile;
+		MetadataReader metaReader;
+
+		private static readonly OpCode[] s_oneByteOpCodes;
+		private static readonly OpCode[] s_twoByteOpCodes;
+
+		static CSComponentInspector ()
+		{
+			s_oneByteOpCodes = new OpCode[0x100];
+			s_twoByteOpCodes = new OpCode[0x100];
+
+			var typeOfOpCode = typeof(OpCode);
+
+			foreach (FieldInfo fi in typeof(OpCodes).GetTypeInfo().DeclaredFields) {
+				if (fi.FieldType != typeOfOpCode) {
+					continue;
+				}
+
+				OpCode opCode = (OpCode)fi.GetValue (null);
+				var value = unchecked((ushort)opCode.Value);
+				if (value < 0x100) {
+					s_oneByteOpCodes [value] = opCode;
+				} else if ((value & 0xff00) == 0xfe00) {
+					s_twoByteOpCodes [value & 0xff] = opCode;
+				}
+			}
+		}
+
+		private static ulong ReadUInt64 (ImmutableArray<byte> buffer, ref int pos)
+		{
+			ulong result =
+				buffer [pos] |
+				(ulong)buffer [pos + 1] << 8 |
+				(ulong)buffer [pos + 2] << 16 |
+				(ulong)buffer [pos + 3] << 24 |
+				(ulong)buffer [pos + 4] << 32 |
+				(ulong)buffer [pos + 5] << 40 |
+				(ulong)buffer [pos + 6] << 48 |
+				(ulong)buffer [pos + 7] << 56;
+
+			pos += sizeof(ulong);
+			return result;
+		}
+
+		private static uint ReadUInt32 (ImmutableArray<byte> buffer, ref int pos)
+		{
+			uint result = buffer [pos] | (uint)buffer [pos + 1] << 8 | (uint)buffer [pos + 2] << 16 | (uint)buffer [pos + 3] << 24;
+			pos += sizeof(uint);
+			return result;
+		}
+
+		private static int ReadInt32 (ImmutableArray<byte> buffer, ref int pos)
+		{
+			return unchecked((int)ReadUInt32 (buffer, ref pos));
+		}
+
+		private static ushort ReadUInt16 (ImmutableArray<byte> buffer, ref int pos)
+		{
+			ushort result = (ushort)(buffer [pos] | buffer [pos + 1] << 8);
+			pos += sizeof(ushort);
+			return result;
+		}
+
+		private static byte ReadByte (ImmutableArray<byte> buffer, ref int pos)
+		{
+			byte result = buffer [pos];
+			pos += sizeof(byte);
+			return result;
+		}
+
+		private static sbyte ReadSByte (ImmutableArray<byte> buffer, ref int pos)
+		{
+			sbyte result = unchecked((sbyte)buffer [pos]);
+			pos += 1;
+			return result;
+		}
+
+		private unsafe static float ReadSingle (ImmutableArray<byte> buffer, ref int pos)
+		{
+			uint value = ReadUInt32 (buffer, ref pos);
+			return *(float*)&value;
+		}
+
+		private unsafe static double ReadDouble (ImmutableArray<byte> buffer, ref int pos)
+		{
+			ulong value = ReadUInt64 (buffer, ref pos);
+			return *(double*)&value;
+		}
+
+		public enum HandlerKind
+		{
+			Try,
+			Catch,
+			Filter,
+			Finally,
+			Fault
+		}
+
+		public struct HandlerSpan : IComparable<HandlerSpan>
+		{
+			public readonly HandlerKind Kind;
+			public readonly object ExceptionType;
+			public readonly int StartOffset;
+			public readonly int FilterHandlerStart;
+			public readonly int EndOffset;
+
+			public HandlerSpan (HandlerKind kind, object exceptionType, int startOffset, int endOffset, int filterHandlerStart = 0)
+			{
+				this.Kind = kind;
+				this.ExceptionType = exceptionType;
+				this.StartOffset = startOffset;
+				this.EndOffset = endOffset;
+				this.FilterHandlerStart = filterHandlerStart;
+			}
+
+			public int CompareTo (HandlerSpan other)
+			{
+				int result = this.StartOffset - other.StartOffset;
+				if (result == 0) {
+					// Both blocks have same start. Order larger (outer) before smaller (inner).
+					result = other.EndOffset - this.EndOffset;
+				}
+
+				return result;
+			}
+
+			public string ToString (CSComponentInspector visualizer)
+			{
+				switch (this.Kind) {
+				default:
+					return ".try";
+				case HandlerKind.Catch:
+					return "catch **exceptiontype**";// + visualizer.VisualizeLocalType(this.ExceptionType);
+				case HandlerKind.Filter:
+					return "filter";
+				case HandlerKind.Finally:
+					return "finally";
+				case HandlerKind.Fault:
+					return "fault";
+				}
+			}
+
+			public override string ToString ()
+			{
+				throw new NotSupportedException ("Use ToString(CSComponentInspector)");
+			}
+		}
+
+		private static bool StartsSpan (IReadOnlyList<HandlerSpan> spans, int spanIndex, int curIndex)
+		{
+			return spans != null && spanIndex < spans.Count && spans [spanIndex].StartOffset == (uint)curIndex;
+		}
+
+		private static bool EndsSpan (IReadOnlyList<HandlerSpan> spans, int spanIndex, int curIndex)
+		{
+			return spans != null && spanIndex >= 0 && spans [spanIndex].EndOffset == (uint)curIndex;
+		}
+
+		private static bool StartsFilterHandler (IReadOnlyList<HandlerSpan> spans, int spanIndex, int curIndex)
+		{
+			return spans != null &&
+			spanIndex < spans.Count &&
+			spans [spanIndex].Kind == HandlerKind.Filter &&
+			spans [spanIndex].FilterHandlerStart == (uint)curIndex;
+		}
+
+		public static IReadOnlyList<HandlerSpan> GetHandlerSpans (ImmutableArray<ExceptionRegion> entries)
+		{
+			if (entries.Length == 0) {
+				return new HandlerSpan[0];
+			}
+
+			var result = new List<HandlerSpan> ();
+			foreach (ExceptionRegion entry in entries) {
+				int tryStartOffset = entry.TryOffset;
+				int tryEndOffset = entry.TryOffset + entry.TryLength;
+				var span = new HandlerSpan (HandlerKind.Try, null, tryStartOffset, tryEndOffset);
+
+				if (result.Count == 0 || span.CompareTo (result [result.Count - 1]) != 0) {
+					result.Add (span);
+				}
+			}
+
+			foreach (ExceptionRegion entry in entries) {
+				int handlerStartOffset = entry.HandlerOffset;
+				int handlerEndOffset = entry.HandlerOffset + entry.HandlerLength;
+
+				HandlerSpan span;
+				switch (entry.Kind) {
+				case ExceptionRegionKind.Catch:
+					span = new HandlerSpan (HandlerKind.Catch, MetadataTokens.GetToken (entry.CatchType), handlerStartOffset, handlerEndOffset);
+					break;
+
+				case ExceptionRegionKind.Fault:
+					span = new HandlerSpan (HandlerKind.Fault, null, handlerStartOffset, handlerEndOffset);
+					break;
+
+				case ExceptionRegionKind.Filter:
+					span = new HandlerSpan (HandlerKind.Filter, null, handlerStartOffset, handlerEndOffset, entry.FilterOffset);
+					break;
+
+				case ExceptionRegionKind.Finally:
+					span = new HandlerSpan (HandlerKind.Finally, null, handlerStartOffset, handlerEndOffset);
+					break;
+
+				default:
+					throw new InvalidOperationException ();
+				}
+
+				result.Add (span);
+			}
+
+			return result;
+		}
+
+		public void Dump ()
+		{
+			/*
+				foreach (var entry in InspectorFields) {
+					var field = entry.Value;
+
+					Console.WriteLine ("Inspector Field: {0}", field.Name);
+
+					Console.WriteLine ("   Type Name: {0}", field.TypeName);
+					Console.WriteLine ("   Default Value: {0}", field.DefaultValue);
+
+					Console.WriteLine ("   Positional Custom Attr:");
+					foreach (var p in field.CustomAttrPositionalArgs)
+					if (p.Length != 0)
+					Console.WriteLine ("      {0}", p);
+					Console.WriteLine ("   Named Custom Attr:");
+					foreach (var nentry in field.CustomAttrNamedArgs)
+					Console.WriteLine ("      {0}:{1}", nentry.Key, nentry.Value);
+				}
+				*/
+		}
+
+	}
+
+	internal static class TokenTypeIds
+	{
+		internal const uint Module = 0x00000000;
+		internal const uint TypeRef = 0x01000000;
+		internal const uint TypeDef = 0x02000000;
+		internal const uint FieldDef = 0x04000000;
+		internal const uint MethodDef = 0x06000000;
+		internal const uint ParamDef = 0x08000000;
+		internal const uint InterfaceImpl = 0x09000000;
+		internal const uint MemberRef = 0x0a000000;
+		internal const uint CustomAttribute = 0x0c000000;
+		internal const uint Permission = 0x0e000000;
+		internal const uint Signature = 0x11000000;
+		internal const uint Event = 0x14000000;
+		internal const uint Property = 0x17000000;
+		internal const uint ModuleRef = 0x1a000000;
+		internal const uint TypeSpec = 0x1b000000;
+		internal const uint Assembly = 0x20000000;
+		internal const uint AssemblyRef = 0x23000000;
+		internal const uint File = 0x26000000;
+		internal const uint ExportedType = 0x27000000;
+		internal const uint ManifestResource = 0x28000000;
+		internal const uint GenericParam = 0x2a000000;
+		internal const uint MethodSpec = 0x2b000000;
+		internal const uint GenericParamConstraint = 0x2c000000;
+		internal const uint String = 0x70000000;
+		internal const uint Name = 0x71000000;
+		internal const uint BaseType = 0x72000000;
+		// Leave this on the high end value. This does not correspond to metadata table???
+
+		internal const uint RIDMask = 0x00FFFFFF;
+		internal const uint TokenTypeMask = 0xFF000000;
+	}
+
+
+}

+ 549 - 0
Script/AtomicNET/AtomicNET/AtomicNETTools/MiniJSON.cs

@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 2012 Calvin Rien
+ *
+ * Based on the JSON parser by Patrick van Bergen
+ * http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html
+ *
+ * Simplified it so that it doesn't throw exceptions
+ * and can be used in Unity iPhone with maximum code stripping.
+ *
+ * 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.
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace MiniJSON {
+    // Example usage:
+    //
+    //  using UnityEngine;
+    //  using System.Collections;
+    //  using System.Collections.Generic;
+    //  using MiniJSON;
+    //
+    //  public class MiniJSONTest : MonoBehaviour {
+    //      void Start () {
+    //          var jsonString = "{ \"array\": [1.44,2,3], " +
+    //                          "\"object\": {\"key1\":\"value1\", \"key2\":256}, " +
+    //                          "\"string\": \"The quick brown fox \\\"jumps\\\" over the lazy dog \", " +
+    //                          "\"unicode\": \"\\u3041 Men\u00fa sesi\u00f3n\", " +
+    //                          "\"int\": 65536, " +
+    //                          "\"float\": 3.1415926, " +
+    //                          "\"bool\": true, " +
+    //                          "\"null\": null }";
+    //
+    //          var dict = Json.Deserialize(jsonString) as Dictionary<string,object>;
+    //
+    //          Debug.Log("deserialized: " + dict.GetType());
+    //          Debug.Log("dict['array'][0]: " + ((List<object>) dict["array"])[0]);
+    //          Debug.Log("dict['string']: " + (string) dict["string"]);
+    //          Debug.Log("dict['float']: " + (double) dict["float"]); // floats come out as doubles
+    //          Debug.Log("dict['int']: " + (long) dict["int"]); // ints come out as longs
+    //          Debug.Log("dict['unicode']: " + (string) dict["unicode"]);
+    //
+    //          var str = Json.Serialize(dict);
+    //
+    //          Debug.Log("serialized: " + str);
+    //      }
+    //  }
+
+    /// <summary>
+    /// This class encodes and decodes JSON strings.
+    /// Spec. details, see http://www.json.org/
+    ///
+    /// JSON uses Arrays and Objects. These correspond here to the datatypes IList and IDictionary.
+    /// All numbers are parsed to doubles.
+    /// </summary>
+    public static class Json {
+        /// <summary>
+        /// Parses the string json into a value
+        /// </summary>
+        /// <param name="json">A JSON string.</param>
+        /// <returns>An List&lt;object&gt;, a Dictionary&lt;string, object&gt;, a double, an integer,a string, null, true, or false</returns>
+        public static object Deserialize(string json) {
+            // save the string for debug information
+            if (json == null) {
+                return null;
+            }
+
+            return Parser.Parse(json);
+        }
+
+        sealed class Parser : IDisposable {
+            const string WHITE_SPACE = " \t\n\r";
+            const string WORD_BREAK = " \t\n\r{}[],:\"";
+
+            enum TOKEN {
+                NONE,
+                CURLY_OPEN,
+                CURLY_CLOSE,
+                SQUARED_OPEN,
+                SQUARED_CLOSE,
+                COLON,
+                COMMA,
+                STRING,
+                NUMBER,
+                TRUE,
+                FALSE,
+                NULL
+            };
+
+            StringReader json;
+
+            Parser(string jsonString) {
+                json = new StringReader(jsonString);
+            }
+
+            public static object Parse(string jsonString) {
+                using (var instance = new Parser(jsonString)) {
+                    return instance.ParseValue();
+                }
+            }
+
+            public void Dispose() {
+                json.Dispose();
+                json = null;
+            }
+
+            Dictionary<string, object> ParseObject() {
+                Dictionary<string, object> table = new Dictionary<string, object>();
+
+                // ditch opening brace
+                json.Read();
+
+                // {
+                while (true) {
+                    switch (NextToken) {
+                    case TOKEN.NONE:
+                        return null;
+                    case TOKEN.COMMA:
+                        continue;
+                    case TOKEN.CURLY_CLOSE:
+                        return table;
+                    default:
+                        // name
+                        string name = ParseString();
+                        if (name == null) {
+                            return null;
+                        }
+
+                        // :
+                        if (NextToken != TOKEN.COLON) {
+                            return null;
+                        }
+                        // ditch the colon
+                        json.Read();
+
+                        // value
+                        table[name] = ParseValue();
+                        break;
+                    }
+                }
+            }
+
+            List<object> ParseArray() {
+                List<object> array = new List<object>();
+
+                // ditch opening bracket
+                json.Read();
+
+                // [
+                var parsing = true;
+                while (parsing) {
+                    TOKEN nextToken = NextToken;
+
+                    switch (nextToken) {
+                    case TOKEN.NONE:
+                        return null;
+                    case TOKEN.COMMA:
+                        continue;
+                    case TOKEN.SQUARED_CLOSE:
+                        parsing = false;
+                        break;
+                    default:
+                        object value = ParseByToken(nextToken);
+
+                        array.Add(value);
+                        break;
+                    }
+                }
+
+                return array;
+            }
+
+            object ParseValue() {
+                TOKEN nextToken = NextToken;
+                return ParseByToken(nextToken);
+            }
+
+            object ParseByToken(TOKEN token) {
+                switch (token) {
+                case TOKEN.STRING:
+                    return ParseString();
+                case TOKEN.NUMBER:
+                    return ParseNumber();
+                case TOKEN.CURLY_OPEN:
+                    return ParseObject();
+                case TOKEN.SQUARED_OPEN:
+                    return ParseArray();
+                case TOKEN.TRUE:
+                    return true;
+                case TOKEN.FALSE:
+                    return false;
+                case TOKEN.NULL:
+                    return null;
+                default:
+                    return null;
+                }
+            }
+
+            string ParseString() {
+                StringBuilder s = new StringBuilder();
+                char c;
+
+                // ditch opening quote
+                json.Read();
+
+                bool parsing = true;
+                while (parsing) {
+
+                    if (json.Peek() == -1) {
+                        parsing = false;
+                        break;
+                    }
+
+                    c = NextChar;
+                    switch (c) {
+                    case '"':
+                        parsing = false;
+                        break;
+                    case '\\':
+                        if (json.Peek() == -1) {
+                            parsing = false;
+                            break;
+                        }
+
+                        c = NextChar;
+                        switch (c) {
+                        case '"':
+                        case '\\':
+                        case '/':
+                            s.Append(c);
+                            break;
+                        case 'b':
+                            s.Append('\b');
+                            break;
+                        case 'f':
+                            s.Append('\f');
+                            break;
+                        case 'n':
+                            s.Append('\n');
+                            break;
+                        case 'r':
+                            s.Append('\r');
+                            break;
+                        case 't':
+                            s.Append('\t');
+                            break;
+                        case 'u':
+                            var hex = new StringBuilder();
+
+                            for (int i=0; i< 4; i++) {
+                                hex.Append(NextChar);
+                            }
+
+                            s.Append((char) Convert.ToInt32(hex.ToString(), 16));
+                            break;
+                        }
+                        break;
+                    default:
+                        s.Append(c);
+                        break;
+                    }
+                }
+
+                return s.ToString();
+            }
+
+            object ParseNumber() {
+                string number = NextWord;
+
+                if (number.IndexOf('.') == -1) {
+                    long parsedInt;
+                    Int64.TryParse(number, out parsedInt);
+                    return parsedInt;
+                }
+
+                double parsedDouble;
+                Double.TryParse(number, out parsedDouble);
+                return parsedDouble;
+            }
+
+            void EatWhitespace() {
+                while (WHITE_SPACE.IndexOf(PeekChar) != -1) {
+                    json.Read();
+
+                    if (json.Peek() == -1) {
+                        break;
+                    }
+                }
+            }
+
+            char PeekChar {
+                get {
+                    return Convert.ToChar(json.Peek());
+                }
+            }
+
+            char NextChar {
+                get {
+                    return Convert.ToChar(json.Read());
+                }
+            }
+
+            string NextWord {
+                get {
+                    StringBuilder word = new StringBuilder();
+
+                    while (WORD_BREAK.IndexOf(PeekChar) == -1) {
+                        word.Append(NextChar);
+
+                        if (json.Peek() == -1) {
+                            break;
+                        }
+                    }
+
+                    return word.ToString();
+                }
+            }
+
+            TOKEN NextToken {
+                get {
+                    EatWhitespace();
+
+                    if (json.Peek() == -1) {
+                        return TOKEN.NONE;
+                    }
+
+                    char c = PeekChar;
+                    switch (c) {
+                    case '{':
+                        return TOKEN.CURLY_OPEN;
+                    case '}':
+                        json.Read();
+                        return TOKEN.CURLY_CLOSE;
+                    case '[':
+                        return TOKEN.SQUARED_OPEN;
+                    case ']':
+                        json.Read();
+                        return TOKEN.SQUARED_CLOSE;
+                    case ',':
+                        json.Read();
+                        return TOKEN.COMMA;
+                    case '"':
+                        return TOKEN.STRING;
+                    case ':':
+                        return TOKEN.COLON;
+                    case '0':
+                    case '1':
+                    case '2':
+                    case '3':
+                    case '4':
+                    case '5':
+                    case '6':
+                    case '7':
+                    case '8':
+                    case '9':
+                    case '-':
+                        return TOKEN.NUMBER;
+                    }
+
+                    string word = NextWord;
+
+                    switch (word) {
+                    case "false":
+                        return TOKEN.FALSE;
+                    case "true":
+                        return TOKEN.TRUE;
+                    case "null":
+                        return TOKEN.NULL;
+                    }
+
+                    return TOKEN.NONE;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Converts a IDictionary / IList object or a simple type (string, int, etc.) into a JSON string
+        /// </summary>
+        /// <param name="json">A Dictionary&lt;string, object&gt; / List&lt;object&gt;</param>
+        /// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns>
+        public static string Serialize(object obj) {
+            return Serializer.Serialize(obj);
+        }
+
+        sealed class Serializer {
+            StringBuilder builder;
+
+            Serializer() {
+                builder = new StringBuilder();
+            }
+
+            public static string Serialize(object obj) {
+                var instance = new Serializer();
+
+                instance.SerializeValue(obj);
+
+                return instance.builder.ToString();
+            }
+
+            void SerializeValue(object value) {
+                IList asList;
+                IDictionary asDict;
+                string asStr;
+
+                if (value == null) {
+                    builder.Append("null");
+                }
+                else if ((asStr = value as string) != null) {
+                    SerializeString(asStr);
+                }
+                else if (value is bool) {
+                    builder.Append(value.ToString().ToLower());
+                }
+                else if ((asList = value as IList) != null) {
+                    SerializeArray(asList);
+                }
+                else if ((asDict = value as IDictionary) != null) {
+                    SerializeObject(asDict);
+                }
+                else if (value is char) {
+                    SerializeString(value.ToString());
+                }
+                else {
+                    SerializeOther(value);
+                }
+            }
+
+            void SerializeObject(IDictionary obj) {
+                bool first = true;
+
+                builder.Append('{');
+
+                foreach (object e in obj.Keys) {
+                    if (!first) {
+                        builder.Append(',');
+                    }
+
+                    SerializeString(e.ToString());
+                    builder.Append(':');
+
+                    SerializeValue(obj[e]);
+
+                    first = false;
+                }
+
+                builder.Append('}');
+            }
+
+            void SerializeArray(IList anArray) {
+                builder.Append('[');
+
+                bool first = true;
+
+                foreach (object obj in anArray) {
+                    if (!first) {
+                        builder.Append(',');
+                    }
+
+                    SerializeValue(obj);
+
+                    first = false;
+                }
+
+                builder.Append(']');
+            }
+
+            void SerializeString(string str) {
+                builder.Append('\"');
+
+                char[] charArray = str.ToCharArray();
+                foreach (var c in charArray) {
+                    switch (c) {
+                    case '"':
+                        builder.Append("\\\"");
+                        break;
+                    case '\\':
+                        builder.Append("\\\\");
+                        break;
+                    case '\b':
+                        builder.Append("\\b");
+                        break;
+                    case '\f':
+                        builder.Append("\\f");
+                        break;
+                    case '\n':
+                        builder.Append("\\n");
+                        break;
+                    case '\r':
+                        builder.Append("\\r");
+                        break;
+                    case '\t':
+                        builder.Append("\\t");
+                        break;
+                    default:
+                        int codepoint = Convert.ToInt32(c);
+                        if ((codepoint >= 32) && (codepoint <= 126)) {
+                            builder.Append(c);
+                        }
+                        else {
+                            builder.Append("\\u" + Convert.ToString(codepoint, 16).PadLeft(4, '0'));
+                        }
+                        break;
+                    }
+                }
+
+                builder.Append('\"');
+            }
+
+            void SerializeOther(object value) {
+                if (value is float
+                    || value is int
+                    || value is uint
+                    || value is long
+                    || value is double
+                    || value is sbyte
+                    || value is byte
+                    || value is short
+                    || value is ushort
+                    || value is ulong
+                    || value is decimal) {
+                    builder.Append(value.ToString());
+                }
+                else {
+                    SerializeString(value.ToString());
+                }
+            }
+        }
+    }
+}

+ 44 - 0
Script/AtomicNET/AtomicNET/build.cmd

@@ -0,0 +1,44 @@
+
+csc /out:../../../Artifacts/AtomicNET/TPA/AtomicNETBootstrap.dll /nostdlib+ /noconfig /t:library ^
+/lib:../../../Submodules/CoreCLR/Windows/Release/x64/ ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/System.Collections.Concurrent.dll ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/System.Runtime.dll ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/System.Linq.dll ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/System.Collections.dll ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/mscorlib.ni.dll ^
+AtomicNETBootstrap/*.cs
+
+csc /out:../../../Artifacts/AtomicNET/AtomicNETEngine.dll /nostdlib+ /noconfig /t:library /w:0 ^
+/lib:../../../Submodules/CoreCLR/Windows/Release/x64/ ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/System.Runtime.dll ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/System.IO.dll ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/System.IO.FileSystem.dll ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/System.Linq.dll ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/mscorlib.ni.dll ^
+../../../Build/Source/Generated/WINDOWS/CSharp/Packages/Atomic/Managed/*.cs ^
+../../../Build/Source/Generated/WINDOWS/CSharp/Packages/AtomicNET/Managed/*.cs ^
+../../../Build/Source/Generated/WINDOWS/CSharp/Packages/AtomicPlayer/Managed/*.cs ^
+AtomicNETEngine/*.cs
+
+csc /unsafe /out:../../../Artifacts/AtomicNET/AtomicNETTools.dll /nostdlib+ /noconfig /t:library /w:0 ^
+/lib:../../../Submodules/CoreCLR/Windows/Release/x64/ ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/System.Runtime.dll ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/System.IO.dll ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/System.Linq.dll ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/System.Reflection.Primitives.dll ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/System.Reflection.Metadata.dll ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/System.Collections.dll ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/System.Collections.Immutable.dll ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/mscorlib.ni.dll ^
+/r:../../../Artifacts/AtomicNET/AtomicNETEngine.dll ^
+AtomicNETTools/*.cs
+
+csc /out:../../../Artifacts/AtomicNET/AtomicNETTestCompile.dll ^
+/debug+ /nostdlib+ /noconfig /t:library /w:0 ^
+/lib:../../../Submodules/CoreCLR/Windows/Release/x64/ ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/System.Runtime.dll ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/System.IO.dll ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/System.IO.FileSystem.dll ^
+/r:../../../Submodules/CoreCLR/Windows/Release/x64/mscorlib.ni.dll ^
+/r:../../../Artifacts/AtomicNET/AtomicNETEngine.dll ^
+../AtomicNETTest/MyClass.cs

+ 29 - 0
Script/AtomicNET/AtomicNET/build.sh

@@ -0,0 +1,29 @@
+
+/usr/local/bin/mcs /out:../../../Artifacts/AtomicNET/TPA/AtomicNETBootstrap.dll /nostdlib /noconfig /t:library \
+/lib:../../../Submodules/CoreCLR/MacOSX/Debug/x64/ \
+/r:System.Console.dll /r:System.Runtime.dll /r:System.IO.dll /r:System.IO.FileSystem.dll /r:mscorlib.dll \
+/r:System.Collections.dll /r:System.Collections.Concurrent.dll /r:System.Linq.dll \
+AtomicNETBootstrap/*.cs
+
+/usr/local/bin/mcs /out:../../../Artifacts/AtomicNET/AtomicNETEngine.dll /nostdlib /noconfig /t:library /w:0 \
+/lib:../../../Submodules/CoreCLR/MacOSX/Debug/x64/ \
+/r:System.Console.dll /r:System.Runtime.dll /r:System.IO.dll /r:System.IO.FileSystem.dll /r:mscorlib.dll \
+/r:System.Linq.dll \
+../../../Build/Source/Generated/MACOSX/CSharp/Packages/Atomic/Managed/*.cs \
+../../../Build/Source/Generated/MACOSX/CSharp/Packages/AtomicNET/Managed/*.cs \
+../../../Build/Source/Generated/MACOSX/CSharp/Packages/AtomicPlayer/Managed/*.cs \
+AtomicNETEngine/*.cs
+
+/usr/local/bin/mcs /unsafe /out:../../../Artifacts/AtomicNET/AtomicNETTools.dll /nostdlib /noconfig /t:library /w:0 \
+/lib:../../../Submodules/CoreCLR/MacOSX/Debug/x64/ \
+/r:System.Console.dll /r:System.Runtime.dll /r:System.IO.dll /r:System.IO.FileSystem.dll /r:mscorlib.dll \
+/r:System.Linq.dll /r:System.Reflection.Primitives.dll /r:System.Reflection.Metadata.dll \
+/r:System.Collections.dll /r:System.Collections.Immutable.dll \
+/r:../../../Artifacts/AtomicNET/AtomicNETEngine.dll \
+AtomicNETTools/*.cs
+
+/usr/local/bin/mcs /out:../../../Artifacts/AtomicNET/AtomicNETTestCompile.dll /nostdlib /noconfig /t:library /w:0 \
+/lib:../../../Submodules/CoreCLR/MacOSX/Debug/x64/ \
+/r:System.Console.dll /r:System.Runtime.dll /r:System.IO.dll /r:System.IO.FileSystem.dll /r:mscorlib.dll \
+/r:../../../Artifacts/AtomicNET/AtomicNETEngine.dll \
+../AtomicNETTest/MyClass.cs

+ 54 - 0
Script/AtomicNET/AtomicNETProjects.json

@@ -0,0 +1,54 @@
+{
+  "solution" : {
+    "name" : "AtomicNET",
+    "outputPath" : "$ATOMIC_ROOT$/Artifacts/AtomicNET/Build/"
+  },
+  "projects" : [
+    {
+      "name": "AtomicNETBootstrap",
+      "outputType" : "Library",
+      "rootNamespace" : "Atomic.Bootstrap",
+      "assemblyName" : "AtomicNETBootstrap",
+      "assemblyOutputPath" : "$ATOMIC_ROOT$/Artifacts/AtomicNET/TPA/",
+      "references" : [
+        "System.Runtime", "System.Collections", "System.Collections.Concurrent", "System.Linq"
+      ],
+      "sources" : [
+        "$ATOMIC_ROOT$/Script/AtomicNET/AtomicNET/AtomicNETBootstrap/"
+      ]
+    },
+    {
+      "name": "AtomicNETEngine",
+      "outputType" : "Library",
+      "rootNamespace" : "AtomicEngine",
+      "assemblyName" : "AtomicNETEngine",
+      "assemblyOutputPath" : "$ATOMIC_ROOT$/Artifacts/AtomicNET/",
+      "references" : [
+        "System.Runtime" , "System.Linq"
+      ],
+      "sources" : [
+        "$ATOMIC_ROOT$/Script/AtomicNET/AtomicNET/AtomicNETEngine/",
+        "$ATOMIC_ROOT$/Build/Source/Generated/$SCRIPT_PLATFORM$/CSharp/Packages/Atomic/Managed/",
+        "$ATOMIC_ROOT$/Build/Source/Generated/$SCRIPT_PLATFORM$/CSharp/Packages/AtomicNET/Managed/",
+        "$ATOMIC_ROOT$/Build/Source/Generated/$SCRIPT_PLATFORM$/CSharp/Packages/AtomicPlayer/Managed/"
+      ]
+    },
+    {
+      "name": "AtomicNETTools",
+      "outputType" : "Library",
+      "rootNamespace" : "AtomicTools",
+      "assemblyName" : "AtomicNETTools",
+      "assemblyOutputPath" : "$ATOMIC_ROOT$/Artifacts/AtomicNET/",
+      "assemblySearchPaths" : "$ATOMIC_ROOT$/Artifacts/AtomicNET/",
+      "references" : [
+        "System.Runtime" , "System.IO",
+        "System.Reflection.Metadata", "System.Reflection.Primitives", "System.Collections.Immutable",
+        "System.Linq",
+        "AtomicNETEngine"
+      ],
+      "sources" : [
+        "$ATOMIC_ROOT$/Script/AtomicNET/AtomicNET/AtomicNETTools/"
+      ]
+    }
+  ]
+}

+ 1 - 2
Script/Packages/Atomic/Package.json

@@ -5,8 +5,7 @@
 
 	"modules" : ["Container", "Math", "Core", "Scene", "Graphics", "Atomic3D", "Atomic2D", "Audio",
 	"Physics", "Navigation", "Input", "UI", "Resource", "Network", "IO",
-	"Engine", "Javascript", "Environment", "Web"],
-
+	"Engine", "Script", "Javascript", "Environment", "Web"],
 	"moduleExclude" : {
 		"WEB" : ["Network", "Navigation"]
 	}

+ 3 - 2
Script/Packages/Atomic/Scene.json

@@ -18,7 +18,8 @@
 			"GetChild" : ["String", "bool"],
 			"SetScale" : ["Vector3"],
 			"SetPosition2D" : ["Vector2"],
-			"SetScale2D" : ["Vector2"]
+			"SetScale2D" : ["Vector2"],
+			"RemoveComponent" : ["Component"]
 		},
 		"ValueAnimationInfo" : {
 			"ValueAnimationInfo" : ["ValueAnimation", "WrapMode", "float"]
@@ -49,7 +50,7 @@
 		]
 	},
 	"haxe_decl" : {
-		
+
 		"Node" : [
 			"function saveXML(file:File):Bool;",
 			"function getChildrenWithName(name:String, ?recursive:Bool):Array<Node>;",

+ 5 - 0
Script/Packages/Atomic/Script.json

@@ -0,0 +1,5 @@
+{
+	"name" : "Script",
+	"sources" : ["Source/Atomic/Script"],
+	"classes" : ["ScriptComponent", "ScriptComponentFile"]
+}

+ 6 - 0
Script/Packages/AtomicNET/NETCore.json

@@ -0,0 +1,6 @@
+{
+	"name" : "NETCore",
+	"sources" : ["Source/AtomicNET/NETCore"],
+	"classes" : ["NETCore", "NETVariantMap"]
+
+}

+ 6 - 0
Script/Packages/AtomicNET/NETScript.json

@@ -0,0 +1,6 @@
+{
+	"name" : "NETScript",
+	"sources" : ["Source/AtomicNET/NETScript"],
+	"classes" : ["CSManaged", "CSComponentAssembly", "CSScriptObject", "CSComponent"]
+
+}

+ 7 - 0
Script/Packages/AtomicNET/Package.json

@@ -0,0 +1,7 @@
+
+{
+  "name" : "AtomicNET",
+  "namespace" : "Atomic",
+  "dependencies" : ["Script/Packages/Atomic"],
+  "modules" : ["NETCore", "NETScript"]
+}

+ 2 - 1
Script/Packages/ToolCore/ToolCore.json

@@ -7,7 +7,8 @@
 								"Project", "ProjectFile", "Platform", "PlatformMac", "PlatformWeb",
 							 "PlatformWindows", "PlatformAndroid", "PlatformIOS", "Command", "PlayCmd", "OpenAssetImporter",
 							 "Asset", "AssetDatabase", "AssetImporter", "AudioImporter", "ModelImporter", "MaterialImporter", "AnimationImportInfo",
-							 "PrefabImporter", "JavascriptImporter", "TextureImporter", "SpriterImporter", "PEXImporter", "LicenseSystem",
+							 "PrefabImporter", "JavascriptImporter", "TextureImporter", "SpriterImporter", "PEXImporter", "NETAssemblyImporter",
+							 "LicenseSystem",
 						 	 "ProjectUserPrefs", "ProjectBuildSettings",
 						 	 "BuildBase", "BuildSystem", "BuildMac", "BuildWeb", "BuildWindows", "BuildAndroid", "BuildIOS",
 						 	 "ProjectBuildSettings", "MacBuildSettings", "WindowsBuildSettings", "WebBuildSettings", "AndroidBuildSettings", "IOSBuildSettings"],

+ 11 - 0
Script/TypeScript/AtomicWork.d.ts

@@ -209,6 +209,17 @@ declare module Atomic {
 
 }
 
+declare module AtomicNET {
+
+    export interface CSComponentClassChangedEvent {
+
+      cscomponent: CSComponent;
+      classname: string;
+
+    }
+
+}
+
 declare module ToolCore {
 
     export interface ResourceAddedEvent {

+ 18 - 18
Script/tsconfig.json

@@ -15,7 +15,6 @@
         "./AtomicEditor/**/*.ts"
     ],
     "files": [
-        "./ToolCore/build/BuildSettings.ts",
         "./AtomicEditor/editor/Editor.ts",
         "./AtomicEditor/editor/EditorEvents.ts",
         "./AtomicEditor/editor/EditorLicense.ts",
@@ -24,15 +23,7 @@
         "./AtomicEditor/resources/ResourceOps.ts",
         "./AtomicEditor/ui/EditorStrings.ts",
         "./AtomicEditor/ui/EditorUI.ts",
-        "./AtomicEditor/ui/MainToolbar.ts",
-        "./AtomicEditor/ui/ScriptWidget.ts",
-        "./AtomicEditor/ui/Shortcuts.ts",
-        "./AtomicEditor/ui/UIEvents.ts",
         "./AtomicEditor/ui/frames/HierarchyFrame.ts",
-        "./AtomicEditor/ui/frames/MainFrame.ts",
-        "./AtomicEditor/ui/frames/ProjectFrame.ts",
-        "./AtomicEditor/ui/frames/ResourceFrame.ts",
-        "./AtomicEditor/ui/frames/WelcomeFrame.ts",
         "./AtomicEditor/ui/frames/inspector/ArrayEditWidget.ts",
         "./AtomicEditor/ui/frames/inspector/ComponentInspector.ts",
         "./AtomicEditor/ui/frames/inspector/CreateComponentButton.ts",
@@ -44,19 +35,16 @@
         "./AtomicEditor/ui/frames/inspector/ModelInspector.ts",
         "./AtomicEditor/ui/frames/inspector/NodeInspector.ts",
         "./AtomicEditor/ui/frames/inspector/TextureSelector.ts",
+        "./AtomicEditor/ui/frames/MainFrame.ts",
         "./AtomicEditor/ui/frames/menus/HierarchyFrameMenu.ts",
         "./AtomicEditor/ui/frames/menus/MainFrameMenu.ts",
         "./AtomicEditor/ui/frames/menus/MenuItemSources.ts",
         "./AtomicEditor/ui/frames/menus/ProjectFrameMenu.ts",
+        "./AtomicEditor/ui/frames/ProjectFrame.ts",
+        "./AtomicEditor/ui/frames/ResourceFrame.ts",
+        "./AtomicEditor/ui/frames/WelcomeFrame.ts",
+        "./AtomicEditor/ui/MainToolbar.ts",
         "./AtomicEditor/ui/modal/About.ts",
-        "./AtomicEditor/ui/modal/CreateProject.ts",
-        "./AtomicEditor/ui/modal/MessageModal.ts",
-        "./AtomicEditor/ui/modal/ModalOps.ts",
-        "./AtomicEditor/ui/modal/ModalWindow.ts",
-        "./AtomicEditor/ui/modal/NewProject.ts",
-        "./AtomicEditor/ui/modal/ProgressModal.ts",
-        "./AtomicEditor/ui/modal/ResourceSelection.ts",
-        "./AtomicEditor/ui/modal/UIResourceOps.ts",
         "./AtomicEditor/ui/modal/build/BuildComplete.ts",
         "./AtomicEditor/ui/modal/build/BuildOutput.ts",
         "./AtomicEditor/ui/modal/build/BuildSettingsWindow.ts",
@@ -66,13 +54,25 @@
         "./AtomicEditor/ui/modal/build/platforms/MacSettingsWidget.ts",
         "./AtomicEditor/ui/modal/build/platforms/WebSettingsWidget.ts",
         "./AtomicEditor/ui/modal/build/platforms/WindowsSettingsWidget.ts",
+        "./AtomicEditor/ui/modal/CreateProject.ts",
         "./AtomicEditor/ui/modal/license/ActivationSuccessWindow.ts",
         "./AtomicEditor/ui/modal/license/ActivationWindow.ts",
         "./AtomicEditor/ui/modal/license/EULAWindow.ts",
         "./AtomicEditor/ui/modal/license/ManageLicense.ts",
         "./AtomicEditor/ui/modal/license/Pro3DWindow.ts",
         "./AtomicEditor/ui/modal/license/ProPlatformWindow.ts",
+        "./AtomicEditor/ui/modal/MessageModal.ts",
+        "./AtomicEditor/ui/modal/ModalOps.ts",
+        "./AtomicEditor/ui/modal/ModalWindow.ts",
+        "./AtomicEditor/ui/modal/NewProject.ts",
+        "./AtomicEditor/ui/modal/ProgressModal.ts",
+        "./AtomicEditor/ui/modal/ResourceSelection.ts",
+        "./AtomicEditor/ui/modal/UIResourceOps.ts",
+        "./AtomicEditor/ui/playmode/PlayerOutput.ts",
         "./AtomicEditor/ui/playmode/PlayMode.ts",
-        "./AtomicEditor/ui/playmode/PlayerOutput.ts"
+        "./AtomicEditor/ui/ScriptWidget.ts",
+        "./AtomicEditor/ui/Shortcuts.ts",
+        "./AtomicEditor/ui/UIEvents.ts",
+        "./ToolCore/build/BuildSettings.ts"
     ]
 }

+ 2 - 2
Source/Atomic/Atomic2D/TmxFile2D.h

@@ -40,7 +40,7 @@ class TmxLayer2D : public RefCounted
     REFCOUNTED(TmxLayer2D)
 
 public:
-    TmxLayer2D(TmxFile2D* tmxFile, TileMapLayerType2D type);
+    TmxLayer2D(TmxFile2D* tmxFile = 0, TileMapLayerType2D type = LT_TILE_LAYER);
     virtual ~TmxLayer2D();
 
     /// Return tmx file.
@@ -95,7 +95,7 @@ class TmxTileLayer2D : public TmxLayer2D
     REFCOUNTED(TmxTileLayer2D)
 
 public:
-    TmxTileLayer2D(TmxFile2D* tmxFile);
+    TmxTileLayer2D(TmxFile2D* tmxFile = 0);
 
     /// Load from XML element.
     bool Load(const XMLElement& element, const TileMapInfo2D& info);

+ 1 - 1
Source/Atomic/Atomic3D/BillboardSet.h

@@ -35,7 +35,7 @@ class IndexBuffer;
 class VertexBuffer;
 
 /// One billboard in the billboard set.
-struct ATOMIC_API Billboard : public RefCounted
+class ATOMIC_API Billboard : public RefCounted
 {
     friend class BillboardSet;
     friend class ParticleEmitter;

+ 3 - 1
Source/Atomic/CMakeLists.txt

@@ -19,6 +19,7 @@ file (GLOB RESOURCE_SOURCE Resource/*.cpp Resource/*.h)
 file (GLOB AUDIO_SOURCE Audio/*.cpp Audio/*.h)
 file (GLOB NETWORK_SOURCE Network/*.cpp Network/*.h)
 file (GLOB WEB_SOURCE Web/*.cpp Web/*.h)
+file (GLOB SCRIPT_SOURCE Script/*.cpp Script/*.h)
 
 if (NOT EMSCRIPTEN AND NOT IOS AND NOT ANDROID)
   file (GLOB IPC_SOURCE IPC/*.cpp IPC/*.h)
@@ -72,7 +73,8 @@ set (SOURCE_FILES ${CONTAINER_SOURCE} ${CORE_SOURCE} ${ENGINE_SOURCE} ${INPUT_SO
                   ${GRAPHICS_SOURCE} ${GRAPHICS_IMPL_SOURCE}
                   ${ATOMIC3D_SOURCE}
                   ${ATOMIC2D_SOURCE} ${ENVIRONMENT_SOURCE}
-                  ${SCENE_SOURCE} ${UI_SOURCE} ${SYSTEM_UI_SOURCE} ${WEB_SOURCE}
+                  ${SCENE_SOURCE} ${UI_SOURCE} ${SYSTEM_UI_SOURCE}
+                  ${WEB_SOURCE} ${SCRIPT_SOURCE}
                   ${PLATFORM_SOURCE})
 
 if (NOT EMSCRIPTEN)

+ 7 - 0
Source/Atomic/Container/RefCounted.cpp

@@ -29,6 +29,8 @@
 namespace Atomic
 {
 
+RefCountedDeletedFunction RefCounted::refCountedDeletedFunction_ = 0;
+
 RefCounted::RefCounted() :
     refCount_(new RefCount()),
     jsHeapPtr_(0)
@@ -43,6 +45,9 @@ RefCounted::~RefCounted()
     assert(refCount_->refs_ == 0);
     assert(refCount_->weakRefs_ > 0);
 
+    if (refCountedDeletedFunction_)
+        refCountedDeletedFunction_(this);
+
     // Mark object as expired, release the self weak ref and delete the refcount if no other weak refs exist
     refCount_->refs_ = -1;
     (refCount_->weakRefs_)--;
@@ -63,7 +68,9 @@ void RefCounted::ReleaseRef()
     assert(refCount_->refs_ > 0);
     (refCount_->refs_)--;
     if (!refCount_->refs_)
+    {
         delete this;
+    }
 }
 
 int RefCounted::Refs() const

+ 11 - 0
Source/Atomic/Container/RefCounted.h

@@ -22,11 +22,15 @@
 
 #pragma once
 
+#include "HashMap.h"
+
 namespace Atomic
 {
 
 // ATOMIC BEGIN
 
+class RefCounted;
+typedef void (*RefCountedDeletedFunction)(RefCounted*);
 typedef const void* ClassID;
 
 /// Macro to be included in RefCounted derived classes for efficient RTTI
@@ -88,8 +92,12 @@ public:
     virtual ClassID GetClassID() const  = 0;
     static ClassID GetClassIDStatic() { static const int typeID = 0; return (ClassID) &typeID; }
 
+    /// JavaScript VM, heap object which can be pushed directly on stack without any lookups
     inline void* JSGetHeapPtr() const { return jsHeapPtr_; }
     inline void  JSSetHeapPtr(void* heapptr) { jsHeapPtr_ = heapptr; }
+
+    static void SetRefCountedDeletedFunction(RefCountedDeletedFunction function) { refCountedDeletedFunction_ = function; }
+
     // ATOMIC END
 
 private:
@@ -101,7 +109,10 @@ private:
     /// Pointer to the reference count structure.
     RefCount* refCount_;
 
+    // ATOMIC BEGIN
     void* jsHeapPtr_;
+    static RefCountedDeletedFunction refCountedDeletedFunction_;
+    // ATOMIC END
 
 
 };

+ 1 - 2
Source/Atomic/Core/Context.cpp

@@ -54,8 +54,7 @@ void RemoveNamedAttribute(HashMap<StringHash, Vector<AttributeInfo> >& attribute
 
 Context::Context() :
     eventHandler_(0),
-    editorContext_(false),
-    globalEventListener_(0)
+    editorContext_(false)
 {
 #ifdef ANDROID
     // Always reset the random seed on Android, as the Urho3D library might not be unloaded between runs

+ 13 - 4
Source/Atomic/Core/Context.h

@@ -159,7 +159,8 @@ public:
     // ATOMIC BEGIN
 
     // hook for listening into events
-    void SetGlobalEventListener(GlobalEventListener* listener) { globalEventListener_ = listener; }
+    void AddGlobalEventListener(GlobalEventListener* listener) { globalEventListeners_.Push(listener); }
+    void RemoveGlobalEventListener(GlobalEventListener* listener) { globalEventListeners_.Erase(globalEventListeners_.Find(listener)); }
 
     /// Get whether an Editor Context
     void SetEditorContext(bool editor) { editorContext_ = editor; }
@@ -181,10 +182,18 @@ private:
     void SetEventHandler(EventHandler* handler) { eventHandler_ = handler; }
 
     /// Begin event send.
-    void BeginSendEvent(Object* sender, StringHash eventType, VariantMap& eventData) { if (globalEventListener_) globalEventListener_->BeginSendEvent(this, sender, eventType, eventData); eventSenders_.Push(sender); }
+    void BeginSendEvent(Object* sender, StringHash eventType, VariantMap& eventData) {
+        for (unsigned i = 0; i < globalEventListeners_.Size(); i++)
+            globalEventListeners_[i]->BeginSendEvent(this, sender, eventType, eventData);
+        eventSenders_.Push(sender);
+    }
 
     /// End event send. Clean up event receivers removed in the meanwhile.
-    void EndSendEvent(Object* sender, StringHash eventType, VariantMap& eventData) { if (globalEventListener_) globalEventListener_->EndSendEvent(this, sender, eventType, eventData); eventSenders_.Pop(); }
+    void EndSendEvent(Object* sender, StringHash eventType, VariantMap& eventData) {
+        for (unsigned i = 0; i < globalEventListeners_.Size(); i++)
+            globalEventListeners_[i]->EndSendEvent(this, sender, eventType, eventData);
+        eventSenders_.Pop();
+    }
 
     /// Object factories.
     HashMap<StringHash, SharedPtr<ObjectFactory> > factories_;
@@ -208,7 +217,7 @@ private:
     HashMap<String, Vector<StringHash> > objectCategories_;
 
     // ATOMIC BEGIN
-    GlobalEventListener* globalEventListener_;
+    PODVector<GlobalEventListener*> globalEventListeners_;
     bool editorContext_;
     // ATOMIC END
 };

+ 1 - 1
Source/Atomic/Graphics/Drawable.h

@@ -106,7 +106,7 @@ class ATOMIC_API Drawable : public Component
 
 public:
     /// Construct.
-    Drawable(Context* context, unsigned char drawableFlags);
+    Drawable(Context* context, unsigned char drawableFlags = 0);
     /// Destruct.
     virtual ~Drawable();
     /// Register object attributes. Drawable must be registered first.

+ 15 - 0
Source/Atomic/Resource/JSONFile.cpp

@@ -140,6 +140,21 @@ bool JSONFile::BeginLoad(Deserializer& source)
     return true;
 }
 
+bool JSONFile::ParseJSON(const String& json, JSONValue& value)
+{
+    rapidjson::Document document;
+    if (document.Parse<0>(json.CString()).HasParseError())
+    {
+        LOGERROR("Could not parse JSON data from string");
+        return false;
+    }
+
+    ToJSONValue(value, document);
+
+    return true;
+
+}
+
 static void ToRapidjsonValue(rapidjson::Value& rapidjsonValue, const JSONValue& jsonValue, rapidjson::MemoryPoolAllocator<>& allocator)
 {
     switch (jsonValue.GetValueType())

+ 6 - 0
Source/Atomic/Resource/JSONFile.h

@@ -53,6 +53,12 @@ public:
     /// Return root value.
     const JSONValue& GetRoot() const { return root_; }
 
+    // ATOMIC BEGIN
+
+    static bool ParseJSON(const String& json, JSONValue& value);
+
+    // ATOMIC END
+
 private:
     /// JSON root value.
     JSONValue root_;

+ 25 - 0
Source/Atomic/Script/ScriptComponent.cpp

@@ -0,0 +1,25 @@
+
+#include "../Core/Context.h"
+#include "ScriptComponentFile.h"
+#include "ScriptComponent.h"
+
+namespace Atomic
+{
+
+ScriptComponent::ScriptComponent(Context* context) : Component(context)
+{
+
+}
+
+void ScriptComponent::RegisterObject(Context* context)
+{
+    ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    ATTRIBUTE("FieldValues", VariantMap, fieldValues_, Variant::emptyVariantMap, AM_FILE);
+}
+
+ScriptComponent::~ScriptComponent()
+{
+
+}
+
+}

+ 37 - 0
Source/Atomic/Script/ScriptComponent.h

@@ -0,0 +1,37 @@
+
+#pragma once
+
+#include <Atomic/Scene/Component.h>
+
+namespace Atomic
+{
+
+class ScriptComponentFile;
+
+class ATOMIC_API ScriptComponent : public Component
+{
+    OBJECT(ScriptComponent);
+
+public:
+
+    /// Construct.
+    ScriptComponent(Context* context);
+    /// Destruct.
+    virtual ~ScriptComponent();
+
+    static void RegisterObject(Context* context);
+
+    virtual const String& GetComponentClassName() const = 0;
+
+    virtual ScriptComponentFile* GetComponentFile() = 0;
+
+    VariantMap& GetFieldValues() { return fieldValues_; }
+
+
+protected:
+
+    VariantMap fieldValues_;
+
+};
+
+}

+ 131 - 0
Source/Atomic/Script/ScriptComponentFile.cpp

@@ -0,0 +1,131 @@
+
+#include "ScriptComponentFile.h"
+
+namespace Atomic
+{
+
+FieldMap ScriptComponentFile::emptyFieldMap_;
+EnumMap ScriptComponentFile::emptyEnumMap_;
+VariantMap ScriptComponentFile::emptyDefaultValueMap_;
+
+ScriptComponentFile::ScriptComponentFile(Context* context) : Resource(context)
+{
+
+}
+
+ScriptComponentFile::~ScriptComponentFile()
+{
+
+}
+
+void ScriptComponentFile::RegisterObject(Context* context)
+{
+    //context->RegisterFactory<ScriptComponentFile>();
+}
+
+void ScriptComponentFile::AddEnum(const String& enumName, const EnumInfo& enumInfo, const String& classname)
+{
+    EnumMap& enums = classEnums_[classname];
+    Vector<EnumInfo>& enumValues = enums[enumName];
+    enumValues.Push(enumInfo);
+}
+
+void ScriptComponentFile::AddField(const String& fieldName, VariantType variantType, const String &classname)
+{
+    FieldMap& fields = classFields_[classname];
+    fields[fieldName] = variantType;
+}
+
+void ScriptComponentFile::AddDefaultValue(const String& fieldName, const Variant& value, const String& classname)
+{
+    VariantMap& defaultValues = classDefaultFieldValues_[classname];
+    defaultValues[fieldName] = value;
+}
+
+void ScriptComponentFile::Clear()
+{
+    classFields_.Clear();
+    classDefaultFieldValues_.Clear();
+    classEnums_.Clear();
+}
+
+const FieldMap& ScriptComponentFile::GetFields(const String& classname) const
+{
+    FieldMap* fieldMap = classFields_[classname];
+
+    if (fieldMap)
+        return *fieldMap;
+
+    return emptyFieldMap_;
+}
+const VariantMap& ScriptComponentFile::GetDefaultFieldValues(const String& classname) const
+{
+    VariantMap *vmap = classDefaultFieldValues_[classname];
+
+    if (vmap)
+        return *vmap;
+
+    return emptyDefaultValueMap_;
+}
+
+const EnumMap& ScriptComponentFile::GetEnums(const String& classname) const
+{
+    EnumMap* enumMap = classEnums_[classname];
+
+    if (enumMap)
+        return *enumMap;
+
+    return emptyEnumMap_;
+}
+
+void ScriptComponentFile::GetDefaultFieldValue(const String& name, Variant& v,const String& classname) const
+{
+    v = Variant::EMPTY;
+
+    // first see if we have a default value for this field
+    const VariantMap* defaultValues = classDefaultFieldValues_[classname];
+
+    if (!defaultValues)
+        return;
+
+    const Variant* variant = (*defaultValues)[name];
+
+    if (variant)
+    {
+        v = *variant;
+        return;
+    }
+
+    // we don't have a default value, so we need to generate one based on the field type
+
+    const FieldMap* fieldMap = classFields_[classname];
+
+    if (!fieldMap)
+        return;
+
+    const VariantType* variantType = (*fieldMap)[name];
+    if (!variantType)
+        return;
+
+    switch (*variantType)
+    {
+    case VAR_BOOL:
+        v = false;
+        break;
+    case VAR_STRING:
+        v = "";
+        break;
+    case VAR_FLOAT:
+        v = 0.0f;
+        break;
+    case VAR_VECTOR3:
+        v = Vector3::ZERO;
+        break;
+    default:
+        break;
+    }
+
+}
+
+
+}

+ 69 - 0
Source/Atomic/Script/ScriptComponentFile.h

@@ -0,0 +1,69 @@
+
+#pragma once
+
+#include "../Resource/Resource.h"
+#include "../Core/Variant.h"
+
+namespace Atomic
+{
+
+struct EnumInfo
+{
+    EnumInfo(const String& name = String::EMPTY, const Variant& v = Variant::EMPTY)
+    {
+        name_ = name;
+        value_ = v;
+    }
+
+    String name_;
+    Variant value_;
+};
+
+typedef HashMap<String, VariantType> FieldMap;
+typedef HashMap<String, Vector<EnumInfo>> EnumMap;
+
+typedef HashMap<StringHash, FieldMap> ClassFieldMap;
+typedef HashMap<StringHash, EnumMap> ClassEnumMap;
+typedef HashMap<StringHash, VariantMap> ClassDefaultValueMap;
+
+/// NET Assembly resource.
+class ATOMIC_API ScriptComponentFile : public Resource
+{
+    OBJECT(ScriptComponentFile);
+
+public:
+
+    /// Construct.
+    ScriptComponentFile(Context* context);
+    /// Destruct.
+    virtual ~ScriptComponentFile();
+
+    static void RegisterObject(Context* context);
+
+    const EnumMap& GetEnums(const String& classname = String::EMPTY) const;
+    const FieldMap& GetFields(const String& classname = String::EMPTY) const;
+    const VariantMap& GetDefaultFieldValues(const String& classname = String::EMPTY) const;
+
+    void GetDefaultFieldValue(const String& name, Variant& v,const String& classname = String::EMPTY) const;
+
+protected:
+
+    void Clear();
+
+    void AddEnum(const String& enumName, const EnumInfo& enumInfo, const String& classname = String::EMPTY);
+    void AddField(const String& fieldName, VariantType variantType, const String& classname = String::EMPTY);
+    void AddDefaultValue(const String& fieldName, const Variant& value, const String& classname = String::EMPTY);
+
+private:
+
+    ClassFieldMap classFields_;
+    ClassDefaultValueMap classDefaultFieldValues_;
+    ClassEnumMap classEnums_;
+
+    static FieldMap emptyFieldMap_;
+    static EnumMap emptyEnumMap_;
+    static VariantMap emptyDefaultValueMap_;
+
+};
+
+}

+ 26 - 0
Source/Atomic/Script/ScriptSystem.cpp

@@ -0,0 +1,26 @@
+#include "ScriptSystem.h"
+#include "ScriptComponent.h"
+#include "ScriptComponentFile.h"
+
+namespace Atomic
+{
+
+void RegisterScriptLibrary(Context* context);
+
+ScriptSystem::ScriptSystem(Context* context) : Object(context)
+{
+    RegisterScriptLibrary(context);
+}
+
+ScriptSystem::~ScriptSystem()
+{
+
+}
+
+void RegisterScriptLibrary(Context* context)
+{
+    ScriptComponentFile::RegisterObject(context);
+    ScriptComponent::RegisterObject(context);
+}
+
+}

+ 20 - 0
Source/Atomic/Script/ScriptSystem.h

@@ -0,0 +1,20 @@
+
+#include "../Core/Object.h"
+
+#pragma once
+
+namespace Atomic
+{
+  class ScriptSystem : public Object
+  {
+      OBJECT(ScriptSystem);
+
+  public:
+
+      /// Construct.
+      ScriptSystem(Context* context);
+      /// Destruct.
+      virtual ~ScriptSystem();
+  };
+
+}

+ 2 - 2
Source/Atomic/UI/UISelectList.cpp

@@ -68,12 +68,12 @@ void UISelectList::SetValue(int value)
 
 }
 
-int UISelectList::GetValue()
+double UISelectList::GetValue()
 {
     if (!widget_)
         return 0;
 
-    return ((TBSelectList*)widget_)->GetValue();
+    return (double) ((TBSelectList*)widget_)->GetValue();
 
 }
 

+ 1 - 1
Source/Atomic/UI/UISelectList.h

@@ -48,7 +48,7 @@ public:
     void InvalidateList();
 
     void SetValue(int value);
-    int GetValue();
+    double GetValue();
 
     String GetHoverItemID();
     String GetSelectedItemID();

+ 27 - 0
Source/Atomic/UI/UIWidget.cpp

@@ -189,6 +189,24 @@ void UIWidget::OnDelete()
     ReleaseRef();
 }
 
+void UIWidget::AddChildAfter(UIWidget* child, UIWidget* otherChild)
+{
+    if (!widget_ || !child || !child->widget_ || !otherChild || !otherChild->widget_)
+        return;
+
+    widget_->AddChildRelative(child->widget_, tb::WIDGET_Z_REL_AFTER, otherChild->widget_);
+
+}
+
+void UIWidget::AddChildBefore(UIWidget* child, UIWidget* otherChild)
+{
+    if (!widget_ || !child || !child->widget_ || !otherChild || !otherChild->widget_)
+        return;
+
+    widget_->AddChildRelative(child->widget_, tb::WIDGET_Z_REL_BEFORE, otherChild->widget_);
+
+}
+
 void UIWidget::AddChild(UIWidget* child)
 {
     if (!widget_ || !child || !child->widget_)
@@ -398,6 +416,15 @@ void UIWidget::SetSkinBg(const String& id)
 
 }
 
+void UIWidget::Remove()
+{
+    if (!widget_ || !widget_->GetParent())
+        return;
+
+    widget_->GetParent()->RemoveChild(widget_);
+
+}
+
 void UIWidget::RemoveChild(UIWidget* child, bool cleanup)
 {
     if (!widget_ || !child)

+ 5 - 1
Source/Atomic/UI/UIWidget.h

@@ -179,6 +179,7 @@ class UIWidget : public Object, public tb::TBWidgetDelegate
     void SetLayoutParams(UILayoutParams* params);
     void SetFontDescription(UIFontDescription* fd);
 
+    void Remove();
     void RemoveChild(UIWidget* child, bool cleanup = true);
 
     void DeleteAllChildren();
@@ -190,7 +191,7 @@ class UIWidget : public Object, public tb::TBWidgetDelegate
     void SetGravity(UI_GRAVITY gravity);
 
     void SetValue(double value);
-    double GetValue();
+    virtual double GetValue();
 
     void SetFocus();
     bool GetFocus();
@@ -229,6 +230,9 @@ class UIWidget : public Object, public tb::TBWidgetDelegate
 
     virtual void AddChild(UIWidget* child);
 
+    void AddChildAfter(UIWidget* child, UIWidget* otherChild);
+    void AddChildBefore(UIWidget* child, UIWidget* otherChild);
+
     /// Add the child to this widget. See AddChild for adding a child to the top or bottom.
     /// This takes a relative Z and insert the child before or after the given reference widget.
     void AddChildRelative(UIWidget* child, UI_WIDGET_Z_REL z, UIWidget* reference);

+ 2 - 26
Source/AtomicEditor/Application/AEEditorApp.cpp

@@ -17,7 +17,6 @@
 
 #include <AtomicJS/Javascript/Javascript.h>
 
-#include <ToolCore/ToolSystem.h>
 #include <ToolCore/ToolEnvironment.h>
 #include <ToolCore/License/LicenseEvents.h>
 #include <ToolCore/License/LicenseSystem.h>
@@ -28,11 +27,6 @@
 
 using namespace ToolCore;
 
-namespace ToolCore
-{
-    extern void jsapi_init_toolcore(JSVM* vm);
-}
-
 namespace AtomicEditor
 {
 
@@ -63,7 +57,6 @@ void AEEditorApp::Start()
     SubscribeToEvent(E_JSERROR, HANDLER(AEEditorApp, HandleJSError));
     SubscribeToEvent(E_EXITREQUESTED, HANDLER(AEEditorApp, HandleExitRequested));
 
-    jsapi_init_toolcore(vm_);
     jsapi_init_editor(vm_);
 
     duk_get_global_string(vm_->GetJSContext(), "require");
@@ -80,28 +73,11 @@ void AEEditorApp::Start()
 
 void AEEditorApp::Setup()
 {
-    AEEditorCommon::Setup();
-
     context_->SetEditorContext(true);
 
-    ToolEnvironment* env = new ToolEnvironment(context_);
-    context_->RegisterSubsystem(env);
-
-    ToolSystem* system = new ToolSystem(context_);
-    context_->RegisterSubsystem(system);
-
-#ifdef ATOMIC_DEV_BUILD
-
-    if (!env->InitFromJSON())
-    {
-        ErrorExit(ToString("Unable to initialize tool environment from %s", env->GetDevConfigFilename().CString()));
-        return;
-    }
-#else
-
-    env->InitFromPackage();
+    AEEditorCommon::Setup();
 
-#endif
+    ToolEnvironment* env = GetSubsystem<ToolEnvironment>();
 
     engineParameters_["WindowTitle"] = "AtomicEditor";
     engineParameters_["WindowResizable"] = true;

+ 93 - 7
Source/AtomicEditor/Application/AEEditorCommon.cpp

@@ -13,10 +13,33 @@
 // Move me to Engine
 #include <Atomic/Environment/Environment.h>
 
+#include <Atomic/Script/ScriptSystem.h>
 #include <AtomicJS/Javascript/Javascript.h>
 
+#include <ToolCore/ToolSystem.h>
+#include <ToolCore/ToolEnvironment.h>
+
+#ifdef ATOMIC_DOTNET
+#include <AtomicNET/NETCore/NETHost.h>
+#include <AtomicNET/NETCore/NETCore.h>
+#include <AtomicNET/NETScript/NETScript.h>
+#endif
+
 #include "AEEditorCommon.h"
 
+namespace Atomic
+{
+    void jsapi_init_atomicnet(JSVM* vm);
+}
+
+using namespace ToolCore;
+
+namespace ToolCore
+{
+    extern void jsapi_init_toolcore(JSVM* vm);
+}
+
+
 namespace AtomicEditor
 {
 
@@ -31,16 +54,16 @@ void AEEditorCommon::Start()
     Input* input = GetSubsystem<Input>();
     input->SetMouseVisible(true);
 
-    // Register IPC system
-    context_->RegisterSubsystem(new IPC(context_));
-
-    // Instantiate and register the Javascript subsystem
-    Javascript* javascript = new Javascript(context_);
-    context_->RegisterSubsystem(javascript);
-
+    Javascript* javascript = GetSubsystem<Javascript>();
     vm_ = javascript->InstantiateVM("MainVM");
     vm_->InitJSContext();
 
+    jsapi_init_toolcore(vm_);
+
+#ifdef ATOMIC_DOTNET
+    jsapi_init_atomicnet(vm_);
+#endif
+
 }
 
 void AEEditorCommon::Setup()
@@ -50,6 +73,60 @@ void AEEditorCommon::Setup()
     RegisterEnvironmentLibrary(context_);
 #endif
 
+#ifdef ATOMIC_DOTNET
+    RegisterNETScriptLibrary(context_);
+#endif
+
+    // Register IPC system
+    context_->RegisterSubsystem(new IPC(context_));
+
+    context_->RegisterSubsystem(new ScriptSystem(context_));
+
+    // Instantiate and register the Javascript subsystem
+    Javascript* javascript = new Javascript(context_);
+    context_->RegisterSubsystem(javascript);
+
+    ToolEnvironment* env = new ToolEnvironment(context_);
+    context_->RegisterSubsystem(env);
+
+#ifdef ATOMIC_DEV_BUILD
+
+    if (!env->InitFromJSON())
+    {
+        ErrorExit(ToString("Unable to initialize tool environment from %s", env->GetDevConfigFilename().CString()));
+        return;
+    }
+#else
+
+    env->InitFromPackage();
+
+#endif
+
+#ifdef ATOMIC_DOTNET
+
+    // Instantiate and register the AtomicNET subsystem
+    SharedPtr<NETCore> netCore (new NETCore(context_));
+    context_->RegisterSubsystem(netCore);
+    String netCoreErrorMsg;
+
+    NETHost::SetCoreCLRFilesAbsPath(env->GetNETCoreCLRAbsPath());
+    NETHost::SetCoreCLRTPAPaths(env->GetNETTPAPaths());
+    NETHost::SetCoreCLRAssemblyLoadPaths(env->GetNETAssemblyLoadPaths());
+
+    if (!netCore->Initialize(netCoreErrorMsg))
+    {
+        LOGERRORF("NetCore: Unable to initialize! %s", netCoreErrorMsg.CString());
+        context_->RemoveSubsystem(NETCore::GetTypeStatic());
+    }
+    else
+    {
+
+    }
+#endif
+
+    ToolSystem* system = new ToolSystem(context_);
+    context_->RegisterSubsystem(system);
+
 }
 
 void AEEditorCommon::Stop()
@@ -62,6 +139,15 @@ void AEEditorCommon::Stop()
     // make sure JSVM is really down and no outstanding refs
     // as if not, will hold on engine subsystems, which is bad
     assert(!JSVM::GetJSVM(0));
+
+#ifdef ATOMIC_DOTNET
+    NETCore* netCore = GetSubsystem<NETCore>();
+    if (netCore)
+    {
+        netCore->Shutdown();
+        context_->RemoveSubsystem<NETCore>();
+    }
+#endif
 }
 
 }

+ 35 - 4
Source/AtomicEditor/Application/AEPlayerApp.cpp

@@ -22,6 +22,11 @@
 
 #include <AtomicJS/Javascript/Javascript.h>
 
+#ifdef ATOMIC_DOTNET
+#include <AtomicNET/NETCore/NETCore.h>
+#include <AtomicNET/NETScript/NETScript.h>
+#endif
+
 
 #include "../PlayerMode/AEPlayerMode.h"
 #include <AtomicPlayer/Player.h>
@@ -43,7 +48,8 @@ namespace AtomicEditor
 {
 
 AEPlayerApplication::AEPlayerApplication(Context* context) :
-    AEEditorCommon(context)
+    AEEditorCommon(context),
+    debugPlayer_(false)
 {
 }
 
@@ -96,6 +102,10 @@ void AEPlayerApplication::Setup()
             {
                 SubscribeToEvent(E_LOGMESSAGE, HANDLER(AEPlayerApplication, HandleLogMessage));
             }
+            else if (argument == "--debug")
+            {
+                debugPlayer_ = true;
+            }
             else if (argument == "--project" && value.Length())
             {
                 engineParameters_["ResourcePrefixPath"] = "";
@@ -107,8 +117,8 @@ void AEPlayerApplication::Setup()
 
 #ifdef ATOMIC_DEV_BUILD
 
-                String resourcePaths = ToString("%s/Resources/CoreData;%s/Resources/PlayerData;%s/;%s/Resources;%s;%sCache",
-                         ATOMIC_ROOT_SOURCE_DIR, ATOMIC_ROOT_SOURCE_DIR, value.CString(), value.CString(), value.CString(), value.CString());
+                String resourcePaths = ToString("%s/Resources/CoreData;%s/Resources/PlayerData;%sResources;%s;%sCache",
+                         ATOMIC_ROOT_SOURCE_DIR, ATOMIC_ROOT_SOURCE_DIR, value.CString(), value.CString(), value.CString());
 
 #else
 
@@ -126,6 +136,12 @@ void AEPlayerApplication::Setup()
 
                 engineParameters_["ResourcePaths"] = resourcePaths;
 
+#ifdef ATOMIC_DOTNET
+                NETCore* netCore = GetSubsystem<NETCore>();
+                String assemblyLoadPath = GetNativePath(ToString("%sResources/Assemblies/", value.CString()));
+                netCore->AddAssemblyLoadPath(assemblyLoadPath);
+#endif
+
             }
         }
     }
@@ -150,12 +166,27 @@ void AEPlayerApplication::Start()
 
     SubscribeToEvent(E_JSERROR, HANDLER(AEPlayerApplication, HandleJSError));
 
+#ifdef ATOMIC_DOTNET
+        if (debugPlayer_)
+        {
+           GetSubsystem<NETCore>()->WaitForDebuggerConnect();
+        }
+#endif
+
     vm_->SetModuleSearchPaths("Modules");
 
     // Instantiate and register the Player subsystem
     context_->RegisterSubsystem(new AtomicPlayer::Player(context_));
     AtomicPlayer::jsapi_init_atomicplayer(vm_);
 
+#ifdef ATOMIC_DOTNET
+    // Initialize Scripting Subsystem
+    NETScript* netScript = new NETScript(context_);
+    context_->RegisterSubsystem(netScript);
+    netScript->Initialize();
+    netScript->ExecMainAssembly();
+#endif
+
     if (!playerMode->launchedByEditor())
     {
         JSVM* vm = JSVM::GetJSVM(0);
@@ -164,8 +195,8 @@ void AEPlayerApplication::Start()
         {
             SendEvent(E_EXITREQUESTED);
         }
-
     }
+
     return;
 }
 

+ 2 - 0
Source/AtomicEditor/Application/AEPlayerApp.h

@@ -41,6 +41,8 @@ private:
 
     void HandleLogMessage(StringHash eventType, VariantMap& eventData);
 
+    bool debugPlayer_;
+
 };
 
 }

+ 14 - 9
Source/AtomicEditor/CMakeLists.txt

@@ -1,7 +1,9 @@
-include_directories (${CMAKE_SOURCE_DIR}/Source/ThirdParty/rapidjson/include
-                     ${CMAKE_SOURCE_DIR}/Source/ThirdParty
-                     ${CMAKE_SOURCE_DIR}/Source/ThirdParty/nativefiledialog)
-
+include_directories ( ${CMAKE_SOURCE_DIR}/Source/ThirdParty
+                      ${CMAKE_SOURCE_DIR}/Source/ThirdParty/rapidjson/include
+                      ${CMAKE_SOURCE_DIR}/Source/ThirdParty/kNet/include
+                      ${CMAKE_SOURCE_DIR}/Source/ThirdParty/FreeType/include
+                      ${CMAKE_SOURCE_DIR}/Source/ThirdParty/Box2D
+                      ${CMAKE_SOURCE_DIR}/Source/ThirdParty/nativefiledialog )
 
 file (GLOB_RECURSE SOURCE_FILES *.cpp *.h)
 
@@ -22,6 +24,8 @@ file (GLOB JAVASCRIPT_BINDINGS_SOURCE ${CMAKE_SOURCE_DIR}/Build/Source/Generated
 
 set (SOURCE_FILES ${SOURCE_FILES} ${JAVASCRIPT_BINDINGS_SOURCE})
 
+set (SOURCE_FILES ${SOURCE_FILES} ${CSHARP_BINDINGS_SOURCE} ${CSHARPATOMICPLAYER_BINDINGS_SOURCE} ${CSHARPATOMICNET_BINDINGS_SOURCE})
+
 if (APPLE)
 
     file (GLOB_RECURSE OBJC_FILES *.mm *.h)
@@ -49,11 +53,12 @@ endif(APPLE)
 
 add_executable(AtomicEditor ${EXE_TYPE} ${SOURCE_FILES} ${ATOMIC_EDITOR_ICON})
 
-target_link_libraries(AtomicEditor ToolCore AtomicJS AtomicPlayerJS ToolCoreJS Poco nativefiledialog ${ATOMIC_LINK_LIBRARIES})
+target_link_libraries(AtomicEditor ToolCore AtomicJS AtomicPlayerJS AtomicNETJS ToolCoreJS Poco nativefiledialog ${ATOMIC_LINK_LIBRARIES})
 
 if (APPLE)
     set (TARGET_PROPERTIES MACOSX_BUNDLE_INFO_PLIST MacOSXBundleInfo.plist.template)
-    target_link_libraries(AtomicEditor curl)
+
+    target_link_libraries(AtomicEditor NETCore NETScript curl)
 
     # compile the editor scripts
     add_custom_command (TARGET AtomicEditor POST_BUILD
@@ -61,7 +66,7 @@ if (APPLE)
     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
 
 elseif(LINUX)
-    target_link_libraries(AtomicEditor curl nativefiledialog ${GTK3_LIBRARIES})
+    target_link_libraries(AtomicEditor NETCore NETScript curl nativefiledialog ${GTK3_LIBRARIES})
 
     # check for nodejs install
     # look for either 'node' or 'nodejs' ( debian uses both names )
@@ -82,9 +87,9 @@ elseif(LINUX)
         add_custom_command (TARGET AtomicEditor POST_BUILD
         COMMAND  ${NODEJS_CMD} "${CMAKE_SOURCE_DIR}/Build/TypeScript/tsc.js" "-p" "./Script"
         WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
-    endif() 
+    endif()
 else()
-    target_link_libraries(AtomicEditor libcurl Iphlpapi Wldap32)
+    target_link_libraries(AtomicEditor NETCore NETScript libcurl Iphlpapi Wldap32)
 
     # compile the editor scripts
     add_custom_command (TARGET AtomicEditor POST_BUILD

+ 9 - 1
Source/AtomicEditor/EditorMode/AEEditorMode.cpp

@@ -87,7 +87,7 @@ void EditorMode::HandleIPCJSError(StringHash eventType, VariantMap& eventData)
 
 }
 
-bool EditorMode::PlayProject()
+bool EditorMode::PlayProject(bool debug)
 {
     ToolEnvironment* env = GetSubsystem<ToolEnvironment>();
     ToolSystem* tsystem = GetSubsystem<ToolSystem>();
@@ -117,6 +117,9 @@ bool EditorMode::PlayProject()
 
     vargs = args.Split(' ');
 
+    if (debug)
+        vargs.Insert(0, "--debug");
+
     String dump;
     dump.Join(vargs, " ");
     LOGINFOF("Launching Broker %s %s", editorBinary.CString(), dump.CString());
@@ -135,4 +138,9 @@ bool EditorMode::PlayProject()
 
 }
 
+bool EditorMode::PlayProjectDebug()
+{
+    return PlayProject(true);
+}
+
 }

Some files were not shown because too many files changed in this diff