Browse Source

Dictionary serialization works

Marko Pintera 11 years ago
parent
commit
5dfcb3a403

+ 3 - 1
GameObjectSerialization.txt

@@ -5,7 +5,9 @@ TODO
  ---------------------------------------
 
 IMMEDIATE:
-Implement TODO ScriptSerializableList.cpp & ScriptSerializableDictionary.cpp methods
+In some places (especially list and dict) I do: if(mono_class_is_valuetype(mono_object_get_class(obj))).
+This will return true for strings, which don't work as intended when unboxed (or at least don't show consistent behaviour with other types)
+
 setValue in ScriptSerializableObject & ScriptSerializableArray should check if value is null and if the field type isn't a value type (can't be null)
 
 LOW PRIORITY

+ 1 - 0
MBansheeEngine/DbgComponent.cs

@@ -13,5 +13,6 @@ namespace BansheeEngine
         public SceneObject otherSO;
         public int[][][] zeArray;
         public List<DbgSerzObj> zeList;
+        public Dictionary<string, int> zeDict;
     }
 }

+ 13 - 2
MBansheeEngine/Program.cs

@@ -24,6 +24,7 @@ namespace BansheeEngine
             dbgComponent.otherSO = otherSO;
             dbgComponent.zeArray = new int[5][][];
             dbgComponent.zeList = new List<DbgSerzObj>();
+            dbgComponent.zeDict = new Dictionary<string, int>();
 
             dbgComponent.zeList.Add(new DbgSerzObj());
             dbgComponent.zeList.Add(new DbgSerzObj());
@@ -32,6 +33,16 @@ namespace BansheeEngine
 
             dbgComponent.zeList[2].someValue = 101;
 
+            dbgComponent.zeDict["supSup"] = 10001;
+            dbgComponent.zeDict["lolz"] = 696969;
+
+            var enumerator = dbgComponent.zeDict.GetEnumerator();
+            int all = 0;
+            while (enumerator.MoveNext())
+            {
+                all += enumerator.Current.Value;
+            }
+
             for (int i = 0; i < dbgComponent.zeArray.Length; i++)
             {
                 dbgComponent.zeArray[i] = new int[6][];
@@ -47,7 +58,7 @@ namespace BansheeEngine
             for (int i = 0; i < so.GetNumChildren(); i++)
             {
                 SceneObject childSO = so.GetChild(i);
-                reportDbgValue(childSO.GetComponent<DbgComponent>().zeList[2].someValue, childSO.GetComponent<DbgComponent>().zeArray[4][1][3], typeof(DbgComponent));
+                reportDbgValue(childSO.GetComponent<DbgComponent>().zeDict["lolz"], childSO.GetComponent<DbgComponent>().zeList[2].someValue, childSO.GetComponent<DbgComponent>().zeArray[4][1][3], typeof(DbgComponent));
             }
 
             //Color newColor = Color.red;
@@ -61,6 +72,6 @@ namespace BansheeEngine
         private static extern void dbgTestComponentClone(SceneObject so);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void reportDbgValue(int dbgVal, int dbgVal2, Type type);
+        private static extern void reportDbgValue(int dbgVal, int dbgVal2, int dbgVal3, Type type);
     }
 }

+ 4 - 4
SBansheeEngine/Include/BsScriptSerializableDictionaryRTTI.h

@@ -21,10 +21,10 @@ namespace BansheeEngine
 		CM::UINT32 getNumKeyEntries(ScriptSerializableDictionary* obj) { return (CM::UINT32)obj->mKeyEntries.size(); }
 		void setNumKeyEntries(ScriptSerializableDictionary* obj, CM::UINT32 numEntries) { obj->mKeyEntries.resize(numEntries); }
 
-		ScriptSerializableFieldDataPtr getValueEntry(ScriptSerializableDictionary* obj, CM::UINT32 arrayIdx) { return obj->mKeyEntries[arrayIdx]; }
-		void setValueEntry(ScriptSerializableDictionary* obj, CM::UINT32 arrayIdx, ScriptSerializableFieldDataPtr val) { obj->mKeyEntries[arrayIdx] = val; }
-		CM::UINT32 getNumValueEntries(ScriptSerializableDictionary* obj) { return (CM::UINT32)obj->mKeyEntries.size(); }
-		void setNumValueEntries(ScriptSerializableDictionary* obj, CM::UINT32 numEntries) { obj->mKeyEntries.resize(numEntries); }
+		ScriptSerializableFieldDataPtr getValueEntry(ScriptSerializableDictionary* obj, CM::UINT32 arrayIdx) { return obj->mValueEntries[arrayIdx]; }
+		void setValueEntry(ScriptSerializableDictionary* obj, CM::UINT32 arrayIdx, ScriptSerializableFieldDataPtr val) { obj->mValueEntries[arrayIdx] = val; }
+		CM::UINT32 getNumValueEntries(ScriptSerializableDictionary* obj) { return (CM::UINT32)obj->mValueEntries.size(); }
+		void setNumValueEntries(ScriptSerializableDictionary* obj, CM::UINT32 numEntries) { obj->mValueEntries.resize(numEntries); }
 
 	public:
 		ScriptSerializableDictionaryRTTI()

