Browse Source

Merge pull request #981 from AtomicGameEngine/JME-ATOMIC-972

C# support for Vector/PODVector of RefCounted return and parameter values, C# support for method overloading
JoshEngebretson 9 years ago
parent
commit
e43fdb2c82
38 changed files with 963 additions and 162 deletions
  1. 3 3
      Script/AtomicNET/AtomicNET/Core/AObject.cs
  2. 4 4
      Script/AtomicNET/AtomicNET/Core/AtomicNET.cs
  3. 8 8
      Script/AtomicNET/AtomicNET/Core/NativeCore.cs
  4. 2 2
      Script/AtomicNET/AtomicNET/Core/NativeEvents.cs
  5. 10 2
      Script/AtomicNET/AtomicNET/Core/RefCounted.cs
  6. 64 0
      Script/AtomicNET/AtomicNET/Core/Vector.cs
  7. 2 10
      Script/AtomicNET/AtomicNET/Graphics/Graphics.cs
  8. 2 2
      Script/AtomicNET/AtomicNET/Graphics/VertexBuffer.cs
  9. 0 8
      Script/AtomicNET/AtomicNET/Graphics/Viewport.cs
  10. 2 2
      Script/AtomicNET/AtomicNET/IPC/IPC.cs
  11. 36 0
      Script/AtomicNET/AtomicNET/Scene/Node.cs
  12. 2 2
      Script/AtomicNET/AtomicNET/Script/ScriptVariantMap.cs
  13. 1 1
      Script/Packages/Atomic/Script.json
  14. 9 0
      Source/Atomic/Script/ScriptVector.cpp
  15. 171 0
      Source/Atomic/Script/ScriptVector.h
  16. 26 26
      Source/AtomicNET/NETNative/NETCInterop.cpp
  17. 12 7
      Source/ToolCore/JSBind/CSharp/CSClassWriter.cpp
  18. 194 17
      Source/ToolCore/JSBind/CSharp/CSFunctionWriter.cpp
  19. 4 0
      Source/ToolCore/JSBind/CSharp/CSFunctionWriter.h
  20. 2 0
      Source/ToolCore/JSBind/CSharp/CSModuleWriter.cpp
  21. 69 14
      Source/ToolCore/JSBind/CSharp/CSTypeHelper.cpp
  22. 17 7
      Source/ToolCore/JSBind/JSBClass.cpp
  23. 8 1
      Source/ToolCore/JSBind/JSBClass.h
  24. 1 1
      Source/ToolCore/JSBind/JSBDoc.cpp
  25. 18 0
      Source/ToolCore/JSBind/JSBFunction.cpp
  26. 47 10
      Source/ToolCore/JSBind/JSBFunction.h
  27. 1 1
      Source/ToolCore/JSBind/JSBHaxe.cpp
  28. 107 17
      Source/ToolCore/JSBind/JSBHeaderVisitor.h
  29. 12 0
      Source/ToolCore/JSBind/JSBModule.cpp
  30. 2 0
      Source/ToolCore/JSBind/JSBModule.h
  31. 19 0
      Source/ToolCore/JSBind/JSBType.cpp
  32. 12 6
      Source/ToolCore/JSBind/JSBType.h
  33. 5 5
      Source/ToolCore/JSBind/JSBTypeScript.cpp
  34. 36 0
      Source/ToolCore/JSBind/JSBindTypes.h
  35. 37 3
      Source/ToolCore/JSBind/JavaScript/JSClassWriter.cpp
  36. 4 0
      Source/ToolCore/JSBind/JavaScript/JSClassWriter.h
  37. 12 1
      Source/ToolCore/JSBind/JavaScript/JSFunctionWriter.cpp
  38. 2 2
      Source/ToolCore/JSBind/JavaScript/JSModuleWriter.cpp

+ 3 - 3
Script/AtomicNET/AtomicNET/Core/AObject.cs

@@ -36,14 +36,14 @@ namespace AtomicEngine
         public void SendEvent(string eventType, ScriptVariantMap eventData = null)
         public void SendEvent(string eventType, ScriptVariantMap eventData = null)
         {
         {
 
 
-            csb_Atomic_AObject_SendEvent(this.nativeInstance, eventType, eventData == null ? IntPtr.Zero : eventData.nativeInstance);
+            csi_Atomic_AObject_SendEvent(this.nativeInstance, eventType, eventData == null ? IntPtr.Zero : eventData.nativeInstance);
 
 
         }
         }
 
 
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
-        private static extern void csb_Atomic_AObject_SendEvent(IntPtr self, string eventType, IntPtr variantMap);
+        private static extern void csi_Atomic_AObject_SendEvent(IntPtr self, string eventType, IntPtr variantMap);
 
 
 
 
     }
     }
 
 
-}
+}

+ 4 - 4
Script/AtomicNET/AtomicNET/Core/AtomicNET.cs

@@ -40,11 +40,11 @@ namespace AtomicEngine
 
 
         public static uint StringToStringHash(string value)
         public static uint StringToStringHash(string value)
         {
         {
-            return csb_Atomic_AtomicNET_StringToStringHash(value);
+            return csi_Atomic_AtomicNET_StringToStringHash(value);
         }
         }
 
 
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
-        private static extern uint csb_Atomic_AtomicNET_StringToStringHash(string name);
+        private static extern uint csi_Atomic_AtomicNET_StringToStringHash(string name);
 
 
         public static void Initialize()
         public static void Initialize()
         {
         {
@@ -77,7 +77,7 @@ namespace AtomicEngine
             coreDelegates.eventDispatch = NativeCore.EventDispatch;
             coreDelegates.eventDispatch = NativeCore.EventDispatch;
             coreDelegates.updateDispatch = NativeCore.UpdateDispatch;
             coreDelegates.updateDispatch = NativeCore.UpdateDispatch;
 
 
-            IntPtr coreptr = csb_Atomic_NETCore_Initialize(ref coreDelegates);
+            IntPtr coreptr = csi_Atomic_NETCore_Initialize(ref coreDelegates);
 
 
             NETCore core = (coreptr == IntPtr.Zero ? null : NativeCore.WrapNative<NETCore>(coreptr));
             NETCore core = (coreptr == IntPtr.Zero ? null : NativeCore.WrapNative<NETCore>(coreptr));
 
 
@@ -96,7 +96,7 @@ namespace AtomicEngine
         }
         }
 
 
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
-        private static extern IntPtr csb_Atomic_NETCore_Initialize(ref CoreDelegates delegates);
+        private static extern IntPtr csi_Atomic_NETCore_Initialize(ref CoreDelegates delegates);
 
 
         private static Context context;
         private static Context context;
         private static CoreDelegates coreDelegates;
         private static CoreDelegates coreDelegates;

+ 8 - 8
Script/AtomicNET/AtomicNET/Core/NativeCore.cs

@@ -161,7 +161,7 @@ namespace AtomicEngine
                 if (!w.TryGetTarget(out r))
                 if (!w.TryGetTarget(out r))
                 {
                 {
                     // expired
                     // expired
-                    csb_AtomicEngine_ReleaseRef(native);
+                    csi_AtomicEngine_ReleaseRef(native);
                     nativeLookup.Remove(native);
                     nativeLookup.Remove(native);
                     nativesRemoved++;
                     nativesRemoved++;
                 }
                 }
@@ -233,18 +233,18 @@ namespace AtomicEngine
                     // we were seen before, but have since been GC'd, remove!
                     // we were seen before, but have since been GC'd, remove!
                     nativeLookup.Remove(native);
                     nativeLookup.Remove(native);
 
 
-                    if (csb_Atomic_RefCounted_Refs(native) == 1)
+                    if (csi_Atomic_RefCounted_Refs(native) == 1)
                     {
                     {
                         // only managed ref remains, so release and return null
                         // only managed ref remains, so release and return null
-                        csb_AtomicEngine_ReleaseRef(native);
+                        csi_AtomicEngine_ReleaseRef(native);
                         return null;
                         return null;
                     }
                     }
 
 
-                    csb_AtomicEngine_ReleaseRef(native);
+                    csi_AtomicEngine_ReleaseRef(native);
                 }
                 }
             }
             }
 
 
-            IntPtr classID = RefCounted.csb_Atomic_RefCounted_GetClassID(native);
+            IntPtr classID = RefCounted.csi_Atomic_RefCounted_GetClassID(native);
 
 
             // and store, with downcast support for instance Component -> StaticModel
             // and store, with downcast support for instance Component -> StaticModel
             // we never want to hit this path for script inherited natives
             // we never want to hit this path for script inherited natives
@@ -268,10 +268,10 @@ namespace AtomicEngine
         }
         }
 
 
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
-        private static extern IntPtr csb_Atomic_AObject_GetTypeName(IntPtr self);
+        private static extern IntPtr csi_Atomic_AObject_GetTypeName(IntPtr self);
 
 
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
-        private static extern int csb_Atomic_RefCounted_Refs(IntPtr self);
+        private static extern int csi_Atomic_RefCounted_Refs(IntPtr self);
 
 
         public static void RegisterNativeType(NativeType nativeType)
         public static void RegisterNativeType(NativeType nativeType)
         {
         {
@@ -343,7 +343,7 @@ namespace AtomicEngine
         internal static Dictionary<Type, NativeType> typeToNativeType = new Dictionary<Type, NativeType>();
         internal static Dictionary<Type, NativeType> typeToNativeType = new Dictionary<Type, NativeType>();
 
 
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
-        private static extern void csb_AtomicEngine_ReleaseRef(IntPtr refCounted);
+        private static extern void csi_AtomicEngine_ReleaseRef(IntPtr refCounted);
 
 
     }
     }
 
 

+ 2 - 2
Script/AtomicNET/AtomicNET/Core/NativeEvents.cs

@@ -28,11 +28,11 @@ namespace AtomicEngine
     {
     {
         public void CopyVariantMap(IntPtr vm)
         public void CopyVariantMap(IntPtr vm)
         {
         {
-            csb_Atomic_AtomicNET_ScriptVariantMapCopyVariantMap(nativeInstance, vm);
+            csi_Atomic_AtomicNET_ScriptVariantMapCopyVariantMap(nativeInstance, vm);
         }
         }
 
 
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
-        private static extern IntPtr csb_Atomic_AtomicNET_ScriptVariantMapCopyVariantMap(IntPtr svm, IntPtr vm);
+        private static extern IntPtr csi_Atomic_AtomicNET_ScriptVariantMapCopyVariantMap(IntPtr svm, IntPtr vm);
 
 
     }
     }
 
 

+ 10 - 2
Script/AtomicNET/AtomicNET/Core/RefCounted.cs

@@ -17,12 +17,20 @@ namespace AtomicEngine
             nativeInstance = native;
             nativeInstance = native;
         }
         }
 
 
+        public static implicit operator IntPtr(RefCounted refCounted)
+        {
+            if (refCounted == null)
+                return IntPtr.Zero;
+                
+            return refCounted.nativeInstance;
+        }
+
         public IntPtr nativeInstance = IntPtr.Zero;
         public IntPtr nativeInstance = IntPtr.Zero;
 
 
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
-        public static extern IntPtr csb_Atomic_RefCounted_GetClassID(IntPtr self);
+        public static extern IntPtr csi_Atomic_RefCounted_GetClassID(IntPtr self);
 
 
     }
     }
 
 
 
 
-}
+}

+ 64 - 0
Script/AtomicNET/AtomicNET/Core/Vector.cs

