소스 검색

Working on C#

Josh Engebretson 10 년 전
부모
커밋
b028751f7e

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

@@ -88,6 +88,7 @@ public:
     virtual ClassID GetClassID() const  = 0;
     static ClassID GetClassIDStatic() { static const int typeID = 0; return (ClassID) &typeID; }
 
+    /// JavaScript VM, heap object which can be pushed directly on stack without any lookups
     inline void* JSGetHeapPtr() const { return jsHeapPtr_; }
     inline void  JSSetHeapPtr(void* heapptr) { jsHeapPtr_ = heapptr; }
     // ATOMIC END

+ 26 - 0
Source/AtomicSharp/AtomicSharp.cpp

@@ -0,0 +1,26 @@
+
+#include "AtomicSharp.h"
+
+
+namespace Atomic
+{
+
+WeakPtr<Context> AtomicSharp::csContext_;
+WeakPtr<AtomicSharp> AtomicSharp::instance_;
+
+AtomicSharp::AtomicSharp(Context* context) :
+    Object(context)
+{
+    assert(!instance_);
+    instance_ = this;
+    csContext_ = context;
+}
+
+AtomicSharp::~AtomicSharp()
+{
+    instance_ = NULL;
+}
+
+
+}
+

+ 55 - 0
Source/AtomicSharp/AtomicSharp.h

@@ -0,0 +1,55 @@
+//
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+#include <Atomic/Core/Context.h>
+#include <Atomic/Core/Object.h>
+
+namespace Atomic
+{
+
+class ATOMIC_API AtomicSharp : public Object
+{
+
+    OBJECT(AtomicSharp);
+
+public:
+    /// Construct.
+    AtomicSharp(Context* context);
+    /// Destruct.
+    virtual ~AtomicSharp();
+
+    /// We access this directly in binding code, where there isn't a context
+    /// to get a reference from
+    static inline Context* GetContext() { return instance_->csContext_; }
+
+private:
+
+    /// weak local context ref, so avoid recursion in static GetContext call
+    static WeakPtr<Context> csContext_;
+
+    static WeakPtr<AtomicSharp> instance_;
+
+};
+
+}

+ 21 - 0
Source/AtomicSharp/AtomicSharpAPI.cpp

@@ -0,0 +1,21 @@
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "AtomicSharp.h"
+
+using namespace Atomic;
+
+extern "C"
+{
+
+}

+ 12 - 0
Source/AtomicSharp/AtomicSharpAPI.h

@@ -0,0 +1,12 @@
+//
+// 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.
+//

+ 32 - 3
Source/AtomicSharp/AtomicSharpApp.cpp

@@ -41,6 +41,7 @@
 
 #include <AtomicPlayer/Player.h>
 
+#include "AtomicSharp.h"
 #include "AtomicSharpApp.h"
 
 #include <Atomic/DebugNew.h>
@@ -85,9 +86,9 @@ namespace AtomicPlayer
         engineParameters_["ResourcePaths"] = "AtomicResources";
 #else
         engineParameters_["FullScreen"] = false;
-        engineParameters_["WindowWidth"] = 1280;
-        engineParameters_["WindowHeight"] = 720;
-        engineParameters_["ResourcePaths"] = "/Users/josh/Dev/atomic/AtomicGameEngineSharp/Resources/CoreData;/Users/josh/Dev/atomic/AtomicGameEngineSharp/Resources/PlayerData";
+        engineParameters_["WindowWidth"] = 1280 * .55f;
+        engineParameters_["WindowHeight"] = 720 * .55f;
+        engineParameters_["ResourcePaths"] = "/Users/josh/Dev/atomic/AtomicGameEngineSharp/Resources/CoreData;/Users/josh/Dev/atomic/AtomicGameEngineSharp/Resources/PlayerData;/Users/josh/Dev/atomic/AtomicExamples/Basic3D/Resources;/Users/josh/Dev/atomic/AtomicExamples/Basic3D/";
 #endif
 
 #if ATOMIC_PLATFORM_WINDOWS