+ 0 - 20
SBansheeEngine/Include/BsScriptSerializableField.h

@@ -29,7 +29,6 @@ namespace BansheeEngine
 	public:
 		static ScriptSerializableFieldDataPtr create(const ScriptSerializableTypeInfoPtr& typeInfo, void* value);
 		virtual void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo) = 0;
-		virtual bool isValueType() const = 0;
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -65,7 +64,6 @@ namespace BansheeEngine
 		bool value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return true; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -83,7 +81,6 @@ namespace BansheeEngine
 		wchar_t value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return true; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -101,7 +98,6 @@ namespace BansheeEngine
 		CM::INT8 value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return true; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -119,7 +115,6 @@ namespace BansheeEngine
 		CM::UINT8 value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return true; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -137,7 +132,6 @@ namespace BansheeEngine
 		CM::INT16 value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return true; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -155,7 +149,6 @@ namespace BansheeEngine
 		CM::UINT16 value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return true; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -173,7 +166,6 @@ namespace BansheeEngine
 		CM::INT32 value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return true; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -191,7 +183,6 @@ namespace BansheeEngine
 		CM::UINT32 value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return true; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -209,7 +200,6 @@ namespace BansheeEngine
 		CM::INT64 value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return true; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -227,7 +217,6 @@ namespace BansheeEngine
 		CM::UINT64 value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return true; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -245,7 +234,6 @@ namespace BansheeEngine
 		float value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return true; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -264,7 +252,6 @@ namespace BansheeEngine
 		double value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return true; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -282,7 +269,6 @@ namespace BansheeEngine
 		CM::WString value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return false; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -300,7 +286,6 @@ namespace BansheeEngine
 		CM::HResource value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return false; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -318,7 +303,6 @@ namespace BansheeEngine
 		CM::HGameObject value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return false; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -336,7 +320,6 @@ namespace BansheeEngine
 		ScriptSerializableObjectPtr value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return false; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -354,7 +337,6 @@ namespace BansheeEngine
 		ScriptSerializableArrayPtr value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return false; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -372,7 +354,6 @@ namespace BansheeEngine
 		ScriptSerializableListPtr value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return false; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -390,7 +371,6 @@ namespace BansheeEngine
 		ScriptSerializableDictionaryPtr value;
 
 		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
-		bool isValueType() const { return false; }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/

+ 6 - 0
SBansheeEngine/Include/BsScriptSerializableObjectInfo.h

@@ -40,6 +40,7 @@ namespace BansheeEngine
 
 		virtual bool matches(const ScriptSerializableTypeInfoPtr& typeInfo) const = 0;
 		virtual bool isTypeLoaded() const = 0;
+		virtual bool isMonoObject() const = 0;
 		virtual ::MonoClass* getMonoClass() const = 0;
 
 		/************************************************************************/
@@ -58,6 +59,7 @@ namespace BansheeEngine
 
 		bool matches(const ScriptSerializableTypeInfoPtr& typeInfo) const;
 		bool isTypeLoaded() const;
+		bool isMonoObject() const;
 		::MonoClass* getMonoClass() const;
 
 		/************************************************************************/
@@ -78,6 +80,7 @@ namespace BansheeEngine
 
 		bool matches(const ScriptSerializableTypeInfoPtr& typeInfo) const;
 		bool isTypeLoaded() const;
+		bool isMonoObject() const { return true; }
 		::MonoClass* getMonoClass() const;
 
 		/************************************************************************/
@@ -97,6 +100,7 @@ namespace BansheeEngine
 
 		bool matches(const ScriptSerializableTypeInfoPtr& typeInfo) const;
 		bool isTypeLoaded() const;
+		bool isMonoObject() const { return true; }
 		::MonoClass* getMonoClass() const;
 
 		/************************************************************************/
@@ -115,6 +119,7 @@ namespace BansheeEngine
 
 		bool matches(const ScriptSerializableTypeInfoPtr& typeInfo) const;
 		bool isTypeLoaded() const;
+		bool isMonoObject() const { return true; }
 		::MonoClass* getMonoClass() const;
 
 		/************************************************************************/
@@ -134,6 +139,7 @@ namespace BansheeEngine
 
 		bool matches(const ScriptSerializableTypeInfoPtr& typeInfo) const;
 		bool isTypeLoaded() const;
