瀏覽代碼

Documentation
Fix for a null reference in inspector

Marko Pintera 10 年之前
父節點
當前提交
4527457d2f

+ 6 - 0
MBansheeEditor/Inspector/InspectableObject.cs

@@ -29,6 +29,12 @@ namespace BansheeEditor
                 return true;
                 return true;
 
 
             object newPropertyValue = property.GetValue<object>();
             object newPropertyValue = property.GetValue<object>();
+            if (propertyValue == null)
+                return newPropertyValue != null;
+            
+            if (newPropertyValue == null)
+                return propertyValue != null;
+            
             if (!propertyValue.Equals(newPropertyValue))
             if (!propertyValue.Equals(newPropertyValue))
                 return true;
                 return true;
 
 

+ 142 - 17
SBansheeEngine/Include/BsManagedSerializableDictionary.h

@@ -7,19 +7,7 @@
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	/**
 	/**
-	 * @brief	TODO
-	 *
-	 * @note	This class can be in two states:
-	 *			 - Linked - When the object has a link to a managed object. This is the default 
-	 *                      state when a new instance of ManagedSerializableObject is created.
-	 *						Any operations during this state will operate directly on the linked
-	 *						managed object.
-	 *			 - Serialized - When the object has no link to the managed object but instead just
-	 *							contains cached object and field data that may be used for initializing
-	 *							a managed object. Any operations during this state will operate
-	 *							only on the cached internal data.
-	 *			You can transfer between these states by calling serialize(linked->serialized) &
-	 *	
+	 * @brief	Contains key and value data used for serializing a managed dictionary.
 	 */
 	 */
 	struct BS_SCR_BE_EXPORT ManagedSerializableDictionaryKeyValue : public IReflectable
 	struct BS_SCR_BE_EXPORT ManagedSerializableDictionaryKeyValue : public IReflectable
 	{
 	{
@@ -36,19 +24,42 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableDictionaryKeyValueRTTI;
 		friend class ManagedSerializableDictionaryKeyValueRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Allows access to an underlying managed dictionary, or a cached version of that dictionary that
+	 *			can be serialized/deserialized.
+	 *
+	 * @note	This class can be in two states:
+	 *			 - Linked - When the object has a link to a managed object. This is the default 
+	 *                      state when a new instance of ManagedSerializableObject is created.
+	 *						Any operations during this state will operate directly on the linked
+	 *						managed object.
+	 *			 - Serialized - When the object has no link to the managed object but instead just
+	 *							contains cached object and field data that may be used for initializing
+	 *							a managed object. Any operations during this state will operate
+	 *							only on the cached internal data.
+	 *			You can transfer between these states by calling serialize(linked->serialized) &
+	 *			deserialize (serialized->linked).
+	 *	
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableDictionary : public IReflectable
 	class BS_SCR_BE_EXPORT ManagedSerializableDictionary : public IReflectable
 	{
 	{
 	private:
 	private:
 		struct ConstructPrivately {};
 		struct ConstructPrivately {};
 		
 		
+		/**
+		 * @brief	Generates a hash value for field data.
+		 */
 		struct BS_SCR_BE_EXPORT Hash
 		struct BS_SCR_BE_EXPORT Hash
 		{
 		{
 			inline size_t operator()(const ManagedSerializableFieldDataPtr& x) const;
 			inline size_t operator()(const ManagedSerializableFieldDataPtr& x) const;
 		};
 		};
 
 
+		/**
+		 * @brief	Compares two field data objects.
+		 */
 		struct BS_SCR_BE_EXPORT Equals
 		struct BS_SCR_BE_EXPORT Equals
 		{
 		{
 			inline bool operator()(const ManagedSerializableFieldDataPtr& a, const ManagedSerializableFieldDataPtr& b) const;
 			inline bool operator()(const ManagedSerializableFieldDataPtr& a, const ManagedSerializableFieldDataPtr& b) const;
@@ -57,14 +68,43 @@ namespace BansheeEngine
 	public:
 	public:
 		typedef UnorderedMap<ManagedSerializableFieldDataPtr, ManagedSerializableFieldDataPtr> CachedEntriesMap;
 		typedef UnorderedMap<ManagedSerializableFieldDataPtr, ManagedSerializableFieldDataPtr> CachedEntriesMap;
 
 
+		/**
+		 * @brief	Helper class that enumerates over all entires in a managed dictionary. Operates on 
+		 *			managed object if the parent dictionary is in linked state, or on cached data otherwise.
+		 */
 		class Enumerator
 		class Enumerator
 		{
 		{
 		public:
 		public:
+			/**
+			 * @brief	Constructs a new enumerator for the provided managed object.
+			 *
+			 * @param	instance	Managed instance of type System.Collections.Generic.Dictionary.
+			 * @param	parent		Serializable parent of the managed instance.
+			 */
 			Enumerator(MonoObject* instance, const ManagedSerializableDictionary* parent);
 			Enumerator(MonoObject* instance, const ManagedSerializableDictionary* parent);
 
 
+			/**
+			 * @brief	Returns the wrapped key data at the current enumerator position.
+			 *			Only valid to call this if enumerator is valid (i.e. last call to 
+			 *			::moveNext returned true).
+			 */
 			ManagedSerializableFieldDataPtr getKey() const;
 			ManagedSerializableFieldDataPtr getKey() const;
+
+			/**
+			 * @brief	Returns the wrapped value data at the current enumerator position.
+			 *			Only valid to call this if enumerator is valid (i.e. last call to 
+			 *			::moveNext returned true).
+			 */
 			ManagedSerializableFieldDataPtr getValue() const;
 			ManagedSerializableFieldDataPtr getValue() const;
 
 
+			/**
+			 * @brief	Moves the enumerator to the next position. Initially enumerator is
+			 *			at an invalid position and must be called at least once before accesing
+			 *			its data.
+			 *
+			 * @return	Returns if the enumerator is at valid position. When the enumerator returns
+			 *			false it means there are no more elements to enumerate.
+			 */
 			bool moveNext();
 			bool moveNext();
 
 
 		private:
 		private:
@@ -80,23 +120,107 @@ namespace BansheeEngine
 		ManagedSerializableDictionary(const ConstructPrivately& dummy, const ManagedSerializableTypeInfoDictionaryPtr& typeInfo, MonoObject* managedInstance);
 		ManagedSerializableDictionary(const ConstructPrivately& dummy, const ManagedSerializableTypeInfoDictionaryPtr& typeInfo, MonoObject* managedInstance);
 		ManagedSerializableDictionary(const ConstructPrivately& dummy);
 		ManagedSerializableDictionary(const ConstructPrivately& dummy);
 
 
+		/**
+		 * @brief	Returns the internal managed instance of the dictionary. This will return null if
+		 *			the object is in serialized mode.
+		 */
 		MonoObject* getManagedInstance() const { return mManagedInstance; }
 		MonoObject* getManagedInstance() const { return mManagedInstance; }
+
+		/**
+		 * @brief	Returns the type information for the internal dictionary.
+		 */
 		ManagedSerializableTypeInfoDictionaryPtr getTypeInfo() const { return mDictionaryTypeInfo; }
 		ManagedSerializableTypeInfoDictionaryPtr getTypeInfo() const { return mDictionaryTypeInfo; }
 
 
+		/**
+		 * @brief	Returns the dictionary value at the specified key. If the key doesn't exist
+		 *			the default value for the type is returned. Operates on managed object if in 
+		 *			linked state, or on cached data otherwise.
+		 *
+		 * @param	key		Wrapper around the key data at which to retrieve the value.
+		 *
+		 * @return	A wrapper around the value in the dictionary at the specified key.
+		 */
 		ManagedSerializableFieldDataPtr getFieldData(const ManagedSerializableFieldDataPtr& key);
 		ManagedSerializableFieldDataPtr getFieldData(const ManagedSerializableFieldDataPtr& key);
+
+		/**
+		 * @brief	Sets the dictionary value at the specified key. Operates on managed object if in 
+		 *			linked state, or on cached data otherwise.
+		 *
+		 * @param	key		Wrapper around the key data at which to set the value.
+		 * @param	val		Wrapper around the value to set at the specified key.
+		 */
 		void setFieldData(const ManagedSerializableFieldDataPtr& key, const ManagedSerializableFieldDataPtr& val);
 		void setFieldData(const ManagedSerializableFieldDataPtr& key, const ManagedSerializableFieldDataPtr& val);
+
+		/**
+		 * @brief	Deletes the key/value pair at the specified key. If the key doesn't exist
+		 *			this operation does nothing. Operates on managed object if in linked state, 
+		 *			or on cached data otherwise.
+		 *
+		 * @param	key		Wrapper around the key data at which to delete the value.
+		 */
 		void removeFieldData(const ManagedSerializableFieldDataPtr& key);
 		void removeFieldData(const ManagedSerializableFieldDataPtr& key);
+
+		/**
+		 * @brief	Checks if the dictionary contains the specified key. Operates on managed object 
+		 *			if in linked state, or on cached data otherwise.
+		 *
+		 * @param	key		Wrapper around the key data which to check.
+		 */
 		bool contains(const ManagedSerializableFieldDataPtr& key) const;
 		bool contains(const ManagedSerializableFieldDataPtr& key) const;
+
+		/**
+		 * @brief	Returns an enumerator object that allows you to iterate over
+		 *			all key/value pairs in the dictionary.
+		 */
 		Enumerator getEnumerator() const;
 		Enumerator getEnumerator() const;
 
 
+		/**
+		 * @brief	Serializes the internal managed object into a set of cached data that can be saved
+		 *			in memory/disk and can be deserialized later. Does nothing if object is already is 
+		 *			serialized mode. When in serialized mode the reference to the managed instance will be lost.
+		 */
 		void serialize();
 		void serialize();
+
+		/**
+		 * @brief	Deserializes a set of cached data into a managed object. This action may fail in case the cached
+		 *			data contains a type that no longer exists. You may check if it completely successfully if ::getManagedInstance
+		 *			returns non-null after.
+		 *
+		 *			This action transfers the object into linked mode. All further operations will operate directly on the managed instance
+		 *			and the cached data will be cleared. If you call this method on an already linked object the old object will be
+		 *			replaced and initialized with empty data (since cached data does not exist).
+		 */
 		void deserialize();
 		void deserialize();
 
 
+		/**
+		 * @brief	Creates a managed serializable dictionary that references an existing managed dictionary. Created object will be in linked mode.
+		 *
+		 * @param	managedInstance		Constructed managed instance of the dictionary to link with. Its type must correspond with the provided type info.
+		 * @param	typeInfo			Type information for the dictionary and its key/value pair.
+		 */
 		static ManagedSerializableDictionaryPtr createFromExisting(MonoObject* managedInstance, const ManagedSerializableTypeInfoDictionaryPtr& typeInfo);
 		static ManagedSerializableDictionaryPtr createFromExisting(MonoObject* managedInstance, const ManagedSerializableTypeInfoDictionaryPtr& typeInfo);
+
+		/**
+		 * @brief	Creates a managed serializable dictionary that creates and references a brand new managed dictionary instance.
+		 *
+		 * @param	typeInfo	Type of the dictionary to create.
+		 */
 		static ManagedSerializableDictionaryPtr createNew(const ManagedSerializableTypeInfoDictionaryPtr& typeInfo);
 		static ManagedSerializableDictionaryPtr createNew(const ManagedSerializableTypeInfoDictionaryPtr& typeInfo);
+
+		/**
+		 * @brief	Creates a managed dictionary instance.
+		 *
+		 * @param	typeInfo	Type of the dictionary to create.
+		 */
 		static MonoObject* createManagedInstance(const ManagedSerializableTypeInfoDictionaryPtr& typeInfo);
 		static MonoObject* createManagedInstance(const ManagedSerializableTypeInfoDictionaryPtr& typeInfo);
 
 
 	protected:
 	protected:
+		/**
+		 * @brief	Retrieves needed Mono types and methods. Should be called
+		 *			before performing any operations with the managed object.
+		 */
+		void initMonoObjects(MonoClass* dictionaryClass);
+
 		MonoObject* mManagedInstance;
 		MonoObject* mManagedInstance;
 
 
 		MonoMethod* mAddMethod;
 		MonoMethod* mAddMethod;
@@ -112,17 +236,18 @@ namespace BansheeEngine
 		ManagedSerializableTypeInfoDictionaryPtr mDictionaryTypeInfo;
 		ManagedSerializableTypeInfoDictionaryPtr mDictionaryTypeInfo;
 		CachedEntriesMap mCachedEntries;
 		CachedEntriesMap mCachedEntries;
 
 
-		void initMonoObjects(MonoClass* dictionaryClass);
-
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
 		
 		
+		/**
+		 * @brief	Creates an empty and uninitialized object used for serialization purposes.
+		 */
 		static ManagedSerializableDictionaryPtr createEmpty();
 		static ManagedSerializableDictionaryPtr createEmpty();
 
 
 	public:
 	public:
 		friend class ManagedSerializableDictionaryRTTI;
 		friend class ManagedSerializableDictionaryRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 }
 }

+ 132 - 22
SBansheeEngine/Include/BsManagedSerializableDiff.h

@@ -5,9 +5,25 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
+	/**
+	 * @brief	Handles creation and applying of managed diffs. A diff contains differences
+	 *			between two objects of identical types. If the initial state of an object
+	 *			is known the recorded differences can be saved and applied to the original
+	 *			state to restore the modified object.
+	 *
+	 *			Differences are recorded per primitive field in an object. 
+	 *			Complex objects are recursed. Special handling is implemented
+	 *			to properly generate diffs for arrays, lists and dictionaries.
+	 *
+	 *			All primitive types supported by managed serialization are supported.
+	 *			(see ScriptPrimitiveType)
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableDiff : public IReflectable
 	class BS_SCR_BE_EXPORT ManagedSerializableDiff : public IReflectable
 	{
 	{
 	public:
 	public:
+		/**
+		 * @brief	A base class for all modifications recorded in a diff.
+		 */
 		struct BS_SCR_BE_EXPORT Modification : public IReflectable
 		struct BS_SCR_BE_EXPORT Modification : public IReflectable
 		{
 		{
 			virtual ~Modification();
 			virtual ~Modification();
@@ -18,18 +34,22 @@ namespace BansheeEngine
 		public:
 		public:
 			friend class ModificationRTTI;
 			friend class ModificationRTTI;
 			static RTTITypeBase* getRTTIStatic();
 			static RTTITypeBase* getRTTIStatic();
-			virtual RTTITypeBase* getRTTI() const;
+			virtual RTTITypeBase* getRTTI() const override;
 		};
 		};
 
 
+		/**
+		 * @brief	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 : public IReflectable
 		{
 		{
 			ModifiedField() { }
 			ModifiedField() { }
 			ModifiedField(const ManagedSerializableTypeInfoPtr& parentType,
 			ModifiedField(const ManagedSerializableTypeInfoPtr& parentType,
 				const ManagedSerializableFieldInfoPtr& fieldType, const SPtr<Modification>& modification);
 				const ManagedSerializableFieldInfoPtr& fieldType, const SPtr<Modification>& modification);
 
 
-			ManagedSerializableTypeInfoPtr parentType;
-			ManagedSerializableFieldInfoPtr fieldType;
-			SPtr<Modification> modification;
+			ManagedSerializableTypeInfoPtr parentType; /**< Type of the parent object the field belongs to. */
+			ManagedSerializableFieldInfoPtr fieldType; /**< Data type of the field. */
+			SPtr<Modification> modification; /**< Recorded modification(s) on the field. */
 
 
 			/************************************************************************/
 			/************************************************************************/
 			/* 								RTTI		                     		*/
 			/* 								RTTI		                     		*/
@@ -37,16 +57,19 @@ namespace BansheeEngine
 		public:
 		public:
 			friend class ModifiedFieldRTTI;
 			friend class ModifiedFieldRTTI;
 			static RTTITypeBase* getRTTIStatic();
 			static RTTITypeBase* getRTTIStatic();
-			virtual RTTITypeBase* getRTTI() const;
+			virtual RTTITypeBase* getRTTI() const override;
 		};
 		};
 
 
+		/**
+		 * @brief	Represents a single modified array or list entry.
+		 */
 		struct BS_SCR_BE_EXPORT ModifiedArrayEntry : public IReflectable
 		struct BS_SCR_BE_EXPORT ModifiedArrayEntry : public IReflectable
 		{
 		{
 			ModifiedArrayEntry() { }
 			ModifiedArrayEntry() { }
 			ModifiedArrayEntry(UINT32 idx, const SPtr<Modification>& modification);
 			ModifiedArrayEntry(UINT32 idx, const SPtr<Modification>& modification);
 
 
-			UINT32 idx;
-			SPtr<Modification> modification;
+			UINT32 idx; /**< Index of the array/list entry that is modified. */
+			SPtr<Modification> modification; /**< Recorded modification(s) on the entry. */
 
 
 			/************************************************************************/
 			/************************************************************************/
 			/* 								RTTI		                     		*/
 			/* 								RTTI		                     		*/
@@ -54,16 +77,19 @@ namespace BansheeEngine
 		public:
 		public:
 			friend class ModifiedArrayEntryRTTI;
 			friend class ModifiedArrayEntryRTTI;
 			static RTTITypeBase* getRTTIStatic();
 			static RTTITypeBase* getRTTIStatic();
-			virtual RTTITypeBase* getRTTI() const;
+			virtual RTTITypeBase* getRTTI() const override;
 		};
 		};
 
 
+		/**
+		 * @brief	Represents a single modified dictionary entry.
+		 */
 		struct BS_SCR_BE_EXPORT ModifiedDictionaryEntry : public IReflectable
 		struct BS_SCR_BE_EXPORT ModifiedDictionaryEntry : public IReflectable
 		{
 		{
 			ModifiedDictionaryEntry() { }
 			ModifiedDictionaryEntry() { }
 			ModifiedDictionaryEntry(const ManagedSerializableFieldDataPtr& key, const SPtr<Modification>& modification);
 			ModifiedDictionaryEntry(const ManagedSerializableFieldDataPtr& key, const SPtr<Modification>& modification);
 
 
-			ManagedSerializableFieldDataPtr key;
-			SPtr<Modification> modification;
+			ManagedSerializableFieldDataPtr key; /**< Serialized value of the key for the modified entry. */
+			SPtr<Modification> modification; /**< Recorded modification(s) on the dictionary entry value. */
 
 
 			/************************************************************************/
 			/************************************************************************/
 			/* 								RTTI		                     		*/
 			/* 								RTTI		                     		*/
@@ -71,14 +97,18 @@ namespace BansheeEngine
 		public:
 		public:
 			friend class ModifiedArrayEntryRTTI;
 			friend class ModifiedArrayEntryRTTI;
 			static RTTITypeBase* getRTTIStatic();
 			static RTTITypeBase* getRTTIStatic();
-			virtual RTTITypeBase* getRTTI() const;
+			virtual RTTITypeBase* getRTTI() const override;
 		};
 		};
 
 
+		/**
+		 * @brief	Contains data about all modifications in a single complex object.
+		 *			(aside from arrays, list, dictionaries which are handled specially).
+		 */
 		struct BS_SCR_BE_EXPORT ModifiedObject : Modification
 		struct BS_SCR_BE_EXPORT ModifiedObject : Modification
 		{
 		{
 			static SPtr<ModifiedObject> create();
 			static SPtr<ModifiedObject> create();
 
 
-			Vector<ModifiedField> entries;
+			Vector<ModifiedField> entries; /**< A list of entries containing each modified field in the object. */
 
 
 			/************************************************************************/
 			/************************************************************************/
 			/* 								RTTI		                     		*/
 			/* 								RTTI		                     		*/
@@ -86,16 +116,19 @@ namespace BansheeEngine
 		public:
 		public:
 			friend class ModifiedObjectRTTI;
 			friend class ModifiedObjectRTTI;
 			static RTTITypeBase* getRTTIStatic();
 			static RTTITypeBase* getRTTIStatic();
-			virtual RTTITypeBase* getRTTI() const;
+			virtual RTTITypeBase* getRTTI() const override;
 		};
 		};
 
 
+		/**
+		 * @brief	Contains data about all modifications in an array or a list.
+		 */
 		struct BS_SCR_BE_EXPORT ModifiedArray : Modification
 		struct BS_SCR_BE_EXPORT ModifiedArray : Modification
 		{
 		{
 			static SPtr<ModifiedArray> create();
 			static SPtr<ModifiedArray> create();
 
 
-			Vector<ModifiedArrayEntry> entries;
-			Vector<UINT32> origSizes;
-			Vector<UINT32> newSizes;
+			Vector<ModifiedArrayEntry> entries; /**< A list of all modified array/list entries along with their indices. */
+			Vector<UINT32> origSizes; /**< Original size of the array/list (one size per dimension). */
+			Vector<UINT32> newSizes; /**< New size of the array/list (one size per dimension). */
 
 
 			/************************************************************************/
 			/************************************************************************/
 			/* 								RTTI		                     		*/
 			/* 								RTTI		                     		*/
@@ -103,15 +136,18 @@ namespace BansheeEngine
 		public:
 		public:
 			friend class ModifiedArrayRTTI;
 			friend class ModifiedArrayRTTI;
 			static RTTITypeBase* getRTTIStatic();
 			static RTTITypeBase* getRTTIStatic();
-			virtual RTTITypeBase* getRTTI() const;
+			virtual RTTITypeBase* getRTTI() const override;
 		};
 		};
 
 
+		/**
+		 * @brief	Contains data about all modifications in a dictionary.
+		 */
 		struct BS_SCR_BE_EXPORT ModifiedDictionary : Modification
 		struct BS_SCR_BE_EXPORT ModifiedDictionary : Modification
 		{
 		{
 			static SPtr<ModifiedDictionary> create();
 			static SPtr<ModifiedDictionary> create();
 
 
-			Vector<ModifiedDictionaryEntry> entries;
-			Vector<ManagedSerializableFieldDataPtr> removed;
+			Vector<ModifiedDictionaryEntry> entries; /**< A list of modified entries in the dictionary. */
+			Vector<ManagedSerializableFieldDataPtr> removed; /**< A list of keys for entries that were removed from the dictionary. */
 
 
 			/************************************************************************/
 			/************************************************************************/
 			/* 								RTTI		                     		*/
 			/* 								RTTI		                     		*/
@@ -119,9 +155,13 @@ namespace BansheeEngine
 		public:
 		public:
 			friend class ModifiedDictionaryRTTI;
 			friend class ModifiedDictionaryRTTI;
 			static RTTITypeBase* getRTTIStatic();
 			static RTTITypeBase* getRTTIStatic();
-			virtual RTTITypeBase* getRTTI() const;
+			virtual RTTITypeBase* getRTTI() const override;
 		};
 		};
 
 
+		/**
+		 * @brief	Contains data about modification of a primitive field.
+		 *			(i.e. fields new value)
+		 */
 		struct BS_SCR_BE_EXPORT ModifiedEntry : Modification
 		struct BS_SCR_BE_EXPORT ModifiedEntry : Modification
 		{
 		{
 			ModifiedEntry() { }
 			ModifiedEntry() { }
@@ -137,24 +177,94 @@ namespace BansheeEngine
 		public:
 		public:
 			friend class ModifiedEntryRTTI;
 			friend class ModifiedEntryRTTI;
 			static RTTITypeBase* getRTTIStatic();
 			static RTTITypeBase* getRTTIStatic();
-			virtual RTTITypeBase* getRTTI() const;
+			virtual RTTITypeBase* getRTTI() const override;
 		};
 		};
 
 
 	public:
 	public:
 		ManagedSerializableDiff();
 		ManagedSerializableDiff();
 		~ManagedSerializableDiff();
 		~ManagedSerializableDiff();
 
 
+		/**
+		 * @brief	Generates a new managed diff object by comparing two objects of the same type. Callers must
+		 *			ensure both objects are not null and of identical types.
+		 *
+		 * @param	oldObj	Original object. This is the object you can apply the diff to to convert it to /p newObj.
+		 * @param	newObj	New modified object. Any values in this object that differ from the original object will be
+		 *					recorded in the diff.
+		 *
+		 * @return	Returns null if objects are identical.
+		 */
 		static ManagedSerializableDiffPtr create(const ManagedSerializableObjectPtr& oldObj, const ManagedSerializableObjectPtr& newObj);
 		static ManagedSerializableDiffPtr create(const ManagedSerializableObjectPtr& oldObj, const ManagedSerializableObjectPtr& newObj);
+
+		/**
+		 * @brief	Applies the diff data stored in this object to the specified object, modifying all
+		 *			fields in the object to correspond to the stored diff data.
+		 */
 		void apply(const ManagedSerializableObjectPtr& obj);
 		void apply(const ManagedSerializableObjectPtr& obj);
 
 
 	private:
 	private:
+		/**
+		 * @brief	Recursively generates a diff between all fields of the specified objects. Returns null if objects are identical.
+		 */
 		SPtr<ModifiedObject> generateDiff(const ManagedSerializableObjectPtr& oldObj, const ManagedSerializableObjectPtr& newObj);
 		SPtr<ModifiedObject> generateDiff(const ManagedSerializableObjectPtr& oldObj, const ManagedSerializableObjectPtr& newObj);
+
+		/**
+		 * @brief	Generates a diff between two fields. Fields can be of any type and the system will generate the diff appropriately.
+		 *			Diff is generated recursively on all complex objects as well. Returns null if fields contain identical data.
+		 */
 		SPtr<Modification> generateDiff(const ManagedSerializableFieldDataPtr& oldData, const ManagedSerializableFieldDataPtr& newData,
 		SPtr<Modification> generateDiff(const ManagedSerializableFieldDataPtr& oldData, const ManagedSerializableFieldDataPtr& newData,
 			UINT32 fieldTypeId);
 			UINT32 fieldTypeId);
+
+		/**
+		 * @brief	Applies an object modification to a managed object. Modifications are applied recursively.
+		 *
+		 * @param	mod Object modification to apply.
+		 * @param	obj	Object to apply the modification to.
+		 *
+		 * @return	New field data in the case modification needed the object to be re-created instead of just modified.
+		 */
 		ManagedSerializableFieldDataPtr applyDiff(const SPtr<ModifiedObject>& mod, const ManagedSerializableObjectPtr& obj);
 		ManagedSerializableFieldDataPtr applyDiff(const SPtr<ModifiedObject>& mod, const ManagedSerializableObjectPtr& obj);
+
+		/**
+		 * @brief	Applies an array modification to a managed array. Modifications are applied recursively.
+		 *
+		 * @param	mod Array modification to apply.
+		 * @param	obj	Array to apply the modification to.
+		 *
+		 * @return	New field data in the case modification needed the array to be re-created instead of just modified.
+		 */
 		ManagedSerializableFieldDataPtr applyDiff(const SPtr<ModifiedArray>& mod, const ManagedSerializableArrayPtr& obj);
 		ManagedSerializableFieldDataPtr applyDiff(const SPtr<ModifiedArray>& mod, const ManagedSerializableArrayPtr& obj);
+
+		/**
+		 * @brief	Applies an list modification to a managed list. Modifications are applied recursively.
+		 *
+		 * @param	mod List modification to apply.
+		 * @param	obj	List to apply the modification to.
+		 *
+		 * @return	New field data in the case modification needed the list to be re-created instead of just modified.
+		 */
 		ManagedSerializableFieldDataPtr applyDiff(const SPtr<ModifiedArray>& mod, const ManagedSerializableListPtr& obj);
 		ManagedSerializableFieldDataPtr applyDiff(const SPtr<ModifiedArray>& mod, const ManagedSerializableListPtr& obj);
+
+		/**
+		 * @brief	Applies an dictionary modification to a managed dictionary. Modifications are applied recursively.
+		 *
+		 * @param	mod Dictionary modification to apply.
+		 * @param	obj	Dictionary to apply the modification to.
+		 *
+		 * @return	New field data in the case modification needed the dictionary to be re-created instead of just modified.
+		 */
 		ManagedSerializableFieldDataPtr applyDiff(const SPtr<ModifiedDictionary>& mod, const ManagedSerializableDictionaryPtr& obj);
 		ManagedSerializableFieldDataPtr applyDiff(const SPtr<ModifiedDictionary>& mod, const ManagedSerializableDictionaryPtr& obj);
+
+		/**
+		 * @brief	Applies a modification to a single field. Field type is determined and the modification is applied
+		 *			to the specific field type as needed. Modifications are applied recursively.
+		 *
+		 * @param	mod			Modification to apply.
+		 * @param	fieldType	Type of the field we're applying the modification to.
+		 * @param	origData	Original data of the field.
+		 *
+		 * @return	New field data in the case modification needed the field data to be re-created instead of just modified.
+		 */
 		ManagedSerializableFieldDataPtr applyDiff(const SPtr<Modification>& mod, const ManagedSerializableTypeInfoPtr& fieldType,
 		ManagedSerializableFieldDataPtr applyDiff(const SPtr<Modification>& mod, const ManagedSerializableTypeInfoPtr& fieldType,
 			const ManagedSerializableFieldDataPtr& origData);
 			const ManagedSerializableFieldDataPtr& origData);
 
 
@@ -166,6 +276,6 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableDiffRTTI;
 		friend class ManagedSerializableDiffRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 }
 }

+ 543 - 61
SBansheeEngine/Include/BsManagedSerializableField.h

@@ -6,11 +6,27 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
+	/**
+	 * @brief	Contains data that can be used for identifying a field in an object
+	 *			when cross referenced with the object type.
+	 *
+	 * @note	Essentially a light-weight identifier for the field so that we
+	 *			don't need to store entire field type for each field when serializing.
+	 *			Instead field types are stored separately and we just use this object
+	 *			for lookup.
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldKey : public IReflectable
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldKey : public IReflectable
 	{
 	{
 	public:
 	public:
 		ManagedSerializableFieldKey();
 		ManagedSerializableFieldKey();
 		ManagedSerializableFieldKey(UINT16 typeId, UINT16 fieldId);
 		ManagedSerializableFieldKey(UINT16 typeId, UINT16 fieldId);
+
+		/**
+		 * @brief	Creates a new field key.
+		 *
+		 * @param	typeId	Unique ID of the parent type the field belongs to. See ManagedSerializableTypeInfoObject.
+		 * @param	fieldId	Unique ID of the field within its parent class. See ManagedSerializableObjectInfo.
+		 */
 		static ManagedSerializableFieldKeyPtr create(UINT16 typeId, UINT16 fieldId);
 		static ManagedSerializableFieldKeyPtr create(UINT16 typeId, UINT16 fieldId);
 
 
 		UINT16 mTypeId;
 		UINT16 mTypeId;
@@ -23,21 +39,77 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ScriptSerializableFieldDataKeyRTTI;
 		friend class ScriptSerializableFieldDataKeyRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains value of a single field in a managed object. This
+	 *			class can contain any data type and should be overridden for specific types.
+	 *
+	 *			Stored values can be serialized and stored for later use, and deserialized
+	 *			back to managed objects when needed. You must call ::serialize before
+	 *			performing RTTI serialization. After field data has been serialized
+	 *			you should not call any methods on it before calling ::deserialize.
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldData : public IReflectable
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldData : public IReflectable
 	{
 	{
 	public:
 	public:
 		virtual ~ManagedSerializableFieldData() { }
 		virtual ~ManagedSerializableFieldData() { }
 
 
+		/**
+		 * @brief	Creates a new data wrapper for some field data.
+		 *
+		 * @param	typeInfo	Type of the data we're storing.
+		 * @param	value		Managed boxed value to store in the field. Value will be copied 
+		 *						into the internal buffer and stored.
+		 */
 		static ManagedSerializableFieldDataPtr create(const ManagedSerializableTypeInfoPtr& typeInfo, MonoObject* value);
 		static ManagedSerializableFieldDataPtr create(const ManagedSerializableTypeInfoPtr& typeInfo, MonoObject* value);
+
+		/**
+		 * @brief	Returns the internal value.
+		 *
+		 * @param	typeInfo	Type of the data we're looking to retrieve. This isn't required
+		 *						for actually retrieving the data but is used as an extra check
+		 *						to ensure the field contains the data type we're looking for.
+		 *
+		 * @return	Pointer to the internal serialized data. Caller must ensure the pointer
+		 *			is cast to the proper type.
+		 */
 		virtual void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) = 0;
 		virtual void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) = 0;
+
+		/**
+		 * @brief	Boxes the internal value and returns it.
+		 *
+		 * @param	typeInfo	Type of the data we're looking to retrieve. This isn't required
+		 *						for actually retrieving the data but is used as an extra check
+		 *						to ensure the field contains the data type we're looking for.
+		 *
+		 * @return	Boxed representation of the internal value.
+		 */
 		virtual MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) = 0;
 		virtual MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) = 0;
+
+		/**
+		 * @brief	Checks if the internal value stored in this object matches the value stored in another.
+		 *			Does shallow comparison for complex objects.
+		 */
 		virtual bool equals(const ManagedSerializableFieldDataPtr& other) = 0;
 		virtual bool equals(const ManagedSerializableFieldDataPtr& other) = 0;
+
+		/**
+		 * @brief	Returns a hash value for the internally stored value.
+		 */
 		virtual size_t getHash() = 0;
 		virtual size_t getHash() = 0;
 
 
+		/**
+		 * @brief	Serializes the internal value so that it may be stored and deserialized later.
+		 *
+		 * @note	This is generally only relevant for complex objects, as primitive types have their
+		 *			values copied and serialized automatically whenever field data is created.
+		 */
 		virtual void serialize() { }
 		virtual void serialize() { }
+
+		/**
+		 * @brief	Deserializes the internal value so that the managed instance can be retrieved.
+		 */
 		virtual void deserialize() { }
 		virtual void deserialize() { }
 
 
 		/************************************************************************/
 		/************************************************************************/
@@ -47,9 +119,12 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataRTTI;
 		friend class ManagedSerializableFieldDataRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains type and value of a single field in an object.
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataEntry : public IReflectable
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataEntry : public IReflectable
 	{
 	{
 	public:
 	public:
@@ -65,19 +140,39 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataEntryRTTI;
 		friend class ManagedSerializableFieldDataEntryRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains boolean field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataBool : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataBool : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		bool value = false;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		bool value = false;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -85,19 +180,39 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataBoolRTTI;
 		friend class ManagedSerializableFieldDataBoolRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains wide character field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataChar : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataChar : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		wchar_t value = 0;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		wchar_t value = 0;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -105,19 +220,39 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataCharRTTI;
 		friend class ManagedSerializableFieldDataCharRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains signed 8-bit integer field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */	
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataI8 : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataI8 : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		INT8 value = 0;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		INT8 value = 0;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -125,19 +260,39 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataI8RTTI;
 		friend class ManagedSerializableFieldDataI8RTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains unsigned 8-bit integer field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataU8 : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataU8 : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		UINT8 value = 0;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		UINT8 value = 0;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -145,19 +300,39 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataU8RTTI;
 		friend class ManagedSerializableFieldDataU8RTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains signed 16-bit integer field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataI16 : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataI16 : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		INT16 value = 0;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		INT16 value = 0;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -165,19 +340,39 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataI16RTTI;
 		friend class ManagedSerializableFieldDataI16RTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains unsigned 16-bit field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataU16 : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataU16 : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		UINT16 value = 0;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		UINT16 value = 0;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -185,19 +380,39 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataU16RTTI;
 		friend class ManagedSerializableFieldDataU16RTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains signed 32-bit integer field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataI32 : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataI32 : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		INT32 value = 0;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		INT32 value = 0;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -205,19 +420,39 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataI32RTTI;
 		friend class ManagedSerializableFieldDataI32RTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains unsigned 32-bit integer field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataU32 : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataU32 : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		UINT32 value = 0;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		UINT32 value = 0;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -225,19 +460,39 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataU32RTTI;
 		friend class ManagedSerializableFieldDataU32RTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains signed 64-bit integer field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataI64 : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataI64 : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		INT64 value = 0;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		INT64 value = 0;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -245,19 +500,39 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataI64RTTI;
 		friend class ManagedSerializableFieldDataI64RTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains unsigned 64-bit integer field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataU64 : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataU64 : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		UINT64 value = 0;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		UINT64 value = 0;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -265,19 +540,39 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataU64RTTI;
 		friend class ManagedSerializableFieldDataU64RTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains single precision floating point field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataFloat : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataFloat : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		float value = 0.0f;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		float value = 0.0f;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -285,20 +580,39 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataFloatRTTI;
 		friend class ManagedSerializableFieldDataFloatRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
-
+	/**
+	 * @brief	Contains double precision floating point field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataDouble : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataDouble : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		double value = 0.0;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		double value = 0.0;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -306,19 +620,39 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataDoubleRTTI;
 		friend class ManagedSerializableFieldDataDoubleRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains wide character string field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataString : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataString : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		WString value;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		WString value;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -326,19 +660,39 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataStringRTTI;
 		friend class ManagedSerializableFieldDataStringRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains resource reference field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataResourceRef : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataResourceRef : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		HResource value;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		HResource value;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -346,19 +700,39 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataResourceRefRTTI;
 		friend class ManagedSerializableFieldDataResourceRefRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains game object reference field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataGameObjectRef : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataGameObjectRef : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		HGameObject value;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		HGameObject value;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -366,22 +740,49 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataGameObjectRefRTTI;
 		friend class ManagedSerializableFieldDataGameObjectRefRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains complex object field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataObject : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataObject : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		ManagedSerializableObjectPtr value;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		/**
+		 * @copydoc ManagedSerializableFieldData::serialize
+		 */
 		virtual void serialize() override;
 		virtual void serialize() override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::deserialize
+		 */
 		virtual void deserialize() override;
 		virtual void deserialize() override;
 
 
+		ManagedSerializableObjectPtr value;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -389,22 +790,49 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataObjectRTTI;
 		friend class ManagedSerializableFieldDataObjectRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains array field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataArray : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataArray : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		ManagedSerializableArrayPtr value;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		/**
+		 * @copydoc ManagedSerializableFieldData::serialize
+		 */
 		virtual void serialize() override;
 		virtual void serialize() override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::deserialize
+		 */
 		virtual void deserialize() override;
 		virtual void deserialize() override;
 
 
+		ManagedSerializableArrayPtr value;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -412,22 +840,49 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataArrayRTTI;
 		friend class ManagedSerializableFieldDataArrayRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains list field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataList : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataList : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		ManagedSerializableListPtr value;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		/**
+		 * @copydoc ManagedSerializableFieldData::serialize
+		 */
 		virtual void serialize() override;
 		virtual void serialize() override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::deserialize
+		 */
 		virtual void deserialize() override;
 		virtual void deserialize() override;
 
 
+		ManagedSerializableListPtr value;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -435,22 +890,49 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataListRTTI;
 		friend class ManagedSerializableFieldDataListRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 
 
+	/**
+	 * @brief	Contains dictionary field data.
+	 *
+	 * @copydoc	ManagedSerializableFieldData
+	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataDictionary : public ManagedSerializableFieldData
 	class BS_SCR_BE_EXPORT ManagedSerializableFieldDataDictionary : public ManagedSerializableFieldData
 	{
 	{
 	public:
 	public:
-		ManagedSerializableDictionaryPtr value;
-
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValue
+		 */
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		void* getValue(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getValueBoxed
+		 */
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
 		MonoObject* getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::equals
+		 */
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
 		bool equals(const ManagedSerializableFieldDataPtr& other) override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::getHash
+		 */
 		size_t getHash() override;
 		size_t getHash() override;
 
 
+		/**
+		 * @copydoc ManagedSerializableFieldData::serialize
+		 */
 		virtual void serialize() override;
 		virtual void serialize() override;
+
+		/**
+		 * @copydoc ManagedSerializableFieldData::deserialize
+		 */
 		virtual void deserialize() override;
 		virtual void deserialize() override;
 
 
+		ManagedSerializableDictionaryPtr value;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
@@ -458,6 +940,6 @@ namespace BansheeEngine
 	public:
 	public:
 		friend class ManagedSerializableFieldDataDictionaryRTTI;
 		friend class ManagedSerializableFieldDataDictionaryRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 }
 }

+ 95 - 6
SBansheeEngine/Include/BsManagedSerializableList.h

@@ -7,7 +7,8 @@
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	/**
 	/**
-	 * @brief	TODO
+	 * @brief	Allows access to an underlying managed list, or a cached version of that list that
+	 *			can be serialized/deserialized.
 	 *
 	 *
 	 * @note	This class can be in two states:
 	 * @note	This class can be in two states:
 	 *			 - Linked - When the object has a link to a managed object. This is the default 
 	 *			 - Linked - When the object has a link to a managed object. This is the default 
@@ -19,6 +20,7 @@ namespace BansheeEngine
 	 *							a managed object. Any operations during this state will operate
 	 *							a managed object. Any operations during this state will operate
 	 *							only on the cached internal data.
 	 *							only on the cached internal data.
 	 *			You can transfer between these states by calling serialize(linked->serialized) &
 	 *			You can transfer between these states by calling serialize(linked->serialized) &
+	 *			deserialize (serialized->linked).
 	 *	
 	 *	
 	 */
 	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableList : public IReflectable
 	class BS_SCR_BE_EXPORT ManagedSerializableList : public IReflectable
@@ -30,22 +32,110 @@ namespace BansheeEngine
 		ManagedSerializableList(const ConstructPrivately& dummy, const ManagedSerializableTypeInfoListPtr& typeInfo, MonoObject* managedInstance);
 		ManagedSerializableList(const ConstructPrivately& dummy, const ManagedSerializableTypeInfoListPtr& typeInfo, MonoObject* managedInstance);
 		ManagedSerializableList(const ConstructPrivately& dummy);
 		ManagedSerializableList(const ConstructPrivately& dummy);
 
 
+		/**
+		 * @brief	Returns the internal managed instance of the list. This will return null if
+		 *			the object is in serialized mode.
+		 */
 		MonoObject* getManagedInstance() const { return mManagedInstance; }
 		MonoObject* getManagedInstance() const { return mManagedInstance; }
+
+		/**
+		 * @brief	Returns the type information for the internal list.
+		 */
 		ManagedSerializableTypeInfoListPtr getTypeInfo() const { return mListTypeInfo; }
 		ManagedSerializableTypeInfoListPtr getTypeInfo() const { return mListTypeInfo; }
 
 
+		/**
+		 * @brief	Changes the size of the list. Operates on managed object if in linked state, 
+		 *			or on cached data otherwise.
+		 */
 		void resize(UINT32 newSize);
 		void resize(UINT32 newSize);
+
+		/**
+		 * @brief	Sets a new element value at the specified list index. Operates on 
+		 *			managed object if in linked state, or on cached data otherwise.
+		 *
+		 * @param	arrayIdx	Index at which to set the value.
+		 * @param	val			Wrapper around the value to store in the list. Must be of the
+		 *						list element type.
+		 */
 		void setFieldData(UINT32 arrayIdx, const ManagedSerializableFieldDataPtr& val);
 		void setFieldData(UINT32 arrayIdx, const ManagedSerializableFieldDataPtr& val);
+
+		/**
+		 * @brief	Returns the element value at the specified list index. Operates on 
+		 *			managed object if in linked state, or on cached data otherwise.
+		 *
+		 * @param	arrayIdx	Index at which to retrieve the value.
+		 *
+		 * @return	A wrapper around the element value in the list.
+		 */
 		ManagedSerializableFieldDataPtr getFieldData(UINT32 arrayIdx);
 		ManagedSerializableFieldDataPtr getFieldData(UINT32 arrayIdx);
+
+		/**
+		 * @brief	Returns the size of the list. Operates on managed object 
+		 *			if in linked state, or on cached data otherwise.
+		 */
 		UINT32 getLength() const { return mNumElements; }
 		UINT32 getLength() const { return mNumElements; }
 
 
+		/**
+		 * @brief	Serializes the internal managed object into a set of cached data that can be saved
+		 *			in memory/disk and can be deserialized later. Does nothing if object is already is 
+		 *			serialized mode. When in serialized mode the reference to the managed instance will be lost.
+		 */
 		void serialize();
 		void serialize();
+
+		/**
+		 * @brief	Deserializes a set of cached data into a managed object. This action may fail in case the cached
+		 *			data contains a type that no longer exists. You may check if it completely successfully if ::getManagedInstance
+		 *			returns non-null after.
+		 *
+		 *			This action transfers the object into linked mode. All further operations will operate directly on the managed instance
+		 *			and the cached data will be cleared. If you call this method on an already linked object the old object will be
+		 *			replaced and initialized with empty data (since cached data does not exist).
+		 */
 		void deserialize();
 		void deserialize();
 
 
+		/**
+		 * @brief	Creates a managed serializable list that references an existing managed list. Created object will be in linked mode.
+		 *
+		 * @param	managedInstance		Constructed managed instance of the list to link with. Its type must correspond with the provided type info.
+		 * @param	typeInfo			Type information for the list and its elements.
+		 */
 		static ManagedSerializableListPtr createFromExisting(MonoObject* managedInstance, const ManagedSerializableTypeInfoListPtr& typeInfo);
 		static ManagedSerializableListPtr createFromExisting(MonoObject* managedInstance, const ManagedSerializableTypeInfoListPtr& typeInfo);
+
+		/**
+		 * @brief	Creates a managed serializable list that creates and references a brand new managed list instance.
+		 *
+		 * @param	typeInfo	Type of the list to create.
+		 * @param	size		Initial size of the list.
+		 */
 		static ManagedSerializableListPtr createNew(const ManagedSerializableTypeInfoListPtr& typeInfo, UINT32 size);
 		static ManagedSerializableListPtr createNew(const ManagedSerializableTypeInfoListPtr& typeInfo, UINT32 size);
+
+		/**
+		 * @brief	Creates a managed list instance.
+		 *
+		 * @param	typeInfo	Type of the list to create.
+		 * @param	size		Initial size of the list.
+		 */
 		static MonoObject* createManagedInstance(const ManagedSerializableTypeInfoListPtr& typeInfo, UINT32 size);
 		static MonoObject* createManagedInstance(const ManagedSerializableTypeInfoListPtr& typeInfo, UINT32 size);
 
 
 	protected:
 	protected:
+		/**
+		 * @brief	Retrieves needed Mono types and methods. Should be called
+		 *			before performing any operations with the managed object.
+		 */
+		void initMonoObjects(MonoClass* listClass);
+
+		/**
+		 * @brief	Returns the size of the list. Operates on the 
+		 *			internal managed object.
+		 */
+		UINT32 getLengthInternal() const;
+
+		/**
+		 * @brief	Appends data to the end of the list. Operates on
+		 *			the internal managed object.
+		 */
+		void addFieldDataInternal(const ManagedSerializableFieldDataPtr& val);
+
 		MonoObject* mManagedInstance;
 		MonoObject* mManagedInstance;
 
 
 		MonoMethod* mAddMethod;
 		MonoMethod* mAddMethod;
@@ -59,19 +149,18 @@ namespace BansheeEngine
 		Vector<ManagedSerializableFieldDataPtr> mCachedEntries;
 		Vector<ManagedSerializableFieldDataPtr> mCachedEntries;
 		UINT32 mNumElements;
 		UINT32 mNumElements;
 
 
-		void initMonoObjects(MonoClass* listClass);
-		UINT32 getLengthInternal() const;
-		void addFieldDataInternal(const ManagedSerializableFieldDataPtr& val);
-
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
 		
 		
+		/**
+		 * @brief	Creates an empty and uninitialized object used for serialization purposes.
+		 */
 		static ManagedSerializableListPtr createEmpty();
 		static ManagedSerializableListPtr createEmpty();
 
 
 	public:
 	public:
 		friend class ManagedSerializableListRTTI;
 		friend class ManagedSerializableListRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 }
 }

+ 72 - 3
SBansheeEngine/Include/BsManagedSerializableObject.h

@@ -8,7 +8,8 @@
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	/**
 	/**
-	 * @brief	TODO
+	 * @brief	Allows access to an underlying managed object, or a cached version of that object that
+	 *			can be serialized/deserialized.
 	 *
 	 *
 	 * @note	This class can be in two states:
 	 * @note	This class can be in two states:
 	 *			 - Linked - When the object has a link to a managed object. This is the default 
 	 *			 - Linked - When the object has a link to a managed object. This is the default 
@@ -20,18 +21,25 @@ namespace BansheeEngine
 	 *							a managed object. Any operations during this state will operate
 	 *							a managed object. Any operations during this state will operate
 	 *							only on the cached internal data.
 	 *							only on the cached internal data.
 	 *			You can transfer between these states by calling serialize(linked->serialized) &
 	 *			You can transfer between these states by calling serialize(linked->serialized) &
-	 *			deserialize(serialized->linked).
+	 *			deserialize (serialized->linked).
+	 *	
 	 */
 	 */
 	class BS_SCR_BE_EXPORT ManagedSerializableObject : public IReflectable
 	class BS_SCR_BE_EXPORT ManagedSerializableObject : public IReflectable
 	{
 	{
 	private:
 	private:
 		struct ConstructPrivately {};
 		struct ConstructPrivately {};
 
 
+		/**
+		 * @brief	Generates a hash value for field key data identifying a single field in the object.
+		 */
 		struct BS_SCR_BE_EXPORT Hash
 		struct BS_SCR_BE_EXPORT Hash
 		{
 		{
 			inline size_t operator()(const ManagedSerializableFieldKey& x) const;
 			inline size_t operator()(const ManagedSerializableFieldKey& x) const;
 		};
 		};
 
 
+		/**
+		 * @brief	Compares two field key objects.
+		 */
 		struct BS_SCR_BE_EXPORT Equals
 		struct BS_SCR_BE_EXPORT Equals
 		{
 		{
 			inline bool operator()(const ManagedSerializableFieldKey& a, const ManagedSerializableFieldKey& b) const;
 			inline bool operator()(const ManagedSerializableFieldKey& a, const ManagedSerializableFieldKey& b) const;
@@ -41,17 +49,75 @@ namespace BansheeEngine
 		ManagedSerializableObject(const ConstructPrivately& dummy, ManagedSerializableObjectInfoPtr objInfo, MonoObject* managedInstance);
 		ManagedSerializableObject(const ConstructPrivately& dummy, ManagedSerializableObjectInfoPtr objInfo, MonoObject* managedInstance);
 		ManagedSerializableObject(const ConstructPrivately& dummy);
 		ManagedSerializableObject(const ConstructPrivately& dummy);
 
 
+		/**
+		 * @brief	Returns the internal managed instance of the object. This will return null if
+		 *			the object is in serialized mode.
+		 */
 		MonoObject* getManagedInstance() const { return mManagedInstance; }
 		MonoObject* getManagedInstance() const { return mManagedInstance; }
+
+		/**
+		 * @brief	Returns the type information for the internal object.
+		 */
 		ManagedSerializableObjectInfoPtr getObjectInfo() const { return mObjInfo; }
 		ManagedSerializableObjectInfoPtr getObjectInfo() const { return mObjInfo; }
 
 
+		/**
+		 * @brief	Sets a new value of the specified field. Operates on 
+		 *			managed object if in linked state, or on cached data otherwise.
+		 *
+		 * @param	fieldInfo	Object describing the field to which to set the value. This field
+		 *						must belong to the type this object is initialized with.
+		 * @param	val			Wrapper around the value to store in the field.
+		 */
 		void setFieldData(const ManagedSerializableFieldInfoPtr& fieldInfo, const ManagedSerializableFieldDataPtr& val);
 		void setFieldData(const ManagedSerializableFieldInfoPtr& fieldInfo, const ManagedSerializableFieldDataPtr& val);
+
+		/**
+		 * @brief	Returns the value of the specified field. Operates on managed object 
+		 *			if in linked state, or on cached data otherwise.
+		 *
+		 * @param	fieldInfo	Object describing the field to which to set the value. This field
+		 *						must belong to the type this object is initialized with.
+		 *
+		 * @return	A wrapper around the value of the field.
+		 */
 		ManagedSerializableFieldDataPtr getFieldData(const ManagedSerializableFieldInfoPtr& fieldInfo) const;
 		ManagedSerializableFieldDataPtr getFieldData(const ManagedSerializableFieldInfoPtr& fieldInfo) const;
 
 
+		/**
+		 * @brief	Serializes the internal managed object into a set of cached data that can be saved
+		 *			in memory/disk and can be deserialized later. Does nothing if object is already is 
+		 *			serialized mode. When in serialized mode the reference to the managed instance will be lost.
+		 */
 		void serialize();
 		void serialize();
+
+		/**
+		 * @brief	Deserializes a set of cached data into a managed object. This action may fail in case the cached
+		 *			data contains a type that no longer exists. You may check if it completely successfully if ::getManagedInstance
+		 *			returns non-null after.
+		 *
+		 *			This action transfers the object into linked mode. All further operations will operate directly on the managed instance
+		 *			and the cached data will be cleared. If you call this method on an already linked object the old object will be
+		 *			replaced and initialized with empty data (since cached data does not exist).
+		 */
 		void deserialize();
 		void deserialize();
 
 
+		/**
+		 * @brief	Creates a managed serializable object that references an existing managed object. Created object will be in linked mode.
+		 *
+		 * @param	managedInstance		Constructed managed instance of the object to link with.
+		 */
 		static ManagedSerializableObjectPtr createFromExisting(MonoObject* managedInstance);
 		static ManagedSerializableObjectPtr createFromExisting(MonoObject* managedInstance);
+
+		/**
+		 * @brief	Creates a managed serializable object that creates and references a brand new managed object instance.
+		 *
+		 * @param	type	Type of the object to create.
+		 */
 		static ManagedSerializableObjectPtr createNew(const ManagedSerializableTypeInfoObjectPtr& type);
 		static ManagedSerializableObjectPtr createNew(const ManagedSerializableTypeInfoObjectPtr& type);
+
+		/**
+		 * @brief	Creates a managed object instance.
+		 *
+		 * @param	type	Type of the object to create.
+		 */
 		static MonoObject* createManagedInstance(const ManagedSerializableTypeInfoObjectPtr& type);
 		static MonoObject* createManagedInstance(const ManagedSerializableTypeInfoObjectPtr& type);
 	protected:
 	protected:
 		MonoObject* mManagedInstance;
 		MonoObject* mManagedInstance;
@@ -63,11 +129,14 @@ namespace BansheeEngine
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 		/************************************************************************/
 		
 		
+		/**
+		 * @brief	Creates an empty and uninitialized object used for serialization purposes.
+		 */
 		static ManagedSerializableObjectPtr createEmpty();
 		static ManagedSerializableObjectPtr createEmpty();
 
 
 	public:
 	public:
 		friend class ManagedSerializableObjectRTTI;
 		friend class ManagedSerializableObjectRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
+		virtual RTTITypeBase* getRTTI() const override;
 	};
 	};
 }
 }

+ 4 - 5
TODO.txt

@@ -57,13 +57,12 @@ Code quality improvements:
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 Polish stage 1
 Polish stage 1
 
 
-StringTable TODO:
-  - Issue in ScriptStringTable - I should allow it to be created from C# and in that case I need to call Internal_CreateInstance,
-    but it seems I'm using the default constructor for something else so I can't call it there (or can I?)
-  - Need to actually save & load the string tables from somewhere (probably don't need this for now)
+Fix inspector crashes:
+ - Try expanding/collapsing foldouts
+ - Had one with invalid index in Layout.InsertElement called from InspectableObject.Update
+ - And another 
 
 
 Test inspector selection, selecting a resource and adding/removing component updates
 Test inspector selection, selecting a resource and adding/removing component updates
-Crash when showing the inspector (invalid index in Layout.InsertElement called from InspectableObject.Update)
 Handle seems to lag behind the selected mesh
 Handle seems to lag behind the selected mesh
 ProjectLibrary seems to import some files on every start-up
 ProjectLibrary seems to import some files on every start-up
 Crash on shutdown in mono_gchandle_free
 Crash on shutdown in mono_gchandle_free