@@ -0,0 +1,64 @@
+
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace AtomicEngine
+{
+	// Type safe wrapper around ScriptVector
+	public class Vector<T> where T : RefCounted
+	{
+
+		public uint Size
+		{
+			get
+			{
+				return scriptVector.GetSize();
+			}
+		}
+
+		public void Push(T refCounted)
+		{
+			scriptVector.Push(refCounted);
+		}
+
+		public T At(uint index)
+		{
+			return (T)scriptVector.At(index);
+		}
+
+
+		public T this[int key]
+		{
+			get
+			{
+				return At((uint)key);
+			}
+		}
+
+		public T this[uint key]
+		{
+			get
+			{
+				return At(key);
+			}
+		}
+
+
+
+		public static implicit operator IntPtr(Vector<T> vector)
+		{
+			if (vector == null)
+				return IntPtr.Zero;
+
+			return vector.scriptVector.nativeInstance;
+		}
+
+		public ScriptVector GetScriptVector() { return scriptVector; }
+
+
+		ScriptVector scriptVector = new ScriptVector();
+    }
+}
+

+ 2 - 10
Script/AtomicNET/AtomicNET/Graphics/Graphics.cs

@@ -12,19 +12,11 @@ namespace AtomicEngine
 
 
         public void SetShaderParameter(string param, Matrix3x4 matrix)
         public void SetShaderParameter(string param, Matrix3x4 matrix)
         {
         {
-            csb_Atomic_Graphics_SetShaderParameter_Matrix3x4(nativeInstance, param, ref matrix);
+            csi_Atomic_Graphics_SetShaderParameter_Matrix3x4(nativeInstance, param, ref matrix);
         }
         }
 
 
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
-        private static extern IntPtr csb_Atomic_Graphics_SetShaderParameter_Matrix3x4(IntPtr self, string param, ref Matrix3x4 matrix);
-
-        public void SetShaderParameter(string param, Color color)
-        {
-            csb_Atomic_Graphics_SetShaderParameter_Color(nativeInstance, param, ref color);
-        }
-
-        [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
-        private static extern IntPtr csb_Atomic_Graphics_SetShaderParameter_Color(IntPtr self, string param, ref Color color);
+        private static extern IntPtr csi_Atomic_Graphics_SetShaderParameter_Matrix3x4(IntPtr self, string param, ref Matrix3x4 matrix);
 
 
 
 
     };
     };

+ 2 - 2
Script/AtomicNET/AtomicNET/Graphics/VertexBuffer.cs

@@ -8,12 +8,12 @@ namespace AtomicEngine
 
 
         public IntPtr Lock(uint start, uint count, bool discard = false)
         public IntPtr Lock(uint start, uint count, bool discard = false)
         {
         {
-            return csb_Atomic_VertexBuffer_Lock(this.nativeInstance, start, count, discard);
+            return csi_Atomic_VertexBuffer_Lock(this.nativeInstance, start, count, discard);
         }
         }
 
 
 
 
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
-        private static extern IntPtr csb_Atomic_VertexBuffer_Lock(IntPtr self, uint start, uint count, bool discard);
+        private static extern IntPtr csi_Atomic_VertexBuffer_Lock(IntPtr self, uint start, uint count, bool discard);
 
 
     };
     };
 
 

+ 0 - 8
Script/AtomicNET/AtomicNET/Graphics/Viewport.cs

@@ -8,14 +8,6 @@ namespace AtomicEngine
     public partial class Viewport : AObject
     public partial class Viewport : AObject
     {
     {
 
 
-        public void SetRenderPath(RenderPath renderPath)
-        {
-            csb_Atomic_Viewport_SetRenderPath_RenderPath(nativeInstance, renderPath != null ? renderPath.nativeInstance : IntPtr.Zero);
-        }
-
-        [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
-        private static extern IntPtr csb_Atomic_Viewport_SetRenderPath_RenderPath(IntPtr self, IntPtr renderPath);
-
     };
     };
 
 
 }
 }

+ 2 - 2
Script/AtomicNET/AtomicNET/IPC/IPC.cs

@@ -9,11 +9,11 @@ namespace AtomicEngine
     {
     {
         public void SendEventToBroker(string eventType, ScriptVariantMap eventData)
         public void SendEventToBroker(string eventType, ScriptVariantMap eventData)
         {
         {
-            csb_Atomic_IPC_SendEventToBrokerWithEventData(nativeInstance, eventType, eventData == null ? IntPtr.Zero : eventData.nativeInstance);
+            csi_Atomic_IPC_SendEventToBrokerWithEventData(nativeInstance, eventType, eventData == null ? IntPtr.Zero : eventData.nativeInstance);
         }
         }
 
 
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
-        private static extern void csb_Atomic_IPC_SendEventToBrokerWithEventData(IntPtr self, string eventType, IntPtr variantMap);
+        private static extern void csi_Atomic_IPC_SendEventToBrokerWithEventData(IntPtr self, string eventType, IntPtr variantMap);
 
 
     }
     }
 
 

+ 36 - 0
Script/AtomicNET/AtomicNET/Scene/Node.cs

@@ -23,6 +23,42 @@ namespace AtomicEngine
             return (T) CreateComponent(type.Name, mode, id);
             return (T) CreateComponent(type.Name, mode, id);
         }
         }
 
 
+		public void GetChildrenWithComponent<T>(Vector<Node> dest, bool recursive = false)
+		{
+			var type = typeof(T);
+
+			// If we're a CSComponent, get "CSComponents" native side and filter here
+			if (type.IsSubclassOf(typeof(CSComponent)))
+			{
+				Vector<Node> temp = new Vector<Node>();
+
+				GetChildrenWithComponent(temp, "CSComponent", recursive);
+
+				// filter based on actual type
+
+				for (uint i = 0; i < temp.Size; i++)
+				{
+					var node = temp[i];
+
+					Vector<Component> components = new Vector<Component>();
+
+					node.GetComponents(components, "Component", false);
+
+					for (uint j = 0; j < components.Size; j++)
+					{
+						if (components[j].GetType() == type)
+						{
+							dest.Push(node);
+							break;
+						}						
+					}
+				}
+
+				return;
+			}
+
+			GetChildrenWithComponent(dest, type.Name, recursive);
+		}
 
 
     }
     }
 
 

+ 2 - 2
Script/AtomicNET/AtomicNET/Script/ScriptVariantMap.cs

@@ -22,11 +22,11 @@ namespace AtomicEngine
 
 
         public IntPtr GetVoidPtr(string key)
         public IntPtr GetVoidPtr(string key)
         {
         {
-            return csb_Atomic_AtomicNET_ScriptVariantMap_GetVoidPtr(nativeInstance, key);
+            return csi_Atomic_AtomicNET_ScriptVariantMap_GetVoidPtr(nativeInstance, key);
         }
         }
 
 
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
         [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
-        private static extern IntPtr csb_Atomic_AtomicNET_ScriptVariantMap_GetVoidPtr(IntPtr self, string key);
+        private static extern IntPtr csi_Atomic_AtomicNET_ScriptVariantMap_GetVoidPtr(IntPtr self, string key);
 
 
     }
     }
 }
 }

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

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

+ 9 - 0
Source/Atomic/Script/ScriptVector.cpp

@@ -0,0 +1,9 @@
+
+#include "ScriptVector.h"
+
+namespace Atomic
+{
+
+
+
+}

+ 171 - 0
Source/Atomic/Script/ScriptVector.h

@@ -0,0 +1,171 @@
+
+#include "ScriptSystem.h"
+
+#pragma once
+
+namespace Atomic
+{
+
+class ScriptVector : public RefCounted
+{
+    ATOMIC_REFCOUNTED(ScriptVector)
+
+public:
+
+    ScriptVector() : RefCounted()
+    {
+
+    }
+
+    virtual ~ScriptVector()
+    {
+
+    }
+
+    RefCounted* At(unsigned index) const
+    {
+        if (index >= refVector_.Size())
+            return 0;
+
+        return refVector_[index];
+    }
+
+    void Push(RefCounted* refCounted)
+    {
+        // TODO: check null?
+
+        refVector_.Push(SharedPtr<RefCounted>(refCounted));
+    }
+
+    unsigned GetSize() const
+    {
+        return refVector_.Size();
+    }
+
+    template <class T>
+    bool AdaptFromVector(PODVector<T> vectorIn)
+    {
+
+        Vector<SharedPtr<RefCounted>> keepAlive = refVector_;
+
+        refVector_.Clear();
+
+        for (unsigned i = 0; i < vectorIn.Size(); i++)
+        {
+            refVector_.Push(SharedPtr<RefCounted>(vectorIn[i]));
+        }
+
+        return true;
+    }
+
+    template <class T>
+    bool AdaptFromVector(Vector<T> vectorIn)
+    {
+        Vector<SharedPtr<RefCounted>> keepAlive = refVector_;
+
+        refVector_.Clear();
+
+        for (unsigned i = 0; i < vectorIn.Size(); i++)
+        {
+            refVector_.Push((T) vectorIn[i]);
+        }
+
+        return true;
+
+    }
+
+    template <class T>
+    bool AdaptFromVector(Vector<WeakPtr<T>> vectorIn)
+    {
+        Vector<SharedPtr<RefCounted>> keepAlive = refVector_;
+
+        refVector_.Clear();
+
+        for (unsigned i = 0; i < vectorIn.Size(); i++)
+        {
+            refVector_.Push(SharedPtr<RefCounted>((RefCounted*) vectorIn[i]));
+        }
+
+        return true;
+
+    }
+
+    template <class T>
+    bool AdaptFromVector(Vector<SharedPtr<T>> vectorIn)
+    {
+        Vector<SharedPtr<RefCounted>> keepAlive = refVector_;
+
+        refVector_.Clear();
+
+        for (unsigned i = 0; i < vectorIn.Size(); i++)
+        {
+            refVector_.Push(SharedPtr<RefCounted>((RefCounted*) vectorIn[i]));
+        }
+
+        return true;
+
+    }
+
+    template <class T>
+    bool AdaptToVector(PODVector<T> vectorOut)
+    {
+        vectorOut.Clear();
+
+        for (unsigned i = 0; i < refVector_.Size(); i++)
+        {
+            vectorOut.Push(static_cast<T>(refVector_[i].Get()));
+        }
+
+        return true;
+
+    }
+
+    template <class T>
+    bool AdaptToVector(Vector<T> vectorOut)
+    {
+        vectorOut.Clear();
+
+        for (unsigned i = 0; i < refVector_.Size(); i++)
+        {
+            vectorOut.Push((T) refVector_[i]);
+        }
+
+        return true;
+
+    }
+
+    template <class T>
+    bool AdaptToVector(Vector<SharedPtr<T>> vectorOut)
+    {
+        vectorOut.Clear();
+
+        for (unsigned i = 0; i < refVector_.Size(); i++)
+        {
+            vectorOut.Push(SharedPtr<T>((T) refVector_[i]));
+        }
+
+        return true;
+
+    }
+
+    template <class T>
+    bool AdaptToVector(Vector<WeakPtr<T>> vectorOut)
+    {
+        vectorOut.Clear();
+
+        for (unsigned i = 0; i < refVector_.Size(); i++)
+        {
+            vectorOut.Push(WeakPtr<T>((T) refVector_[i]));
+        }
+
+        return true;
+    }
+
+
+private:
+
+    Vector<SharedPtr<RefCounted>> refVector_;
+
+};
+
+}