+		bool isMonoObject() const { return true; }
 		::MonoClass* getMonoClass() const;
 
 		/************************************************************************/

+ 9 - 2
SBansheeEngine/Source/BsRuntimeScriptObjects.cpp

@@ -6,6 +6,7 @@
 #include "BsMonoAssembly.h"
 #include "BsMonoClass.h"
 #include "BsMonoField.h"
+#include "BsMonoMethod.h"
 #include "BsMonoProperty.h"
 #include "BsMonoUtil.h"
 #include "CmRTTIType.h"
@@ -301,8 +302,14 @@ namespace BansheeEngine
 			{
 				std::shared_ptr<ScriptSerializableTypeInfoDictionary> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoDictionary>();
 
-				MonoProperty& keyProperty = monoClass->getProperty("Key");
-				MonoProperty& valueProperty = monoClass->getProperty("Value");
+				MonoMethod& getEnumerator = monoClass->getMethod("GetEnumerator");
+				MonoClass* enumClass = getEnumerator.getReturnType();
+
+				MonoProperty& currentProp = enumClass->getProperty("Current");
+				MonoClass* keyValuePair = currentProp.getReturnType();
+
+				MonoProperty& keyProperty = keyValuePair->getProperty("Key");
+				MonoProperty& valueProperty = keyValuePair->getProperty("Value");
 
 				MonoClass* keyClass = keyProperty.getReturnType();
 				if(keyClass != nullptr)

+ 1 - 1
SBansheeEngine/Source/BsScriptEnginePlugin.cpp

@@ -23,7 +23,7 @@ namespace BansheeEngine
 		cloneSO->setParent(SO);
 	}
 
-	void reportDbgValue(int dbgValue, int dbgValue2, MonoReflectionType* type)
+	void reportDbgValue(int dbgValue, int dbgValue2, int dbgValue3, MonoReflectionType* type)
 	{
 		::MonoClass* monoClass = mono_type_get_class(mono_reflection_type_get_type(type));
 

+ 1 - 1
SBansheeEngine/Source/BsScriptSerializableArray.cpp

@@ -89,7 +89,7 @@ namespace BansheeEngine
 
 	void ScriptSerializableArray::setFieldData(CM::UINT32 arrayIdx, const ScriptSerializableFieldDataPtr& val)
 	{
-		if(val->isValueType())
+		if(!mArrayTypeInfo->mElementType->isMonoObject())
 			setValue(arrayIdx, val->getValue(mArrayTypeInfo->mElementType));
 		else
 		{

+ 9 - 3
SBansheeEngine/Source/BsScriptSerializableDictionary.cpp

@@ -37,9 +37,15 @@ namespace BansheeEngine
 
 	bool ScriptSerializableDictionary::Enumerator::moveNext()
 	{
-		mCurrent = mParent->mEnumMoveNext->invoke(mInstance, nullptr);
+		MonoObject* returnVal = mParent->mEnumMoveNext->invoke(mInstance, nullptr);
+		bool isValid = *(bool*)mono_object_unbox(returnVal);
 
-		return mCurrent != nullptr;
+		if(isValid)
+			mCurrent = (MonoObject*)mono_object_unbox(mParent->mEnumCurrentProp->get(mInstance));
+		else
+			mCurrent = nullptr;
+
+		return isValid;
 	}
 
 	ScriptSerializableDictionary::ScriptSerializableDictionary(const ConstructPrivately& dummy)
@@ -127,7 +133,7 @@ namespace BansheeEngine
 
 	ScriptSerializableDictionary::Enumerator ScriptSerializableDictionary::getEnumerator() const
 	{
-		return Enumerator(mGetEnumerator->invoke(mManagedInstance, nullptr), this);
+		return Enumerator((MonoObject*)mono_object_unbox(mGetEnumerator->invoke(mManagedInstance, nullptr)), this);
 	}
 
 	void ScriptSerializableDictionary::initMonoObjects(MonoClass* dictionaryClass)

+ 15 - 0
SBansheeEngine/Source/BsScriptSerializableObjectInfo.cpp

@@ -127,6 +127,21 @@ namespace BansheeEngine
 		return nullptr;
 	}
 
+	bool ScriptSerializableTypeInfoPrimitive::isMonoObject() const
+	{
+		switch(mType)
+		{
+			case ScriptPrimitiveType::SceneObjectRef:
+			case ScriptPrimitiveType::ComponentRef:
+			case ScriptPrimitiveType::TextureRef:
+			case ScriptPrimitiveType::SpriteTextureRef:
+			case ScriptPrimitiveType::String:
+				return true;
+		}
+
+		return false;
+	}
+
 	RTTITypeBase* ScriptSerializableTypeInfoPrimitive::getRTTIStatic()
 	{
 		return ScriptSerializableTypeInfoPrimitiveRTTI::instance();