Browse Source

Support defining different action buttons for different resource types in the editor.
Added functionality to test animations in the editor.
Expose RefCounted class properly to script so that WeakHandle can point to all RefCounted types instead of just Object.

Lasse Öörni 12 years ago
parent
commit
e908a9076a

+ 1 - 0
Bin/Data/Scripts/Editor.as

@@ -85,6 +85,7 @@ void HandleUpdate(StringHash eventType, VariantMap& eventData)
     UpdateView(timeStep);
     UpdateView(timeStep);
     UpdateStats(timeStep);
     UpdateStats(timeStep);
     UpdateScene(timeStep);
     UpdateScene(timeStep);
+    UpdateTestAnimation(timeStep);
     UpdateGizmo();
     UpdateGizmo();
     UpdateDirtyUI();
     UpdateDirtyUI();
 }
 }

+ 142 - 64
Bin/Data/Scripts/Editor/AttributeEditor.as

@@ -23,8 +23,13 @@ Color nonEditableTextColor(0.7f, 0.7f, 0.7f);
 
 
 String sceneResourcePath;
 String sceneResourcePath;
 
 
+WeakHandle testAnimState;
+
 UIElement@ SetEditable(UIElement@ element, bool editable)
 UIElement@ SetEditable(UIElement@ element, bool editable)
 {
 {
+    if (element is null)
+        return element;
+
     element.enabled = editable;
     element.enabled = editable;
     element.colors[C_TOPLEFT] = editable ? element.colors[C_BOTTOMRIGHT] : nonEditableTextColor;
     element.colors[C_TOPLEFT] = editable ? element.colors[C_BOTTOMRIGHT] : nonEditableTextColor;
     element.colors[C_BOTTOMLEFT] = element.colors[C_TOPLEFT];
     element.colors[C_BOTTOMLEFT] = element.colors[C_TOPLEFT];
@@ -215,15 +220,19 @@ UIElement@ CreateResourceRefAttributeEditor(ListView@ list, Array<Serializable@>
 {
 {
     UIElement@ parent;
     UIElement@ parent;
     ShortStringHash resourceType;
     ShortStringHash resourceType;
-    VariantType attrType = info.type;
-    if (attrType == VAR_RESOURCEREF)
+
+    // Get the real attribute info from the serializable for the correct resource type
+    AttributeInfo attrInfo = serializables[0].attributeInfos[index];
+    if (attrInfo.type == VAR_RESOURCEREF)
         resourceType = serializables[0].attributes[index].GetResourceRef().type;
         resourceType = serializables[0].attributes[index].GetResourceRef().type;
-    else if (attrType == VAR_RESOURCEREFLIST)
+    else if (attrInfo.type == VAR_RESOURCEREFLIST)
         resourceType = serializables[0].attributes[index].GetResourceRefList().type;
         resourceType = serializables[0].attributes[index].GetResourceRefList().type;
-    else if (attrType == VAR_VARIANTVECTOR)
+    else if (attrInfo.type == VAR_VARIANTVECTOR)
         resourceType = serializables[0].attributes[index].GetVariantVector()[subIndex].GetResourceRef().type;
         resourceType = serializables[0].attributes[index].GetVariantVector()[subIndex].GetResourceRef().type;
 
 
-     // Create the attribute name on a separate non-interactive line to allow for more space
+    ResourcePicker@ picker = GetResourcePicker(resourceType);
+
+    // Create the attribute name on a separate non-interactive line to allow for more space
     parent = CreateAttributeEditorParentWithSeparatedLabel(list, info.name, index, subIndex, suppressedSeparatedLabel);
     parent = CreateAttributeEditorParentWithSeparatedLabel(list, info.name, index, subIndex, suppressedSeparatedLabel);
 
 
     UIElement@ container = UIElement();
     UIElement@ container = UIElement();
@@ -235,39 +244,49 @@ UIElement@ CreateResourceRefAttributeEditor(ListView@ list, Array<Serializable@>
     attrEdit.vars[TYPE_VAR] = resourceType.value;
     attrEdit.vars[TYPE_VAR] = resourceType.value;
     SubscribeToEvent(attrEdit, "TextFinished", "EditAttribute");
     SubscribeToEvent(attrEdit, "TextFinished", "EditAttribute");
 
 
-    Button@ pickButton = Button();
-    container.AddChild(pickButton);
-    pickButton.style = AUTO_STYLE;
-    pickButton.SetFixedSize(36, ATTR_HEIGHT - 2);
-    pickButton.vars["Index"] = index;
-    pickButton.vars["SubIndex"] = subIndex;
-    SetAttributeEditorID(pickButton, serializables);
-
-    Text@ pickButtonText = Text();
-    pickButton.AddChild(pickButtonText);
-    pickButtonText.style = "EditorAttributeText";
-    pickButtonText.SetAlignment(HA_CENTER, VA_CENTER);
-    pickButtonText.text = "Pick";
-    SubscribeToEvent(pickButton, "Released", "PickResource");
-
-    Button@ openButton = Button();
-    container.AddChild(openButton);
-    openButton.style = AUTO_STYLE;
-    openButton.SetFixedSize(36, ATTR_HEIGHT - 2);
-    openButton.vars["Index"] = index;
-    openButton.vars["SubIndex"] = subIndex;
-    SetAttributeEditorID(openButton, serializables);
-
-    Text@ openButtonText = Text();
-    openButton.AddChild(openButtonText);
-    openButtonText.style = "EditorAttributeText";
-    openButtonText.SetAlignment(HA_CENTER, VA_CENTER);
-    openButtonText.text = "Open";
-    SubscribeToEvent(openButton, "Released", "OpenResource");
+    if ((picker.actions & ACTION_PICK) != 0)
+    {
+        Button@ pickButton = CreateResourcePickerButton(container, serializables, index, subIndex, "Pick");
+        SubscribeToEvent(pickButton, "Released", "PickResource");
+    }
+    if ((picker.actions & ACTION_OPEN) != 0)
+    {
+        Button@ openButton = CreateResourcePickerButton(container, serializables, index, subIndex, "Open");
+        SubscribeToEvent(openButton, "Released", "OpenResource");
+    }
+    if ((picker.actions & ACTION_EDIT) != 0)
+    {
+        Button@ editButton = CreateResourcePickerButton(container, serializables, index, subIndex, "Edit");
+        SubscribeToEvent(editButton, "Released", "EditResource");
+    }
+    if ((picker.actions & ACTION_TEST) != 0)
+    {
+        Button@ testButton = CreateResourcePickerButton(container, serializables, index, subIndex, "Test");
+        SubscribeToEvent(testButton, "Released", "TestResource");
+    }
 
 
     return parent;
     return parent;
 }
 }
 
 
+Button@ CreateResourcePickerButton(UIElement@ container, Array<Serializable@>@ serializables, uint index, uint subIndex, const String&in text)
+{
+    Button@ button = Button();
+    container.AddChild(button);
+    button.style = AUTO_STYLE;
+    button.SetFixedSize(36, ATTR_HEIGHT - 2);
+    button.vars["Index"] = index;
+    button.vars["SubIndex"] = subIndex;
+    SetAttributeEditorID(button, serializables);
+
+    Text@ buttonText = Text();
+    button.AddChild(buttonText);
+    buttonText.style = "EditorAttributeText";
+    buttonText.SetAlignment(HA_CENTER, VA_CENTER);
+    buttonText.text = text;
+
+    return button;
+}
+
 UIElement@ CreateAttributeEditor(ListView@ list, Array<Serializable@>@ serializables, const AttributeInfo&in info, uint index, uint subIndex, bool suppressedSeparatedLabel = false)
 UIElement@ CreateAttributeEditor(ListView@ list, Array<Serializable@>@ serializables, const AttributeInfo&in info, uint index, uint subIndex, bool suppressedSeparatedLabel = false)
 {
 {
     UIElement@ parent;
     UIElement@ parent;
@@ -447,7 +466,8 @@ void LoadAttributeEditor(UIElement@ parent, const Variant&in value, const Attrib
     {
     {
         SetEditable(SetValue(parent.children[1].children[0], cache.GetResourceName(value.GetResourceRef().id), sameValue), editable && sameValue);
         SetEditable(SetValue(parent.children[1].children[0], cache.GetResourceName(value.GetResourceRef().id), sameValue), editable && sameValue);
         SetEditable(parent.children[1].children[1], editable && sameValue);  // If editable then can pick
         SetEditable(parent.children[1].children[1], editable && sameValue);  // If editable then can pick
-        SetEditable(parent.children[1].children[2], sameValue); // If same value then can open
+        for (uint i = 2; i < parent.children[1].numChildren; ++i)
+            SetEditable(parent.children[1].children[i], sameValue); // If same value then can open/edit/test
     }
     }
     else if (type == VAR_RESOURCEREFLIST)
     else if (type == VAR_RESOURCEREFLIST)
     {
     {
@@ -797,26 +817,36 @@ void EditAttribute(StringHash eventType, VariantMap& eventData)
 }
 }
 
 
 // Resource picker functionality
 // Resource picker functionality
+const uint ACTION_PICK = 1;
+const uint ACTION_OPEN = 2;
+const uint ACTION_EDIT = 4;
+const uint ACTION_TEST = 8;
 
 
 class ResourcePicker
 class ResourcePicker
 {
 {
-    String resourceType;
+    String typeName;
+    ShortStringHash type;
     String lastPath;
     String lastPath;
     uint lastFilter;
     uint lastFilter;
     Array<String> filters;
     Array<String> filters;
+    uint actions;
 
 
-    ResourcePicker(const String&in resourceType_, const String&in filter_)
+    ResourcePicker(const String&in typeName_, const String&in filter_, uint actions_ = ACTION_PICK | ACTION_OPEN)
     {
     {
-        resourceType = resourceType_;
+        typeName = typeName_;
+        type = ShortStringHash(typeName_);
+        actions = actions_;
         filters.Push(filter_);
         filters.Push(filter_);
         filters.Push("*.*");
         filters.Push("*.*");
         lastFilter = 0;
         lastFilter = 0;
     }
     }
 
 
-    ResourcePicker(const String&in resourceType_, const Array<String>@ filters_)
+    ResourcePicker(const String&in typeName_, const Array<String>@ filters_, uint actions_ = ACTION_PICK | ACTION_OPEN)
     {
     {
-        resourceType = resourceType_;
+        typeName = typeName_;
+        type = ShortStringHash(typeName_);
         filters = filters_;
         filters = filters_;
+        actions = actions_;
         filters.Push("*.*");
         filters.Push("*.*");
         lastFilter = 0;
         lastFilter = 0;
     }
     }
@@ -837,10 +867,10 @@ void InitResourcePicker()
     Array<String> soundFilters = {"*.wav","*.ogg"};
     Array<String> soundFilters = {"*.wav","*.ogg"};
     Array<String> scriptFilters = {"*.as", "*.asc"};
     Array<String> scriptFilters = {"*.as", "*.asc"};
     Array<String> materialFilters = {"*.xml", "*.material"};
     Array<String> materialFilters = {"*.xml", "*.material"};
-    resourcePickers.Push(ResourcePicker("Animation", "*.ani"));
+    resourcePickers.Push(ResourcePicker("Animation", "*.ani", ACTION_PICK | ACTION_TEST));
     resourcePickers.Push(ResourcePicker("Font", fontFilters));
     resourcePickers.Push(ResourcePicker("Font", fontFilters));
     resourcePickers.Push(ResourcePicker("Image", imageFilters));
     resourcePickers.Push(ResourcePicker("Image", imageFilters));
-    resourcePickers.Push(ResourcePicker("Model", "*.mdl"));
+    resourcePickers.Push(ResourcePicker("Model", "*.mdl", ACTION_PICK));
     resourcePickers.Push(ResourcePicker("Material", materialFilters));
     resourcePickers.Push(ResourcePicker("Material", materialFilters));
     resourcePickers.Push(ResourcePicker("Texture2D", textureFilters));
     resourcePickers.Push(ResourcePicker("Texture2D", textureFilters));
     resourcePickers.Push(ResourcePicker("TextureCube", "*.xml"));
     resourcePickers.Push(ResourcePicker("TextureCube", "*.xml"));
@@ -850,11 +880,11 @@ void InitResourcePicker()
     sceneResourcePath = AddTrailingSlash(fileSystem.programDir + "Data");
     sceneResourcePath = AddTrailingSlash(fileSystem.programDir + "Data");
 }
 }
 
 
-ResourcePicker@ GetResourcePicker(const String&in resourceType)
+ResourcePicker@ GetResourcePicker(ShortStringHash resourceType)
 {
 {
     for (uint i = 0; i < resourcePickers.length; ++i)
     for (uint i = 0; i < resourcePickers.length; ++i)
     {
     {
-        if (resourcePickers[i].resourceType.Compare(resourceType, false) == 0)
+        if (resourcePickers[i].type == resourceType)
             return resourcePickers[i];
             return resourcePickers[i];
     }
     }
     return null;
     return null;
@@ -873,25 +903,15 @@ void PickResource(StringHash eventType, VariantMap& eventData)
     resourcePickSubIndex = attrEdit.vars["SubIndex"].GetUInt();
     resourcePickSubIndex = attrEdit.vars["SubIndex"].GetUInt();
     AttributeInfo info = targets[0].attributeInfos[resourcePickIndex];
     AttributeInfo info = targets[0].attributeInfos[resourcePickIndex];
 
 
+    ShortStringHash resourceType;
     if (info.type == VAR_RESOURCEREF)
     if (info.type == VAR_RESOURCEREF)
-    {
-        String resourceType = GetTypeName(targets[0].attributes[resourcePickIndex].GetResourceRef().type);
-        @resourcePicker = GetResourcePicker(resourceType);
-    }
+        resourceType = targets[0].attributes[resourcePickIndex].GetResourceRef().type;
     else if (info.type == VAR_RESOURCEREFLIST)
     else if (info.type == VAR_RESOURCEREFLIST)
-    {
-        String resourceType = GetTypeName(targets[0].attributes[resourcePickIndex].GetResourceRefList().type);
-        @resourcePicker = GetResourcePicker(resourceType);
-    }
+        resourceType = targets[0].attributes[resourcePickIndex].GetResourceRefList().type;
     else if (info.type == VAR_VARIANTVECTOR)
     else if (info.type == VAR_VARIANTVECTOR)
-    {
-        String resourceType = GetTypeName(targets[0].attributes[resourcePickIndex].GetVariantVector()
-            [resourcePickSubIndex].GetResourceRef().type);
-        @resourcePicker = GetResourcePicker(resourceType);
-    }
-    else
-        @resourcePicker = null;
+        resourceType = targets[0].attributes[resourcePickIndex].GetVariantVector()[resourcePickSubIndex].GetResourceRef().type;
 
 
+    @resourcePicker = GetResourcePicker(resourceType);
     if (resourcePicker is null)
     if (resourcePicker is null)
         return;
         return;
 
 
@@ -902,7 +922,7 @@ void PickResource(StringHash eventType, VariantMap& eventData)
     String lastPath = resourcePicker.lastPath;
     String lastPath = resourcePicker.lastPath;
     if (lastPath.empty)
     if (lastPath.empty)
         lastPath = sceneResourcePath;
         lastPath = sceneResourcePath;
-    CreateFileSelector("Pick " + resourcePicker.resourceType, "OK", "Cancel", lastPath, resourcePicker.filters, resourcePicker.lastFilter);
+    CreateFileSelector("Pick " + resourcePicker.typeName, "OK", "Cancel", lastPath, resourcePicker.filters, resourcePicker.lastFilter);
     SubscribeToEvent(uiFileSelector, "FileSelected", "PickResourceDone");
     SubscribeToEvent(uiFileSelector, "FileSelected", "PickResourceDone");
 }
 }
 
 
@@ -937,11 +957,11 @@ void PickResourceDone(StringHash eventType, VariantMap& eventData)
         if (!resourceName.ToLower().StartsWith(resourceDirs[i].ToLower()))
         if (!resourceName.ToLower().StartsWith(resourceDirs[i].ToLower()))
             continue;
             continue;
         resourceName = resourceName.Substring(resourceDirs[i].length);
         resourceName = resourceName.Substring(resourceDirs[i].length);
-        res = cache.GetResource(resourcePicker.resourceType, resourceName);
+        res = cache.GetResource(resourcePicker.typeName, resourceName);
         break;
         break;
     }
     }
     if (res is null) {
     if (res is null) {
-        log.Warning("Cannot find resource type: " + resourcePicker.resourceType + " Name:" +resourceName);
+        log.Warning("Cannot find resource type: " + resourcePicker.typeName + " Name:" + resourceName);
         return;
         return;
     }
     }
 
 
@@ -958,7 +978,7 @@ void PickResourceDone(StringHash eventType, VariantMap& eventData)
         if (info.type == VAR_RESOURCEREF)
         if (info.type == VAR_RESOURCEREF)
         {
         {
             ResourceRef ref = target.attributes[resourcePickIndex].GetResourceRef();
             ResourceRef ref = target.attributes[resourcePickIndex].GetResourceRef();
-            ref.type = ShortStringHash(resourcePicker.resourceType);
+            ref.type = resourcePicker.type;
             ref.id = StringHash(resourceName);
             ref.id = StringHash(resourceName);
             target.attributes[resourcePickIndex] = Variant(ref);
             target.attributes[resourcePickIndex] = Variant(ref);
             target.ApplyAttributes();
             target.ApplyAttributes();
@@ -977,7 +997,7 @@ void PickResourceDone(StringHash eventType, VariantMap& eventData)
         {
         {
             Array<Variant>@ attrs = target.attributes[resourcePickIndex].GetVariantVector();
             Array<Variant>@ attrs = target.attributes[resourcePickIndex].GetVariantVector();
             ResourceRef ref = attrs[resourcePickSubIndex].GetResourceRef();
             ResourceRef ref = attrs[resourcePickSubIndex].GetResourceRef();
-            ref.type = ShortStringHash(resourcePicker.resourceType);
+            ref.type = resourcePicker.type;
             ref.id = StringHash(resourceName);
             ref.id = StringHash(resourceName);
             attrs[resourcePickSubIndex] = ref;
             attrs[resourcePickSubIndex] = ref;
             target.attributes[resourcePickIndex] = Variant(attrs);
             target.attributes[resourcePickIndex] = Variant(attrs);
@@ -1013,6 +1033,64 @@ void OpenResource(StringHash eventType, VariantMap& eventData)
     }
     }
 }
 }
 
 
+void EditResource(StringHash eventType, VariantMap& eventData)
+{
+    UIElement@ button = eventData["Element"].GetUIElement();
+    LineEdit@ attrEdit = button.parent.children[0];
+
+    String fileName = attrEdit.text.Trimmed();
+    if (fileName.empty)
+        return;
+
+    /// \todo Implement
+}
+
+void TestResource(StringHash eventType, VariantMap& eventData)
+{
+    UIElement@ button = eventData["Element"].GetUIElement();
+    LineEdit@ attrEdit = button.parent.children[0];
+
+    ShortStringHash resourceType(attrEdit.vars[TYPE_VAR].GetUInt());
+    ShortStringHash animType("Animation");
+    if (resourceType == animType)
+        TestAnimation(attrEdit);
+}
+
+void TestAnimation(UIElement@ attrEdit)
+{
+    // Note: only supports the AnimationState array in AnimatedModel, and if only 1 model selected
+    Array<Serializable@>@ targets = GetAttributeEditorTargets(attrEdit);
+    if (targets.length != 1)
+        return;
+    AnimatedModel@ model = cast<AnimatedModel>(targets[0]);
+    if (model is null)
+        return;
+
+    uint animStateIndex = (attrEdit.vars["SubIndex"].GetUInt() - 1) / 6;
+    if (testAnimState.Get() is null)
+    {
+        testAnimState = model.GetAnimationState(animStateIndex);
+        AnimationState@ animState = testAnimState.Get();
+        if (animState !is null)
+        {
+            animState.time = 0; // Start from beginning
+            UpdateAttributeInspector(false);
+        }
+    }
+    else
+        testAnimState = null;
+}
+
+void UpdateTestAnimation(float timeStep)
+{
+    AnimationState@ animState = testAnimState.Get();
+    if (animState !is null)
+    {
+        animState.AddTime(timeStep);
+        UpdateAttributeInspector(false);
+    }
+}
+
 // VariantVector decoding & editing for certain components
 // VariantVector decoding & editing for certain components
 
 
 class VectorStruct
 class VectorStruct

+ 1 - 0
Bin/Data/Scripts/Editor/EditorUI.as

@@ -178,6 +178,7 @@ void CreateMenuBar()
         popup.AddChild(CreateMenuItem("Unparent", @SceneUnparent, 'U', QUAL_CTRL));
         popup.AddChild(CreateMenuItem("Unparent", @SceneUnparent, 'U', QUAL_CTRL));
         CreateChildDivider(popup);
         CreateChildDivider(popup);
         popup.AddChild(CreateMenuItem("Toggle update", @ToggleUpdate, 'P', QUAL_CTRL));
         popup.AddChild(CreateMenuItem("Toggle update", @ToggleUpdate, 'P', QUAL_CTRL));
+        popup.AddChild(CreateMenuItem("Stop test animation", @StopTestAnimation));
         CreateChildDivider(popup);
         CreateChildDivider(popup);
         popup.AddChild(CreateMenuItem("Rebuild navigation data", @SceneRebuildNavigation));
         popup.AddChild(CreateMenuItem("Rebuild navigation data", @SceneRebuildNavigation));
         FinalizedPopupMenu(popup);
         FinalizedPopupMenu(popup);

+ 6 - 0
Bin/Data/Scripts/Editor/EditorView.as

@@ -553,3 +553,9 @@ bool ToggleUpdate()
     runUpdate = !runUpdate;
     runUpdate = !runUpdate;
     return true;
     return true;
 }
 }
+
+bool StopTestAnimation()
+{
+    testAnimState = null;
+    return true;
+}

+ 1 - 1
Docs/Reference.dox

@@ -447,7 +447,7 @@ There are some complexities of the scripting system one has to watch out for:
 
 
 The following changes have been made to AngelScript in Urho3D:
 The following changes have been made to AngelScript in Urho3D:
 
 
-- For performance reasons and to guarantee immediate removal of expired objects, AngelScript garbage collection has been disabled for script classes and the Array type. This has the downside that circular references will not be detected. Therefore, whenever you have object handles in your script, think of them as if they were C++ shared pointers and avoid creating circular references with them. For safety, consider using the value type WeakHandle, which is a WeakPtr<Object> exposed to script and can be used to point to any engine object (but not to script objects.) An example of using WeakHandle:
+- For performance reasons and to guarantee immediate removal of expired objects, AngelScript garbage collection has been disabled for script classes and the Array type. This has the downside that circular references will not be detected. Therefore, whenever you have object handles in your script, think of them as if they were C++ shared pointers and avoid creating circular references with them. For safety, consider using the value type WeakHandle, which is a WeakPtr<RefCounted> exposed to script and can be used to point to any engine object (but not to script objects.) An example of using WeakHandle:
 
 
 \code
 \code
 WeakHandle rigidBodyWeak = node.CreateComponent("RigidBody");
 WeakHandle rigidBodyWeak = node.CreateComponent("RigidBody");

File diff suppressed because it is too large
+ 150 - 143
Docs/ScriptAPI.dox


+ 2 - 5
Engine/Script/APITemplates.h

@@ -282,6 +282,7 @@ template <class T> void RegisterRefCounted(asIScriptEngine* engine, const char*
     engine->RegisterObjectBehaviour(className, asBEHAVE_RELEASE, "void f()", asMETHODPR(T, ReleaseRef, (), void), asCALL_THISCALL);
     engine->RegisterObjectBehaviour(className, asBEHAVE_RELEASE, "void f()", asMETHODPR(T, ReleaseRef, (), void), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "int get_refs() const", asMETHODPR(T, Refs, () const, int), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "int get_refs() const", asMETHODPR(T, Refs, () const, int), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "int get_weakRefs() const", asMETHODPR(T, WeakRefs, () const, int), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "int get_weakRefs() const", asMETHODPR(T, WeakRefs, () const, int), asCALL_THISCALL);
+    RegisterSubclass<RefCounted, T>(engine, "RefCounted", className);
 }
 }
 
 
 template <class T> void ObjectSendEvent(const String& eventType, VariantMap& eventData,  T* ptr)
 template <class T> void ObjectSendEvent(const String& eventType, VariantMap& eventData,  T* ptr)
@@ -293,14 +294,10 @@ template <class T> void ObjectSendEvent(const String& eventType, VariantMap& eve
 /// Template function for registering a class derived from Object.
 /// Template function for registering a class derived from Object.
 template <class T> void RegisterObject(asIScriptEngine* engine, const char* className)
 template <class T> void RegisterObject(asIScriptEngine* engine, const char* className)
 {
 {
-    engine->RegisterObjectType(className, 0, asOBJ_REF);
-    engine->RegisterObjectBehaviour(className, asBEHAVE_ADDREF, "void f()", asMETHODPR(T, AddRef, (), void), asCALL_THISCALL);
-    engine->RegisterObjectBehaviour(className, asBEHAVE_RELEASE, "void f()", asMETHODPR(T, ReleaseRef, (), void), asCALL_THISCALL);
+    RegisterRefCounted<T>(engine, className);
     engine->RegisterObjectMethod(className, "ShortStringHash get_type() const", asMETHODPR(T, GetType, () const, ShortStringHash), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "ShortStringHash get_type() const", asMETHODPR(T, GetType, () const, ShortStringHash), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "const String& get_typeName() const", asMETHODPR(T, GetTypeName, () const, const String&), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "const String& get_typeName() const", asMETHODPR(T, GetTypeName, () const, const String&), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "const String& get_category() const", asMETHODPR(T, GetCategory, () const, const String&), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "const String& get_category() const", asMETHODPR(T, GetCategory, () const, const String&), asCALL_THISCALL);
-    engine->RegisterObjectMethod(className, "int get_refs() const", asMETHODPR(T, Refs, () const, int), asCALL_THISCALL);
-    engine->RegisterObjectMethod(className, "int get_weakRefs() const", asMETHODPR(T, WeakRefs, () const, int), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void SendEvent(const String&in, VariantMap& eventData = VariantMap())", asFUNCTION(ObjectSendEvent<T>), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "void SendEvent(const String&in, VariantMap& eventData = VariantMap())", asFUNCTION(ObjectSendEvent<T>), asCALL_CDECL_OBJLAST);
     RegisterSubclass<Object, T>(engine, "Object", className);
     RegisterSubclass<Object, T>(engine, "Object", className);
 }
 }

+ 13 - 12
Engine/Script/CoreAPI.cpp

@@ -732,24 +732,24 @@ static const String& GetTypeName(ShortStringHash type)
     return GetScriptContext()->GetTypeName(type);
     return GetScriptContext()->GetTypeName(type);
 }
 }
 
 
-static void ConstructWeakHandle(WeakPtr<Object>* ptr)
+static void ConstructWeakHandle(WeakPtr<RefCounted>* ptr)
 {
 {
-    new(ptr) WeakPtr<Object>();
+    new(ptr) WeakPtr<RefCounted>();
 }
 }
 
 
-static void ConstructWeakHandleCopy(const WeakPtr<Object>& src, WeakPtr<Object>* ptr)
+static void ConstructWeakHandleCopy(const WeakPtr<RefCounted>& src, WeakPtr<RefCounted>* ptr)
 {
 {
-    new(ptr) WeakPtr<Object>(src);
+    new(ptr) WeakPtr<RefCounted>(src);
 }
 }
 
 
-static void ConstructWeakHandlePtr(Object* object, WeakPtr<Object>* ptr)
+static void ConstructWeakHandlePtr(RefCounted* object, WeakPtr<RefCounted>* ptr)
 {
 {
-    new(ptr) WeakPtr<Object>(object);
+    new(ptr) WeakPtr<RefCounted>(object);
 }
 }
 
 
-static void DestructWeakHandle(WeakPtr<Object>* ptr)
+static void DestructWeakHandle(WeakPtr<RefCounted>* ptr)
 {
 {
-    ptr->~WeakPtr<Object>();
+    ptr->~WeakPtr<RefCounted>();
 }
 }
 
 
 void RegisterObject(asIScriptEngine* engine)
 void RegisterObject(asIScriptEngine* engine)
@@ -765,6 +765,7 @@ void RegisterObject(asIScriptEngine* engine)
     engine->RegisterObjectProperty("AttributeInfo", "Variant defaultValue", offsetof(AttributeInfo, defaultValue_));
     engine->RegisterObjectProperty("AttributeInfo", "Variant defaultValue", offsetof(AttributeInfo, defaultValue_));
     engine->RegisterObjectProperty("AttributeInfo", "uint mode", offsetof(AttributeInfo, mode_));
     engine->RegisterObjectProperty("AttributeInfo", "uint mode", offsetof(AttributeInfo, mode_));
 
 
+    RegisterRefCounted<RefCounted>(engine, "RefCounted");
     RegisterObject<Object>(engine, "Object");
     RegisterObject<Object>(engine, "Object");
 
 
     engine->RegisterGlobalFunction("void SendEvent(const String&in, VariantMap& eventData = VariantMap())", asFUNCTION(SendEvent), asCALL_CDECL);
     engine->RegisterGlobalFunction("void SendEvent(const String&in, VariantMap& eventData = VariantMap())", asFUNCTION(SendEvent), asCALL_CDECL);
@@ -778,14 +779,14 @@ void RegisterObject(asIScriptEngine* engine)
     engine->RegisterGlobalFunction("Object@+ GetEventSender()", asFUNCTION(GetEventSender), asCALL_CDECL);
     engine->RegisterGlobalFunction("Object@+ GetEventSender()", asFUNCTION(GetEventSender), asCALL_CDECL);
     engine->RegisterGlobalFunction("const String& GetTypeName(ShortStringHash)", asFUNCTION(GetTypeName), asCALL_CDECL);
     engine->RegisterGlobalFunction("const String& GetTypeName(ShortStringHash)", asFUNCTION(GetTypeName), asCALL_CDECL);
 
 
-    engine->RegisterObjectType("WeakHandle", sizeof(WeakPtr<Object>), asOBJ_VALUE | asOBJ_APP_CLASS_CDAK);
+    engine->RegisterObjectType("WeakHandle", sizeof(WeakPtr<RefCounted>), asOBJ_VALUE | asOBJ_APP_CLASS_CDAK);
     engine->RegisterObjectBehaviour("WeakHandle", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructWeakHandle), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("WeakHandle", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructWeakHandle), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("WeakHandle", asBEHAVE_CONSTRUCT, "void f(const WeakHandle&in)", asFUNCTION(ConstructWeakHandleCopy), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("WeakHandle", asBEHAVE_CONSTRUCT, "void f(const WeakHandle&in)", asFUNCTION(ConstructWeakHandleCopy), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectBehaviour("WeakHandle", asBEHAVE_CONSTRUCT, "void f(Object@+)", asFUNCTION(ConstructWeakHandlePtr), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("WeakHandle", asBEHAVE_CONSTRUCT, "void f(RefCounted@+)", asFUNCTION(ConstructWeakHandlePtr), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("WeakHandle", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructWeakHandle), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("WeakHandle", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructWeakHandle), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("WeakHandle", "WeakHandle& opAssign(const WeakHandle&in)", asMETHODPR(WeakPtr<Object>, operator =, (const WeakPtr<Object>&), WeakPtr<Object>&), asCALL_THISCALL);
     engine->RegisterObjectMethod("WeakHandle", "WeakHandle& opAssign(const WeakHandle&in)", asMETHODPR(WeakPtr<Object>, operator =, (const WeakPtr<Object>&), WeakPtr<Object>&), asCALL_THISCALL);
-    engine->RegisterObjectMethod("WeakHandle", "WeakHandle& opAssign(Object@+)", asMETHODPR(WeakPtr<Object>, operator =, (Object*), WeakPtr<Object>&), asCALL_THISCALL);
-    engine->RegisterObjectMethod("WeakHandle", "Object@+ Get() const", asMETHODPR(WeakPtr<Object>, Get, () const, Object*), asCALL_THISCALL);
+    engine->RegisterObjectMethod("WeakHandle", "WeakHandle& opAssign(RefCounted@+)", asMETHODPR(WeakPtr<Object>, operator =, (Object*), WeakPtr<Object>&), asCALL_THISCALL);
+    engine->RegisterObjectMethod("WeakHandle", "RefCounted@+ Get() const", asMETHODPR(WeakPtr<Object>, Get, () const, Object*), asCALL_THISCALL);
     engine->RegisterObjectMethod("WeakHandle", "int get_refs() const", asMETHOD(WeakPtr<Object>, Refs), asCALL_THISCALL);
     engine->RegisterObjectMethod("WeakHandle", "int get_refs() const", asMETHOD(WeakPtr<Object>, Refs), asCALL_THISCALL);
     engine->RegisterObjectMethod("WeakHandle", "int get_weakRefs() const", asMETHOD(WeakPtr<Object>, WeakRefs), asCALL_THISCALL);
     engine->RegisterObjectMethod("WeakHandle", "int get_weakRefs() const", asMETHOD(WeakPtr<Object>, WeakRefs), asCALL_THISCALL);
     engine->RegisterObjectMethod("WeakHandle", "bool get_expired() const", asMETHOD(WeakPtr<Object>, Expired), asCALL_THISCALL);
     engine->RegisterObjectMethod("WeakHandle", "bool get_expired() const", asMETHOD(WeakPtr<Object>, Expired), asCALL_THISCALL);

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