+ 26 - 26
Source/AtomicNET/NETNative/NETCInterop.cpp

@@ -17,13 +17,15 @@
 
 
 // TODO: Split into separate module files
 // TODO: Split into separate module files
 
 
+// IMPORTANT: methods here are prefaced with csi_ instead of csb_, the later being automatically generated bindings
+
 namespace Atomic
 namespace Atomic
 {
 {
 
 
     extern "C"
     extern "C"
     {
     {
 
 
-        ATOMIC_EXPORT_API ClassID csb_Atomic_RefCounted_GetClassID(RefCounted* refCounted)
+        ATOMIC_EXPORT_API ClassID csi_Atomic_RefCounted_GetClassID(RefCounted* refCounted)
         {
         {
             if (!refCounted)
             if (!refCounted)
                 return 0;
                 return 0;
@@ -31,7 +33,7 @@ namespace Atomic
             return refCounted->GetClassID();
             return refCounted->GetClassID();
         }
         }
 
 
-        ATOMIC_EXPORT_API void csb_AtomicEngine_ReleaseRef(RefCounted* refCounted)
+        ATOMIC_EXPORT_API void csi_AtomicEngine_ReleaseRef(RefCounted* refCounted)
         {
         {
             if (!refCounted)
             if (!refCounted)
                 return;
                 return;
@@ -39,12 +41,26 @@ namespace Atomic
             refCounted->ReleaseRef();
             refCounted->ReleaseRef();
         }
         }
 
 
-        ATOMIC_EXPORT_API void csb_Atomic_AObject_SendEvent(Object* obj, const char* eventType, ScriptVariantMap* vmap)
+        ATOMIC_EXPORT_API const char* csi_Atomic_AObject_GetTypeName(Object* self)
+        {
+
+           static String returnValue;
+           returnValue = self->GetTypeName();
+           return returnValue.CString();
+        }
+
+        ATOMIC_EXPORT_API int csi_Atomic_RefCounted_Refs(RefCounted* self)
+        {
+           return self->Refs();
+        }
+
+
+        ATOMIC_EXPORT_API void csi_Atomic_AObject_SendEvent(Object* obj, const char* eventType, ScriptVariantMap* vmap)
         {
         {
             obj->SendEvent(eventType, vmap ? vmap->GetVariantMap() : obj->GetEventDataMap());
             obj->SendEvent(eventType, vmap ? vmap->GetVariantMap() : obj->GetEventDataMap());
         }
         }
 
 
-        ATOMIC_EXPORT_API ClassID csb_Atomic_NETCore_Initialize(NETCoreDelegates* delegates)
+        ATOMIC_EXPORT_API ClassID csi_Atomic_NETCore_Initialize(NETCoreDelegates* delegates)
         {
         {
             Context* context = new Context();
             Context* context = new Context();
             NETCore* netCore = new NETCore(context, delegates);
             NETCore* netCore = new NETCore(context, delegates);
@@ -52,7 +68,7 @@ namespace Atomic
             return netCore;
             return netCore;
         }
         }
 
 
-        ATOMIC_EXPORT_API unsigned csb_Atomic_AtomicNET_StringToStringHash(const char* str)
+        ATOMIC_EXPORT_API unsigned csi_Atomic_AtomicNET_StringToStringHash(const char* str)
         {
         {
             unsigned hash = 0;
             unsigned hash = 0;
 
 
@@ -70,7 +86,7 @@ namespace Atomic
             return hash;
             return hash;
         }
         }
 
 
-        ATOMIC_EXPORT_API void csb_Atomic_AtomicNET_ScriptVariantMapCopyVariantMap(ScriptVariantMap* svm, VariantMap* vm)
+        ATOMIC_EXPORT_API void csi_Atomic_AtomicNET_ScriptVariantMapCopyVariantMap(ScriptVariantMap* svm, VariantMap* vm)
         {
         {
             if (!svm)
             if (!svm)
                 return;
                 return;
@@ -85,7 +101,7 @@ namespace Atomic
 
 
         }
         }
 
 
-        ATOMIC_EXPORT_API void* csb_Atomic_AtomicNET_ScriptVariantMap_GetVoidPtr(ScriptVariantMap* svm, const char* key)
+        ATOMIC_EXPORT_API void* csi_Atomic_AtomicNET_ScriptVariantMap_GetVoidPtr(ScriptVariantMap* svm, const char* key)
         {
         {
             if (!svm || !key || !strlen(key))
             if (!svm || !key || !strlen(key))
                 return nullptr;
                 return nullptr;
@@ -95,7 +111,7 @@ namespace Atomic
         }
         }
 
 
         // IPC
         // IPC
-        ATOMIC_EXPORT_API void csb_Atomic_IPC_SendEventToBrokerWithEventData(IPC* ipc, const char* eventType, ScriptVariantMap* variantMap)
+        ATOMIC_EXPORT_API void csi_Atomic_IPC_SendEventToBrokerWithEventData(IPC* ipc, const char* eventType, ScriptVariantMap* variantMap)
         {
         {
             if (variantMap)
             if (variantMap)
                 ipc->SendEventToBroker(eventType, variantMap->GetVariantMap());
                 ipc->SendEventToBroker(eventType, variantMap->GetVariantMap());
@@ -104,7 +120,7 @@ namespace Atomic
 
 
         }
         }
 
 
-        ATOMIC_EXPORT_API void* csb_Atomic_VertexBuffer_Lock(VertexBuffer* vb , unsigned start, unsigned count, bool discard)
+        ATOMIC_EXPORT_API void* csi_Atomic_VertexBuffer_Lock(VertexBuffer* vb , unsigned start, unsigned count, bool discard)
         {
         {
             if (!vb)
             if (!vb)
                 return nullptr;
                 return nullptr;
@@ -113,7 +129,7 @@ namespace Atomic
 
 
         }
         }
 
 
-        ATOMIC_EXPORT_API void csb_Atomic_Graphics_SetShaderParameter_Matrix3x4(Graphics* graphics, const char* param, Matrix3x4* matrix)
+        ATOMIC_EXPORT_API void csi_Atomic_Graphics_SetShaderParameter_Matrix3x4(Graphics* graphics, const char* param, Matrix3x4* matrix)
         {
         {
             if (!graphics || !param || !strlen(param))
             if (!graphics || !param || !strlen(param))
                 return;
                 return;
@@ -121,22 +137,6 @@ namespace Atomic
             graphics->SetShaderParameter(param, *matrix);
             graphics->SetShaderParameter(param, *matrix);
         }
         }
 
 
-        ATOMIC_EXPORT_API void csb_Atomic_Graphics_SetShaderParameter_Color(Graphics* graphics, const char* param, Color* color)
-        {
-            if (!graphics || !param || !strlen(param) || !color)
-                return;
-
-            graphics->SetShaderParameter(param, *color);
-        }
-
-
-        ATOMIC_EXPORT_API void csb_Atomic_Viewport_SetRenderPath_RenderPath(Viewport* viewport, RenderPath* renderPath)
-        {
-            if (!viewport)
-                return;
-
-            viewport->SetRenderPath(renderPath);
-        }
 
 
     }
     }
 }
 }

+ 12 - 7
Source/ToolCore/JSBind/CSharp/CSClassWriter.cpp

@@ -188,9 +188,13 @@ void CSClassWriter::GenerateManagedSource(String& sourceOut)
     String line;
     String line;
 
 
     if (klass_->GetBaseClass())
     if (klass_->GetBaseClass())
-        line = "public partial class " + klass_->GetName() + " : " + klass_->GetBaseClass()->GetName() + "\n";
+    {
+        line = ToString("public partial class %s%s : %s\n", klass_->GetName().CString(), klass_->IsGeneric() ? "<T>" : "", klass_->GetBaseClass()->GetName().CString());
+    }
     else
     else
-        line = "public partial class " + klass_->GetName() + "\n";
+    {
+        line = ToString("public partial class %s%s\n", klass_->GetName().CString(), klass_->IsGeneric() ? "<T>" : "");
+    }
 
 
 
 
     source += IndentLine(line);
     source += IndentLine(line);
@@ -215,7 +219,9 @@ void CSClassWriter::GenerateManagedSource(String& sourceOut)
     Dedent();
     Dedent();
 
 
     // managed functions
     // managed functions
-    bool wroteConstructor = false;
+
+    CSFunctionWriter::SetWroteConstructor(false);
+
     for (unsigned i = 0; i < klass_->functions_.Size(); i++)
     for (unsigned i = 0; i < klass_->functions_.Size(); i++)
     {
     {
         JSBFunction* function = klass_->functions_.At(i);
         JSBFunction* function = klass_->functions_.At(i);
@@ -229,9 +235,6 @@ void CSClassWriter::GenerateManagedSource(String& sourceOut)
         if (CSTypeHelper::OmitFunction(function))
         if (CSTypeHelper::OmitFunction(function))
             continue;
             continue;
 
 
-        if (function->IsConstructor())
-            wroteConstructor = true;
-
         CSFunctionWriter fwriter(function);
         CSFunctionWriter fwriter(function);
         fwriter.GenerateManagedSource(source);
         fwriter.GenerateManagedSource(source);
 
 
@@ -239,7 +242,7 @@ void CSClassWriter::GenerateManagedSource(String& sourceOut)
 
 
     // There are some constructors being skipped (like HTTPRequest as it uses a vector of strings in args)
     // There are some constructors being skipped (like HTTPRequest as it uses a vector of strings in args)
     // Make sure we have at least a IntPtr version
     // Make sure we have at least a IntPtr version
-    if (!wroteConstructor)
+    if (!CSFunctionWriter::GetWroteConstructor() && klass_->GetName() != "RefCounted")
     {
     {
         ATOMIC_LOGINFOF("WARNING: %s class didn't write a constructor, filling in generated native constructor", klass_->GetName().CString());
         ATOMIC_LOGINFOF("WARNING: %s class didn't write a constructor, filling in generated native constructor", klass_->GetName().CString());
 
 
@@ -249,6 +252,8 @@ void CSClassWriter::GenerateManagedSource(String& sourceOut)
         source += IndentLine("}\n\n");
         source += IndentLine("}\n\n");
     }
     }
 
 
+    CSFunctionWriter::SetWroteConstructor(false);
+
     source += IndentLine("}\n");
     source += IndentLine("}\n");
 
 
     Dedent();
     Dedent();

+ 194 - 17
Source/ToolCore/JSBind/CSharp/CSFunctionWriter.cpp

@@ -113,6 +113,8 @@ RefCounted* csb_ObjectAnimation_Constructor()
 namespace ToolCore
 namespace ToolCore
 {
 {
 
 
+bool CSFunctionWriter::wroteConstructor_ = false;
+
 CSFunctionWriter::CSFunctionWriter(JSBFunction *function) : JSBFunctionWriter(function)
 CSFunctionWriter::CSFunctionWriter(JSBFunction *function) : JSBFunctionWriter(function)
 {
 {
 
 
@@ -152,15 +154,26 @@ void CSFunctionWriter::GenNativeCallParameters(String& sig)
                     continue;
                     continue;
                 }
                 }
 
 
-                if (klass->IsNumberArray())
+                if (klass->IsNumberArray() || ptype->isReference_)
                     args.Push(ToString("*%s", ptype->name_.CString()));
                     args.Push(ToString("*%s", ptype->name_.CString()));
                 else
                 else
                     args.Push(ToString("%s", ptype->name_.CString()));
                     args.Push(ToString("%s", ptype->name_.CString()));
 
 
             }
             }
+            else if (ptype->type_->asVectorType())
+            {
+                args.Push(ToString("%s__vector", ptype->name_.CString()));
+            }
             else
             else
             {
             {
-                args.Push(ToString("%s", ptype->name_.CString()));
+                if (ptype->type_->asStringType() || ptype->type_->asStringHashType())
+                {
+                    args.Push(ToString("%s ? String(%s) : String::EMPTY", ptype->name_.CString(), ptype->name_.CString()));
+                }
+                else
+                {
+                    args.Push(ToString("%s", ptype->name_.CString()));
+                }
             }
             }
 
 
         }
         }