@@ -123,12 +124,32 @@ namespace AtomicPlayer
     {
         Application::Start();
 
+        // Instantiate and register AtomicSharp subsystem
+        context_->RegisterSubsystem(new AtomicSharp(context_));
+
+        // Instantiate and register the Javascript subsystem
+        Javascript* javascript = new Javascript(context_);
+        context_->RegisterSubsystem(javascript);
+
+        vm_ = javascript->InstantiateVM("MainVM");
+        vm_->InitJSContext();
+
         UI* ui = GetSubsystem<UI>();
         ui->Initialize("DefaultUI/language/lng_en.tb.txt");
         ui->LoadDefaultPlayerSkin();
 
+        vm_->SetModuleSearchPaths("Modules");
+
         // Instantiate and register the Player subsystem
         context_->RegisterSubsystem(new AtomicPlayer::Player(context_));
+        AtomicPlayer::jsapi_init_atomicplayer(vm_);
+
+        JSVM* vm = JSVM::GetJSVM(0);
+
+        if (!vm->ExecuteMain())
+        {
+            SendEvent(E_EXITREQUESTED);
+        }
 
 
         return;
@@ -236,6 +257,14 @@ static SharedPtr<AtomicPlayer::AtomicPlayerApp> sApplication;
 
 extern "C" {
 
+void atomicsharp_hrmph(Vector3* in, Vector3* out)
+{
+    out->x_ = in->x_ + 1;
+    out->y_ = in->y_ + 2;
+    out->z_ = in->z_ + 3;
+
+}
+
 int atomicsharp_initialize()
 {
     sContext = new Atomic::Context();

+ 1 - 0
Source/AtomicSharp/AtomicSharpApp.h

@@ -56,6 +56,7 @@ public:
 
 private:
 
+    SharedPtr<JSVM> vm_;
 
     /// Handle reload start of the script file.
     void HandleScriptReloadStarted(StringHash eventType, VariantMap& eventData);

+ 3 - 0
Source/ToolCore/JSBind/CSharp/CSClassWriter.cpp

@@ -50,6 +50,9 @@ void CSClassWriter::GenerateSource(String& sourceOut)
     if (klass_->IsNumberArray())
         return;
 
+    source.AppendWithFormat("ClassID csb_%s_GetClassID()\n{\n", klass_->GetNativeName().CString());
+    source.AppendWithFormat("return %s::GetClassIDStatic();\n}\n", klass_->GetNativeName().CString());
+
     WriteFunctions(source);
 
     sourceOut += source;

+ 100 - 3
Source/ToolCore/JSBind/CSharp/CSFunctionWriter.cpp

@@ -16,6 +16,84 @@
 
 #include "CSFunctionWriter.h"
 
+/*
+ *
+ C# getters/setters
+ local instance storage so we're not constantly creating managed Vector3, etc
+ Vector2/Vector3/BoundingBox, etc C# structs so assign by value
+ Object lifetime
+
+ C# enum of module types for type info?
+ C# version of push class instance?
+
+ new instance from C# needs constructor
+ wrapping does not, wrapping doesn't use constructors at all (JS needs this for prototype)
+
+ Store GCHandle to keep an object alive (Component, UI) C# side?
+
+ typedef const void* ClassID;
+ which changed based on address, so need register at startup
+ so at package startup time, need to setup mapping between
+ IntPtr and C# class, we also need to be able to new a class
+ instance with existing native or create a native when new'ing from C#
+
+ IntPtr to RefCounted native side is the "ID", like JSHeapPtr
+
+ Lifetime:
+
+ // you cannot derive from native engine classes, other than script components
+
+ a C# instance can be new'd, handed to native, stored in native, the C# side could be GC'd
+ future access to this instance would be a new instance
+
+*/
+
+
+/*
+
+// struct marshal Vector2, Vector3, BoundingBox, etc
+// RefCounted*
+// primitive bool, int, uint, float, double
+// String
+
+RefCounted* csb_Node_Constructor()
+{
+    return new Node(AtomicSharp::GetContext());
+}
+
+void csb_Node_GetPosition(Node* self, Vector3* out)
+{
+    *out = self->GetPosition();
+}
+
+void csb_Node_SetPosition(Node* self, Vector3*__arg0)
+{
+    self->SetPosition(*__arg0);
+}
+
+void csb_Node_SetPosition(Node* self, Vector3*__arg0)
+{
+    self->SetPosition(*__arg0);
+}
+
+bool csb_Audio_Play(Audio* self)
+{
+    bool retValue = self->Play();
+    return retValue;
+}
+
+const RefCounted* csb_Node_GetParent(Node* self)
+{
+    const RefCounted* retValue = self->GetParent();
+    return RefCounted;
+}
+
+RefCounted* csb_ObjectAnimation_Constructor()
+{
+    return new ObjectAnimation(AtomicSharp::GetContext());
+}
+
+*/
 namespace ToolCore
 {
 
@@ -31,6 +109,25 @@ void CSFunctionWriter::WriteParameterMarshal(String& source)
 
 void CSFunctionWriter::WriteConstructor(String& source)
 {
+    JSBClass* klass = function_->class_;
+
+    if (klass->IsAbstract())
+        return;
+
+    // just object for now, as constructor takes a context
+    if (!klass->IsObject())
+        return;
+
+    // more than context arg, don't marshal yet
+    if (function_->GetParameters().Size() > 1)
+    {
+        return;
+    }
+
+
+    source.AppendWithFormat("RefCounted* csb_%s_Constructor()\n{\nreturn new %s(AtomicSharp::GetContext());\n}\n",
+                            klass->GetName().CString(), klass->GetNativeName().CString());
+
 
 }
 
@@ -137,7 +234,7 @@ void CSFunctionWriter::WriteFunction(String& source)
     {
         if (returnType->type_->asStringType())
         {
-            rTypeString = "String";
+            rTypeString = "const String&";
         }
         else if (returnType->type_->asPrimitiveType())
         {
@@ -186,7 +283,7 @@ void CSFunctionWriter::WriteFunction(String& source)
 
 
 
-    source.AppendWithFormat("%s csb_%s_%s(%s* self%s)\n{\n", rTypeString == "String" ? "const char*" : rTypeString.CString(), klass->GetName().CString(),
+    source.AppendWithFormat("%s csb_%s_%s(%s* self%s)\n{\n", rTypeString == "const String&" ? "const char*" : rTypeString.CString(), klass->GetName().CString(),
                             function_->name_.CString(), klass->GetNativeName().CString(), sig.Length() ? (", " + sig).CString() : "");
 
     if (rTypeString != "void")
@@ -215,7 +312,7 @@ void CSFunctionWriter::WriteFunction(String& source)
 
     if (rTypeString != "void")
     {
-        if (rTypeString == "String")
+        if (rTypeString == "const String&")
             source.AppendWithFormat("\nreturn retValue.CString();\n");
         else
             source.AppendWithFormat("\nreturn retValue;\n");

+ 138 - 11
Source/ToolCore/JSBind/CSharp/CSModuleWriter.cpp

@@ -94,20 +94,15 @@ void CSModuleWriter::GenerateNativeSource()
         source += "#ifdef ATOMIC_3D\n";
     }
 
-    source += "#include <Duktape/duktape.h>\n";
-    source += "#include <AtomicJS/Javascript/JSVM.h>\n";
-    source += "#include <AtomicJS/Javascript/JSAPI.h>\n";
-
     WriteIncludes(source);
 
+    source += "\n#include <AtomicSharp/AtomicSharp.h>\n";
+
     String ns = module_->GetPackage()->GetNamespace();
 
-    if (ns != "Atomic")
-    {
-        source += "\n\nusing namespace " + ns + ";\n\n";
-    }
+    source += "\n\nusing namespace " + ns + ";\n\n";
 
-    source += "\n\nnamespace Atomic\n{\n \n";
+    source += "\n\nextern \"C\" \n{\n \n";
 
     source += "// Begin Class Declarations\n";
 
@@ -144,12 +139,144 @@ void CSModuleWriter::GenerateNativeSource()
 
 }
 
+String CSModuleWriter::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";
+
+    return "int";
+}
+
+
+void CSModuleWriter::GenerateManagedEnumsAndConstants(String& source)
+{
+    Vector<SharedPtr<JSBEnum>> enums = module_->enums_.Values();
+
+    Indent();
+
+    for (unsigned i = 0; i < enums.Size(); i++)
+    {
+        JSBEnum* jenum = enums[i];
+
+        source += "\n";
+        String line = "public enum " + jenum->GetName() + "\n";
+        source += IndentLine(line);
+        source += IndentLine("{\n");
+
+        HashMap<String, String>& values = jenum->GetValues();
+
+        HashMap<String, String>::ConstIterator itr = values.Begin();
+
+        Indent();
+
+        while (itr != values.End())
+        {
+            String name = (*itr).first_;
+            String value = (*itr).second_;
+
+            if (value.Length())
+            {
+                line = name + " = " + value;
+            }
+            else
+            {
+                line = name;
+            }
+
+            itr++;
+
+            if (itr != values.End())
+                line += ",";
+
+            line += "\n";
+
+            source += IndentLine(line);
+
+        }
+
+        source += "\n";
+
+        Dedent();
+
+        source += IndentLine("}\n");
+
+    }
+
+    // constants
+
+    HashMap<String, JSBModule::Constant>& constants = module_->GetConstants();
+
+    if (constants.Size())
+    {
+
+        source += "\n";
+
+        String line = "public static class Constants\n";
+        source += IndentLine(line);
+        source += IndentLine("{\n");
+
+        const Vector<String>& constantsName = constants.Keys();
+
+        Indent();
+
+        for (unsigned i = 0; i < constantsName.Size(); i++)
+        {
+            const String& cname = constantsName.At(i);
+
+            JSBModule::Constant& constant = constants[cname];
+
+            String managedType = GetManagedPrimitiveType(constant.type);
+
+            String value = constant.value;
+            //static const unsigned M_MIN_UNSIGNED = 0x00000000;
+//            /static const unsigned M_MAX_UNSIGNED = 0xffffffff;
+
+            if (value == "M_MAX_UNSIGNED")
+                value = "0xffffffff";
+
+            String line = "public static " + managedType + " " + cname + " = " + value;
+
+            if (managedType == "float" && !line.EndsWith("f"))
+                line += "f";
+
+            line += ";\n";
+
+            source += IndentLine(line);
+
+        }
+
+        Dedent();
+
+        source += "\n";
+        line = "}\n";
+        source += IndentLine(line);
+
+    }
+
+
+    Dedent();
+
+}
+
 void CSModuleWriter::GenerateManagedSource()
 {
-    String source = "// Hello C#!";
+    String source;
 
-    JSBind* jsbind = module_->GetSubsystem<JSBind>();
+    source += "namespace " + module_->GetPackage()->GetName() + "\n";
+    source += "{\n";
+
+    GenerateManagedEnumsAndConstants(source);
 
+    source += "}\n";
+
+
+    JSBind* jsbind = module_->GetSubsystem<JSBind>();
     String filepath = jsbind->GetDestScriptFolder() + "/CSModule" + module_->name_ + ".cs";
 
     File file(module_->GetContext());

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

@@ -33,6 +33,10 @@ public:
 
 private:
 
+    String GetManagedPrimitiveType(JSBPrimitiveType* ptype);
+    void GenerateManagedEnumsAndConstants(String& source);
+
+
     void WriteIncludes(String& source);
 
 };

+ 11 - 4
Source/ToolCore/JSBind/JSBDoc.cpp

@@ -249,14 +249,21 @@ void JSBDoc::ExportModuleEnums(JSBModule* module)
 
         source_ += " var " + _enum->GetName() + " =  {\n";
 
-        Vector<String>& values = _enum->GetValues();
+        HashMap<String, String>& values = _enum->GetValues();
 
-        for (unsigned j = 0; j < values.Size(); j++)
+        HashMap<String, String>::ConstIterator itr = values.Begin();
+
+        while (itr != values.End())
         {
-            source_ += "    " + values[j] + " : undefined";
+            String name = (*itr).first_;
+
+            source_ += "    " + name + " : undefined";
 
-            if (j !=  values.Size() - 1)
+            itr++;
+
+            if (itr !=  values.End())
                 source_ += ",\n";
+
         }
 
         source_ += "\n\n};\n\n";

+ 26 - 25
Source/ToolCore/JSBind/JSBEnum.cpp

@@ -38,13 +38,13 @@ void JSBEnum::Preprocess()
     {
         values_.Clear();
 
-        values_.Push("TU_DIFFUSE");
-        values_.Push("TU_ALBEDOBUFFER");
-        values_.Push("TU_NORMAL");
-        values_.Push("TU_NORMALBUFFER");
-        values_.Push("TU_SPECULAR");
-        values_.Push("TU_EMISSIVE");
-        values_.Push("TU_ENVIRONMENT");
+        values_["TU_DIFFUSE"] = "0";
+        values_["TU_ALBEDOBUFFER"] = "0";
+        values_["TU_NORMAL"] = "1";
+        values_["TU_NORMALBUFFER"] = "1";
+        values_["TU_SPECULAR"] = "2";
+        values_["TU_EMISSIVE"] = "3";
+        values_["TU_ENVIRONMENT"] = "4";
 
         String platform = jsbind->GetPlatform();
 
@@ -52,27 +52,28 @@ void JSBEnum::Preprocess()
 
         if (mobile)
         {
-            values_.Push("TU_LIGHTRAMP");
-            values_.Push("TU_LIGHTSHAPE");
-            values_.Push("TU_SHADOWMAP");
-            values_.Push("MAX_MATERIAL_TEXTURE_UNITS");
-            values_.Push("MAX_TEXTURE_UNITS");
+            values_["TU_LIGHTRAMP"] = "5";
+            values_["TU_LIGHTSHAPE"] = "6";
+            values_["TU_SHADOWMAP"] = "7";
+            values_["MAX_MATERIAL_TEXTURE_UNITS"] = "5";
+            values_["MAX_TEXTURE_UNITS"] = "8";
         }
         else
         {
-            values_.Push("TU_VOLUMEMAP");
-            values_.Push("TU_CUSTOM1");
-            values_.Push("TU_CUSTOM2");
-            values_.Push("TU_LIGHTRAMP");
-            values_.Push("TU_LIGHTSHAPE");
-            values_.Push("TU_SHADOWMAP");
-            values_.Push("TU_FACESELECT");
-            values_.Push("TU_INDIRECTION");
-            values_.Push("TU_DEPTHBUFFER");
-            values_.Push("TU_LIGHTBUFFER");
-            values_.Push("TU_ZONE");
-            values_.Push("MAX_MATERIAL_TEXTURE_UNITS");
-            values_.Push("MAX_TEXTURE_UNITS");
+            values_["TU_VOLUMEMAP"] = "5";
+            values_["TU_CUSTOM1"] = "6";
+            values_["TU_CUSTOM2"] = "7";
+            values_["TU_LIGHTRAMP"] = "8";
+            values_["TU_LIGHTSHAPE"] = "9";
+            values_["TU_SHADOWMAP"] = "10";
+            values_["TU_FACESELECT"] = "11";
+            values_["TU_INDIRECTION"] = "12";
+            values_["TU_DEPTHBUFFER"] = "13";
+            values_["TU_LIGHTBUFFER"] = "14";
+            values_["TU_ZONE"] = "15";
+            values_["MAX_MATERIAL_TEXTURE_UNITS"] = "8";
+            values_["MAX_TEXTURE_UNITS"] = "16";
+
         }
 
     }

+ 3 - 3
Source/ToolCore/JSBind/JSBEnum.h

@@ -30,13 +30,13 @@ public:
     const String& GetName() { return name_; }
     JSBHeader* GetHeader() { return header_; }
 
-    Vector<String>& GetValues() { return values_; }
+    HashMap<String, String>& GetValues() { return values_; }
 
     void SetHeader(JSBHeader* header) { header_ = header; }
 
     void Preprocess();
 
-    void AddValue(const String& value) { values_.Push(value); }
+    void AddValue(const String& name, const String& constantValue = String::EMPTY) { values_[name] = constantValue; }
 
 private:
 
@@ -44,7 +44,7 @@ private:
 
     SharedPtr<JSBModule> module_;
 
-    Vector<String> values_;
+    HashMap<String, String> values_;
 
     JSBHeader* header_;
 

+ 13 - 5
Source/ToolCore/JSBind/JSBHaxe.cpp

@@ -367,7 +367,7 @@ namespace ToolCore
 
     void JSBHaxe::ExportModuleConstants(JSBModule* module)
     {
-        HashMap<String, JSBPrimitiveType*>& constants = module->GetConstants();
+        HashMap<String, JSBModule::Constant>& constants = module->GetConstants();
 
         const Vector<String>& constantsName = constants.Keys();
 
@@ -380,7 +380,9 @@ namespace ToolCore
         {
             const String& cname = constantsName.At(i);
 
-            source_ += "    public static var " + cname + ": " + GetPrimitiveType(constants[cname]) + ";\n";
+            JSBModule::Constant& constant = constants[cname];
+
+            source_ += "    public static var " + cname + ": " + GetPrimitiveType(constant.type) + ";\n";
         }
 
         source_ += "\n";
@@ -398,11 +400,17 @@ namespace ToolCore
             source_ += "@:native(\"Atomic\")\n";
             source_ += "extern enum " + _enum->GetName() + " {\n";
 
-            Vector<String>& values = _enum->GetValues();
+            HashMap<String, String>& values = _enum->GetValues();
+
+            HashMap<String, String>::ConstIterator itr = values.Begin();
 
-            for (unsigned j = 0; j < values.Size(); j++)
+            while (itr != values.End())
             {
-                source_ += "    " + values[j] + ";\n";
+                String name = (*itr).first_;
+
+                source_ += "    " + name + ";\n";
+
+                itr++;
             }
 
             source_ += "}\n";

+ 12 - 3
Source/ToolCore/JSBind/JSBHeaderVisitor.h

@@ -406,13 +406,22 @@ public:
             return true;
         }
 
-        if (type->isIntegerType())
+        String value;
+
+        const StringLiteral* init = decl->getInitializer();
+        if (init)
         {
-            module_->RegisterConstant(getNameString(decl->name()).CString(), JSBPrimitiveType::Int);
+            if (init->chars())
+                value = init->chars();
+        }
+
+        if (type->isIntegerType() || _unsigned)
+        {            
+            module_->RegisterConstant(getNameString(decl->name()).CString(), value, JSBPrimitiveType::Int, _unsigned);
         }
         else
         {
-            module_->RegisterConstant(getNameString(decl->name()).CString(), JSBPrimitiveType::Float);
+            module_->RegisterConstant(getNameString(decl->name()).CString(), value, JSBPrimitiveType::Float);
         }
 
         return true;

+ 5 - 2
Source/ToolCore/JSBind/JSBModule.cpp

@@ -369,7 +369,7 @@ bool JSBModule::ContainsConstant(const String& constantName)
     return constants_.Contains(constantName);
 }
 
-void JSBModule::RegisterConstant(const String& constantName, unsigned type)
+void JSBModule::RegisterConstant(const String& constantName, const String& value, unsigned type, bool isUnsigned)
 {
     // MAX_CASCADE_SPLITS is defined differently for desktop/mobile
     if (constantName == "MAX_CASCADE_SPLITS" && JSBPackage::ContainsConstantAllPackages(constantName))
@@ -382,7 +382,10 @@ void JSBModule::RegisterConstant(const String& constantName, unsigned type)
         ErrorExit(ToString("Constant collision: %s", constantName.CString()));
     }
 
-    constants_[constantName] = new JSBPrimitiveType(type);
+    Constant c;
+    c.type = new JSBPrimitiveType(type, isUnsigned);
+    c.value = value;
+    constants_[constantName] = c;
 }
 
 bool JSBModule::Load(const String& jsonFilename)

+ 12 - 3
Source/ToolCore/JSBind/JSBModule.h

@@ -34,6 +34,13 @@ class JSBModule : public Object
 
 public:
 
+    struct Constant
+    {
+        JSBPrimitiveType* type;
+        String value;
+    };
+
+
     JSBModule(Context* context, JSBPackage* package);
     virtual ~JSBModule();
 
@@ -43,7 +50,7 @@ public:
     JSBClass* GetClass(const String& name);
     Vector<SharedPtr<JSBClass>> GetClasses();
     Vector<SharedPtr<JSBEnum>> GetEnums();
-    HashMap<String, JSBPrimitiveType*>& GetConstants() { return constants_; }
+    HashMap<String, Constant>& GetConstants() { return constants_; }
 
     void RegisterClass(String name);
 
@@ -51,7 +58,7 @@ public:
     void RegisterEnum(JSBEnum* jenum);
 
     bool ContainsConstant(const String& constantName);
-    void RegisterConstant(const String& constantName, unsigned type);
+    void RegisterConstant(const String& constantName, const String& value, unsigned type, bool isUnsigned = false);
 
     bool Requires(const String& requirement) { return requirements_.Contains(requirement); }
 
@@ -86,7 +93,9 @@ private:
     // native name -> JSBClass
     HashMap<StringHash, SharedPtr<JSBClass> > classes_;
     HashMap<StringHash, SharedPtr<JSBEnum> > enums_;
-    HashMap<String, JSBPrimitiveType*> constants_;
+
+    HashMap<String, Constant> constants_;
+
     Vector<String> requirements_;
 
     SharedPtr<JSONFile> moduleJSON_;

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

@@ -7,16 +7,14 @@
 
 #pragma once
 
-#include <Atomic/Container/Str.h>
-
-using namespace Atomic;
+#include "JSBSourceWriter.h"
 
 namespace ToolCore
 {
 
 class JSBModule;
 
-class JSBModuleWriter
+class JSBModuleWriter : public JSBSourceWriter
 {
 
 public:

+ 17 - 1
Source/ToolCore/JSBind/JSBPreprocessVisitor.h

@@ -57,7 +57,23 @@ public:
         for (unsigned i = 0; i < penum->memberCount(); i++)
         {
             Symbol* symbol = penum->memberAt(i);
-            jenum->AddValue(getNameString(symbol->name()));
+
+            String name = getNameString(symbol->name());
+            String value = "";
+
+            Declaration* decl = symbol->asDeclaration();
+            if (decl)
+            {
+                EnumeratorDeclaration* enumDecl = decl->asEnumeratorDeclarator();
+                const StringLiteral* constantValue = enumDecl->constantValue();
+                if (constantValue)
+                {
+                    value = constantValue->chars();
+                }
+            }
+
+            jenum->AddValue(name);
+
         }
 
         jenum->Preprocess();

+ 2 - 0
Source/ToolCore/JSBind/JSBSourceWriter.cpp

@@ -0,0 +1,2 @@
+
+#include "JSBSourceWriter.h"

+ 52 - 0
Source/ToolCore/JSBind/JSBSourceWriter.h

@@ -0,0 +1,52 @@
+//
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+// LICENSE: Atomic Game Engine Editor and Tools EULA
+// Please see LICENSE_ATOMIC_EDITOR_AND_TOOLS.md in repository root for
+// license information: https://github.com/AtomicGameEngine/AtomicGameEngine
+//
+
+#pragma once
+
+#include <Atomic/Container/Str.h>
+
+using namespace Atomic;
+
+namespace ToolCore
+{
+
+class JSBSourceWriter
+{
+
+public:
+
+    void SetIndentSpaces(int spaces) { indentSpaces_ = spaces; }
+
+    void Indent() { indentLevel_++; GenerateIndentSpaces(); }
+    void Dedent() { indentLevel_--; assert(indentLevel_ >= 0); GenerateIndentSpaces(); }
+
+    String IndentLine(const String& line) { return indent_ + line; }
+
+    const String& GetIndent() { return indent_; }
+
+protected:
+
+    void GenerateIndentSpaces() {
+
+        int spaces = indentSpaces_ * indentLevel_;
+        indent_.Clear();
+        while (spaces--) {
+            indent_ += " ";
+        }
+    }
+
+    String indent_;
+
+    JSBSourceWriter() : indentLevel_(0), indentSpaces_(3) {}
+    ~JSBSourceWriter() {}
+
+    int indentSpaces_;
+    int indentLevel_;
+
+};
+
+}

+ 9 - 3
Source/ToolCore/JSBind/JSBTypeScript.cpp

@@ -276,11 +276,17 @@ void JSBTypeScript::ExportModuleEnums(JSBModule* module)
         source_ += "\n   // enum " + _enum->GetName() + "\n";
         source_ += "   export type " + _enum->GetName() + " = number;\n";
 
-        Vector<String>& values = _enum->GetValues();
+        HashMap<String, String>& values = _enum->GetValues();
 
-        for (unsigned j = 0; j < values.Size(); j++)
+        HashMap<String, String>::ConstIterator itr = values.Begin();
+
+        while (itr != values.End())
         {
-            source_ += "   export var " + values[j] + ": " +  _enum->GetName() + ";\n";
+            String name = (*itr).first_;
+
+            source_ += "   export var " + name + ": " +  _enum->GetName() + ";\n";
+
+            itr++;
         }
 
         source_ += "\n";

+ 0 - 28
Source/ToolCore/JSBind/JavaScript/JSFunctionWriter.cpp

@@ -247,34 +247,6 @@ void JSFunctionWriter::WriteConstructor(String& source)
     // Constructor
     source.AppendWithFormat("duk_ret_t jsb_constructor_%s(duk_context* ctx)\n{\n", klass->GetName().CString());
 
-    /*
-
-duk_ret_t jsb_constructor_MyJSClass(duk_context* ctx)
-{
-    JSVM* vm = JSVM::GetJSVM(ctx);
-    duk_push_this(ctx);
-    void *ptr = duk_get_heapptr(ctx, -1);
-    duk_pop(ctx);
-
-    if (!vm->GetObjectPtr(ptr, true))
-    {
-        if (!duk_get_top(ctx) || !duk_is_pointer(ctx, 0))
-        {
-            MyJSClass* native = new MyJSClass(JSVM::GetJSVM(ctx)->GetContext());
-            vm->AddObject(ptr, native);
-        }
-        else if (duk_is_pointer(ctx, 0))
-        {
-            vm->AddObject(ptr, (RefCounted*) duk_get_pointer(ctx, 0));
-        }
-    }
-
-    js_constructor_basecall(ctx, "Atomic", "AObject");
-    return 0;
-}
-
-     */
-
     source.Append( "\nJSVM* vm = JSVM::GetJSVM(ctx);\n" \
                    "duk_push_this(ctx);\n" \
                    "void *ptr = duk_get_heapptr(ctx, -1);\n" \

+ 8 - 4
Source/ToolCore/JSBind/JavaScript/JSModuleWriter.cpp

@@ -193,12 +193,16 @@ void JSModuleWriter::WriteModulePreInit(String& source)
     {
         JSBEnum* jenum = enums[i];
 
-        Vector<String>& values = jenum->GetValues();
+        HashMap<String, String>& values = jenum->GetValues();
 
-        for (unsigned k = 0; k < values.Size(); k++)
+        HashMap<String, String>::ConstIterator itr = values.Begin();
+
+        while (itr != values.End())
         {
-            source.AppendWithFormat("duk_push_number(ctx, (double) %s);\n", values[k].CString());
-            source.AppendWithFormat("duk_put_prop_string(ctx, -2, \"%s\");\n",values[k].CString());
+            String name = (*itr).first_;
+            source.AppendWithFormat("duk_push_number(ctx, (double) %s);\n", name.CString());
+            source.AppendWithFormat("duk_put_prop_string(ctx, -2, \"%s\");\n",name.CString());
+            itr++;
         }
     }
     source += "// constants\n";

+ 13 - 0
Source/ToolCore/JSBind/cplusplus/Bind.cpp

@@ -1891,6 +1891,19 @@ bool Bind::visit(SimpleDeclarationAST *ast)
                 decl->setInitializer(asStringLiteral(startOfExpression, endOfExpression));
             }
         }
+        else
+        {
+            // ATOMIC BEGIN
+            // store initializer
+            const ExpressionAST *initializer = it->value->initializer;
+            if (initializer)
+            {
+                unsigned startOfExpression = initializer->firstToken();
+                unsigned endOfExpression = initializer->lastToken();
+                decl->setInitializer(asStringLiteral(startOfExpression, endOfExpression));
+            }
+            // ATOMIC END
+        }
 
         if (_scope->isClass()) {
             decl->setVisibility(_visibility);