瀏覽代碼

Merge pull request #1397 from AtomicGameEngine/JME-ATOMIC-REFLISTVECTOR

Adding support for resource arrays and fixed array sizes to vector inspector
JoshEngebretson 9 年之前
父節點
當前提交
a0e3751847

+ 0 - 5
Script/AtomicEditor/editor/EditorEvents.ts

@@ -161,11 +161,6 @@ export interface InspectorProjectReferenceEvent {
 
 }
 
-export const RemoveCurrentAssetAssigned = "RemoveCurrentAssetAssigned";
-export interface RemoveCurrentAssetAssignedEvent {
-
-}
-
 export const UserPreferencesChangedNotification  = "UserPreferencesChangedNotification";
 export interface UserPreferencesChangedEvent {
     /**

+ 11 - 7
Script/AtomicEditor/ui/frames/inspector/AttributeInfoEdit.ts

@@ -831,9 +831,9 @@ class ResourceRefAttributeEdit extends AttributeInfoEdit {
                 // for cached resources, use the asset name, otherwise use the resource path name
                 var resource: Atomic.Resource;
                 if (this.refListIndex != -1) {
-                    resource = object.getAttribute(this.attrInfo.name).resources[this.refListIndex];
+                    resource = object.getAttribute(this.attrInfo.name).resources[this.refListIndex, this.arrayIndex];
                 } else {
-                    resource = <Atomic.Resource>object.getAttribute(this.attrInfo.name);
+                    resource = <Atomic.Resource>object.getAttribute(this.attrInfo.name, this.arrayIndex);
                 }
 
                 var text = "";
@@ -857,7 +857,7 @@ class ResourceRefAttributeEdit extends AttributeInfoEdit {
 
                     if (ev.type == Atomic.UI_EVENT_TYPE.UI_EVENT_TYPE_POINTER_DOWN) {
 
-                        resource = <Atomic.Resource>object.getAttribute(this.attrInfo.name);
+                        resource = <Atomic.Resource>object.getAttribute(this.attrInfo.name, this.arrayIndex);
 
                         if (resource instanceof Atomic.JSComponentFile) {
 
@@ -930,7 +930,7 @@ class ResourceRefAttributeEdit extends AttributeInfoEdit {
 
                 }
 
-                this.editType.onAttributeInfoEdited(this.attrInfo, resource, this.refListIndex);
+                this.editType.onAttributeInfoEdited(this.attrInfo, resource, this.refListIndex, true, this.arrayIndex);
                 this.onResourceChanged(resource);
                 this.refresh();
 
@@ -961,7 +961,7 @@ class ResourceRefAttributeEdit extends AttributeInfoEdit {
 
                     var resource = asset.getResource(resourceTypeName);
 
-                    this.editType.onAttributeInfoEdited(this.attrInfo, resource, this.refListIndex);
+                    this.editType.onAttributeInfoEdited(this.attrInfo, resource, this.refListIndex, true, this.arrayIndex);
                     this.onResourceChanged(resource);
                     this.refresh();
 
@@ -1182,12 +1182,16 @@ class ArrayAttributeEdit extends AttributeInfoEdit {
         lp.width = 304;
         layout.layoutParams = lp;
 
-        var name = this.attrInfo.name + " Size";
-        if (name == "AnimationResources Size")
+        var name = this.attrInfo.name;
+        if (name == "AnimationResources")
             name = "Animations";
 
         var sizeEdit = this.sizeEdit = InspectorUtils.createAttrEditField(name, layout);
 
+        if (this.attrInfo.fixedArraySize) {
+            sizeEdit.disable();
+        }
+
         lp = new Atomic.UILayoutParams();
         lp.width = 160;
         sizeEdit.layoutParams = lp;

+ 7 - 7
Script/AtomicEditor/ui/frames/inspector/ComponentAttributeUI.ts

@@ -146,21 +146,21 @@ class SubmeshAttributeEdit extends AttributeInfoEdit {
         this.name = name;
         this.hideName = true;
 
-        this.subscribeToEvent(EditorEvents.RemoveCurrentAssetAssigned, (ev: EditorEvents.RemoveCurrentAssetAssignedEvent) => {
-
-            this.editType.onAttributeInfoEdited(this.attrInfo, null, this.matIndex);
-            this.refresh();
-        });
-
 
     }
 
     openResourceSelectionBox(materialIndex: number, resourceTypeName: string, importerName: string) {
 
         this.matIndex = materialIndex;
-
+        
         EditorUI.getModelOps().showResourceSelection("Select " + resourceTypeName + " Resource", importerName, resourceTypeName, function (retObject: any) {
 
+            if (retObject == null) {
+                this.editType.onAttributeInfoEdited(this.attrInfo, null, this.matIndex);
+                this.refresh();
+                return;
+            }
+
             var resource: Atomic.Resource = null;
 
             if (retObject instanceof ToolCore.Asset) {

+ 8 - 6
Script/AtomicEditor/ui/frames/inspector/MaterialInspector.ts

@@ -92,7 +92,6 @@ class MaterialInspector extends ScriptWidget {
         this.fd.id = "Vera";
         this.fd.size = 11;
 
-        this.subscribeToEvent(EditorEvents.RemoveCurrentAssetAssigned, (ev: EditorEvents.RemoveCurrentAssetAssignedEvent) => this.createTextureRemoveButtonCallback(this.tunit, this.textureWidget));
         this.subscribeToEvent("ResourceAdded", (ev: ToolCore.ResourceAddedEvent) => this.refreshTechniquesPopup());
     }
 
@@ -270,18 +269,21 @@ class MaterialInspector extends ScriptWidget {
 
     openTextureSelectionBox(textureUnit: number, textureWidget: Atomic.UITextureWidget) {
 
-        var inspector = this;
-
         EditorUI.getModelOps().showResourceSelection("Select Texture", "TextureImporter", "Texture2D", function (asset: ToolCore.Asset, args: any) {
 
+            if (asset == null) {
+                this.createTextureRemoveButtonCallback(this.tunit, this.textureWidget);
+                return;
+            }
+            
             var texture = <Atomic.Texture2D>Atomic.cache.getResource("Texture2D", asset.path);
 
             if (texture) {
-                inspector.material.setTexture(textureUnit, texture);
-                textureWidget.texture = inspector.getTextureThumbnail(texture);
+                this.material.setTexture(textureUnit, texture);
+                textureWidget.texture = this.getTextureThumbnail(texture);
             }
 
-        });
+        }.bind(this));
 
     }
 

+ 4 - 0
Script/AtomicEditor/ui/frames/inspector/SelectionInspector.ts

@@ -165,6 +165,10 @@ class JSComponentSection extends ComponentSection {
         let jsc = this.editType.getFirstObject() as Atomic.JSComponent;
         if (jsc && jsc.componentFile) {
             this.text = jsc.componentFile.name.split("/").pop();
+            let jscf = <Atomic.JSComponentFile> jsc.componentFile;
+            if (jscf.typeScriptClass) {
+                this.text = this.text.replace(".js", ".ts");
+            }            
         }
     }
 

+ 1 - 1
Script/AtomicEditor/ui/modal/ResourceSelection.ts

@@ -159,7 +159,7 @@ class ResourceSelection extends ModalWindow {
         var id = this.folderList.selectedItemID;
 
         if (id == "") {
-            this.sendEvent(EditorEvents.RemoveCurrentAssetAssigned);
+            this.callback(null, this.args);
             this.hide();
             return true;
         }

+ 4 - 1
Script/AtomicNET/AtomicNET/Scene/CSComponentCore.cs

@@ -182,7 +182,10 @@ namespace AtomicEngine
                                     {
                                          array.SetValue(variant.GetColor(), i);
                                     }
-
+                                    else if (elementType.IsSubclassOf(typeof(Resource)))
+                                    {
+                                        array.SetValue(variant.GetResource(), i);
+                                    }
                                     break;
                             }                            
                     

+ 14 - 1
Script/AtomicNET/AtomicNET/Scene/InspectorAttribute.cs

@@ -13,7 +13,20 @@ namespace AtomicEngine
 
         public readonly string DefaultValue;
 
-        // Tooltip which will be displayed in editor
+        /// <summary>
+        ///Specify a fixed array size for field 
+        /// </summary>
+        public int ArraySize
+        {
+            get { return arraySize; }
+            set { arraySize = value; }
+        }
+
+        private int arraySize = 0;
+
+        /// <summary>
+        /// Tooltip which will be displayed in editor 
+        /// </summary>
         public string Tooltip
         {
             get { return tooltip; }

+ 17 - 6
Script/AtomicNET/AtomicNETService/CSComponentInspector.cs

@@ -317,8 +317,8 @@ namespace AtomicTools
 
                 var typeCode = argsReader.ReadSerializationTypeCode();
 
-                // support string custom attr for now to simplify things
-                if (typeCode != SerializationTypeCode.String)
+                // support string/int custom attr for now to simplify things
+                if (typeCode != SerializationTypeCode.String && typeCode != SerializationTypeCode.Int32)
                     return false;
 
                 string name;
@@ -326,12 +326,23 @@ namespace AtomicTools
                 if (!CrackStringInAttributeValue(out name, ref argsReader))
                     return false;
 
-                string value;
+                if (typeCode == SerializationTypeCode.Int32)
+                {
+                    int value;
+                    value = argsReader.ReadInt32();
+                    inspectorField.CustomAttrNamedArgs[name] = value.ToString();
+                }
+                else
+                {
+                    string value;
 
-                if (!CrackStringInAttributeValue(out value, ref argsReader))
-                    return false;
+                    if (!CrackStringInAttributeValue(out value, ref argsReader))
+                        return false;
+
+                    inspectorField.CustomAttrNamedArgs[name] = value;
+                }
 
-                inspectorField.CustomAttrNamedArgs[name] = value;
+                
 
             }
 

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

@@ -122,6 +122,7 @@ declare module Atomic {
         dynamic: boolean;
         tooltip: string;
         isArray:boolean;
+        fixedArraySize:number;
     }
 
     export interface ShaderParameter {

+ 24 - 2
Source/Atomic/Script/ScriptComponentFile.cpp

@@ -53,10 +53,10 @@ void ScriptComponentFile::AddEnum(const String& enumName, const EnumInfo& enumIn
     enumValues.Push(enumInfo);
 }
 
-void ScriptComponentFile::AddField(const String& fieldName, VariantType variantType, bool isArray, const String &classname, const String& tooltip)
+void ScriptComponentFile::AddField(const String& fieldName, VariantType variantType, const String& resourceTypeName, bool isArray, unsigned fixedArraySize, const String &classname, const String& tooltip)
 {
     FieldMap& fields = classFields_[classname];
-    FieldInfo finfo(fieldName, variantType, isArray);
+    FieldInfo finfo(fieldName, variantType, resourceTypeName, isArray, fixedArraySize);
     fields[fieldName] = finfo;
 
     if (tooltip.Length())
@@ -161,15 +161,37 @@ void ScriptComponentFile::GetDefaultFieldValue(const String& name, Variant& v,co
     case VAR_BOOL:
         v = false;
         break;
+    case VAR_INT:
+        v = 0;
+    case VAR_DOUBLE:
+        v = 0;
     case VAR_STRING:
         v = "";
         break;
     case VAR_FLOAT:
         v = 0.0f;
         break;
+    case VAR_VECTOR2:
+        v = Vector2::ZERO;
+        break;
     case VAR_VECTOR3:
         v = Vector3::ZERO;
         break;
+    case VAR_VECTOR4:
+        v = Vector4::ZERO;
+        break;
+    case VAR_INTVECTOR2:
+        v = IntVector2::ZERO;
+        break;
+    case VAR_COLOR:
+        v = Color::WHITE;
+        break;
+    case VAR_QUATERNION:
+        v = Quaternion::IDENTITY;
+        break;
+    case VAR_RESOURCEREF:
+        v = Quaternion::IDENTITY;
+        break;
     default:
         break;
     }

+ 9 - 3
Source/Atomic/Script/ScriptComponentFile.h

@@ -37,18 +37,24 @@ struct FieldInfo
         name_ = "UNINITIALIZED_FIELDINFO";
         variantType_ = VAR_NONE;
         isArray_ = false;
+        fixedArraySize_ = 0;
     }
 
-    FieldInfo(const String& name, VariantType variantType, bool isArray = false)
+    FieldInfo(const String& name, VariantType variantType, const String& resourceTypeName = String::EMPTY, bool isArray = false, unsigned fixedArraySize = 0)
     {
-        name_ = name;
+        name_ = name;        
         variantType_ = variantType;
+        resourceTypeName_ = resourceTypeName;
         isArray_ = isArray;
+        fixedArraySize_ = fixedArraySize;
     }
 
     String name_;
     VariantType variantType_;
+    // for resource ref variants
+    String resourceTypeName_;
     bool isArray_;
+    unsigned fixedArraySize_;
 };
 
 struct EnumInfo
@@ -102,7 +108,7 @@ protected:
     void Clear();
 
     void AddEnum(const String& enumName, const EnumInfo& enumInfo, const String& classname = String::EMPTY);
-    void AddField(const String& fieldName, VariantType variantType, bool isArray, const String& classname = String::EMPTY, const String& tooltip = String::EMPTY);
+    void AddField(const String& fieldName, VariantType variantType, const String& resourceTypeName = String::EMPTY, bool isArray = false, unsigned fixedArraySize = 0, const String& classname = String::EMPTY, const String& tooltip = String::EMPTY);
     void AddDefaultValue(const String& fieldName, const Variant& value, const String& classname = String::EMPTY);
 
     // only valid in editor

+ 32 - 0
Source/Atomic/Script/ScriptVariant.cpp

@@ -20,3 +20,35 @@
 // THE SOFTWARE.
 //
 
+#include "ScriptVariant.h"
+
+namespace Atomic
+
+{
+
+Resource* ScriptVariant::GetResource() const
+{
+    if (variant_.GetType() == VAR_RESOURCEREF)
+    {
+        const ResourceRef& ref = variant_.GetResourceRef();
+
+        if (!ref.name_.Length() || !ref.type_)
+            return 0;
+
+        ResourceCache* cache = ScriptSystem::GetContext()->GetSubsystem<ResourceCache>();
+
+        return cache->GetResource(ref.type_, ref.name_);       
+    }
+}
+
+void ScriptVariant::SetResource(Resource* resource)
+{
+    if (!resource)
+    {
+        variant_ = ResourceRef();
+        return;
+    }
+    variant_ = ResourceRef(resource->GetType(), resource->GetName());
+}
+
+}

+ 4 - 0
Source/Atomic/Script/ScriptVariant.h

@@ -78,6 +78,10 @@ namespace Atomic
 
         const Vector3& GetVector3() const { return variant_.GetVector3(); }
 
+        Resource* GetResource() const;
+
+        void SetResource(Resource* resource);
+
         void SetVector3(const Vector3& value) { variant_ = value; }
 
         const Quaternion& GetQuaternion() const { return variant_.GetQuaternion(); }

+ 6 - 3
Source/AtomicJS/Javascript/JSAPI.cpp

@@ -304,7 +304,7 @@ namespace Atomic
         return true;
     }
 
-    void js_push_default_variant(duk_context* ctx, VariantType variantType, Variant& value)
+    void js_get_default_variant(VariantType variantType, Variant& value)
     {
         value = Variant::EMPTY;
         
@@ -363,11 +363,14 @@ namespace Atomic
             value = 0.0f;
             break;
 
+        case VAR_RESOURCEREF:            
+            value = ResourceRef();
+            break;
+
         default:
             break;
         }
-
-        js_push_variant(ctx, value);
+        
     }
 
     void js_to_variant(duk_context* ctx, int variantIdx, Variant &v, VariantType variantType)

+ 2 - 2
Source/AtomicJS/Javascript/JSAPI.h

@@ -61,8 +61,8 @@ void js_define_native_event(duk_context* ctx, const String& eventType, const Str
 void js_push_variant(duk_context* ctx, const Variant &v, int arrayIndex = -1);
 void js_push_variantmap(duk_context* ctx, const VariantMap &vmap);
 
-// Push a default value for the given variant type and set variantOut to the pushed value
-void js_push_default_variant(duk_context* ctx, VariantType variantType, Variant& variantOut);
+// Get a default value for the given variant type and set variantOut
+void js_get_default_variant(VariantType variantType, Variant& variantOut);
 
 /// Sets a variant value from the duktape stack
 void js_to_variant(duk_context* ctx, int variantIdx, Variant &v, VariantType variantType = VAR_NONE);

+ 9 - 2
Source/AtomicJS/Javascript/JSComponentFile.cpp

@@ -36,7 +36,8 @@ namespace Atomic
 
 JSComponentFile::JSComponentFile(Context* context) :
     ScriptComponentFile(context),
-    scriptClass_(false)
+    scriptClass_(false),
+    typescriptClass_(false)
 {
 }
 
@@ -181,6 +182,8 @@ bool JSComponentFile::InitModule()
 
 bool JSComponentFile::BeginLoad(Deserializer& source)
 {
+    typescriptClass_ = false;
+
     if (!InitModule())
         return false;
 
@@ -211,6 +214,10 @@ bool JSComponentFile::BeginLoad(Deserializer& source)
     {
         String line = lines[i];
 
+        // TODO: better TS detection
+        if (line.Contains("function __() { this.constructor = d; }"))
+            typescriptClass_ = true;
+
         bool added = false;
 
         if (!eval.Length())
@@ -415,7 +422,7 @@ bool JSComponentFile::BeginLoad(Deserializer& source)
 
                     if (variantType != VAR_NONE)
                     {
-                        AddField(name, variantType, false);
+                        AddField(name, variantType);
                     }
 
                     duk_pop_2(ctx);  // pop key value

+ 4 - 0
Source/AtomicJS/Javascript/JSComponentFile.h

@@ -54,6 +54,9 @@ public:
 
     bool GetScriptClass() { return scriptClass_; }
 
+    /// Returns true is this component file containes a TypeScript class
+    bool GetTypeScriptClass() { return typescriptClass_; }
+
     SharedPtr<JSComponent> CreateJSComponent();
     bool PushModule();
 
@@ -62,6 +65,7 @@ private:
     bool InitModule();
 
     bool scriptClass_;
+    bool typescriptClass_;
 
 };
 

+ 129 - 42
Source/AtomicJS/Javascript/JSSceneSerializable.cpp

@@ -97,10 +97,9 @@ namespace Atomic
         }
 
 
-        Variant v;
-        js_to_variant(ctx, 1, v, variantType);
-
-        ScriptComponent* jsc = NULL;
+        ScriptComponent* jsc = 0;
+        FieldInfo *fieldInfo = 0;
+        const HashMap<String, Vector<EnumInfo>>* enums = 0;
 
         // check dynamic
         if (!isAttr)
@@ -118,31 +117,37 @@ namespace Atomic
                     const FieldMap& fields = file->GetFields(className);
                     const HashMap<String, Vector<EnumInfo>>& enums = file->GetEnums(className);
 
-                    if (FieldInfo *finfo = fields[name])
+                    if (fieldInfo = fields[name])
                     {
-                        variantType = finfo->variantType_;
+                        variantType = fieldInfo->variantType_;
 
-                        if (finfo->isArray_)
+                        if (fieldInfo->isArray_)
                         {
                             arrayVariantType = variantType;
                             variantType = VAR_VARIANTVECTOR;
                         }
-                        else if (enums.Contains(name))
-                        {
-                            int idx = (int)v.GetFloat();
-
-                            if (idx > 0 && idx < enums[name]->Size())
-                            {
-                                VariantMap& values = jsc->GetFieldValues();
-                                values[name] = enums[name]->At(idx).value_;
-                                return 0;
-                            }
-                        }
                     }
                 }
             }
         }
 
+        Variant v;
+        js_to_variant(ctx, 1, v, variantType);
+
+        if (enums && enums->Contains(name))
+        {
+            int idx = (int)v.GetFloat();
+
+            if (idx > 0 && idx < (*enums)[name]->Size())
+            {
+                VariantMap& values = jsc->GetFieldValues();
+                values[name] = (*enums)[name]->At(idx).value_;
+                return 0;
+            }
+        }
+
+
+
         if (variantType == VAR_NONE)
             return 0;
 
@@ -178,12 +183,18 @@ namespace Atomic
                 v = ResourceRef(resource->GetType(), resource->GetName());
 
             }
+            else
+            {
+                v = ResourceRef();
+            }
 
         }
         else if (variantType == VAR_VARIANTVECTOR)
         {
             if (arrayIndex >= 0)
             {
+                assert(fieldInfo);
+
                 const VariantMap& values = jsc->GetFieldValues();
                 Variant *v2 = values[name];
 
@@ -194,7 +205,29 @@ namespace Atomic
                     {
                         VariantVector* vector = v2->GetVariantVectorPtr();
 
-                        if (v.GetType() == VAR_VECTOR4)
+                        if (arrayVariantType == VAR_RESOURCEREF)
+                        {
+                            RefCounted* ref = v.GetPtr();
+
+                            if (ref && ref->IsObject())
+                            {
+                                Object* o = (Object*)ref;
+
+                                // TODO: calling code must ensure we are a resource, can this be done here?
+                                Resource* resource = (Resource*)o;
+
+                                if (resource->GetType() == StringHash(fieldInfo->resourceTypeName_))
+                                    v = ResourceRef(resource->GetType(), resource->GetName());
+                                else
+                                    v = ResourceRef();
+                            }
+                            else
+                            {
+                                v = ResourceRef();
+                            }
+
+                        }
+                        else if (v.GetType() == VAR_VECTOR4)
                         {
                             if (arrayVariantType == VAR_COLOR)
                             {
@@ -207,8 +240,7 @@ namespace Atomic
                                 v = Quaternion(v4.w_, v4.x_, v4.y_, v4.z_);
                             }
                         }
-
-                        if (v.GetType() == VAR_FLOAT)
+                        else if (v.GetType() == VAR_FLOAT)
                         {
                             if (arrayVariantType == VAR_INT)
                                 v = (int)v.GetFloat();
@@ -304,6 +336,32 @@ namespace Atomic
 
                             VariantVector* vector = vptr->GetVariantVectorPtr();
 
+                            if (finfo->fixedArraySize_)
+                            {
+                                if (vector->Size() != finfo->fixedArraySize_)
+                                {
+                                    if (vector->Size() < finfo->fixedArraySize_)
+                                    {
+                                        Variant value;
+                                        js_get_default_variant(finfo->variantType_, value);
+
+                                        unsigned oldSize = vector->Size();
+                                        vector->Resize(finfo->fixedArraySize_);
+
+                                        for (unsigned i = oldSize; i < finfo->fixedArraySize_; i++)
+                                        {
+                                            (*vector)[i] = value;
+                                        }
+                                    }
+                                    else
+                                    {
+                                        // truncate
+                                        vector->Resize(finfo->fixedArraySize_);
+                                    }
+                                    
+                                }
+                            }
+
                             if (arrayIndex >= vector->Size())
                             {
                                 duk_push_undefined(ctx);
@@ -315,7 +373,8 @@ namespace Atomic
                             if (current.GetType() != finfo->variantType_)
                             {
                                 Variant value;
-                                js_push_default_variant(ctx, finfo->variantType_, value);
+                                js_get_default_variant(finfo->variantType_, value);
+                                js_push_variant(ctx, value);
                                 (*vector)[arrayIndex] = value;
                             }
                             else
@@ -337,23 +396,36 @@ namespace Atomic
                             if (arrayIndex < 0)
                             {
                                 SharedPtr<ScriptVector> vector(new ScriptVector());
+
+                                if (finfo->fixedArraySize_)
+                                {
+                                    
+                                    VariantVector init(finfo->fixedArraySize_);
+                                    init.Resize(finfo->fixedArraySize_);
+                                    Variant value;
+                                    js_get_default_variant(finfo->variantType_, value);
+                                    
+                                    for (unsigned i = 0; i < finfo->fixedArraySize_; i++)
+                                    {
+                                        init[i] = value;
+                                    }
+
+                                    jsc->GetFieldValues()[finfo->name_] = init;
+
+                                    vector->AdaptFromVector(init);
+
+                                    
+
+                                }
+
                                 js_push_class_object_instance(ctx, vector);
                                 return 1;
                             }
                             else
                             {
-                                Variant value;
-                                js_push_default_variant(ctx, finfo->variantType_, value);
-
-                                VariantVector newVector;
-
-                                if (arrayIndex >= newVector.Size())
-                                {
-                                    newVector.Resize(arrayIndex + 1);
-                                }
-
-                                jsc->GetFieldValues()[name] = newVector;
-
+                                // we don't have the variant in the fieldmap
+                                ATOMIC_LOGERROR("Serializable_GetAttribute - indexing uninitialized array");
+                                duk_push_undefined(ctx);
                                 return 1;
                             }
                         }
@@ -386,18 +458,30 @@ namespace Atomic
                 duk_push_number(ctx, (double)itr->second_.variantType_);
                 duk_put_prop_string(ctx, -2, "type");
 
-                if (itr->second_.variantType_ == VAR_RESOURCEREF && defaultFieldValues.Contains(itr->first_))
+                const FieldInfo& fieldInfo = itr->second_;
+
+                if (fieldInfo.variantType_ == VAR_RESOURCEREF)
                 {
-                    if (defaultFieldValues[itr->first_]->GetType() == VAR_RESOURCEREF)
+                    if (fieldInfo.resourceTypeName_.Length())
                     {
-                        const ResourceRef& ref = defaultFieldValues[itr->first_]->GetResourceRef();
-                        const String& typeName = JSVM::GetJSVM(ctx)->GetContext()->GetTypeName(ref.type_);
-
-                        if (typeName.Length())
+                        duk_push_string(ctx, fieldInfo.resourceTypeName_.CString());
+                        duk_put_prop_string(ctx, -2, "resourceTypeName");
+                    }
+                    else if (defaultFieldValues.Contains(fieldInfo.name_) && defaultFieldValues[fieldInfo.name_]->GetType() == VAR_RESOURCEREF)
+                    {       
+                        if (const Variant* value = defaultFieldValues[fieldInfo.name_])
                         {
-                            duk_push_string(ctx, typeName.CString());
-                            duk_put_prop_string(ctx, -2, "resourceTypeName");
+                            if (value->GetType() == VAR_RESOURCEREF)
+                            {
+                                const ResourceRef& ref = value->GetResourceRef();
+                                const String& typeName = JSVM::GetJSVM(ctx)->GetContext()->GetTypeName(ref.type_);
 
+                                if (typeName.Length())
+                                {
+                                    duk_push_string(ctx, typeName.CString());
+                                    duk_put_prop_string(ctx, -2, "resourceTypeName");
+                                }
+                            }
                         }
                     }
                 }
@@ -417,6 +501,9 @@ namespace Atomic
                 duk_push_boolean(ctx, itr->second_.isArray_ ? 1 : 0);
                 duk_put_prop_string(ctx, -2, "isArray");
 
+                duk_push_number(ctx, itr->second_.fixedArraySize_);
+                duk_put_prop_string(ctx, -2, "fixedArraySize");
+
                 if (tooltips.Contains(itr->first_))
                 {
                     duk_push_string(ctx, tooltips[itr->first_]->CString());

+ 12 - 2
Source/AtomicNET/NETScript/CSComponentAssembly.cpp

@@ -93,7 +93,9 @@ namespace Atomic
 
                 bool isEnum = jfield.Get("isEnum").GetBool();
                 bool isArray = jfield.Get("isArray").GetBool();
-                String typeName = jfield.Get("typeName").GetString();               
+                unsigned fixedArraySize = 0;
+                String typeName = jfield.Get("typeName").GetString();
+                String resourceTypeName;
                 String fieldName = jfield.Get("name").GetString();
                 String defaultValue = jfield.Get("defaultValue").GetString();
                 String tooltip;
@@ -119,6 +121,13 @@ namespace Atomic
                     tooltip = caNamed["Tooltip"].GetString();
                 }
 
+                // fixed array size
+                if (caNamed.Contains("ArraySize"))
+                {
+                    fixedArraySize = (unsigned)ToInt(caNamed["ArraySize"].GetString().CString());
+                }
+
+
                 if (isEnum && assemblyEnums_.Contains(typeName) && !enumsAdded.Contains(fieldName))
                 {
                     varType = VAR_INT;
@@ -142,6 +151,7 @@ namespace Atomic
                         if (itr->second_->GetFactoryTypeName() == typeName)
                         {
                             varType = VAR_RESOURCEREF;
+                            resourceTypeName = typeName;
                             break;
                         }
 
@@ -184,7 +194,7 @@ namespace Atomic
                     }
                 }
 
-                AddField(fieldName, varType, isArray, className, tooltip);
+                AddField(fieldName, varType, resourceTypeName, isArray, fixedArraySize, className, tooltip);
 
             }