@@ -189,9 +202,52 @@ void CSFunctionWriter::WriteNativeFunction(String& source)
 
 
     Indent();
     Indent();
 
 
-
     source += "\n";
     source += "\n";
 
 
+    // vector marshal
+
+    bool hasVectorMarshal = false;
+    Vector<JSBFunctionType*>& fparams = function_->GetParameters();
+
+    for (unsigned i = 0; i < fparams.Size(); i++)
+    {
+        JSBFunctionType* ftype = fparams[i];
+
+        JSBVectorType* vtype = ftype->type_->asVectorType();
+
+        if (!vtype)
+            continue;
+
+        JSBClassType* classType = vtype->vectorType_->asClassType();
+
+        if (!classType)
+            continue;
+
+        String className = classType->class_->GetName();
+
+        String vectorMarshal;
+
+        hasVectorMarshal = true;
+
+        if (vtype->isPODVector_)
+        {
+            const String& pname = ftype->name_;
+            source += IndentLine(ToString("PODVector<%s*> %s__vector;\n", className.CString(), pname.CString()));
+            source += IndentLine(ToString("if (%s) %s->AdaptToVector<%s*>(%s__vector);\n", pname.CString(), pname.CString(), className.CString(), pname.CString()));
+        }
+        else
+        {
+            // vectorMarshal = ToString("PODVector<%s*> %s__vector", className.CString(), ftype->name_.CString());
+        }
+
+        if (vectorMarshal.Length())
+        {
+            source += IndentLine(vectorMarshal);
+            vectorMarshal = String::EMPTY;
+        }
+    }
+
+
     bool returnValue = false;
     bool returnValue = false;
     bool sharedPtrReturn = false;
     bool sharedPtrReturn = false;
 
 
@@ -212,12 +268,30 @@ void CSFunctionWriter::WriteNativeFunction(String& source)
         returnStatement = ToString("SharedPtr<%s> returnValue = ", function_->GetReturnClass()->GetNativeName().CString());
         returnStatement = ToString("SharedPtr<%s> returnValue = ", function_->GetReturnClass()->GetNativeName().CString());
         sharedPtrReturn = true;
         sharedPtrReturn = true;
     }
     }
+    else if (function_->GetReturnType() && function_->GetReturnType()->type_->asVectorType())
+    {
+        // we have an out parameter
+        JSBVectorType* vtype = function_->GetReturnType()->type_->asVectorType();
+
+        if (!vtype->vectorTypeIsSharedPtr_ && !vtype->vectorTypeIsWeakPtr_)
+        {
+            returnStatement = ToString("%sVector<%s*> returnValue__vector = ", vtype->isPODVector_ ? "POD" : "", vtype->vectorType_->asClassType()->class_->GetName().CString());
+        }
+        else
+        {
+            returnStatement = ToString("%sVector<%s<%s>> returnValue__vector = ",  vtype->isPODVector_ ? "POD" : "", vtype->vectorTypeIsSharedPtr_ ? "SharedPtr" : "WeakPtr", vtype->vectorType_->asClassType()->class_->GetName().CString());
+        }
+    }
     else
     else
     {
     {
-        if (returnType != "void")
+        if (returnType != "void" && !hasVectorMarshal)
         {
         {
             returnStatement = "return ";
             returnStatement = "return ";
         }
         }
+        else if (returnType != "void")
+        {
+            returnStatement = ToString("%s returnValue = ", returnType.CString());
+        }
     }
     }
 
 
     String callSig;
     String callSig;
@@ -255,6 +329,44 @@ void CSFunctionWriter::WriteNativeFunction(String& source)
 
 
     source += IndentLine(line);
     source += IndentLine(line);
 
 
+    // Vector marshaling
+
+    for (unsigned i = 0; i < fparams.Size(); i++)
+    {
+        JSBFunctionType* ftype = fparams[i];
+
+        JSBVectorType* vtype = ftype->type_->asVectorType();
+
+        if (!vtype)
+            continue;
+
+        JSBClassType* classType = vtype->vectorType_->asClassType();
+
+        if (!classType)
+            continue;
+
+        String className = classType->class_->GetName();
+
+        String vectorMarshal;
+
+        if (vtype->isPODVector_)
+        {
+            const String& pname = ftype->name_;
+            source += IndentLine(ToString("if (%s) %s->AdaptFromVector<%s*>(%s__vector);\n", pname.CString(), pname.CString(), className.CString(), pname.CString()));
+        }
+        else
+        {
+            // vectorMarshal = ToString("PODVector<%s*> %s__vector", className.CString(), ftype->name_.CString());
+        }
+
+        if (vectorMarshal.Length())
+        {
+            source += IndentLine(vectorMarshal);
+            vectorMarshal = String::EMPTY;
+        }
+    }
+
+
     if (sharedPtrReturn)
     if (sharedPtrReturn)
     {
     {
         source += IndentLine("if (returnValue.NotNull()) returnValue->AddRef();\n");
         source += IndentLine("if (returnValue.NotNull()) returnValue->AddRef();\n");
@@ -264,6 +376,17 @@ void CSFunctionWriter::WriteNativeFunction(String& source)
     {
     {
         source += IndentLine("return returnValue.CString();\n");
         source += IndentLine("return returnValue.CString();\n");
     }
     }
+    else if (function_->GetReturnType() && function_->GetReturnType()->type_->asVectorType())
+    {
+        // we have an out parameter
+        JSBVectorType* vtype = function_->GetReturnType()->type_->asVectorType();
+        source += IndentLine("if (returnValue) returnValue->AdaptFromVector(returnValue__vector);\n");
+
+    }
+    else if (returnType != "void" && hasVectorMarshal)
+    {
+        source += IndentLine("return returnValue;\n");
+    }
 
 
     Dedent();
     Dedent();
 
 
@@ -319,6 +442,10 @@ void CSFunctionWriter::WriteManagedPInvokeFunctionSignature(String& source)
 
 
     String returnType = CSTypeHelper::GetPInvokeTypeString(function_->GetReturnType());
     String returnType = CSTypeHelper::GetPInvokeTypeString(function_->GetReturnType());
 
 
+    // handled by out parameter
+    if (function_->GetReturnType() && function_->GetReturnType()->type_->asVectorType())
+        returnType = "void";
+
     if (returnType == "bool")
     if (returnType == "bool")
     {
     {
         // default boolean marshal is 4 byte windows type BOOL and not 1 byte bool
         // default boolean marshal is 4 byte windows type BOOL and not 1 byte bool
@@ -386,20 +513,25 @@ void CSFunctionWriter::WriteManagedPInvokeFunctionSignature(String& source)
     if (function_->GetReturnClass())
     if (function_->GetReturnClass())
     {
     {
         JSBClass* retClass = function_->GetReturnClass();
         JSBClass* retClass = function_->GetReturnClass();
+
         if (retClass->IsNumberArray())
         if (retClass->IsNumberArray())
         {
         {
             args.Push("ref " + retClass->GetName() + " retValue");
             args.Push("ref " + retClass->GetName() + " retValue");
         }
         }
 
 
     }
     }
+    else if (function_->GetReturnType() && function_->GetReturnType()->type_->asVectorType())
+    {
+        args.Push("IntPtr returnValue");
+    }
 
 
     String pstring;
     String pstring;
     pstring.Join(args, ", ");
     pstring.Join(args, ", ");
 
 
     String fname = function_->IsConstructor() ? "Constructor" : function_->GetName();
     String fname = function_->IsConstructor() ? "Constructor" : function_->GetName();
-    line = ToString("private static extern %s csb_%s_%s_%s(%s);\n",
+    line = ToString("private static extern %s csb_%s_%s_%s_%u(%s);\n",
                     returnType.CString(), package->GetName().CString(), klass->GetName().CString(),
                     returnType.CString(), package->GetName().CString(), klass->GetName().CString(),
-                    fname.CString(), pstring.CString());
+                    fname.CString(), function_->GetID(), pstring.CString());
 
 
     source += IndentLine(line);
     source += IndentLine(line);
 
 
@@ -461,10 +593,16 @@ void CSFunctionWriter::WriteManagedConstructor(String& source)
 
 
     String line;
     String line;
 
 
-    line = ToString("public %s (IntPtr native) : base (native)\n", klass->GetName().CString());
-    source += IndentLine(line);
-    source += IndentLine("{\n");
-    source += IndentLine("}\n\n");
+    if (!wroteConstructor_)
+    {
+        line = ToString("public %s (IntPtr native) : base (native)\n", klass->GetName().CString());
+        source += IndentLine(line);
+        source += IndentLine("{\n");
+        source += IndentLine("}\n\n");
+    }
+
+    // don't add wrapping constructor for overloads
+    wroteConstructor_ = true;
 
 
     String sig;
     String sig;
     GenManagedFunctionParameters(sig);
     GenManagedFunctionParameters(sig);
@@ -498,8 +636,8 @@ void CSFunctionWriter::WriteManagedConstructor(String& source)
 
 
     source += IndentLine("IntPtr nativeInstanceOverride = NativeCore.NativeContructorOverride;\n");
     source += IndentLine("IntPtr nativeInstanceOverride = NativeCore.NativeContructorOverride;\n");
 
 
-    line = ToString("nativeInstance = NativeCore.RegisterNative (nativeInstanceOverride != IntPtr.Zero ? nativeInstanceOverride : csb_%s_%s_Constructor(%s), this);\n",
-                     package->GetName().CString(), klass->GetName().CString(), callSig.CString());
+    line = ToString("nativeInstance = NativeCore.RegisterNative (nativeInstanceOverride != IntPtr.Zero ? nativeInstanceOverride : csb_%s_%s_Constructor_%u(%s), this);\n",
+                     package->GetName().CString(), klass->GetName().CString(), function_->GetID(), callSig.CString());
 
 
     source += IndentLine(line);
     source += IndentLine(line);
 
 
@@ -579,15 +717,23 @@ void CSFunctionWriter::GenPInvokeCallParameters(String& sig)
                 sig += ", ";
                 sig += ", ";
 
 
             JSBClass* klass = function_->GetClass();
             JSBClass* klass = function_->GetClass();
-            sig += ToString("ref %s%sReturnValue", klass->GetName().CString(), function_->GetName().CString());
+            sig += ToString("ref %s%s%uReturnValue", klass->GetName().CString(), function_->GetName().CString(), function_->GetID());
         }
         }
     }
     }
+    else if (!function_->IsStatic() && function_->GetReturnType() && function_->GetReturnType()->type_->asVectorType())
+    {
+        if (sig.Length())
+            sig += ", ";
 
 
+        JSBClass* klass = function_->GetClass();
+        sig += "returnScriptVector";
+    }
 
 
 }
 }
 
 
 void CSFunctionWriter::WriteManagedFunction(String& source)
 void CSFunctionWriter::WriteManagedFunction(String& source)
 {
 {
+
     JSBClass* klass = function_->GetClass();
     JSBClass* klass = function_->GetClass();
     JSBPackage* package = klass->GetPackage();
     JSBPackage* package = klass->GetPackage();
 
 
@@ -635,10 +781,15 @@ void CSFunctionWriter::WriteManagedFunction(String& source)
 
 
     if (function_->GetReturnType())
     if (function_->GetReturnType())
     {
     {
+
         if (function_->GetReturnType()->type_->asStringType() || function_->GetReturnType()->type_->asStringHashType())
         if (function_->GetReturnType()->type_->asStringType() || function_->GetReturnType()->type_->asStringHashType())
         {
         {
             line += "return System.Runtime.InteropServices.Marshal.PtrToStringAnsi(";
             line += "return System.Runtime.InteropServices.Marshal.PtrToStringAnsi(";
         }
         }
+        else if (function_->GetReturnType()->type_->asVectorType())
+        {
+            source += IndentLine(ToString("var returnScriptVector = %s%s%uReturnValue.GetScriptVector();\n", klass->GetName().CString(), function_->GetName().CString(), function_->GetID()));
+        }
         else if (CSTypeHelper::IsSimpleReturn(function_->GetReturnType()))
         else if (CSTypeHelper::IsSimpleReturn(function_->GetReturnType()))
             line += "return ";
             line += "return ";
         else
         else
@@ -659,8 +810,8 @@ void CSFunctionWriter::WriteManagedFunction(String& source)
     if (!function_->IsStatic())
     if (!function_->IsStatic())
         nativeInstance = "nativeInstance";
         nativeInstance = "nativeInstance";
 
 
-    line += ToString("csb_%s_%s_%s(%s",
-                     package->GetName().CString(), klass->GetName().CString(), function_->GetName().CString(), nativeInstance.CString());
+    line += ToString("csb_%s_%s_%s_%u(%s",
+                     package->GetName().CString(), klass->GetName().CString(), function_->GetName().CString(), function_->GetID(), nativeInstance.CString());
 
 
     if (callSig.Length())
     if (callSig.Length())
     {
     {
@@ -690,7 +841,7 @@ void CSFunctionWriter::WriteManagedFunction(String& source)
 
 
             if (retClass->IsNumberArray())
             if (retClass->IsNumberArray())
             {
             {
-                line = ToString("return %s%sReturnValue;", klass->GetName().CString(), function_->GetName().CString());
+                line = ToString("return %s%s%uReturnValue;", klass->GetName().CString(), function_->GetName().CString(), function_->GetID());
             }
             }
             else
             else
             {
             {
@@ -702,6 +853,14 @@ void CSFunctionWriter::WriteManagedFunction(String& source)
             source+= "\n";
             source+= "\n";
         }
         }
     }
     }
+    else if (function_->GetReturnType() && function_->GetReturnType()->type_->asVectorType())
+    {
+        if (!function_->IsStatic())
+        {
+            source += IndentLine(ToString("return %s%s%uReturnValue;", klass->GetName().CString(), function_->GetName().CString(), function_->GetID()));
+            source+= "\n";
+        }
+    }
 
 
     Dedent();
     Dedent();
 
 
@@ -743,6 +902,7 @@ void CSFunctionWriter::GenerateManagedSource(String& sourceOut)
         if (function_->GetReturnClass())
         if (function_->GetReturnClass())
         {
         {
             JSBClass* retClass = function_->GetReturnClass();
             JSBClass* retClass = function_->GetReturnClass();
+
             if (retClass->IsNumberArray())
             if (retClass->IsNumberArray())
             {
             {
                 JSBClass* klass = function_->GetClass();
                 JSBClass* klass = function_->GetClass();
@@ -754,11 +914,28 @@ void CSFunctionWriter::GenerateManagedSource(String& sourceOut)
 
 
                 marshal += managedType + " ";
                 marshal += managedType + " ";
 
 
-                marshal += ToString("%s%sReturnValue = new %s();\n", klass->GetName().CString(), function_->GetName().CString(), managedType.CString());
+                marshal += ToString("%s%s%uReturnValue = new %s();\n", klass->GetName().CString(), function_->GetName().CString(), function_->GetID(), managedType.CString());
 
 
                 sourceOut += IndentLine(marshal);
                 sourceOut += IndentLine(marshal);
             }
             }
         }
         }
+    }
+    else if (!function_->IsStatic() && function_->GetReturnType() && function_->GetReturnType()->type_->asVectorType())
+    {
+        JSBVectorType* vtype = function_->GetReturnType()->type_->asVectorType();
+
+        if (vtype->vectorType_->asClassType())
+        {
+            String classname = vtype->vectorType_->asClassType()->class_->GetName();
+            String typestring = "Vector<" + classname + ">";
+
+            String marshal = "private " + typestring + " ";
+
+            marshal += ToString("%s%s%uReturnValue = new %s();\n", function_->GetClass()->GetName().CString(), function_->GetName().CString(), function_->GetID(), typestring.CString());
+
+            sourceOut += IndentLine(marshal);
+
+        }
 
 
     }
     }
 
 

+ 4 - 0
Source/ToolCore/JSBind/CSharp/CSFunctionWriter.h

@@ -46,6 +46,8 @@ public:
     void GenerateNativeSource(String& sourceOut);
     void GenerateNativeSource(String& sourceOut);
     void GenerateManagedSource(String& sourceOut);
     void GenerateManagedSource(String& sourceOut);
 
 
+    static void SetWroteConstructor(bool value) { wroteConstructor_ = value; }
+    static bool GetWroteConstructor() { return wroteConstructor_; }
 
 
 private:
 private:
 
 
@@ -56,6 +58,8 @@ private:
         String assignment;
         String assignment;
     };
     };
 
 
+    static bool wroteConstructor_;
+
     Vector<DefaultStructParameter> defaultStructParameters_;
     Vector<DefaultStructParameter> defaultStructParameters_;
 
 
     void WriteDefaultStructParameters(String& source);
     void WriteDefaultStructParameters(String& source);

+ 2 - 0
Source/ToolCore/JSBind/CSharp/CSModuleWriter.cpp

@@ -92,6 +92,8 @@ void CSModuleWriter::WriteIncludes(String& source)
         included.Push(header);
         included.Push(header);
     }
     }
 
 
+    source += "\n#include <Atomic/Script/ScriptVector.h>\n";
+
     source += ToString("\n#include \"CSPackage%s.h\"\n", module_->GetPackage()->GetName().CString());
     source += ToString("\n#include \"CSPackage%s.h\"\n", module_->GetPackage()->GetName().CString());
 
 
 }
 }

+ 69 - 14
Source/ToolCore/JSBind/CSharp/CSTypeHelper.cpp

@@ -71,6 +71,16 @@ void CSTypeHelper::GenNativeFunctionParameterSignature(JSBFunction* function, St
         args.Push(ToString("%s* returnValue", function->GetReturnClass()->GetNativeName().CString()));
         args.Push(ToString("%s* returnValue", function->GetReturnClass()->GetNativeName().CString()));
     }
     }
 
 
+    if (function->GetReturnType())
+    {
+        JSBVectorType* vtype = function->GetReturnType()->type_->asVectorType();
+
+        if (vtype)
+        {
+            args.Push("ScriptVector* returnValue");
+        }
+    }
+
     sig.Join(args, ", ");
     sig.Join(args, ", ");
 
 
 }
 }
@@ -117,6 +127,10 @@ String CSTypeHelper::GetNativeFunctionSignature(JSBFunction* function, String& r
         else
         else
         {
         {
             returnType = ToString("%s", CSTypeHelper::GetNativeTypeString(function->GetReturnType()).CString());
             returnType = ToString("%s", CSTypeHelper::GetNativeTypeString(function->GetReturnType()).CString());
+
+            // ScriptVector is handled by a out parameter
+            if (returnType.Contains("ScriptVector"))
+                returnType = "void";
         }
         }
     }
     }
 
 
@@ -124,9 +138,9 @@ String CSTypeHelper::GetNativeFunctionSignature(JSBFunction* function, String& r
     String sig;
     String sig;
     GenNativeFunctionParameterSignature(function, sig);
     GenNativeFunctionParameterSignature(function, sig);
 
 
-    String functionSig = ToString("csb_%s_%s_%s(%s)",
+    String functionSig = ToString("csb_%s_%s_%s_%u(%s)",
                 package->GetName().CString(), klass->GetName().CString(),
                 package->GetName().CString(), klass->GetName().CString(),
-                fname.CString(), sig.CString());
+                fname.CString(), function->GetID(), sig.CString());
 
 
     return functionSig;
     return functionSig;
 }
 }
@@ -179,9 +193,8 @@ String CSTypeHelper::GetManagedTypeString(JSBType* type)
     }
     }
     else if (type->asVectorType())
     else if (type->asVectorType())
     {
     {
-        JSBVectorType* vectorType = type->asVectorType();
 
 
-        value = GetManagedTypeString(vectorType->vectorType_) + "[]";
+        value = ToString("Vector<%s>", type->asVectorType()->vectorType_->asClassType()->class_->GetName().CString());
     }
     }
 
 
     return value;
     return value;
@@ -255,7 +268,7 @@ String CSTypeHelper::GetNativeTypeString(JSBType* type)
     }
     }
     else if (type->asVectorType())
     else if (type->asVectorType())
     {
     {
-        assert(0);
+        value = "ScriptVector*";//type->asVectorType()->ToString();
     }
     }
 
 
     return value;
     return value;
@@ -298,9 +311,8 @@ String CSTypeHelper::GetPInvokeTypeString(JSBType* type)
     }
     }
     else if (type->asVectorType())
     else if (type->asVectorType())
     {
     {
-        JSBVectorType* vectorType = type->asVectorType();
-
-        value = GetManagedTypeString(vectorType->vectorType_) + "[]";
+        // ScriptVector
+        value = "IntPtr";
     }
     }
 
 
     return value;
     return value;
@@ -357,26 +369,69 @@ bool CSTypeHelper::OmitFunction(JSBFunction* function)
     if (!function)
     if (!function)
         return false;
         return false;
 
 
-    if (function->Skip())
+
+    if (function->GetSkipLanguage(BINDINGLANGUAGE_CSHARP))
         return true;
         return true;
 
 
     if (function->IsDestructor())
     if (function->IsDestructor())
+    {
+        function->SetSkipLanguage(BINDINGLANGUAGE_CSHARP);
         return true;
         return true;
+    }
 
 
     // We need to rename GetType
     // We need to rename GetType
     if (function->GetName() == "GetType")
     if (function->GetName() == "GetType")
