Browse Source

Improve serialization of ScriptInstance (#2156)

* Added serialization of Array<String> and Array<Variant> attributes of ScriptInstance.

* Fix error in load content of Array<String> and Array<Vector> attributes in deserealization.
Add metod Swap in Array<T> script object for swap content of two arrays for avoid copy.

* Changes by code review.

* Fix error in deserialize String[] and Vector[] attributes of ScriptInstance in background scene loading.
orefkov 8 years ago
parent
commit
187a353d6b

+ 11 - 0
Source/Urho3D/AngelScript/Addons.cpp

@@ -1112,6 +1112,16 @@ int CScriptArray::FindByRef(asUINT startAt, void *ref) const
     return -1;
 }
 
+bool CScriptArray::Swap(CScriptArray& other)
+{
+    if (other.GetArrayObjectType() == GetArrayObjectType())
+    {
+        Urho3D::Swap(buffer, other.buffer);
+        return true;
+    }
+    return false;
+}
+
 int CScriptArray::Find(void *value) const
 {
     return Find(0, value);
@@ -1647,6 +1657,7 @@ void RegisterArray(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Array<T>", "int Find(uint, const T&in) const", asMETHODPR(CScriptArray, Find, (asUINT, void*) const, int), asCALL_THISCALL);
     engine->RegisterObjectMethod("Array<T>", "int FindByRef(const T&in) const", asMETHODPR(CScriptArray, FindByRef, (void*) const, int), asCALL_THISCALL);
     engine->RegisterObjectMethod("Array<T>", "int FindByRef(uint, const T&in) const", asMETHODPR(CScriptArray, FindByRef, (asUINT, void*) const, int), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Array<T>", "bool Swap(Array<T>&in)", asMETHOD(CScriptArray, Swap), asCALL_THISCALL);
     engine->RegisterObjectMethod("Array<T>", "bool opEquals(const Array<T>&in) const", asMETHOD(CScriptArray, operator==), asCALL_THISCALL);
     engine->RegisterObjectMethod("Array<T>", "uint get_length() const", asMETHOD(CScriptArray, GetSize), asCALL_THISCALL);
     engine->RegisterObjectMethod("Array<T>", "void set_length(uint)", asMETHODPR(CScriptArray, Resize, (asUINT), void), asCALL_THISCALL);

+ 2 - 0
Source/Urho3D/AngelScript/Addons.h

@@ -106,6 +106,8 @@ public:
     int  Find(asUINT startAt, void *value) const;
     int  FindByRef(void *ref) const;
     int  FindByRef(asUINT startAt, void *ref) const;
+    // Swap content of two arrays for avoid copy
+    bool Swap(CScriptArray& other);
 
     // GC methods
     int  GetRefCount();

+ 42 - 1
Source/Urho3D/AngelScript/ScriptInstance.cpp

@@ -25,6 +25,8 @@
 #include "../AngelScript/Script.h"
 #include "../AngelScript/ScriptFile.h"
 #include "../AngelScript/ScriptInstance.h"
+#include "../AngelScript/Addons.h"
+#include "../AngelScript/APITemplates.h"
 #include "../Core/Context.h"
 #include "../Core/Profiler.h"
 #include "../IO/Log.h"
@@ -119,6 +121,30 @@ void ScriptInstance::OnSetAttribute(const AttributeInfo& attr, const Variant& sr
         if (resourcePtr)
             resourcePtr->AddRef();
     }
+    else if (attr.type_ == VAR_VARIANTVECTOR && attr.ptr_)
+    {
+        CScriptArray* arr = reinterpret_cast<CScriptArray*>(attr.ptr_);
+        if (arr)
+        {
+            Vector<Variant> vector = src.GetVariantVector();
+            unsigned size = vector.Size();
+            arr->Resize(size);
+            for (unsigned i = 0; i < size; i++)
+                *(static_cast<Variant*>(arr->At(i))) = vector[i];
+        }
+    }
+    else if (attr.type_ == VAR_STRINGVECTOR && attr.ptr_)
+    {
+        CScriptArray* arr = reinterpret_cast<CScriptArray*>(attr.ptr_);
+        if (arr)
+        {
+            Vector<String> vector = src.GetStringVector();
+            unsigned size = vector.Size();
+            arr->Resize(size);
+            for (unsigned i = 0; i < size; i++)
+                *(static_cast<String*>(arr->At(i))) = vector[i];
+        }
+    }
     else
         Serializable::OnSetAttribute(attr, src);
 }
@@ -154,7 +180,18 @@ void ScriptInstance::OnGetAttribute(const AttributeInfo& attr, Variant& dest) co
         // If resource is non-null get its type and name hash. Otherwise get type from the default value
         dest = GetResourceRef(resource, attr.defaultValue_.GetResourceRef().type_);
     }
-    else
+    else if (attr.type_ == VAR_VARIANTVECTOR && attr.ptr_)
+    {
+        CScriptArray* arr = reinterpret_cast<CScriptArray*>(attr.ptr_);
+        if (arr)
+            dest = ArrayToVector<Variant>(arr);
+    }
+    else if (attr.type_ == VAR_STRINGVECTOR && attr.ptr_)
+    {
+        CScriptArray* arr = reinterpret_cast<CScriptArray*>(attr.ptr_);
+        if (arr)
+            dest = ArrayToVector<String>(arr);
+    } else
         Serializable::OnGetAttribute(attr, dest);
 }
 
@@ -642,6 +679,10 @@ void ScriptInstance::GetScriptAttributes()
                 break;
 
             default:
+                if (typeName == "Variant[]")
+                    typeName = "VariantVector";
+                else if (typeName == "String[]")
+                    typeName = "StringVector";
                 info.type_ = Variant::GetTypeFromName(typeName);
                 break;
             }