Josh Engebretson 10 rokov pred
rodič
commit
23eea41118

+ 58 - 4
Source/ToolCore/JSBind/CSharp/CSClassWriter.cpp

@@ -25,7 +25,7 @@ CSClassWriter::CSClassWriter(JSBClass *klass) : JSBClassWriter(klass)
 
 }
 
-void CSClassWriter::WriteFunctions(String& source)
+void CSClassWriter::WriteNativeFunctions(String& source)
 {
     for (unsigned i = 0; i < klass_->functions_.Size(); i++)
     {
@@ -38,12 +38,12 @@ void CSClassWriter::WriteFunctions(String& source)
             continue;
 
         CSFunctionWriter writer(function);
-        writer.GenerateSource(source);
+        writer.GenerateNativeSource(source);
     }
 
 }
 
-void CSClassWriter::GenerateSource(String& sourceOut)
+void CSClassWriter::GenerateNativeSource(String& sourceOut)
 {
     String source = "";
 
@@ -53,9 +53,63 @@ void CSClassWriter::GenerateSource(String& sourceOut)
     source.AppendWithFormat("ClassID csb_%s_GetClassID()\n{\n", klass_->GetNativeName().CString());
     source.AppendWithFormat("return %s::GetClassIDStatic();\n}\n", klass_->GetNativeName().CString());
 
-    WriteFunctions(source);
+    WriteNativeFunctions(source);
+
+    sourceOut += source;
+}
+
+void CSClassWriter::GenerateManagedSource(String& sourceOut)
+{
+    String source = "";
+
+    if (klass_->IsNumberArray())
+        return;
+
+    Indent();
+
+    source += "\n";
+    String line;
+
+    if (klass_->GetBaseClass())
+        line = "public partial class " + klass_->GetName() + " : " + klass_->GetBaseClass()->GetName() + "\n";
+    else
+        line = "public partial class " + klass_->GetName() + "\n";
+
+
+    source += IndentLine(line);
+    source += IndentLine("{\n");
+
+    Indent();
+
+    // managed functions
+    for (unsigned i = 0; i < klass_->functions_.Size(); i++)
+    {
+        JSBFunction* function = klass_->functions_.At(i);
+
+        if (function->Skip())
+            continue;
+
+        if (function->IsDestructor())
+            continue;
+
+        CSFunctionWriter fwriter(function);
+        fwriter.GenerateManagedSource(source);
+
+    }
+
+
+    Dedent();
+
+    source += IndentLine("}\n");
+
+    Dedent();
 
     sourceOut += source;
+}
+
+
+void CSClassWriter::GenerateSource(String& sourceOut)
+{
 
 }
 

+ 4 - 4
Source/ToolCore/JSBind/CSharp/CSClassWriter.h

@@ -28,13 +28,13 @@ public:
 
     void GenerateSource(String& sourceOut);
 
-    void GenerateNativeSource();
-    void GenerateManagedSource();
+    void GenerateNativeSource(String& sourceOut);
+    void GenerateManagedSource(String& sourceOut);
 
 private:
 
-    void WriteFunctions(String& source);
-
+    void WriteNativeFunctions(String& source);
+    void WriteManagedFunctions(String& source);
 };
 
 }

+ 285 - 6
Source/ToolCore/JSBind/CSharp/CSFunctionWriter.cpp

@@ -14,6 +14,7 @@
 #include "../JSBClass.h"
 #include "../JSBFunction.h"
 