+    {
+        function->SetSkipLanguage(BINDINGLANGUAGE_CSHARP);
         return true;
         return true;
+    }
 
 
-    // avoid vector type for now
-    if (function->GetReturnType() && function->GetReturnType()->type_->asVectorType())
-        return true;
+    if (function->GetReturnType())
+    {
+        if (JSBVectorType* vtype = function->GetReturnType()->type_->asVectorType())
+        {
+            if (!vtype->vectorType_->asClassType() || vtype->vectorType_->asClassType()->class_->IsNumberArray())
+            {
+                function->SetSkipLanguage(BINDINGLANGUAGE_CSHARP);
+                return true;
+            }
+        }
+    }
 
 
     Vector<JSBFunctionType*>& parameters = function->GetParameters();
     Vector<JSBFunctionType*>& parameters = function->GetParameters();
 
 
     for (unsigned i = 0; i < parameters.Size(); i++)
     for (unsigned i = 0; i < parameters.Size(); i++)
     {
     {
-        if (parameters[i]->type_->asVectorType())
-            return true;
+        if (JSBVectorType* vtype = parameters[i]->type_->asVectorType())
+        {
+            if (!vtype->vectorType_->asClassType() || vtype->vectorType_->asClassType()->class_->IsNumberArray())
+            {
+                function->SetSkipLanguage(BINDINGLANGUAGE_CSHARP);
+                return true;
+            }
+
+        }
+
+    }
+
+    // filter overloads which differ in PODVector vs Vector/StringHash vs String, etc
+
+    PODVector<JSBFunction*> allFunctions;
+    function->GetClass()->GetAllFunctions(allFunctions);
+
+    for (unsigned i = 0; i < allFunctions.Size(); i++)
+    {
+        JSBFunction* other = allFunctions[i];
+
+        if (other == function || other->GetSkipLanguage(BINDINGLANGUAGE_CSHARP))
+            continue;
+
+        if (other->Match(function))
+        {
+            if (other->GetClass() == function->GetClass())
+                other->SetSkipLanguage(BINDINGLANGUAGE_CSHARP);
+        }
+
     }
     }
 
 
     return false;
     return false;

+ 17 - 7
Source/ToolCore/JSBind/JSBClass.cpp

@@ -58,6 +58,7 @@ void JSBFunctionSignature::Parse()
 
 
 }
 }
 
 
+
 bool JSBFunctionSignature::Match(JSBFunction* function)
 bool JSBFunctionSignature::Match(JSBFunction* function)
 {
 {
 
 
@@ -125,7 +126,7 @@ bool JSBFunctionSignature::Match(JSBFunction* function)
 
 
 JSBClass::JSBClass(Context* context, JSBModule *module, const String& name, const String& nativeName) : Object(context),
 JSBClass::JSBClass(Context* context, JSBModule *module, const String& name, const String& nativeName) : Object(context),
     module_(module), name_(name), nativeName_(nativeName),
     module_(module), name_(name), nativeName_(nativeName),
-    isAbstract_(false), isObject_(false),
+    isAbstract_(false), isObject_(false), isGeneric_(false),
     numberArrayElements_(0), arrayElementType_("float"),
     numberArrayElements_(0), arrayElementType_("float"),
     hasProperties_(false)
     hasProperties_(false)
 {
 {
@@ -181,11 +182,20 @@ JSBClass* JSBClass::GetBaseClass()
 
 
 }
 }
 
 
-JSBFunction* JSBClass::GetConstructor()
+void JSBClass::GetAllFunctions(PODVector<JSBFunction*>& functions)
+{
+    if (baseClasses_.Size())
+        baseClasses_[0]->GetAllFunctions(functions);
+
+    functions += functions_;
+
+}
+
+JSBFunction* JSBClass::GetConstructor(BindingLanguage bindingLanguage)
 {
 {
     {
     {
         for (unsigned i = 0; i < functions_.Size(); i++)
         for (unsigned i = 0; i < functions_.Size(); i++)
-            if (functions_[i]->IsConstructor() && !functions_[i]->Skip())
+            if (functions_[i]->IsConstructor() && !functions_[i]->Skip(bindingLanguage))
                 return functions_[i];
                 return functions_[i];
     }
     }
 
 
@@ -340,9 +350,9 @@ void JSBClass::Process()
             {
             {
                 function->SetOverload();
                 function->SetOverload();
                 function2->SetOverload();
                 function2->SetOverload();
-                // initially set all overridden functions to skip
-                function->SetSkip(true);
-                function2->SetSkip(true);
+                // initially set all overridden functions to skip (for JavaScript)
+                function->SetSkipLanguage(BINDINGLANGUAGE_JAVASCRIPT);
+                function2->SetSkipLanguage(BINDINGLANGUAGE_JAVASCRIPT);
                 break;
                 break;
             }
             }
         }
         }
@@ -363,7 +373,7 @@ void JSBClass::Process()
                 if (!override->Match(function))
                 if (!override->Match(function))
                     continue;
                     continue;
 
 
-                function->SetSkip(false);
+                function->SetSkipLanguage(BINDINGLANGUAGE_JAVASCRIPT, false);
 
 
                 break;
                 break;
 
 

+ 8 - 1
Source/ToolCore/JSBind/JSBClass.h

@@ -24,6 +24,7 @@
 
 
 #include <Atomic/Core/Object.h>
 #include <Atomic/Core/Object.h>
 
 
+#include "JSBindTypes.h"
 #include "JSBHeader.h"
 #include "JSBHeader.h"
 #include "JSBModule.h"
 #include "JSBModule.h"
 
 
@@ -127,6 +128,10 @@ public:
     PODVector<JSBClass*>& GetBaseClasses() {return baseClasses_; }
     PODVector<JSBClass*>& GetBaseClasses() {return baseClasses_; }
     PODVector<JSBFunction*>& GetFunctions() { return functions_; }
     PODVector<JSBFunction*>& GetFunctions() { return functions_; }
 
 
+    // Get all functions, including those in base classes
+    void GetAllFunctions(PODVector<JSBFunction*>& functions);
+
+    bool IsGeneric() { return isGeneric_; }
     bool IsAbstract() { return isAbstract_; }
     bool IsAbstract() { return isAbstract_; }
 
 
     /// Note that if we at some point want to generate bindings for JSBClass
     /// Note that if we at some point want to generate bindings for JSBClass
@@ -155,10 +160,11 @@ public:
     int  GetNumberArrayElements() { return numberArrayElements_;}
     int  GetNumberArrayElements() { return numberArrayElements_;}
     const String& GetArrayElementType() const { return arrayElementType_; }
     const String& GetArrayElementType() const { return arrayElementType_; }
 
 
-    JSBFunction* GetConstructor();
+    JSBFunction* GetConstructor(BindingLanguage bindingLanguage = BINDINGLANGUAGE_ANY );
 
 
     void SetAbstract(bool value = true) { isAbstract_ = value; }
     void SetAbstract(bool value = true) { isAbstract_ = value; }
     void SetObject(bool value = true) { isObject_ = value; }
     void SetObject(bool value = true) { isObject_ = value; }
+    void SetGeneric(bool value = true) { isGeneric_ = value; }
     void SetHeader(JSBHeader* header) { header_ = header; }
     void SetHeader(JSBHeader* header) { header_ = header; }
     void SetBaseClass(JSBClass* baseClass);
     void SetBaseClass(JSBClass* baseClass);
 
 
@@ -203,6 +209,7 @@ private:
 
 
     bool isAbstract_;
     bool isAbstract_;
     bool isObject_;
     bool isObject_;
+    bool isGeneric_;
 
 
     // Vector3, Color, etc are marshalled via arrays
     // Vector3, Color, etc are marshalled via arrays
     int numberArrayElements_;
     int numberArrayElements_;

+ 1 - 1
Source/ToolCore/JSBind/JSBDoc.cpp

@@ -195,7 +195,7 @@ void JSBDoc::ExportModuleClasses(JSBModule* module)
 
 
         }
         }
 
 
-        JSBFunction* constructor = klass->GetConstructor();
+        JSBFunction* constructor = klass->GetConstructor(BINDINGLANGUAGE_JAVASCRIPT);
         if (constructor)
         if (constructor)
         {
         {
             String docs = GenFunctionDoc(constructor);
             String docs = GenFunctionDoc(constructor);

+ 18 - 0
Source/ToolCore/JSBind/JSBFunction.cpp

@@ -24,6 +24,19 @@
 
 
 namespace ToolCore
 namespace ToolCore
 {
 {
+
+unsigned JSBFunction::idCounter_ = 1;
+
+JSBFunction::JSBFunction(JSBClass* klass) : class_(klass), returnType_(0),
+                                  isConstructor_(false), isDestructor_(false),
+                                  isGetter_(false), isSetter_(false),
+                                  isOverload_(false), skip_(false),
+                                  isVirtual_(false), isStatic_(false)
+{
+    id_ = idCounter_++;
+}
+
+
 void JSBFunction::Process()
 void JSBFunction::Process()
 {
 {
     if (skip_)
     if (skip_)
@@ -31,6 +44,11 @@ void JSBFunction::Process()
         return;
         return;
     }
     }
 
 
+    // only setup properties for methods which weren't skipped for JS, for example overloads
+
+    if (GetSkipLanguage(BINDINGLANGUAGE_JAVASCRIPT))
+        return;
+
     // if not already marked as a getter
     // if not already marked as a getter
     if (!isGetter_)
     if (!isGetter_)
     {
     {

+ 47 - 10
Source/ToolCore/JSBind/JSBFunction.h

@@ -23,6 +23,7 @@
 #pragma once
 #pragma once
 
 
 #include <Atomic/IO/Log.h>
 #include <Atomic/IO/Log.h>
+#include "JSBindTypes.h"
 #include "JSBClass.h"
 #include "JSBClass.h"
 #include "JSBType.h"
 #include "JSBType.h"
 #include "JSBSymbol.h"
 #include "JSBSymbol.h"
@@ -51,6 +52,12 @@ public:
         if (!other)
         if (!other)
             return false;
             return false;
 
 
+        if (type_->asStringType() || type_->asStringHashType())
+        {
+           if (other->type_->asStringType() || other->type_->asStringHashType())
+               return true;
+        }
+
         if (isSharedPtr_ != other->isSharedPtr_)
         if (isSharedPtr_ != other->isSharedPtr_)
             return false;
             return false;
         if (isPointer_ != other->isPointer_)
         if (isPointer_ != other->isPointer_)
@@ -130,14 +137,7 @@ class JSBFunction : public JSBSymbol
 
 
 public:
 public:
 
 
-    JSBFunction(JSBClass* klass) : class_(klass), returnType_(0),
-                                   isConstructor_(false), isDestructor_(false),
-                                   isGetter_(false), isSetter_(false),
-                                   isOverload_(false), skip_(false),
-                                   isVirtual_(false), isStatic_(false)
-    {
-
-    }
+    JSBFunction(JSBClass* klass);
 
 
     const String& GetName() { return name_; }
     const String& GetName() { return name_; }
 
 
@@ -150,7 +150,16 @@ public:
     bool IsOverload() { return isOverload_; }
     bool IsOverload() { return isOverload_; }
     bool IsVirtual() { return isVirtual_; }
     bool IsVirtual() { return isVirtual_; }
     bool IsStatic() { return isStatic_; }
     bool IsStatic() { return isStatic_; }
-    bool Skip() { return skip_; }
+
+    bool Skip(BindingLanguage language = BINDINGLANGUAGE_ANY)
+    {
+        if (skip_ || language == BINDINGLANGUAGE_ANY)
+            return skip_;
+
+        return GetSkipLanguage(language);
+    }
+
+    unsigned GetID() const { return id_; }
 
 
     JSBClass* GetClass() { return class_; }
     JSBClass* GetClass() { return class_; }
     const String& GetPropertyName() { return propertyName_; }
     const String& GetPropertyName() { return propertyName_; }
@@ -175,6 +184,31 @@ public:
     void SetReturnType(JSBFunctionType* retType) { returnType_ = retType; }
     void SetReturnType(JSBFunctionType* retType) { returnType_ = retType; }
     void SetDocString(const String& docString) { docString_ = docString; }
     void SetDocString(const String& docString) { docString_ = docString; }
 
 
+    void SetSkipLanguage(BindingLanguage language, bool skip = true)
+    {
+        if (skip)
+        {
+            if (!skipLanguages_.Contains(language))
+                skipLanguages_.Push(language);
+        }
+        else
+        {
+            if (skipLanguages_.Contains(language))
+                skipLanguages_.Remove(language);
+
+        }
+    }
+
+    /// Returns true is _skip is set or skip is set for specific binding language
+    bool GetSkipLanguage(BindingLanguage language) const
+    {
+        if (skip_)
+            return true;
+
+        return skipLanguages_.Contains(language);
+
+    }
+
     int FirstDefaultParameter()
     int FirstDefaultParameter()
     {
     {
         for (unsigned i = 0; i < parameters_.Size(); i++)
         for (unsigned i = 0; i < parameters_.Size(); i++)
@@ -226,6 +260,9 @@ public:
 
 
 private:
 private:
 
 
+    unsigned id_;
+    static unsigned idCounter_;
+
     SharedPtr<JSBClass> class_;
     SharedPtr<JSBClass> class_;
 
 
     String name_;
     String name_;
@@ -244,7 +281,7 @@ private:
     bool isVirtual_;
     bool isVirtual_;
     bool isStatic_;
     bool isStatic_;
     bool skip_;
     bool skip_;
-
+    PODVector<BindingLanguage> skipLanguages_;
 };
 };
 
 
 }
 }

+ 1 - 1
Source/ToolCore/JSBind/JSBHaxe.cpp

@@ -346,7 +346,7 @@ namespace ToolCore
             if (propertyNames.Size())
             if (propertyNames.Size())
                 source_ += "\n";
                 source_ += "\n";
 
 
-            JSBFunction* constructor = klass->GetConstructor();
+            JSBFunction* constructor = klass->GetConstructor(BINDINGLANGUAGE_JAVASCRIPT);
             if (constructor)
             if (constructor)
             {
             {
                 ExportFunction(constructor);
                 ExportFunction(constructor);

+ 107 - 17
Source/ToolCore/JSBind/JSBHeaderVisitor.h

@@ -71,7 +71,7 @@ public:
         return nvisitor(name);
         return nvisitor(name);
     }
     }
 
 
-    JSBType* processTypeConversion(Type* type)
+    JSBType* processTypeConversion(Type* type, FullySpecifiedType fst)
     {
     {
         JSBType* jtype = NULL;
         JSBType* jtype = NULL;
 
 
@@ -92,18 +92,43 @@ public:
             if (classname.StartsWith("Atomic::"))
             if (classname.StartsWith("Atomic::"))
                 classname.Replace("Atomic::", "");
                 classname.Replace("Atomic::", "");
 
 
-            if (classname == "Vector")
+            if (classname == "Vector" || classname == "PODVector")
             {
             {
-                if (ntype->name()->asTemplateNameId())
+                PODVector<TemplateType> types;
+                unwrapTemplateType(fst, types);
+
+                if (types.Size() == 2)
+                {
+                    JSBType* vtype = processTypeConversion((Type*) types[1].type_, types[1].fstype_);
+
+                    if (vtype)
+                    {
+                        jtype = new JSBVectorType(vtype, classname == "PODVector");
+                    }
+
+                }
+                else if (types.Size() == 3 && ( getNameString(types[1].name_) == "SharedPtr" || getNameString(types[1].name_) == "WeakPtr"))
                 {
                 {
-                    const TemplateNameId* tnid = ntype->name()->asTemplateNameId();
-                    FullySpecifiedType pfst = tnid->templateArgumentAt(0);
-                    JSBType* vtype = processTypeConversion(pfst.type());
+                    JSBType* vtype = processTypeConversion((Type*) types[2].type_, types[2].fstype_);
+
                     if (vtype)
                     if (vtype)
                     {
                     {
-                        jtype = new JSBVectorType(vtype);
+                        JSBVectorType* jvtype = new JSBVectorType(vtype, classname == "PODVector");
+
+                        if (getNameString(types[1].name_) == "SharedPtr")
+                        {
+                            jvtype->vectorTypeIsSharedPtr_ = true;
+                        }
+                        else if (getNameString(types[1].name_) == "WeakPtr")
+                        {
+                            jvtype->vectorTypeIsWeakPtr_ = true;
+                        }
+
+                        jtype = jvtype;
                     }
                     }
+
                 }
                 }
+
             }
             }
             else if (classname == "String")
             else if (classname == "String")
             {
             {
@@ -143,6 +168,71 @@ public:
 
 
     }
     }
 
 
+    struct TemplateType
+    {
+        FullySpecifiedType fstype_;
+        bool isPointer_;
+        bool isReference_;
+        const Name* name_;
+        const Type* type_;
+
+        static void Init(TemplateType& ttype)
+        {
+            ttype.isPointer_ = false;
+            ttype.isReference_ = false;
+            ttype.name_ = 0;
+            ttype.type_ = 0;
+        }
+    };
+
+    bool unwrapTemplateType(const FullySpecifiedType& fstype, PODVector<TemplateType>& types)
+    {
+        TemplateType ttype;
+
+        TemplateType::Init(ttype);
+
+        ttype.fstype_ = fstype;
+        ttype.type_ = fstype.type();
+
+        if (ttype.type_->isPointerType())
+        {
+            ttype.isPointer_=true;
+            FullySpecifiedType pfst = ttype.type_->asPointerType()->elementType();
+            ttype.type_ = pfst.type();
+        }
+
+        if (ttype.type_->isReferenceType())
+        {
+            ttype.isReference_=true;
+            FullySpecifiedType pfst = ttype.type_->asReferenceType()->elementType();
+            ttype.type_ = pfst.type();
+        }
+
+        const NamedType* ntype = ttype.type_->asNamedType();
+
+        if (!ntype)
+            return false;
+
+        if (ntype->name()->asTemplateNameId())
+        {
+            const TemplateNameId* tnid = ntype->name()->asTemplateNameId();
+
+            ttype.name_ = tnid->identifier()->asNameId();
+
+            types.Push(ttype);
+
+            unwrapTemplateType(tnid->templateArgumentAt(0), types);
+
+            return true;
+        }
+
+        ttype.name_ = ntype->name();
+
+        types.Push(ttype);
+
+        return false;
+    }
+
     JSBFunctionType* processFunctionType(FullySpecifiedType fst, bool retType = false)
     JSBFunctionType* processFunctionType(FullySpecifiedType fst, bool retType = false)
     {
     {
         JSBType* jtype = NULL;
         JSBType* jtype = NULL;
@@ -173,14 +263,18 @@ public:
             if (type->isNamedType())
             if (type->isNamedType())
             {
             {
                 NamedType* ntype = type->asNamedType();
                 NamedType* ntype = type->asNamedType();
+
                 if (ntype->name()->asTemplateNameId())
                 if (ntype->name()->asTemplateNameId())
                 {
                 {
-                    const TemplateNameId* tnid = ntype->name()->asTemplateNameId();
-                    String classname = getNameString(tnid->identifier()->asNameId());
-                    if (classname == "SharedPtr")
+                    PODVector<TemplateType> types;
+                    unwrapTemplateType(fst, types);
+
+                    String classname = getNameString(types[0].name_);
+
+                    // SharedPtr
+                    if ( classname == "SharedPtr" && types.Size() == 2 )
                     {
                     {
-                        FullySpecifiedType pfst = tnid->templateArgumentAt(0);
-                        type = pfst.type();
+                        type = (Type*) types[1].type_;
                         isTemplate = true;
                         isTemplate = true;
                         isSharedPtr = true;
                         isSharedPtr = true;
                     }
                     }
@@ -200,7 +294,7 @@ public:
 
 
         if (!jtype)
         if (!jtype)
         {
         {
-            jtype = processTypeConversion(type);
+            jtype = processTypeConversion(type, fst);
 
 
             // explicit script string -> StringHash required
             // explicit script string -> StringHash required
             if (jtype && jtype->asStringHashType())
             if (jtype && jtype->asStringHashType())
@@ -214,10 +308,6 @@ public:
         if (!jtype)
         if (!jtype)
             return NULL;
             return NULL;
 
 
-        // read only vectors atm
-        if (!isConst && jtype->asVectorType())
-            return NULL;
-
         bool skip = false;
         bool skip = false;
 
 
         // no pointers to prim atm
         // no pointers to prim atm

+ 12 - 0
Source/ToolCore/JSBind/JSBModule.cpp

@@ -352,6 +352,11 @@ void JSBModule::RegisterClass(String name)
 
 
         JSBClass* cls = new JSBClass(context_, this, name, nativeName);
         JSBClass* cls = new JSBClass(context_, this, name, nativeName);
 
 
+        if (genericClassnames_.Contains(name))
+        {
+            cls->SetGeneric();
+        }
+
         classes_[nativeName] = cls;
         classes_[nativeName] = cls;
 
 
         package_->RegisterClass(cls);
         package_->RegisterClass(cls);
@@ -446,6 +451,13 @@ bool JSBModule::Load(const String& jsonFilename)
         classnames_.Push(classes[i].GetString());
         classnames_.Push(classes[i].GetString());
     }
     }
 
 
+    JSONArray classesGeneric = root.Get("classes_generic").GetArray();
+
+    for (unsigned i = 0; i < classesGeneric.Size(); i++)
+    {
+        genericClassnames_.Push(classesGeneric[i].GetString());
+    }
+
     JSONValue classes_rename = root.Get("classes_rename");
     JSONValue classes_rename = root.Get("classes_rename");
 
 
     if (classes_rename.IsObject())
     if (classes_rename.IsObject())

+ 2 - 0
Source/ToolCore/JSBind/JSBModule.h

@@ -107,6 +107,8 @@ private:
     Vector<String> sourceDirs_;
     Vector<String> sourceDirs_;
     Vector<String> classnames_;
     Vector<String> classnames_;
 
 
+    Vector<String> genericClassnames_;
+
     HashMap<String, String> classRenames_;
     HashMap<String, String> classRenames_;
 
 
     // native name -> JSBClass
     // native name -> JSBClass

+ 19 - 0
Source/ToolCore/JSBind/JSBType.cpp

@@ -70,4 +70,23 @@ JSBType* JSBType::Parse(const String& value)
 
 
 }
 }
 
 
+String JSBVectorType::ToString()
+{
+    if (vectorType_->asClassType())
+    {
+        String classname = vectorType_->ToString();
+
+        if (vectorTypeIsSharedPtr_)
+            classname = "SharedPtr<" + classname + ">";
+        else if (vectorTypeIsWeakPtr_)
+            classname = "WeakPtr<" + classname + ">";
+        else
+            classname += "*";
+
+        return isPODVector_ ? "PODVector<" + classname + ">" : "Vector<" + classname + ">";
+    }
+
+    return isPODVector_ ? "PODVector<" + vectorType_->ToString() + ">" : "Vector<" + vectorType_->ToString() + ">";
+}
+
 }
 }

+ 12 - 6
Source/ToolCore/JSBind/JSBType.h

@@ -150,7 +150,7 @@ public:
         if (!other)
         if (!other)
             return false;
             return false;
 
 
-        return other->asStringType() == 0 ? false : true;
+        return (other->asStringType() == 0 && other->asStringHashType() == 0) ? false : true;
     }
     }
 
 
 
 
@@ -169,7 +169,7 @@ public:
         if (!other)
         if (!other)
             return false;
             return false;
 
 
-        return other->asStringHashType() == 0 ? false : true;
+        return (other->asStringHashType() == 0 && other->asStringType() == 0)  ? false : true;
     }
     }
 
 
 };
 };
@@ -225,13 +225,14 @@ class JSBVectorType : public JSBType
 
 
 public:
 public:
 
 
-    JSBType* vectorType_;
-
-    JSBVectorType(JSBType* vtype) : vectorType_(vtype) {}
+    JSBVectorType(JSBType* vtype, bool podVector = false) : vectorType_(vtype),
+        vectorTypeIsWeakPtr_(false),
+        vectorTypeIsSharedPtr_(false),
+        isPODVector_(podVector) {}
 
 
     virtual JSBVectorType* asVectorType() { return this; }
     virtual JSBVectorType* asVectorType() { return this; }
 
 
-    String ToString() { return "Vector<" + vectorType_->ToString() + ">"; }
+    String ToString();
 
 
     virtual bool Match (JSBType* other)
     virtual bool Match (JSBType* other)
     {
     {
@@ -246,6 +247,11 @@ public:
         return true;
         return true;
     }
     }
 
 
+    JSBType* vectorType_;
+    bool vectorTypeIsWeakPtr_;
+    bool vectorTypeIsSharedPtr_;
+    bool isPODVector_;
+
 };
 };
 
 
 
 

+ 5 - 5
Source/ToolCore/JSBind/JSBTypeScript.cpp

@@ -111,7 +111,7 @@ void JSBTypeScript::End()
 
 
 void JSBTypeScript::ExportFunction(JSBFunction* function)
 void JSBTypeScript::ExportFunction(JSBFunction* function)
 {
 {
-    if (function->Skip())
+    if (function->Skip(BINDINGLANGUAGE_JAVASCRIPT))
         return;
         return;
 
 
     String scriptName = "constructor";
     String scriptName = "constructor";
@@ -228,11 +228,11 @@ void JSBTypeScript::ExportModuleClasses(JSBModule* module)
 
 
             JSBFunctionType* ftype = NULL;
             JSBFunctionType* ftype = NULL;
 
 
-            if (prop->getter_ && !prop->getter_->Skip())
+            if (prop->getter_ && !prop->getter_->Skip(BINDINGLANGUAGE_JAVASCRIPT))
             {
             {
                 ftype = prop->getter_->GetReturnType();
                 ftype = prop->getter_->GetReturnType();
             }
             }
-            else if (prop->setter_ && !prop->setter_->Skip())
+            else if (prop->setter_ && !prop->setter_->Skip(BINDINGLANGUAGE_JAVASCRIPT))
                 ftype = prop->setter_->GetParameters()[0];
                 ftype = prop->setter_->GetParameters()[0];
 
 
             if (!ftype)
             if (!ftype)
@@ -248,7 +248,7 @@ void JSBTypeScript::ExportModuleClasses(JSBModule* module)
         if (propertyNames.Size())
         if (propertyNames.Size())
             source_ += "\n";
             source_ += "\n";
 
 
-        JSBFunction* constructor = klass->GetConstructor();
+        JSBFunction* constructor = klass->GetConstructor(BINDINGLANGUAGE_JAVASCRIPT);
         if (constructor)
         if (constructor)
         {
         {
             ExportFunction(constructor);
             ExportFunction(constructor);
@@ -262,7 +262,7 @@ void JSBTypeScript::ExportModuleClasses(JSBModule* module)
 
 
             JSBFunction* func = functions[j];
             JSBFunction* func = functions[j];
 
 
-            if (func->IsConstructor() || func->IsDestructor() || func->Skip())
+            if (func->IsConstructor() || func->IsDestructor() || func->Skip(BINDINGLANGUAGE_JAVASCRIPT))
                 continue;
                 continue;
 
 
             ExportFunction(func);
             ExportFunction(func);

+ 36 - 0
Source/ToolCore/JSBind/JSBindTypes.h

@@ -0,0 +1,36 @@
+
+//
+// Copyright (c) 2014-2016 THUNDERBEAST GAMES LLC
+//
+// 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
+
+namespace ToolCore
+{
+
+enum BindingLanguage
+{
+    BINDINGLANGUAGE_ANY = 0,
+    BINDINGLANGUAGE_JAVASCRIPT,
+    BINDINGLANGUAGE_CSHARP
+};
+
+}

+ 37 - 3
Source/ToolCore/JSBind/JavaScript/JSClassWriter.cpp

@@ -47,7 +47,7 @@ void JSClassWriter::WriteFunctions(String& source)
     {
     {
         JSBFunction* function = klass_->functions_.At(i);
         JSBFunction* function = klass_->functions_.At(i);
 
 
-        if (function->Skip())
+        if (function->Skip(BINDINGLANGUAGE_JAVASCRIPT) || OmitFunction(function))
             continue;
             continue;
 
 
         if (function->IsDestructor())
         if (function->IsDestructor())
@@ -95,7 +95,7 @@ void JSClassWriter::GenerateStaticFunctionsSource(String& source, String& packag
     {
     {
         JSBFunction* function = klass_->functions_.At(i);
         JSBFunction* function = klass_->functions_.At(i);
 
 
-        if (function->Skip())
+        if (function->Skip(BINDINGLANGUAGE_JAVASCRIPT) || OmitFunction(function))
             continue;
             continue;
 
 
         if (function->IsConstructor() || function->IsDestructor())
         if (function->IsConstructor() || function->IsDestructor())
@@ -132,7 +132,7 @@ void JSClassWriter::GenerateNonStaticFunctionsSource(String& source, String& pac
     {
     {
         JSBFunction* function = klass_->functions_.At(i);
         JSBFunction* function = klass_->functions_.At(i);
 
 
-        if (function->Skip())
+        if (function->Skip(BINDINGLANGUAGE_JAVASCRIPT) || OmitFunction(function))
             continue;
             continue;
 
 
         if (function->IsConstructor() || function->IsDestructor())
         if (function->IsConstructor() || function->IsDestructor())
@@ -158,5 +158,39 @@ void JSClassWriter::GenerateNonStaticFunctionsSource(String& source, String& pac
     source.Append("duk_pop(ctx);\n");
     source.Append("duk_pop(ctx);\n");
 }
 }
 
 
+bool JSClassWriter::OmitFunction(JSBFunction* function)
+{
+
+    if (function->GetSkipLanguage(BINDINGLANGUAGE_JAVASCRIPT))
+        return true;
+
+    Vector<JSBFunctionType*>& parameters = function->GetParameters();
+
+    if (function->GetReturnType() && function->GetReturnType()->type_->asVectorType())
+    {
+        if (!function->GetReturnType()->isConst_ || function->GetReturnType()->type_->asVectorType()->isPODVector_)
+        {
+            function->SetSkipLanguage(BINDINGLANGUAGE_JAVASCRIPT);
+            return true;
+        }
+    }
+
+    for (unsigned i = 0; i < parameters.Size(); i++)
+    {
+        JSBFunctionType* ptype = parameters[i];
+
+        if (ptype->type_->asVectorType())
+        {
+            if (!ptype->isConst_ || ptype->type_->asVectorType()->isPODVector_)
+            {
+                function->SetSkipLanguage(BINDINGLANGUAGE_JAVASCRIPT);
+                return true;
+            }
+        }
+    }
+
+    return false;
+
+}
 
 
 }
 }

+ 4 - 0
Source/ToolCore/JSBind/JavaScript/JSClassWriter.h

@@ -33,6 +33,7 @@ namespace ToolCore
 
 
 class JSBPackage;
 class JSBPackage;
 class JSBClass;
 class JSBClass;
+class JSBFunction;
 
 
 class JSClassWriter : public JSBClassWriter
 class JSClassWriter : public JSBClassWriter
 {
 {
@@ -45,7 +46,10 @@ public:
 
 
 private:
 private:
 
 
+    bool OmitFunction(JSBFunction* function);
+
     void WriteFunctions(String& source);
     void WriteFunctions(String& source);
+
     void GenerateStaticFunctionsSource(String& source, String& packageName);
     void GenerateStaticFunctionsSource(String& source, String& packageName);
     void GenerateNonStaticFunctionsSource(String& source, String& packageName);
     void GenerateNonStaticFunctionsSource(String& source, String& packageName);
 
 

+ 12 - 1
Source/ToolCore/JSBind/JavaScript/JSFunctionWriter.cpp

@@ -511,9 +511,20 @@ void JSFunctionWriter::WriteFunction(String& source)
         }
         }
         else if (returnType->type_->asVectorType())
         else if (returnType->type_->asVectorType())
         {
         {
+            JSBType* vectorType = returnType->type_->asVectorType()->vectorType_;
+
             source.Append("duk_push_array(ctx);\n");
             source.Append("duk_push_array(ctx);\n");
             source.Append("for (unsigned i = 0; i < retValue.Size(); i++)\n{\n");
             source.Append("for (unsigned i = 0; i < retValue.Size(); i++)\n{\n");
-            source.Append("duk_push_string(ctx, retValue[i].CString());\n");
+
+            if (vectorType->asClassType())
+            {
+                source.AppendWithFormat("js_push_class_object_instance(ctx, retValue[i], \"%s\");\n", vectorType->asClassType()->class_->GetName().CString());
+            }
+            else
+            {
+                source.Append("duk_push_string(ctx, retValue[i].CString());\n");
+            }
+
             source.Append("duk_put_prop_index(ctx, -2, i);\n}\n");
             source.Append("duk_put_prop_index(ctx, -2, i);\n}\n");
         }
         }
 
 

+ 2 - 2
Source/ToolCore/JSBind/JavaScript/JSModuleWriter.cpp

@@ -91,13 +91,13 @@ void JSModuleWriter::WriteClassDeclaration(String& source)
 
 
                 source.Append("duk_push_object(ctx);\n");
                 source.Append("duk_push_object(ctx);\n");
 
 
-                if (prop->getter_ && !prop->getter_->Skip())
+                if (prop->getter_ && !prop->getter_->Skip(BINDINGLANGUAGE_JAVASCRIPT))
                 {
                 {
                     source.AppendWithFormat("duk_push_c_function(ctx, jsb_class_%s_%s, 0);\n",
                     source.AppendWithFormat("duk_push_c_function(ctx, jsb_class_%s_%s, 0);\n",
                                             klass->GetName().CString(), prop->getter_->GetName().CString());
                                             klass->GetName().CString(), prop->getter_->GetName().CString());
                     source.Append("duk_put_prop_string(ctx, -2, \"get\");\n");
                     source.Append("duk_put_prop_string(ctx, -2, \"get\");\n");
                 }
                 }
-                if (prop->setter_ && !prop->setter_->Skip())
+                if (prop->setter_ && !prop->setter_->Skip(BINDINGLANGUAGE_JAVASCRIPT))
                 {
                 {
                     source.AppendWithFormat("duk_push_c_function(ctx, jsb_class_%s_%s, 1);\n",
                     source.AppendWithFormat("duk_push_c_function(ctx, jsb_class_%s_%s, 1);\n",
                                             klass->GetName().CString(), prop->setter_->GetName().CString());
                                             klass->GetName().CString(), prop->setter_->GetName().CString());