Просмотр исходного кода

Refactoring managed RTTI system so managed properties can also be serialized and inspected

BearishSun 9 лет назад
Родитель
Сommit
172c253eea

+ 14 - 2
Source/BansheeMono/Include/BsMonoProperty.h

@@ -53,17 +53,29 @@ namespace BansheeEngine
 		 */
 		void setIndexed(MonoObject* instance, UINT32 index, void* value) const;
 
+		/** Checks does the property contains indexed data, or just a single value. */
+		bool isIndexed() const;
+
 		/**	Returns the data type the property holds. */
-		MonoClass* getReturnType();
+		MonoClass* getReturnType() const;
 	private:
 		friend class MonoClass;
 
 		MonoProperty(::MonoProperty* monoProp);
 
+		/** 
+		 * Some property data is not initialized by default on creation (with the assumption it will never be accessed). 
+		 * This method will initialize that data.
+		 */
+		void initializeDeferred() const;
+
 		::MonoProperty* mProperty;
 		::MonoMethod* mGetMethod;
 		::MonoMethod* mSetMethod;
-		MonoClass* mGetReturnType;
+
+		mutable MonoClass* mGetReturnType;
+		mutable bool mIsIndexed;
+		mutable bool mIsFullyInitialized;
 	};
 
 	/** @} */

+ 45 - 12
Source/BansheeMono/Source/BsMonoProperty.cpp

@@ -8,7 +8,7 @@
 namespace BansheeEngine
 {
 	MonoProperty::MonoProperty(::MonoProperty* monoProp)
-		:mProperty(monoProp), mGetReturnType(nullptr)
+		:mProperty(monoProp), mGetReturnType(nullptr), mIsIndexed(false), mIsFullyInitialized(false)
 	{
 		mGetMethod = mono_property_get_get_method(mProperty);
 		mSetMethod = mono_property_get_set_method(mProperty);
@@ -16,11 +16,17 @@ namespace BansheeEngine
 
 	MonoObject* MonoProperty::get(MonoObject* instance) const
 	{
+		if (mGetMethod == nullptr)
+			return nullptr;
+
 		return mono_runtime_invoke(mGetMethod, instance, nullptr, nullptr);
 	}
 
 	void MonoProperty::set(MonoObject* instance, void* value) const
 	{
+		if (mSetMethod == nullptr)
+			return;
+
 		void* args[1];
 		args[0] = value;
 		mono_runtime_invoke(mSetMethod, instance, args, nullptr);
@@ -39,22 +45,49 @@ namespace BansheeEngine
 		args[0] = &index;
 		args[1] = value;
 		mono_runtime_invoke(mSetMethod, instance, args, nullptr);
-	}	
+	}
 
-	MonoClass* MonoProperty::getReturnType()
+	bool MonoProperty::isIndexed() const
 	{
-		if(mGetReturnType != nullptr)
-			return mGetReturnType;
+		if (!mIsFullyInitialized)
+			initializeDeferred();
 
-		MonoType* returnType = mono_signature_get_return_type(mono_method_signature(mGetMethod));
-		if(returnType == nullptr)
-			return nullptr;
+		return mIsIndexed;
+	}
 
-		::MonoClass* returnClass = mono_class_from_mono_type(returnType);
-		if(returnClass == nullptr)
-			return nullptr;	
+	MonoClass* MonoProperty::getReturnType() const
+	{
+		if (!mIsFullyInitialized)
+			initializeDeferred();
 
-		mGetReturnType = MonoManager::instance().findClass(returnClass);
 		return mGetReturnType;
 	}
+
+	void MonoProperty::initializeDeferred() const
+	{
+		if (mGetMethod != nullptr)
+		{
+			MonoMethodSignature* signature = mono_method_signature(mGetMethod);
+
+			MonoType* returnType = mono_signature_get_return_type(signature);
+			if (returnType != nullptr)
+			{
+				::MonoClass* returnClass = mono_class_from_mono_type(returnType);
+				if (returnClass != nullptr)
+					mGetReturnType = MonoManager::instance().findClass(returnClass);
+			}
+
+			UINT32 numParams = mono_signature_get_param_count(signature);
+			mIsIndexed = numParams == 1;
+		}
+		else if(mSetMethod != nullptr)
+		{
+			MonoMethodSignature* signature = mono_method_signature(mSetMethod);
+
+			UINT32 numParams = mono_signature_get_param_count(signature);
+			mIsIndexed = numParams == 2;
+		}
+
+		mIsFullyInitialized = true;
+	}
 }

+ 14 - 14
Source/SBansheeEngine/Include/BsManagedSerializableDiff.h

@@ -25,7 +25,7 @@ namespace BansheeEngine
 	{
 	public:
 		/**	A base class for all modifications recorded in a diff. */
-		struct BS_SCR_BE_EXPORT Modification : public IReflectable
+		struct BS_SCR_BE_EXPORT Modification : IReflectable
 		{
 			virtual ~Modification();
 
@@ -35,21 +35,21 @@ namespace BansheeEngine
 		public:
 			friend class ModificationRTTI;
 			static RTTITypeBase* getRTTIStatic();
-			virtual RTTITypeBase* getRTTI() const override;
+			RTTITypeBase* getRTTI() const override;
 		};
 
 		/**
 		 * Contains a modification of a specific field in an object along with information about the field and its parent
 		 * object.
 		 */
-		struct BS_SCR_BE_EXPORT ModifiedField : public IReflectable
+		struct BS_SCR_BE_EXPORT ModifiedField : IReflectable
 		{
 			ModifiedField() { }
 			ModifiedField(const SPtr<ManagedSerializableTypeInfo>& parentType,
-				const SPtr<ManagedSerializableFieldInfo>& fieldType, const SPtr<Modification>& modification);
+				const SPtr<ManagedSerializableMemberInfo>& fieldType, const SPtr<Modification>& modification);
 
 			SPtr<ManagedSerializableTypeInfo> parentType; /**< Type of the parent object the field belongs to. */
-			SPtr<ManagedSerializableFieldInfo> fieldType; /**< Data type of the field. */
+			SPtr<ManagedSerializableMemberInfo> fieldType; /**< Data type of the field. */
 			SPtr<Modification> modification; /**< Recorded modification(s) on the field. */
 
 			/************************************************************************/
@@ -58,11 +58,11 @@ namespace BansheeEngine
 		public:
 			friend class ModifiedFieldRTTI;
 			static RTTITypeBase* getRTTIStatic();
-			virtual RTTITypeBase* getRTTI() const override;
+			RTTITypeBase* getRTTI() const override;
 		};
 
 		/**	Represents a single modified array or list entry. */
-		struct BS_SCR_BE_EXPORT ModifiedArrayEntry : public IReflectable
+		struct BS_SCR_BE_EXPORT ModifiedArrayEntry : IReflectable
 		{
 			ModifiedArrayEntry() { }
 			ModifiedArrayEntry(UINT32 idx, const SPtr<Modification>& modification);
@@ -76,11 +76,11 @@ namespace BansheeEngine
 		public:
 			friend class ModifiedArrayEntryRTTI;
 			static RTTITypeBase* getRTTIStatic();
-			virtual RTTITypeBase* getRTTI() const override;
+			RTTITypeBase* getRTTI() const override;
 		};
 
 		/**	Represents a single modified dictionary entry. */
-		struct BS_SCR_BE_EXPORT ModifiedDictionaryEntry : public IReflectable
+		struct BS_SCR_BE_EXPORT ModifiedDictionaryEntry : IReflectable
 		{
 			ModifiedDictionaryEntry() { }
 			ModifiedDictionaryEntry(const SPtr<ManagedSerializableFieldData>& key, const SPtr<Modification>& modification);
@@ -94,7 +94,7 @@ namespace BansheeEngine
 		public:
 			friend class ModifiedArrayEntryRTTI;
 			static RTTITypeBase* getRTTIStatic();
-			virtual RTTITypeBase* getRTTI() const override;
+			RTTITypeBase* getRTTI() const override;
 		};
 
 		/**
@@ -113,7 +113,7 @@ namespace BansheeEngine
 		public:
 			friend class ModifiedObjectRTTI;
 			static RTTITypeBase* getRTTIStatic();
-			virtual RTTITypeBase* getRTTI() const override;
+			RTTITypeBase* getRTTI() const override;
 		};
 
 		/**	Contains data about all modifications in an array or a list. */
@@ -131,7 +131,7 @@ namespace BansheeEngine
 		public:
 			friend class ModifiedArrayRTTI;
 			static RTTITypeBase* getRTTIStatic();
-			virtual RTTITypeBase* getRTTI() const override;
+			RTTITypeBase* getRTTI() const override;
 		};
 
 		/**	Contains data about all modifications in a dictionary. */
@@ -150,7 +150,7 @@ namespace BansheeEngine
 		public:
 			friend class ModifiedDictionaryRTTI;
 			static RTTITypeBase* getRTTIStatic();
-			virtual RTTITypeBase* getRTTI() const override;
+			RTTITypeBase* getRTTI() const override;
 		};
 
 		/** Contains data about modification of a primitive field (field's new value). */
@@ -169,7 +169,7 @@ namespace BansheeEngine
 		public:
 			friend class ModifiedEntryRTTI;
 			static RTTITypeBase* getRTTIStatic();
-			virtual RTTITypeBase* getRTTI() const override;
+			RTTITypeBase* getRTTI() const override;
 		};
 
 	public:

+ 2 - 2
Source/SBansheeEngine/Include/BsManagedSerializableDiffRTTI.h

@@ -27,12 +27,12 @@ namespace BansheeEngine
 			obj->parentType = val;
 		}
 
-		SPtr<ManagedSerializableFieldInfo> getFieldType(ManagedSerializableDiff::ModifiedField* obj)
+		SPtr<ManagedSerializableMemberInfo> getFieldType(ManagedSerializableDiff::ModifiedField* obj)
 		{
 			return obj->fieldType;
 		}
 
-		void setFieldType(ManagedSerializableDiff::ModifiedField* obj, SPtr<ManagedSerializableFieldInfo> val)
+		void setFieldType(ManagedSerializableDiff::ModifiedField* obj, SPtr<ManagedSerializableMemberInfo> val)
 		{
 			obj->fieldType = val;
 		}

+ 30 - 30
Source/SBansheeEngine/Include/BsManagedSerializableField.h

@@ -42,7 +42,7 @@ namespace BansheeEngine
 	public:
 		friend class ScriptSerializableFieldDataKeyRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -136,7 +136,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**	Contains type and value of a single field in an object. */
@@ -155,7 +155,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataEntryRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -189,7 +189,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataBoolRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -223,7 +223,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataCharRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -257,7 +257,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataI8RTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -291,7 +291,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataU8RTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -325,7 +325,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataI16RTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -359,7 +359,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataU16RTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -393,7 +393,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataI32RTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -427,7 +427,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataU32RTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -461,7 +461,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataI64RTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -495,7 +495,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataU64RTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -529,7 +529,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataFloatRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -563,7 +563,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataDoubleRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -598,7 +598,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataStringRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -630,7 +630,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataResourceRefRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -662,7 +662,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataGameObjectRefRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -686,10 +686,10 @@ namespace BansheeEngine
 		size_t getHash() override;
 
 		/** @copydoc ManagedSerializableFieldData::serialize */
-		virtual void serialize() override;
+		void serialize() override;
 
 		/** @copydoc ManagedSerializableFieldData::deserialize */
-		virtual void deserialize() override;
+		void deserialize() override;
 
 		SPtr<ManagedSerializableObject> value;
 
@@ -700,7 +700,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataObjectRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -724,10 +724,10 @@ namespace BansheeEngine
 		size_t getHash() override;
 
 		/** @copydoc ManagedSerializableFieldData::serialize */
-		virtual void serialize() override;
+		void serialize() override;
 
 		/** @copydoc ManagedSerializableFieldData::deserialize */
-		virtual void deserialize() override;
+		void deserialize() override;
 
 		SPtr<ManagedSerializableArray> value;
 
@@ -738,7 +738,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataArrayRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -762,10 +762,10 @@ namespace BansheeEngine
 		size_t getHash() override;
 
 		/** @copydoc ManagedSerializableFieldData::serialize */
-		virtual void serialize() override;
+		void serialize() override;
 
 		/** @copydoc ManagedSerializableFieldData::deserialize */
-		virtual void deserialize() override;
+		void deserialize() override;
 
 		SPtr<ManagedSerializableList> value;
 
@@ -776,7 +776,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataListRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**
@@ -800,10 +800,10 @@ namespace BansheeEngine
 		size_t getHash() override;
 
 		/** @copydoc ManagedSerializableFieldData::serialize */
-		virtual void serialize() override;
+		void serialize() override;
 
 		/** @copydoc ManagedSerializableFieldData::deserialize */
-		virtual void deserialize() override;
+		void deserialize() override;
 
 		SPtr<ManagedSerializableDictionary> value;
 
@@ -814,7 +814,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldDataDictionaryRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/** @} */

+ 2 - 2
Source/SBansheeEngine/Include/BsManagedSerializableObject.h

@@ -64,7 +64,7 @@ namespace BansheeEngine
 		 *							type this object is initialized with.
 		 * @param[in]	val			Wrapper around the value to store in the field.
 		 */
-		void setFieldData(const SPtr<ManagedSerializableFieldInfo>& fieldInfo, const SPtr<ManagedSerializableFieldData>& val);
+		void setFieldData(const SPtr<ManagedSerializableMemberInfo>& fieldInfo, const SPtr<ManagedSerializableFieldData>& val);
 
 		/**
 		 * Returns the value of the specified field. Operates on managed object if in linked state, or on cached data
@@ -74,7 +74,7 @@ namespace BansheeEngine
 		 *							type this object is initialized with.
 		 * @return					A wrapper around the value of the field.
 		 */
-		SPtr<ManagedSerializableFieldData> getFieldData(const SPtr<ManagedSerializableFieldInfo>& fieldInfo) const;
+		SPtr<ManagedSerializableFieldData> getFieldData(const SPtr<ManagedSerializableMemberInfo>& fieldInfo) const;
 
 		/**
 		 * Serializes the internal managed object into a set of cached data that can be saved in memory/disk and can be

+ 72 - 22
Source/SBansheeEngine/Include/BsManagedSerializableObjectInfo.h

@@ -95,7 +95,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableTypeInfoRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**	Contains information about a type of a managed serializable primitive (for example int, float, etc.). */
@@ -119,7 +119,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableTypeInfoPrimitiveRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**	Contains information about a type of a managed serializable game object or resource reference. */
@@ -145,7 +145,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableTypeInfoRefRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**	Contains information about a type of a managed serializable complex object (for example struct or class). */
@@ -172,7 +172,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableTypeInfoObjectRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**	Contains information about a type of a managed serializable Array. */
@@ -197,7 +197,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableTypeInfoArrayRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**	Contains information about a type of a managed serializable List. */
@@ -221,7 +221,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableTypeInfoListRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**	Contains information about a type of a managed serializable Dictionary. */
@@ -246,29 +246,46 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableTypeInfoDictionaryRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
-	/**	Contains data about a single field in a managed complex object. */
-	class BS_SCR_BE_EXPORT ManagedSerializableFieldInfo : public IReflectable
+	/**	Contains data about a single member in a managed complex object. */
+	class BS_SCR_BE_EXPORT ManagedSerializableMemberInfo : public IReflectable
 	{
 	public:
-		ManagedSerializableFieldInfo();
+		ManagedSerializableMemberInfo();
 
-		/**	Determines should the field be serialized when serializing the parent object. */
+		/**	Determines should the member be serialized when serializing the parent object. */
 		bool isSerializable() const { return ((UINT32)mFlags & (UINT32)ScriptFieldFlags::Serializable) != 0; }
 
 		/** Returns the minimum value associated to a Range attribute. */
-		float getRangeMinimum() const;
+		virtual float getRangeMinimum() const = 0;
 
 		/** Returns the maximum value associated to a Range attribute. */
-		float getRangeMaximum() const;
+		virtual float getRangeMaximum() const = 0;
+
+		/** Checks whether the field should be rendered as a slider. */
+		virtual bool renderAsSlider() const = 0;
+
+		/** Returns the step value of the member. */
+		virtual float getStep() const = 0;
 
-		/** Whether the field should be rendered as a slider. */
-		bool renderAsSlider() const;
+		/**
+		 * Returns a boxed value contained in the member in the specified object instance.
+		 *
+		 * @param[in]	instance	Object instance to access the member on.
+		 * @return					A boxed value of the member.
+		 */
+		virtual MonoObject* getValue(MonoObject* instance) const = 0;
 
-		/** Returns the step value of the field. */
-		float getStep() const;
+		/**
+		 * Sets a value of the member in the specified object instance. 
+		 *
+		 * @param[in]	instance	Object instance to access the member on.
+		 * @param[in]	value		Value to set on the property. For value type it should be a pointer to the value and for
+		 *							reference type it should be a pointer to MonoObject.
+		 */
+		virtual void setValue(MonoObject* instance, void* value) const = 0;
 
 		String mName;
 		UINT32 mFieldId;
@@ -277,6 +294,39 @@ namespace BansheeEngine
 		SPtr<ManagedSerializableTypeInfo> mTypeInfo;
 		ScriptFieldFlags mFlags;
 
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class ManagedSerializableMemberInfoRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		RTTITypeBase* getRTTI() const override;
+	};
+
+	/**	Contains data about a single field in a managed complex object. */
+	class BS_SCR_BE_EXPORT ManagedSerializableFieldInfo : public ManagedSerializableMemberInfo
+	{
+	public:
+		ManagedSerializableFieldInfo();
+
+		/** @copydoc ManagedSerializableMemberInfo::getRangeMinimum */
+		float getRangeMinimum() const override;
+
+		/** @copydoc ManagedSerializableMemberInfo::getRangeMaximum */
+		float getRangeMaximum() const override;
+
+		/** @copydoc ManagedSerializableMemberInfo::renderAsSlider */
+		bool renderAsSlider() const override;
+
+		/** @copydoc ManagedSerializableMemberInfo::getStep */
+		float getStep() const override;
+
+		/** @copydoc ManagedSerializableMemberInfo::getValue */
+		MonoObject* getValue(MonoObject* instance) const override;
+
+		/** @copydoc ManagedSerializableMemberInfo::setValue */
+		void setValue(MonoObject* instance, void* value) const override;
+
 		MonoField* mMonoField;
 
 		/************************************************************************/
@@ -285,7 +335,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableFieldInfoRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/** Contains data about fields of a complex object, and the object's class hierarchy if it belongs to one. */
@@ -307,14 +357,14 @@ namespace BansheeEngine
 		 *								ensure the current object's type matches.
 		 * @return						Found field info within this object, or null if not found.
 		 */
-		SPtr<ManagedSerializableFieldInfo> findMatchingField(const SPtr<ManagedSerializableFieldInfo>& fieldInfo,
+		SPtr<ManagedSerializableMemberInfo> findMatchingField(const SPtr<ManagedSerializableMemberInfo>& fieldInfo,
 			const SPtr<ManagedSerializableTypeInfo>& fieldTypeInfo) const;
 
 		SPtr<ManagedSerializableTypeInfoObject> mTypeInfo;
 		MonoClass* mMonoClass;
 
 		UnorderedMap<String, UINT32> mFieldNameToId;
-		UnorderedMap<UINT32, SPtr<ManagedSerializableFieldInfo>> mFields;
+		UnorderedMap<UINT32, SPtr<ManagedSerializableMemberInfo>> mFields;
 
 		SPtr<ManagedSerializableObjectInfo> mBaseClass;
 		Vector<std::weak_ptr<ManagedSerializableObjectInfo>> mDerivedClasses;
@@ -325,7 +375,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableObjectInfoRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/**	Contains information about all managed serializable objects in a specific managed assembly. */
@@ -343,7 +393,7 @@ namespace BansheeEngine
 	public:
 		friend class ManagedSerializableAssemblyInfoRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	/** @} */

+ 67 - 200
Source/SBansheeEngine/Include/BsManagedSerializableObjectInfoRTTI.h

@@ -96,7 +96,7 @@ namespace BansheeEngine
 			obj->mBaseClass = val;
 		}
 
-		SPtr<ManagedSerializableFieldInfo> getSerializableFieldInfo(ManagedSerializableObjectInfo* obj, UINT32 idx) 
+		SPtr<ManagedSerializableMemberInfo> getSerializableFieldInfo(ManagedSerializableObjectInfo* obj, UINT32 idx) 
 		{ 
 			auto iter = obj->mFields.begin();
 			for(UINT32 i = 0; i < idx; i++)
@@ -105,7 +105,7 @@ namespace BansheeEngine
 			return iter->second;
 		}
 
-		void setSerializableFieldInfo(ManagedSerializableObjectInfo* obj, UINT32 idx, SPtr<ManagedSerializableFieldInfo> val) 
+		void setSerializableFieldInfo(ManagedSerializableObjectInfo* obj, UINT32 idx, SPtr<ManagedSerializableMemberInfo> val) 
 		{ 
 			obj->mFieldNameToId[val->mName] = val->mFieldId;
 			obj->mFields[val->mFieldId] = val;
@@ -142,68 +142,48 @@ namespace BansheeEngine
 		}
 	};
 
-	class BS_SCR_BE_EXPORT ManagedSerializableFieldInfoRTTI : public RTTIType<ManagedSerializableFieldInfo, IReflectable, ManagedSerializableFieldInfoRTTI>
+	class BS_SCR_BE_EXPORT ManagedSerializableMemberInfoRTTI : public RTTIType<ManagedSerializableMemberInfo, IReflectable, ManagedSerializableMemberInfoRTTI>
 	{
 	private:
-		SPtr<ManagedSerializableTypeInfo> getTypeInfo(ManagedSerializableFieldInfo* obj)
-		{
-			return obj->mTypeInfo;
-		}
-
-		void setTypeInfo(ManagedSerializableFieldInfo* obj, SPtr<ManagedSerializableTypeInfo> val)
-		{
-			obj->mTypeInfo = val;
-		}
-
-		String& getName(ManagedSerializableFieldInfo* obj)
-		{
-			return obj->mName;
-		}
-
-		void setName(ManagedSerializableFieldInfo* obj, String& val)
-		{
-			obj->mName = val;
-		}
-
-		UINT32& getFieldId(ManagedSerializableFieldInfo* obj)
-		{
-			return obj->mFieldId;
-		}
-
-		void setFieldId(ManagedSerializableFieldInfo* obj, UINT32& val)
-		{
-			obj->mFieldId = val;
-		}
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(mName, 0)
+			BS_RTTI_MEMBER_REFLPTR(mTypeInfo, 1)
+			BS_RTTI_MEMBER_PLAIN(mFieldId, 2)
+			BS_RTTI_MEMBER_PLAIN(mFlags, 3)
+			BS_RTTI_MEMBER_PLAIN(mParentTypeId, 4)
+		BS_END_RTTI_MEMBERS
+			
+	public:
+		ManagedSerializableMemberInfoRTTI()
+			:mInitMembers(this)
+		{ }
 
-		UINT32& getParentTypeId(ManagedSerializableFieldInfo* obj)
+		const String& getRTTIName() override
 		{
-			return obj->mParentTypeId;
+			static String name = "ScriptSerializableMemberInfo";
+			return name;
 		}
 
-		void setParentTypeId(ManagedSerializableFieldInfo* obj, UINT32& val)
+		UINT32 getRTTIId() override
 		{
-			obj->mParentTypeId = val;
+			return TID_SerializableMemberInfo;
 		}
 
-		UINT32& getFlags(ManagedSerializableFieldInfo* obj)
+		SPtr<IReflectable> newRTTIObject() override
 		{
-			return (UINT32&)obj->mFlags;
+			// This is an abstract class, but it wasn't always. For compatibility sake we return an object instance so old
+			// data can still be properly read.
+			return bs_shared_ptr_new<ManagedSerializableFieldInfo>();
 		}
+	};
 
-		void setFlags(ManagedSerializableFieldInfo* obj, UINT32& val)
-		{
-			obj->mFlags = (ScriptFieldFlags)val;
-		}
+	class BS_SCR_BE_EXPORT ManagedSerializableFieldInfoRTTI : public RTTIType<ManagedSerializableFieldInfo, ManagedSerializableMemberInfo, ManagedSerializableFieldInfoRTTI>
+	{
+	private:
 
 	public:
 		ManagedSerializableFieldInfoRTTI()
-		{
-			addPlainField("mName", 0, &ManagedSerializableFieldInfoRTTI::getName, &ManagedSerializableFieldInfoRTTI::setName);
-			addReflectablePtrField("mTypeInfo", 1, &ManagedSerializableFieldInfoRTTI::getTypeInfo, &ManagedSerializableFieldInfoRTTI::setTypeInfo);
-			addPlainField("mFieldId", 2, &ManagedSerializableFieldInfoRTTI::getFieldId, &ManagedSerializableFieldInfoRTTI::setFieldId);
-			addPlainField("mFlags", 3, &ManagedSerializableFieldInfoRTTI::getFlags, &ManagedSerializableFieldInfoRTTI::setFlags);
-			addPlainField("mParentTypeId", 4, &ManagedSerializableFieldInfoRTTI::getParentTypeId, &ManagedSerializableFieldInfoRTTI::setParentTypeId);
-		}
+		{ }
 
 		const String& getRTTIName() override
 		{
@@ -228,9 +208,7 @@ namespace BansheeEngine
 
 	public:
 		ManagedSerializableTypeInfoRTTI()
-		{
-
-		}
+		{ }
 
 		const String& getRTTIName() override
 		{
@@ -253,21 +231,14 @@ namespace BansheeEngine
 	class BS_SCR_BE_EXPORT ManagedSerializableTypeInfoPrimitiveRTTI : public RTTIType<ManagedSerializableTypeInfoPrimitive, ManagedSerializableTypeInfo, ManagedSerializableTypeInfoPrimitiveRTTI>
 	{
 	private:
-		ScriptPrimitiveType& getType(ManagedSerializableTypeInfoPrimitive* obj)
-		{
-			return obj->mType;
-		}
-
-		void setType(ManagedSerializableTypeInfoPrimitive* obj, ScriptPrimitiveType& val)
-		{
-			obj->mType = val;
-		}
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(mType, 0)
+		BS_END_RTTI_MEMBERS
 
 	public:
 		ManagedSerializableTypeInfoPrimitiveRTTI()
-		{
-			addPlainField("mType", 0, &ManagedSerializableTypeInfoPrimitiveRTTI::getType, &ManagedSerializableTypeInfoPrimitiveRTTI::setType);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{
@@ -289,43 +260,16 @@ namespace BansheeEngine
 	class BS_SCR_BE_EXPORT ManagedSerializableTypeInfoRefRTTI : public RTTIType<ManagedSerializableTypeInfoRef, ManagedSerializableTypeInfo, ManagedSerializableTypeInfoRefRTTI>
 	{
 	private:
-		ScriptReferenceType& getType(ManagedSerializableTypeInfoRef* obj)
-		{
-			return obj->mType;
-		}
-
-		void setType(ManagedSerializableTypeInfoRef* obj, ScriptReferenceType& val)
-		{
-			obj->mType = val;
-		}
-
-		String& getTypeNamespace(ManagedSerializableTypeInfoRef* obj)
-		{
-			return obj->mTypeNamespace;
-		}
-
-		void setTypeNamespace(ManagedSerializableTypeInfoRef* obj, String& val)
-		{
-			obj->mTypeNamespace = val;
-		}
-
-		String& getTypeName(ManagedSerializableTypeInfoRef* obj)
-		{
-			return obj->mTypeName;
-		}
-
-		void setTypeName(ManagedSerializableTypeInfoRef* obj, String& val)
-		{
-			obj->mTypeName = val;
-		}
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(mType, 0)
+			BS_RTTI_MEMBER_PLAIN(mTypeName, 1)
+			BS_RTTI_MEMBER_PLAIN(mTypeNamespace, 2)
+		BS_END_RTTI_MEMBERS
 
 	public:
 		ManagedSerializableTypeInfoRefRTTI()
-		{
-			addPlainField("mType", 0, &ManagedSerializableTypeInfoRefRTTI::getType, &ManagedSerializableTypeInfoRefRTTI::setType);
-			addPlainField("mTypeName", 1, &ManagedSerializableTypeInfoRefRTTI::getTypeName, &ManagedSerializableTypeInfoRefRTTI::setTypeName);
-			addPlainField("mTypeNamespace", 2, &ManagedSerializableTypeInfoRefRTTI::getTypeNamespace, &ManagedSerializableTypeInfoRefRTTI::setTypeNamespace);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{
@@ -347,54 +291,17 @@ namespace BansheeEngine
 	class BS_SCR_BE_EXPORT ManagedSerializableTypeInfoObjectRTTI : public RTTIType<ManagedSerializableTypeInfoObject, ManagedSerializableTypeInfo, ManagedSerializableTypeInfoObjectRTTI>
 	{
 	private:
-		String& getTypeNamespace(ManagedSerializableTypeInfoObject* obj)
-		{
-			return obj->mTypeNamespace;
-		}
-
-		void setTypeNamespace(ManagedSerializableTypeInfoObject* obj, String& val)
-		{
-			obj->mTypeNamespace = val;
-		}
-
-		String& getTypeName(ManagedSerializableTypeInfoObject* obj)
-		{
-			return obj->mTypeName;
-		}
-
-		void setTypeName(ManagedSerializableTypeInfoObject* obj, String& val)
-		{
-			obj->mTypeName = val;
-		}
-
-		bool& getIsValueType(ManagedSerializableTypeInfoObject* obj)
-		{
-			return obj->mValueType;
-		}
-
-		void setIsValueType(ManagedSerializableTypeInfoObject* obj, bool& val)
-		{
-			obj->mValueType = val;
-		}
-
-		UINT32& getTypeId(ManagedSerializableTypeInfoObject* obj)
-		{
-			return obj->mTypeId;
-		}
-
-		void setTypeId(ManagedSerializableTypeInfoObject* obj, UINT32& val)
-		{
-			obj->mTypeId = val;
-		}
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(mTypeName, 0)
+			BS_RTTI_MEMBER_PLAIN(mTypeNamespace, 1)
+			BS_RTTI_MEMBER_PLAIN(mValueType, 2)
+			BS_RTTI_MEMBER_PLAIN(mTypeId, 4)
+		BS_END_RTTI_MEMBERS
 
 	public:
 		ManagedSerializableTypeInfoObjectRTTI()
-		{
-			addPlainField("mTypeName", 0, &ManagedSerializableTypeInfoObjectRTTI::getTypeName, &ManagedSerializableTypeInfoObjectRTTI::setTypeName);
-			addPlainField("mTypeNamespace", 1, &ManagedSerializableTypeInfoObjectRTTI::getTypeNamespace, &ManagedSerializableTypeInfoObjectRTTI::setTypeNamespace);
-			addPlainField("mValueType", 2, &ManagedSerializableTypeInfoObjectRTTI::getIsValueType, &ManagedSerializableTypeInfoObjectRTTI::setIsValueType);
-			addPlainField("mTypeId", 3, &ManagedSerializableTypeInfoObjectRTTI::getIsValueType, &ManagedSerializableTypeInfoObjectRTTI::setIsValueType);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{
@@ -416,32 +323,15 @@ namespace BansheeEngine
 	class BS_SCR_BE_EXPORT ManagedSerializableTypeInfoArrayRTTI : public RTTIType<ManagedSerializableTypeInfoArray, ManagedSerializableTypeInfo, ManagedSerializableTypeInfoArrayRTTI>
 	{
 	private:
-		SPtr<ManagedSerializableTypeInfo> getElementType(ManagedSerializableTypeInfoArray* obj)
-		{
-			return obj->mElementType;
-		}
-
-		void setElementType(ManagedSerializableTypeInfoArray* obj, SPtr<ManagedSerializableTypeInfo> val)
-		{
-			obj->mElementType = val;
-		}
-
-		UINT32& getRank(ManagedSerializableTypeInfoArray* obj)
-		{
-			return obj->mRank;
-		}
-
-		void setRank(ManagedSerializableTypeInfoArray* obj, UINT32& val)
-		{
-			obj->mRank = val;
-		}
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_REFLPTR(mElementType, 0)
+			BS_RTTI_MEMBER_PLAIN(mRank, 1)
+		BS_END_RTTI_MEMBERS
 
 	public:
 		ManagedSerializableTypeInfoArrayRTTI()
-		{
-			addReflectablePtrField("mElementType", 0, &ManagedSerializableTypeInfoArrayRTTI::getElementType, &ManagedSerializableTypeInfoArrayRTTI::setElementType);
-			addPlainField("mRank", 1, &ManagedSerializableTypeInfoArrayRTTI::getRank, &ManagedSerializableTypeInfoArrayRTTI::setRank);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{
@@ -463,21 +353,14 @@ namespace BansheeEngine
 	class BS_SCR_BE_EXPORT ManagedSerializableTypeInfoListRTTI : public RTTIType<ManagedSerializableTypeInfoList, ManagedSerializableTypeInfo, ManagedSerializableTypeInfoListRTTI>
 	{
 	private:
-		SPtr<ManagedSerializableTypeInfo> getElementType(ManagedSerializableTypeInfoList* obj)
-		{
-			return obj->mElementType;
-		}
-
-		void setElementType(ManagedSerializableTypeInfoList* obj, SPtr<ManagedSerializableTypeInfo> val)
-		{
-			obj->mElementType = val;
-		}
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_REFLPTR(mElementType, 0)
+		BS_END_RTTI_MEMBERS
 
 	public:
 		ManagedSerializableTypeInfoListRTTI()
-		{
-			addReflectablePtrField("mElementType", 0, &ManagedSerializableTypeInfoListRTTI::getElementType, &ManagedSerializableTypeInfoListRTTI::setElementType);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{
@@ -499,32 +382,16 @@ namespace BansheeEngine
 	class BS_SCR_BE_EXPORT ManagedSerializableTypeInfoDictionaryRTTI : public RTTIType<ManagedSerializableTypeInfoDictionary, ManagedSerializableTypeInfo, ManagedSerializableTypeInfoDictionaryRTTI>
 	{
 	private:
-		SPtr<ManagedSerializableTypeInfo> getKeyType(ManagedSerializableTypeInfoDictionary* obj)
-		{
-			return obj->mKeyType;
-		}
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_REFLPTR(mKeyType, 0)
+			BS_RTTI_MEMBER_REFLPTR(mValueType, 1)
+		BS_END_RTTI_MEMBERS
 
-		void setKeyType(ManagedSerializableTypeInfoDictionary* obj, SPtr<ManagedSerializableTypeInfo> val)
-		{
-			obj->mKeyType = val;
-		}
-
-		SPtr<ManagedSerializableTypeInfo> getValueType(ManagedSerializableTypeInfoDictionary* obj)
-		{
-			return obj->mValueType;
-		}
-
-		void setValueType(ManagedSerializableTypeInfoDictionary* obj, SPtr<ManagedSerializableTypeInfo> val)
-		{
-			obj->mValueType = val;
-		}
 
 	public:
 		ManagedSerializableTypeInfoDictionaryRTTI()
-		{
-			addReflectablePtrField("mKeyType", 0, &ManagedSerializableTypeInfoDictionaryRTTI::getKeyType, &ManagedSerializableTypeInfoDictionaryRTTI::setKeyType);
-			addReflectablePtrField("mValueType", 1, &ManagedSerializableTypeInfoDictionaryRTTI::getValueType, &ManagedSerializableTypeInfoDictionaryRTTI::setValueType);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 6 - 6
Source/SBansheeEngine/Include/BsManagedSerializableObjectRTTI.h

@@ -31,10 +31,10 @@ namespace BansheeEngine
 
 		SPtr<ManagedSerializableFieldDataEntry> getFieldEntry(ManagedSerializableObject* obj, UINT32 arrayIdx)
 		{
-			Vector<SPtr<ManagedSerializableFieldInfo>>& sequentialFields =
-				any_cast_ref<Vector<SPtr<ManagedSerializableFieldInfo>>>(obj->mRTTIData);
+			Vector<SPtr<ManagedSerializableMemberInfo>>& sequentialFields =
+				any_cast_ref<Vector<SPtr<ManagedSerializableMemberInfo>>>(obj->mRTTIData);
 
-			SPtr<ManagedSerializableFieldInfo> field = sequentialFields[arrayIdx];
+			SPtr<ManagedSerializableMemberInfo> field = sequentialFields[arrayIdx];
 
 			SPtr<ManagedSerializableFieldKey> fieldKey = ManagedSerializableFieldKey::create(field->mParentTypeId, field->mFieldId);
 			SPtr<ManagedSerializableFieldData> fieldData = obj->getFieldData(field);
@@ -49,8 +49,8 @@ namespace BansheeEngine
 
 		UINT32 getNumFieldEntries(ManagedSerializableObject* obj)
 		{
-			Vector<SPtr<ManagedSerializableFieldInfo>>& sequentialFields =
-				any_cast_ref<Vector<SPtr<ManagedSerializableFieldInfo>>>(obj->mRTTIData);
+			Vector<SPtr<ManagedSerializableMemberInfo>>& sequentialFields =
+				any_cast_ref<Vector<SPtr<ManagedSerializableMemberInfo>>>(obj->mRTTIData);
 
 			return (UINT32)sequentialFields.size();
 		}
@@ -72,7 +72,7 @@ namespace BansheeEngine
 		{
 			ManagedSerializableObject* castObj = static_cast<ManagedSerializableObject*>(obj);
 
-			Vector<SPtr<ManagedSerializableFieldInfo>> sequentialFields;
+			Vector<SPtr<ManagedSerializableMemberInfo>> sequentialFields;
 			SPtr<ManagedSerializableObjectInfo> curType = castObj->mObjInfo;
 			while (curType != nullptr)
 			{

+ 4 - 3
Source/SBansheeEngine/Include/BsScriptEnginePrerequisites.h

@@ -91,7 +91,7 @@ namespace BansheeEngine
 	class ManagedSerializableDictionary;
 	class ManagedSerializableAssemblyInfo;
 	class ManagedSerializableObjectInfo;
-	class ManagedSerializableFieldInfo;
+	class ManagedSerializableMemberInfo;
 	class ManagedSerializableObjectData;
 	class ManagedSerializableDiff;
 	class ManagedResource;
@@ -118,7 +118,7 @@ namespace BansheeEngine
 		TID_ScriptSerializableArray = 50002,
 		TID_SerializableAssemblyInfo = 50004,
 		TID_SerializableObjectInfo = 50005,
-		TID_SerializableFieldInfo = 50006,
+		TID_SerializableMemberInfo = 50006,
 		TID_SerializableTypeInfo = 50007,
 		TID_SerializableTypeInfoPrimitive = 50008,
 		TID_SerializableTypeInfoObject = 50009,
@@ -162,6 +162,7 @@ namespace BansheeEngine
 		TID_ScriptModifiedArrayEntry = 50047,
 		TID_ScriptModifiedDictionaryEntry = 50048,
 		TID_ScriptSerializableDictionaryKeyValue = 50049,
-		TID_SerializableTypeInfoRef = 50050
+		TID_SerializableTypeInfoRef = 50050,
+		TID_SerializableFieldInfo = 50051
 	};
 }

+ 1 - 1
Source/SBansheeEngine/Include/BsScriptRange.h

@@ -7,7 +7,7 @@
 
 namespace BansheeEngine
 {
-	/**	Interop class between C++ & CLR for Range attribute. */
+	/**	Interop class between C++ & CLR for the Range attribute. */
 	class BS_SCR_BE_EXPORT ScriptRange : public ScriptObject <ScriptRange>
 	{
 	public:

+ 3 - 3
Source/SBansheeEngine/Include/BsScriptSerializableField.h

@@ -24,11 +24,11 @@ namespace BansheeEngine
 		 * @param[in]	fieldInfo		Information about the field. Caller must ensure the type matches the type of the
 		 *								provided parent object.
 		 */
-		static ScriptSerializableField* create(MonoObject* parentObject, const SPtr<ManagedSerializableFieldInfo>& fieldInfo);
+		static ScriptSerializableField* create(MonoObject* parentObject, const SPtr<ManagedSerializableMemberInfo>& fieldInfo);
 	private:
-		ScriptSerializableField(MonoObject* instance, const SPtr<ManagedSerializableFieldInfo>& fieldInfo);
+		ScriptSerializableField(MonoObject* instance, const SPtr<ManagedSerializableMemberInfo>& fieldInfo);
 
-		SPtr<ManagedSerializableFieldInfo> mFieldInfo;
+		SPtr<ManagedSerializableMemberInfo> mFieldInfo;
 
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/

+ 3 - 3
Source/SBansheeEngine/Source/BsManagedSerializableDiff.cpp

@@ -12,7 +12,7 @@
 namespace BansheeEngine
 {
 	ManagedSerializableDiff::ModifiedField::ModifiedField(const SPtr<ManagedSerializableTypeInfo>& parentType,
-		const SPtr<ManagedSerializableFieldInfo>& fieldType, const SPtr<Modification>& modification)
+		const SPtr<ManagedSerializableMemberInfo>& fieldType, const SPtr<Modification>& modification)
 		:parentType(parentType), fieldType(fieldType), modification(modification)
 	{
 
@@ -468,10 +468,10 @@ namespace BansheeEngine
 		SPtr<ManagedSerializableObjectInfo> objInfo = obj->getObjectInfo();
 		for (auto& modEntry : mod->entries)
 		{
-			SPtr<ManagedSerializableFieldInfo> fieldType = modEntry.fieldType;
+			SPtr<ManagedSerializableMemberInfo> fieldType = modEntry.fieldType;
 			SPtr<ManagedSerializableTypeInfo> typeInfo = modEntry.parentType;
 
-			SPtr<ManagedSerializableFieldInfo> matchingFieldInfo = objInfo->findMatchingField(fieldType, typeInfo);
+			SPtr<ManagedSerializableMemberInfo> matchingFieldInfo = objInfo->findMatchingField(fieldType, typeInfo);
 			if (matchingFieldInfo == nullptr)
 				continue; // Field no longer exists in the type
 

+ 5 - 5
Source/SBansheeEngine/Source/BsManagedSerializableObject.cpp

@@ -153,7 +153,7 @@ namespace BansheeEngine
 
 					ManagedSerializableFieldKey key(typeID, fieldId);
 
-					SPtr<ManagedSerializableFieldInfo> matchingFieldInfo = objInfo->findMatchingField(field.second, curType->mTypeInfo);
+					SPtr<ManagedSerializableMemberInfo> matchingFieldInfo = objInfo->findMatchingField(field.second, curType->mTypeInfo);
 					if (matchingFieldInfo != nullptr)
 						setFieldData(matchingFieldInfo, mCachedData[key]);
 
@@ -168,10 +168,10 @@ namespace BansheeEngine
 		mCachedData.clear();
 	}
 
-	void ManagedSerializableObject::setFieldData(const SPtr<ManagedSerializableFieldInfo>& fieldInfo, const SPtr<ManagedSerializableFieldData>& val)
+	void ManagedSerializableObject::setFieldData(const SPtr<ManagedSerializableMemberInfo>& fieldInfo, const SPtr<ManagedSerializableFieldData>& val)
 	{
 		if (mManagedInstance != nullptr)
-			fieldInfo->mMonoField->setValue(mManagedInstance, val->getValue(fieldInfo->mTypeInfo));
+			fieldInfo->setValue(mManagedInstance, val->getValue(fieldInfo->mTypeInfo));
 		else
 		{
 			ManagedSerializableFieldKey key(fieldInfo->mParentTypeId, fieldInfo->mFieldId);
@@ -179,11 +179,11 @@ namespace BansheeEngine
 		}
 	}
 
-	SPtr<ManagedSerializableFieldData> ManagedSerializableObject::getFieldData(const SPtr<ManagedSerializableFieldInfo>& fieldInfo) const
+	SPtr<ManagedSerializableFieldData> ManagedSerializableObject::getFieldData(const SPtr<ManagedSerializableMemberInfo>& fieldInfo) const
 	{
 		if (mManagedInstance != nullptr)
 		{
-			MonoObject* fieldValue = fieldInfo->mMonoField->getValueBoxed(mManagedInstance);
+			MonoObject* fieldValue = fieldInfo->getValue(mManagedInstance);
 
 			return ManagedSerializableFieldData::create(fieldInfo->mTypeInfo, fieldValue);
 		}

+ 29 - 3
Source/SBansheeEngine/Source/BsManagedSerializableObjectInfo.cpp

@@ -47,7 +47,7 @@ namespace BansheeEngine
 
 	}
 
-	SPtr<ManagedSerializableFieldInfo> ManagedSerializableObjectInfo::findMatchingField(const SPtr<ManagedSerializableFieldInfo>& fieldInfo,
+	SPtr<ManagedSerializableMemberInfo> ManagedSerializableObjectInfo::findMatchingField(const SPtr<ManagedSerializableMemberInfo>& fieldInfo,
 		const SPtr<ManagedSerializableTypeInfo>& fieldTypeInfo) const
 	{
 		const ManagedSerializableObjectInfo* objInfo = this;
@@ -61,7 +61,7 @@ namespace BansheeEngine
 					auto iterFind2 = objInfo->mFields.find(iterFind->second);
 					if (iterFind2 != objInfo->mFields.end())
 					{
-						SPtr<ManagedSerializableFieldInfo> foundField = iterFind2->second;
+						SPtr<ManagedSerializableMemberInfo> foundField = iterFind2->second;
 						if (foundField->isSerializable())
 						{
 							if (fieldInfo->mTypeInfo->matches(foundField->mTypeInfo))
@@ -92,8 +92,24 @@ namespace BansheeEngine
 		return ManagedSerializableObjectInfo::getRTTIStatic();
 	}
 
+	ManagedSerializableMemberInfo::ManagedSerializableMemberInfo()
+		:mFieldId(0), mFlags((ScriptFieldFlags)0)
+	{
+
+	}
+
+	RTTITypeBase* ManagedSerializableMemberInfo::getRTTIStatic()
+	{
+		return ManagedSerializableMemberInfoRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableMemberInfo::getRTTI() const
+	{
+		return ManagedSerializableMemberInfo::getRTTIStatic();
+	}
+
 	ManagedSerializableFieldInfo::ManagedSerializableFieldInfo()
-		:mFieldId(0), mFlags((ScriptFieldFlags)0), mMonoField(nullptr)
+		:mMonoField(nullptr)
 	{
 
 	}
@@ -162,6 +178,16 @@ namespace BansheeEngine
 		return 0;
 	}
 
+	MonoObject* ManagedSerializableFieldInfo::getValue(MonoObject* instance) const
+	{
+		return mMonoField->getValueBoxed(instance);
+	}
+
+	void ManagedSerializableFieldInfo::setValue(MonoObject* instance, void* value) const
+	{
+		mMonoField->setValue(instance, value);
+	}
+
 	RTTITypeBase* ManagedSerializableFieldInfo::getRTTIStatic()
 	{
 		return ManagedSerializableFieldInfoRTTI::instance();

+ 2 - 0
Source/SBansheeEngine/Source/BsScriptAssemblyManager.cpp

@@ -140,8 +140,10 @@ namespace BansheeEngine
 					if (field->hasAttribute(mSerializeFieldAttribute))
 						fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Serializable);
 				}
+
 				if (field->hasAttribute(mRangeAttribute))
 					fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Range);
+
 				if (field->hasAttribute(mStepAttribute))
 					fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Step);
 

+ 0 - 2
Source/SBansheeEngine/Source/BsScriptRange.cpp

@@ -1,8 +1,6 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-
 #include "BsScriptRange.h"
-#include "BsScriptEnginePrerequisites.h"
 
 namespace BansheeEngine
 {

+ 5 - 5
Source/SBansheeEngine/Source/BsScriptSerializableField.cpp

@@ -12,7 +12,7 @@
 namespace BansheeEngine
 {
 
-	ScriptSerializableField::ScriptSerializableField(MonoObject* instance, const SPtr<ManagedSerializableFieldInfo>& fieldInfo)
+	ScriptSerializableField::ScriptSerializableField(MonoObject* instance, const SPtr<ManagedSerializableMemberInfo>& fieldInfo)
 		:ScriptObject(instance), mFieldInfo(fieldInfo)
 	{
 
@@ -29,7 +29,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_GetStep", &ScriptSerializableField::internal_getStep);
 	}
 
-	ScriptSerializableField* ScriptSerializableField::create(MonoObject* parentObject, const SPtr<ManagedSerializableFieldInfo>& fieldInfo)
+	ScriptSerializableField* ScriptSerializableField::create(MonoObject* parentObject, const SPtr<ManagedSerializableMemberInfo>& fieldInfo)
 	{
 		MonoString* monoStrName = MonoUtil::wstringToMono(toWString(fieldInfo->mName));
 		MonoReflectionType* internalType = MonoUtil::getType(fieldInfo->mTypeInfo->getMonoClass());
@@ -52,7 +52,7 @@ namespace BansheeEngine
 
 	MonoObject* ScriptSerializableField::internal_getValue(ScriptSerializableField* nativeInstance, MonoObject* instance)
 	{
-		return nativeInstance->mFieldInfo->mMonoField->getValueBoxed(instance);
+		return nativeInstance->mFieldInfo->getValue(instance);
 	}
 
 	void ScriptSerializableField::internal_setValue(ScriptSerializableField* nativeInstance, MonoObject* instance, MonoObject* value)
@@ -60,10 +60,10 @@ namespace BansheeEngine
 		if (value != nullptr && MonoUtil::isValueType((MonoUtil::getClass(value))))
 		{
 			void* rawValue = MonoUtil::unbox(value);
-			nativeInstance->mFieldInfo->mMonoField->setValue(instance, rawValue);
+			nativeInstance->mFieldInfo->setValue(instance, rawValue);
 		}
 		else
-			nativeInstance->mFieldInfo->mMonoField->setValue(instance, value);
+			nativeInstance->mFieldInfo->setValue(instance, value);
 	}
 	float ScriptSerializableField::internal_getRangeMaximum(ScriptSerializableField* nativeInstance) { return nativeInstance->mFieldInfo->getRangeMaximum(); }
 	float ScriptSerializableField::internal_getRangeMinimum(ScriptSerializableField* nativeInstance) { return nativeInstance->mFieldInfo->getRangeMinimum(); }

+ 2 - 2
Source/SBansheeEngine/Source/BsScriptSerializableObject.cpp

@@ -61,7 +61,7 @@ namespace BansheeEngine
 
 		ScriptSerializableObject* nativeInstance = new (bs_alloc<ScriptSerializableObject>()) ScriptSerializableObject(instance, typeInfo);
 
-		Vector<SPtr<ManagedSerializableFieldInfo>> sortedFields;
+		Vector<SPtr<ManagedSerializableMemberInfo>> sortedFields;
 		
 		if(objInfo != nullptr)
 		{
@@ -75,7 +75,7 @@ namespace BansheeEngine
 		}
 
 		std::sort(sortedFields.begin(), sortedFields.end(),
-			[&](const SPtr<ManagedSerializableFieldInfo>& x, const SPtr<ManagedSerializableFieldInfo>& y)
+			[&](const SPtr<ManagedSerializableMemberInfo>& x, const SPtr<ManagedSerializableMemberInfo>& y)
 		{
 			return x->mFieldId < y->mFieldId;
 		});