+#include "CSTypeHelper.h"
 #include "CSFunctionWriter.h"
 
 /*
@@ -102,12 +103,12 @@ CSFunctionWriter::CSFunctionWriter(JSBFunction *function) : JSBFunctionWriter(fu
 
 }
 
-void CSFunctionWriter::WriteParameterMarshal(String& source)
+void CSFunctionWriter::WriteNativeParameterMarshal(String& source)
 {
 
 }
 
-void CSFunctionWriter::WriteConstructor(String& source)
+void CSFunctionWriter::WriteNativeConstructor(String& source)
 {
     JSBClass* klass = function_->class_;
 
@@ -216,7 +217,7 @@ void CSFunctionWriter::GenNativeFunctionSignature(String& sig)
 
 }
 
-void CSFunctionWriter::WriteFunction(String& source)
+void CSFunctionWriter::WriteNativeFunction(String& source)
 {
     JSBClass* klass = function_->class_;
 
@@ -322,21 +323,299 @@ void CSFunctionWriter::WriteFunction(String& source)
 
 }
 
-void CSFunctionWriter::GenerateSource(String& sourceOut)
+void CSFunctionWriter::GenerateNativeSource(String& sourceOut)
 {
     String source = "";
 
     if (function_->IsConstructor())
     {
-        WriteConstructor(source);
+        WriteNativeConstructor(source);
     }
     else
     {
-        WriteFunction(source);
+        WriteNativeFunction(source);
     }
 
     sourceOut += source;
 
 }
 
+// MANAGED----------------------------------------------------------------------------------------
+
+void CSFunctionWriter::WriteManagedPInvokeFunctionSignature(String& source)
+{
+    source += "\n";
+
+    String line = "[DllImport (LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]\n";
+    source += IndentLine(line);
+    JSBClass* klass = function_->GetClass();
+    JSBPackage* package = klass->GetPackage();
+
+    line = ToString("private static extern IntPtr csb_%s_%s_%s(IntPtr self);\n",
+                    package->GetName().CString(), klass->GetName().CString(), function_->GetName().CString());
+
+    source += IndentLine(line);
+
+    source += "\n";
+
+}
+
+void CSFunctionWriter::WriteManagedPInvokeConstructorSignature(String& source)
+{
+    source += "\n";
+
+    String line = "[DllImport (LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]\n";
+    source += IndentLine(line);
+    JSBClass* klass = function_->GetClass();
+    JSBPackage* package = klass->GetPackage();
+
+    line = ToString("private static extern IntPtr csb_%s_%s_Constructor(IntPtr self);\n",
+                    package->GetName().CString(), klass->GetName().CString());
+
+    source += IndentLine(line);
+
+    source += "\n";
+
+}
+
+
+void CSFunctionWriter::GenManagedFunctionParameters(String& sig)
+{
+    // generate args
+    Vector<JSBFunctionType*>& parameters = function_->GetParameters();
+
+    if (parameters.Size())
+    {
+        for (unsigned int i = 0; i < parameters.Size(); i++)
+        {
+            JSBFunctionType* ptype = parameters.At(i);
+
+            // ignore "Context" parameters
+            if (ptype->type_->asClassType())
+            {
+                JSBClassType* classType = ptype->type_->asClassType();
+                JSBClass* klass = classType->class_;
+                if (klass->GetName() == "Context")
+                {
+                    continue;
+                }
+            }
+
+            sig += CSTypeHelper::GetManagedTypeString(ptype);
+
+            if (i + 1 != parameters.Size())
+                sig += ", ";
+        }
+    }
+}
+
+void CSFunctionWriter::WriteManagedConstructor(String& source)
+{
+    JSBClass* klass = function_->GetClass();
+
+    String sig;
+    GenManagedFunctionParameters(sig);
+
+    String line = ToString("public %s (%s)\n", klass->GetName().CString(), sig.CString());
+
+    source += IndentLine(line);
+
+    source += IndentLine("{");
+
+
+    source+= "\n";
+
+    source += IndentLine("}\n");
+}
+
+void CSFunctionWriter::GenPInvokeCallParameters(String& sig)
+{
+    // generate args
+    Vector<JSBFunctionType*>& parameters = function_->GetParameters();
+
+    if (parameters.Size())
+    {
+        for (unsigned int i = 0; i < parameters.Size(); i++)
+        {
+            JSBFunctionType* ptype = parameters.At(i);
+
+            // ignore "Context" parameters
+            if (ptype->type_->asClassType())
+            {
+                JSBClassType* classType = ptype->type_->asClassType();
+                JSBClass* klass = classType->class_;
+                if (klass->GetName() == "Context")
+                {
+                    continue;
+                }
+            }
+
+            if (ptype->type_->asClassType())
+            {
+                JSBClass* pclass = ptype->type_->asClassType()->class_;
+                if (pclass->IsNumberArray())
+                {
+                    sig += "ref " + ptype->name_;
+                }
+                else
+                {
+                    sig += ptype->name_ + " == null ? IntPtr.Zero : " + ptype->name_+ ".nativeInstance";
+                }
+
+            }
+            else
+            {
+                sig += ptype->name_;
+            }
+
+            if (i + 1 != parameters.Size())
+                sig += ", ";
+        }
+    }
+
+    // data marshaller
+    if (function_->GetReturnType() && !CSTypeHelper::IsSimpleReturn(function_->GetReturnType()))
+    {
+        if (function_->GetReturnType()->type_->asClassType()->class_->IsNumberArray())
+        {
+            if (sig.Length())
+                sig += ", ";
+
+            JSBClass* klass = function_->GetClass();
+            sig += ToString("ref %s%sReturnValue", klass->GetName().CString(), function_->GetName().CString());
+        }
+    }
+
+
+}
+
+void CSFunctionWriter::WriteManagedFunction(String& source)
+{
+    JSBClass* klass = function_->GetClass();
+    JSBPackage* package = klass->GetPackage();
+
+    String sig;
+    String returnType = CSTypeHelper::GetManagedTypeString(function_->GetReturnType());
+
+    GenManagedFunctionParameters(sig);
+
+    String line = ToString("public %s %s (%s)\n", returnType.CString(), function_->GetName().CString(), sig.CString());
+
+    source += IndentLine(line);
+
+    source += IndentLine("{\n");
+
+    Indent();
+
+    line.Clear();
+
+    if (function_->GetReturnType())
+    {
+        if (CSTypeHelper::IsSimpleReturn(function_->GetReturnType()))
+            line += "return ";
+        else
+        {
+            if (function_->GetReturnType()->type_->asClassType())
+            {
+                if (!function_->GetReturnType()->type_->asClassType()->class_->IsNumberArray())
+                    line += "IntPtr retNativeInstance = ";
+            }
+        }
+    }
+
+    String callSig;
+    GenPInvokeCallParameters(callSig);
+
+    line += ToString("csb_%s_%s_%s(nativeInstance",
+                     package->GetName().CString(), klass->GetName().CString(), function_->GetName().CString());
+
+    if (callSig.Length())
+    {
+        line += ", " + callSig;
+    }
+
+    line += ");\n";
+
+    source += IndentLine(line);
+
+    if (function_->GetReturnType() && !CSTypeHelper::IsSimpleReturn(function_->GetReturnType()))
+    {
+        if (function_->GetReturnType()->type_->asClassType())
+        {
+            JSBClass* retClass = function_->GetReturnType()->type_->asClassType()->class_;
+            JSBClass* klass = function_->GetClass();
+
+            if (retClass->IsNumberArray())
+            {
+                line = ToString("return %s%sReturnValue;", klass->GetName().CString(), function_->GetName().CString());
+            }
+            else
+            {
+                line = ToString("return retNativeInstance == IntPtr.Zero ? null :  NativeCore.WrapNative<%s> (retNativeInstance);", retClass->GetName().CString());
+            }
+
+            source += IndentLine(line);
+        }
+    }
+
+    source+= "\n";
+
+    Dedent();
+
+    source += IndentLine("}\n");
+
+}
+
+void CSFunctionWriter::GenerateManagedSource(String& sourceOut)
+{
+
+    String source = "";
+
+    Indent();
+    Indent();
+    Indent();
+
+    if (function_->IsConstructor())
+        WriteManagedConstructor(source);
+    else
+        WriteManagedFunction(source);
+
+    if (function_->IsConstructor())
+        WriteManagedPInvokeConstructorSignature(source);
+    else
+        WriteManagedPInvokeFunctionSignature(source);
+
+    // data marshaller
+    if (function_->GetReturnType() && !CSTypeHelper::IsSimpleReturn(function_->GetReturnType()))
+    {
+        if (function_->GetReturnType()->type_->asClassType())
+        {
+            JSBClass* retClass = function_->GetReturnType()->type_->asClassType()->class_;
+            if (retClass->IsNumberArray())
+            {
+                JSBClass* klass = function_->GetClass();
+                String managedType = CSTypeHelper::GetManagedTypeString(function_->GetReturnType());
+                String marshal = "private " + managedType + " ";
+
+                marshal += ToString("%s%sReturnValue = new %s();\n", klass->GetName().CString(), function_->GetName().CString(), managedType.CString());
+
+                sourceOut += IndentLine(marshal);
+            }
+        }
+
+    }
+
+    Dedent();
+    Dedent();
+    Dedent();
+
+    sourceOut += source;
+}
+
+
+void CSFunctionWriter::GenerateSource(String& sourceOut)
+{
+
+}
+
 }

+ 16 - 5
Source/ToolCore/JSBind/CSharp/CSFunctionWriter.h

@@ -28,17 +28,28 @@ public:
 
     void GenerateSource(String& sourceOut);
 
-    void GenerateNativeSource();
-    void GenerateManagedSource();
+    void GenerateNativeSource(String& sourceOut);
+    void GenerateManagedSource(String& sourceOut);
 
 
 private:
 
     void GenNativeFunctionSignature(String& sig);
 
-    void WriteFunction(String& source);
-    void WriteConstructor(String& source);
-    void WriteParameterMarshal(String& source);
+    void WriteNativeFunction(String& source);
+    void WriteNativeConstructor(String& source);
+    void WriteNativeParameterMarshal(String& source);
+
+
+    void GenManagedFunctionParameters(String& sig);
+
+    void GenPInvokeCallParameters(String& sig);
+
+    void WriteManagedConstructor(String& source);
+    void WriteManagedFunction(String& source);
+
+    void WriteManagedPInvokeConstructorSignature(String& source);
+    void WriteManagedPInvokeFunctionSignature(String& source);
 
 };
 

+ 21 - 4
Source/ToolCore/JSBind/CSharp/CSModuleWriter.cpp

@@ -115,7 +115,7 @@ void CSModuleWriter::GenerateNativeSource()
     for (unsigned i = 0; i < classes.Size(); i++)
     {
         CSClassWriter clsWriter(classes[i]);
-        clsWriter.GenerateSource(source);
+        clsWriter.GenerateNativeSource(source);
     }
 
     source += "// End Classes\n\n";
@@ -153,6 +153,24 @@ String CSModuleWriter::GetManagedPrimitiveType(JSBPrimitiveType* ptype)
     return "int";
 }
 
+void CSModuleWriter::GenerateManagedClasses(String& source)
+{
+
+    Vector<SharedPtr<JSBClass>> classes = module_->classes_.Values();
+
+    for (unsigned i = 0; i < classes.Size(); i++)
+    {
+        JSBClass* klass = classes.At(i);
+
+        if (klass->IsNumberArray())
+            continue;
+
+        CSClassWriter clsWriter(klass);
+        clsWriter.GenerateManagedSource(source);
+
+    }
+
+}
 
 void CSModuleWriter::GenerateManagedEnumsAndConstants(String& source)
 {
@@ -200,8 +218,6 @@ void CSModuleWriter::GenerateManagedEnumsAndConstants(String& source)
 
         }
 
-        source += "\n";
-
         Dedent();
 
         source += IndentLine("}\n");
@@ -240,7 +256,7 @@ void CSModuleWriter::GenerateManagedEnumsAndConstants(String& source)
             if (value == "M_MAX_UNSIGNED")
                 value = "0xffffffff";
 
-            String line = "public static " + managedType + " " + cname + " = " + value;
+            String line = "public static const " + managedType + " " + cname + " = " + value;
 
             if (managedType == "float" && !line.EndsWith("f"))
                 line += "f";
@@ -272,6 +288,7 @@ void CSModuleWriter::GenerateManagedSource()
     source += "{\n";
 
     GenerateManagedEnumsAndConstants(source);
+    GenerateManagedClasses(source);
 
     source += "}\n";
 

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

@@ -34,6 +34,8 @@ public:
 private:
 
     String GetManagedPrimitiveType(JSBPrimitiveType* ptype);
+
+    void GenerateManagedClasses(String& source);
     void GenerateManagedEnumsAndConstants(String& source);
 
 

+ 112 - 0
Source/ToolCore/JSBind/CSharp/CSTypeHelper.cpp

@@ -0,0 +1,112 @@
+
+
+#include "CSTypeHelper.h"
+
+namespace ToolCore
+{
+
+String CSTypeHelper::GetManagedPrimitiveType(JSBPrimitiveType* ptype)
+{
+    if (ptype->kind_ == JSBPrimitiveType::Bool)
+        return "bool";
+    if (ptype->kind_ == JSBPrimitiveType::Int && ptype->isUnsigned_)
+        return "uint";
+    else if (ptype->kind_ == JSBPrimitiveType::Int)
+        return "int";
+    if (ptype->kind_ == JSBPrimitiveType::Float)
+        return "float";
+    if (ptype->kind_ == JSBPrimitiveType::Char)
+        return "char";
+    if (ptype->kind_ == JSBPrimitiveType::Short)
+        return "short";
+
+    assert(0);
+    return "";
+}
+
+
+String CSTypeHelper::GetManagedTypeString(JSBType* type)
+{
+    String value;
+
+    if (type->asClassType())
+    {
+        JSBClassType* classType = type->asClassType();
+        value = classType->class_->GetName();
+    }
+    else if (type->asStringType() || type->asStringHashType())
+    {
+        value = "String";
+    }
+    else if (type->asEnumType())
+    {
+        value = type->asEnumType()->enum_->GetName();
+    }
+    else if (type->asPrimitiveType())
+    {
+        value = GetManagedPrimitiveType(type->asPrimitiveType());
+    }
+    else if (type->asVectorType())
+    {
+        JSBVectorType* vectorType = type->asVectorType();
+
+        value = GetManagedTypeString(vectorType->vectorType_) + "[]";
+    }
+
+    return value;
+}
+
+String CSTypeHelper::GetManagedTypeString(JSBFunctionType* ftype)
+{
+    if (!ftype)
+        return "void";
+
+    String parameter = GetManagedTypeString(ftype->type_);
+
+    if (ftype->name_.Length())
+    {
+        parameter += " " + ftype->name_;
+        if (ftype->initializer_.Length())
+            parameter += " = " + ftype->initializer_;
+    }
+
+    return parameter;
+
+}
+
+bool CSTypeHelper::IsSimpleReturn(JSBType* type)
+{
+    if (type->asClassType())
+    {
+        return false;
+    }
+    else if (type->asStringType() || type->asStringHashType())
+    {
+        return true;
+    }
+    else if (type->asEnumType())
+    {
+        return true;
+    }
+    else if (type->asPrimitiveType())
+    {
+        return true;
+    }
+    else if (type->asVectorType())
+    {
+        return true;
+    }
+
+    return true;
+}
+
+bool CSTypeHelper::IsSimpleReturn(JSBFunctionType* ftype)
+{
+    if (!ftype)
+        return true;
+
+    return IsSimpleReturn(ftype->type_);
+
+}
+
+}

+ 74 - 0
Source/ToolCore/JSBind/CSharp/CSTypeHelper.h

@@ -0,0 +1,74 @@
+
+#pragma once
+
+#include "../JSBFunction.h"
+
+namespace ToolCore
+{
+
+
+class CSTypeHelper
+{
+
+public:
+
+    // simple float, bool, int, uint
+    // string
+
+    // return value is out Parameter
+    // "ArrayTypes" Vector, BoundingBox, etc
+
+    // RefCounted*
+
+    //JSBFunctionType*
+
+    static bool IsSimpleReturn(JSBType* type);
+    static bool IsSimpleReturn(JSBFunctionType* ftype);
+
+    static String GetManagedPrimitiveType(JSBPrimitiveType* ptype);
+
+    static String GetManagedTypeString(JSBType* type);
+    static String GetManagedTypeString(JSBFunctionType* ftype);
+
+};
+
+/*
+class JSBType
+{
+
+public:
+
+    virtual JSBPrimitiveType* asPrimitiveType() { return 0; }
+    virtual JSBClassType* asClassType() { return 0; }
+    virtual JSBStringType* asStringType() { return 0; }
+    virtual JSBStringHashType* asStringHashType() { return 0; }
+    virtual JSBEnumType* asEnumType() { return 0; }
+    virtual JSBHeapPtrType* asHeapPtrType() { return 0; }
+    virtual JSBVectorType* asVectorType() { return 0; }
+
+    static JSBType* Parse(const String& value);
+
+    virtual String ToString() = 0;
+
+};
+
+class JSBPrimitiveType : public JSBType
+{
+public:
+    // needs to match IntegerType::Kind
+    enum Kind {
+        Char,
+        Char16,
+        Char32,
+        WideChar,
+        Bool,
+        Short,
+        Int,
+        Long,
+        LongLong,
+        Float // this doesn't exist in IntegerType::Kind
+    };
+*/
+
+
+}

+ 2 - 4
Source/ToolCore/JSBind/JSBClassWriter.h

@@ -7,9 +7,7 @@
 
 #pragma once
 
-#include <Atomic/Container/Str.h>
-
-using namespace Atomic;
+#include "JSBSourceWriter.h"
 
 namespace ToolCore
 {
@@ -17,7 +15,7 @@ namespace ToolCore
 class JSBPackage;
 class JSBClass;
 
-class JSBClassWriter
+class JSBClassWriter : public JSBSourceWriter
 {
 
 public:

+ 2 - 4
Source/ToolCore/JSBind/JSBFunctionWriter.h

@@ -7,9 +7,7 @@
 
 #pragma once
 
-#include <Atomic/Container/Str.h>
-
-using namespace Atomic;
+#include "JSBSourceWriter.h"
 
 namespace ToolCore
 {
@@ -17,7 +15,7 @@ namespace ToolCore
 class JSBPackage;
 class JSBFunction;
 
-class JSBFunctionWriter
+class JSBFunctionWriter : public JSBSourceWriter
 {
 
 public: