瀏覽代碼

Added new Print() variant in script API to print a Variant. Fixed StringUtils from erroneously converting numerical string to int/uint using base 8 or base 16 when the string is started with '0' or '0x'. Fixed the same/diff value evaluation for ResourceRefList, VariantVector, and VariantMap.

Wei Tjong Yao 12 年之前
父節點
當前提交
44d663ba41
共有 4 個文件被更改,包括 105 次插入41 次删除
  1. 88 33
      Bin/Data/Scripts/Editor/AttributeEditor.as
  2. 1 0
      Docs/ScriptAPI.dox
  3. 9 8
      Engine/Core/StringUtils.cpp
  4. 7 0
      Engine/Engine/IOAPI.cpp

+ 88 - 33
Bin/Data/Scripts/Editor/AttributeEditor.as

@@ -358,7 +358,7 @@ void LoadAttributeEditor(ListView@ list, Array<Serializable@>@ serializables, bo
     inLoadAttributeEditor = false;
     inLoadAttributeEditor = false;
 }
 }
 
 
-void LoadAttributeEditor(UIElement@ parent, Variant value, VariantType type, Array<String>@ enumNames, Variant defaultValue, bool editable, bool sameValue, Array<Variant> values)
+void LoadAttributeEditor(UIElement@ parent, Variant value, VariantType type, Array<String>@ enumNames, Variant defaultValue, bool editable, bool sameValue, const Array<Variant>&in values)
 {
 {
     uint index = parent.vars["Index"].GetUInt();
     uint index = parent.vars["Index"].GetUInt();
 
 
@@ -402,19 +402,51 @@ void LoadAttributeEditor(UIElement@ parent, Variant value, VariantType type, Arr
             parent = GetAttributeEditorParent(list, index, subIndex);
             parent = GetAttributeEditorParent(list, index, subIndex);
             if (parent is null)
             if (parent is null)
                 break;
                 break;
-            SetEditable(SetValue(parent.children[1].children[0], cache.GetResourceName(refList.ids[subIndex]), sameValue), editable && sameValue);
+            
+            StringHash firstID = refList.ids[subIndex];
+            bool idSameValue = true;
+            if (!sameValue)
+            {
+                // Reevaluate each ID in the list
+                for (uint i = 0; i < values.length; ++i)
+                {
+                    ResourceRefList refList = values[i].GetResourceRefList();
+                    if (subIndex >= refList.length || refList.ids[subIndex] != firstID)
+                    {
+                        idSameValue = false;
+                        break;
+                    }
+                }
+            }
+            SetEditable(SetValue(parent.children[1].children[0], cache.GetResourceName(firstID), sameValue || idSameValue), editable && (sameValue || idSameValue));
         }
         }
     }
     }
     else if (type == VAR_VARIANTVECTOR)
     else if (type == VAR_VARIANTVECTOR)
     {
     {
         UIElement@ list = parent.parent;
         UIElement@ list = parent.parent;
         Array<Variant>@ vector = value.GetVariantVector();
         Array<Variant>@ vector = value.GetVariantVector();
-        for (uint i = 0; i < vector.length; ++i)
+        for (uint subIndex = 0; subIndex < vector.length; ++subIndex)
         {
         {
-            parent = GetAttributeEditorParent(list, index, i);
+            parent = GetAttributeEditorParent(list, index, subIndex);
             if (parent is null)
             if (parent is null)
                 break;
                 break;
-            LoadAttributeEditor(parent, vector[i], vector[i].type, null, Variant(), editable, sameValue, values);
+            
+            Variant firstValue = vector[subIndex];
+            bool varSameValue = true;
+            if (!sameValue)
+            {
+                // Reevaluate aach variant in the vector
+                for (uint i = 0; i < values.length; ++i)
+                {
+                    Array<Variant>@ vector = values[i].GetVariantVector();
+                    if (subIndex >= vector.length || vector[subIndex] != firstValue)
+                    {
+                        varSameValue = false;
+                        break;
+                    }
+                }
+            }
+            LoadAttributeEditor(parent, firstValue, firstValue.type, null, Variant(), editable, sameValue || varSameValue, values);
         }
         }
     }
     }
     else if (type == VAR_VARIANTMAP)
     else if (type == VAR_VARIANTMAP)
@@ -422,13 +454,28 @@ void LoadAttributeEditor(UIElement@ parent, Variant value, VariantType type, Arr
         UIElement@ list = parent.parent;
         UIElement@ list = parent.parent;
         VariantMap map = value.GetVariantMap();
         VariantMap map = value.GetVariantMap();
         Array<ShortStringHash>@ keys = map.keys;
         Array<ShortStringHash>@ keys = map.keys;
-        for (uint i = 0; i < keys.length; ++i)
+        for (uint subIndex = 0; subIndex < keys.length; ++subIndex)
         {
         {
-            parent = GetAttributeEditorParent(list, index, i);
+            parent = GetAttributeEditorParent(list, index, subIndex);
             if (parent is null)
             if (parent is null)
                 break;
                 break;
-            Variant value = map[keys[i]];
-            LoadAttributeEditor(parent, value, value.type, null, Variant(), editable, sameValue, values);
+            
+            Variant firstValue = map[keys[subIndex]];
+            bool varSameValue = true;
+            if (!sameValue)
+            {
+                // Reevaluate each variant in the map
+                for (uint i = 0; i < values.length; ++i)
+                {
+                    VariantMap map = values[i].GetVariantMap();
+                    if (!map.Contains(keys[subIndex]) || map[keys[subIndex]] != firstValue)
+                    {
+                        varSameValue = false;
+                        break;
+                    }
+                }
+            }
+            LoadAttributeEditor(parent, firstValue, firstValue.type, null, Variant(), editable, sameValue || varSameValue, values);
         }
         }
     }
     }
     else
     else
@@ -446,17 +493,21 @@ void LoadAttributeEditor(UIElement@ parent, Variant value, VariantType type, Arr
         }
         }
         for (uint i = 0; i < coordinates[0].length; ++i)
         for (uint i = 0; i < coordinates[0].length; ++i)
         {
         {
-            sameValue = true;
             String value = coordinates[0][i];
             String value = coordinates[0][i];
-            for (uint j = 1; j < coordinates.length; ++j)
+            bool coordinateSameValue = true;
+            if (!sameValue)
             {
             {
-                if (coordinates[j][i] != value)
+                // Reevaluate each coordinate
+                for (uint j = 1; j < coordinates.length; ++j)
                 {
                 {
-                    sameValue = false;
-                    break;
+                    if (coordinates[j][i] != value)
+                    {
+                        coordinateSameValue = false;
+                        break;
+                    }
                 }
                 }
             }
             }
-            SetEditable(SetValue(parent.children[i + 1], value, sameValue), editable && sameValue);
+            SetEditable(SetValue(parent.children[i + 1], value, sameValue || coordinateSameValue), editable && (sameValue || coordinateSameValue));
         }
         }
     }
     }
 }
 }
@@ -490,12 +541,13 @@ void StoreAttributeEditor(UIElement@ parent, Array<Serializable@>@ serializables
     }
     }
     else if (info.type == VAR_VARIANTMAP)
     else if (info.type == VAR_VARIANTMAP)
     {
     {
+        VariantMap map = serializables[0].attributes[index].GetVariantMap();
+        ShortStringHash key(parent.vars["Key"].GetUInt());
+        Variant[] values(1);
+        GetEditorValue(parent, map[key].type, null, coordinate, values);
         for (uint i = 0; i < serializables.length; ++i)
         for (uint i = 0; i < serializables.length; ++i)
         {
         {
-            VariantMap map = serializables[0].attributes[index].GetVariantMap();
-            ShortStringHash key(parent.vars["Key"].GetUInt());
-            Variant[] values(1);
-            GetEditorValue(parent, map[key].type, null, coordinate, values);
+            VariantMap map = serializables[i].attributes[index].GetVariantMap();
             map[key] = values[0];
             map[key] = values[0];
             serializables[i].attributes[index] = Variant(map);
             serializables[i].attributes[index] = Variant(map);
         }
         }
@@ -511,12 +563,21 @@ void StoreAttributeEditor(UIElement@ parent, Array<Serializable@>@ serializables
     }
     }
 }
 }
 
 
-void FillValue(Array<Variant>&inout values, Variant value)
+void FillValue(Array<Variant>& values, Variant value)
 {
 {
     for (uint i = 0; i < values.length; ++i)
     for (uint i = 0; i < values.length; ++i)
         values[i] = value;
         values[i] = value;
 }
 }
-void GetEditorValue(UIElement@ parent, VariantType type, Array<String>@ enumNames, uint coordinate, Array<Variant>&inout values)
+
+void SanitizeNumericalValue(VariantType type, String& value)
+{
+    if (type >= VAR_FLOAT && type <= VAR_COLOR)
+        value = String(value.ToFloat());
+    else if (type == VAR_INT || type == VAR_INTRECT || type == VAR_INTVECTOR2)
+        value = String(value.ToInt());
+}
+
+void GetEditorValue(UIElement@ parent, VariantType type, Array<String>@ enumNames, uint coordinate, Array<Variant>& values)
 {
 {
     LineEdit@ attrEdit = parent.children[coordinate + 1];
     LineEdit@ attrEdit = parent.children[coordinate + 1];
     if (type == VAR_STRING)
     if (type == VAR_STRING)
@@ -530,22 +591,14 @@ void GetEditorValue(UIElement@ parent, VariantType type, Array<String>@ enumName
         FillValue(values, Variant(attrEdit.text.ToFloat()));
         FillValue(values, Variant(attrEdit.text.ToFloat()));
     else if (type == VAR_QUATERNION)
     else if (type == VAR_QUATERNION)
     {
     {
+        float value = attrEdit.text.ToFloat();
         for (uint i = 0; i < values.length; ++i)
         for (uint i = 0; i < values.length; ++i)
         {
         {
             float[] data = values[i].GetQuaternion().eulerAngles.data;
             float[] data = values[i].GetQuaternion().eulerAngles.data;
-            data[coordinate] = attrEdit.text.ToFloat();
+            data[coordinate] = value;
             values[i] = Quaternion(Vector3(data));
             values[i] = Quaternion(Vector3(data));
         }
         }
     }
     }
-    else if (type >= VAR_VECTOR2 && type <= VAR_COLOR)
-    {
-        for (uint i = 0; i < values.length; ++i)
-        {
-            String[] data = values[i].ToString().Split(' ');
-            data[coordinate] = String(attrEdit.text.ToFloat());
-            values[i] = Variant(type, Join(data, " "));
-        }
-    }
     else if (type == VAR_INT)
     else if (type == VAR_INT)
     {
     {
         if (enumNames is null || enumNames.empty)
         if (enumNames is null || enumNames.empty)
@@ -564,12 +617,14 @@ void GetEditorValue(UIElement@ parent, VariantType type, Array<String>@ enumName
         ref.type = ShortStringHash(attrEdit.vars["Type"].GetUInt());
         ref.type = ShortStringHash(attrEdit.vars["Type"].GetUInt());
         FillValue(values, Variant(ref));
         FillValue(values, Variant(ref));
     }
     }
-    else if (type == VAR_INTVECTOR2 || type == VAR_INTRECT)
+    else
     {
     {
+        String value = attrEdit.text;
+        SanitizeNumericalValue(type, value);
         for (uint i = 0; i < values.length; ++i)
         for (uint i = 0; i < values.length; ++i)
         {
         {
             String[] data = values[i].ToString().Split(' ');
             String[] data = values[i].ToString().Split(' ');
-            data[coordinate] = String(attrEdit.text.ToInt());
+            data[coordinate] = value;
             values[i] = Variant(type, Join(data, " "));
             values[i] = Variant(type, Join(data, " "));
         }
         }
     }
     }

+ 1 - 0
Docs/ScriptAPI.dox

@@ -53,6 +53,7 @@ namespace Urho3D
 - void Print(uint, bool arg1 = false)
 - void Print(uint, bool arg1 = false)
 - void Print(float, bool arg1 = false)
 - void Print(float, bool arg1 = false)
 - void Print(bool, bool arg1 = false)
 - void Print(bool, bool arg1 = false)
+- void Print(Variant, bool arg1 = false)
 - String GetPath(const String&)
 - String GetPath(const String&)
 - String GetFileName(const String&)
 - String GetFileName(const String&)
 - String GetExtension(const String&)
 - String GetExtension(const String&)

+ 9 - 8
Engine/Core/StringUtils.cpp

@@ -113,7 +113,8 @@ int ToInt(const char* source)
     if (!source)
     if (!source)
         return 0;
         return 0;
     
     
-    return strtol(source, 0, 0);
+    // Explicitly ask for base 10 to prevent source starts with '0' or '0x' from being converted to base 8 or base 16, respectively
+    return strtol(source, 0, 10);
 }
 }
 
 
 unsigned ToUInt(const String& source)
 unsigned ToUInt(const String& source)
@@ -126,7 +127,7 @@ unsigned ToUInt(const char* source)
     if (!source)
     if (!source)
         return 0;
         return 0;
     
     
-    return strtoul(source, 0, 0);
+    return strtoul(source, 0, 10);
 }
 }
 
 
 float ToFloat(const String& source)
 float ToFloat(const String& source)
@@ -179,10 +180,10 @@ IntRect ToIntRect(const char* source)
         return ret;
         return ret;
     
     
     char* ptr = (char*)source;
     char* ptr = (char*)source;
-    ret.left_ = strtol(ptr, &ptr, 0);
-    ret.top_ = strtol(ptr, &ptr, 0);
-    ret.right_ = strtol(ptr, &ptr, 0);
-    ret.bottom_ = strtol(ptr, &ptr, 0);
+    ret.left_ = strtol(ptr, &ptr, 10);
+    ret.top_ = strtol(ptr, &ptr, 10);
+    ret.right_ = strtol(ptr, &ptr, 10);
+    ret.bottom_ = strtol(ptr, &ptr, 10);
     
     
     return ret;
     return ret;
 }
 }
@@ -201,8 +202,8 @@ IntVector2 ToIntVector2(const char* source)
         return ret;
         return ret;
     
     
     char* ptr = (char*)source;
     char* ptr = (char*)source;
-    ret.x_ = strtol(ptr, &ptr, 0);
-    ret.y_ = strtol(ptr, &ptr, 0);
+    ret.x_ = strtol(ptr, &ptr, 10);
+    ret.y_ = strtol(ptr, &ptr, 10);
     
     
     return ret;
     return ret;
 }
 }

+ 7 - 0
Engine/Engine/IOAPI.cpp

@@ -71,6 +71,11 @@ static void Print(bool value, bool error)
     Log::WriteRaw(String(value) + "\n", error);
     Log::WriteRaw(String(value) + "\n", error);
 }
 }
 
 
+static void Print(Variant value, bool error)
+{
+    Log::WriteRaw(value.ToString() + "\n", error);
+}
+
 static void LogWrite(const String& str, bool error, Log* ptr)
 static void LogWrite(const String& str, bool error, Log* ptr)
 {
 {
     Log::WriteRaw(str + "\n", error);
     Log::WriteRaw(str + "\n", error);
@@ -103,6 +108,7 @@ static void Print(int value, bool error) {}
 static void Print(unsigned value, bool error) {}
 static void Print(unsigned value, bool error) {}
 static void Print(float value, bool error) {}
 static void Print(float value, bool error) {}
 static void Print(bool value, bool error) {}
 static void Print(bool value, bool error) {}
+static void Print(Variant value, bool error) {}
 static void LogWrite(const String& str, bool error, Log* ptr) {}
 static void LogWrite(const String& str, bool error, Log* ptr) {}
 static void LogDebug(const String& str, Log* ptr) {}
 static void LogDebug(const String& str, Log* ptr) {}
 static void LogInfo(const String& str, Log* ptr) {}
 static void LogInfo(const String& str, Log* ptr) {}
@@ -140,6 +146,7 @@ static void RegisterLog(asIScriptEngine* engine)
     engine->RegisterGlobalFunction("void Print(uint, bool error = false)", asFUNCTIONPR(Print, (unsigned, bool), void), asCALL_CDECL);
     engine->RegisterGlobalFunction("void Print(uint, bool error = false)", asFUNCTIONPR(Print, (unsigned, bool), void), asCALL_CDECL);
     engine->RegisterGlobalFunction("void Print(float, bool error = false)", asFUNCTIONPR(Print, (float, bool), void), asCALL_CDECL);
     engine->RegisterGlobalFunction("void Print(float, bool error = false)", asFUNCTIONPR(Print, (float, bool), void), asCALL_CDECL);
     engine->RegisterGlobalFunction("void Print(bool, bool error = false)", asFUNCTIONPR(Print, (bool, bool), void), asCALL_CDECL);
     engine->RegisterGlobalFunction("void Print(bool, bool error = false)", asFUNCTIONPR(Print, (bool, bool), void), asCALL_CDECL);
+    engine->RegisterGlobalFunction("void Print(Variant, bool error = false)", asFUNCTIONPR(Print, (Variant, bool), void), asCALL_CDECL);
 }
 }
 
 
 static File* ConstructFile()
 static File* ConstructFile()