Ver Fonte

Added Animable flag for serializable fields
Added visibility getter for MonoMethod and MonoProperty
Refactored serializable field style properties so they're in a separate structure

BearishSun há 9 anos atrás
pai
commit
65f9081e9c

+ 1 - 11
Source/BansheeMono/Include/BsMonoField.h

@@ -10,16 +10,6 @@ namespace BansheeEngine
 	 *  @{
 	 */
 
-	/**	Returns the level of field visibility in the class. */
-	enum class MonoFieldVisibility
-	{
-		Private,
-		ProtectedInternal,
-		Internal,
-		Protected,
-		Public
-	};
-
 	/**
 	 * Encapsulates information about a single Mono (managed) field belonging to some managed class. This object also
 	 * allows you to set or retrieve values to/from specific instances containing the field.
@@ -68,7 +58,7 @@ namespace BansheeEngine
 		MonoObject* getAttribute(MonoClass* monoClass);
 
 		/**	Returns field visibility in the class. */
-		MonoFieldVisibility getVisibility();
+		MonoMemberVisibility getVisibility();
 
 		/**	Query if the field is static. */
 		bool isStatic();

+ 3 - 0
Source/BansheeMono/Include/BsMonoMethod.h

@@ -74,6 +74,9 @@ namespace BansheeEngine
 		 */
 		MonoObject* getAttribute(MonoClass* monoClass) const;
 
+		/**	Returns method visibility in the class. */
+		MonoMemberVisibility getVisibility();
+
 	private:
 		friend class MonoClass;
 		friend class MonoProperty;

+ 10 - 0
Source/BansheeMono/Include/BsMonoPrerequisites.h

@@ -61,6 +61,16 @@ namespace BansheeEngine
 		Generic,
 		Unknown
 	};
+
+	/**	Returns the level of member visibility in the class. */
+	enum class MonoMemberVisibility // Note: Elements must be ordered from most to least hidden
+	{
+		Private,
+		Protected,
+		Internal,
+		ProtectedInternal,
+		Public
+	};
 }
 
 typedef struct _MonoClass MonoClass;

+ 6 - 0
Source/BansheeMono/Include/BsMonoProperty.h

@@ -70,6 +70,12 @@ namespace BansheeEngine
 		 * attribute.
 		 */
 		MonoObject* getAttribute(MonoClass* monoClass);
+
+		/**	
+		 * Returns property visibility in the class. If getter/setter methods have different visibility, the more 
+		 * restrictive one is returned.
+		 */
+		MonoMemberVisibility getVisibility();
 	private:
 		friend class MonoClass;
 

+ 7 - 7
Source/BansheeMono/Source/BsMonoField.cpp

@@ -78,23 +78,23 @@ namespace BansheeEngine
 		return foundAttr;
 	}
 
-	MonoFieldVisibility MonoField::getVisibility()
+	MonoMemberVisibility MonoField::getVisibility()
 	{
 		uint32_t flags = mono_field_get_flags(mField) & MONO_FIELD_ATTR_FIELD_ACCESS_MASK;
 
 		if(flags == MONO_FIELD_ATTR_PRIVATE)
-			return MonoFieldVisibility::Private;
+			return MonoMemberVisibility::Private;
 		else if(flags == MONO_FIELD_ATTR_FAM_AND_ASSEM)
-			return MonoFieldVisibility::ProtectedInternal;
+			return MonoMemberVisibility::ProtectedInternal;
 		else if(flags == MONO_FIELD_ATTR_ASSEMBLY)
-			return MonoFieldVisibility::Internal;
+			return MonoMemberVisibility::Internal;
 		else if(flags == MONO_FIELD_ATTR_FAMILY)
-			return MonoFieldVisibility::Protected;
+			return MonoMemberVisibility::Protected;
 		else if(flags == MONO_FIELD_ATTR_PUBLIC)
-			return MonoFieldVisibility::Public;
+			return MonoMemberVisibility::Public;
 
 		assert(false);
-		return MonoFieldVisibility::Private;
+		return MonoMemberVisibility::Private;
 	}
 
 	bool MonoField::isStatic()

+ 20 - 0
Source/BansheeMono/Source/BsMonoMethod.cpp

@@ -6,6 +6,7 @@
 #include "BsMonoClass.h"
 #include "BsException.h"
 #include <mono/jit/jit.h>
+#include <mono/metadata/attrdefs.h>
 
 namespace BansheeEngine
 {
@@ -117,6 +118,25 @@ namespace BansheeEngine
 		return foundAttr;
 	}
 
+	MonoMemberVisibility MonoMethod::getVisibility()
+	{
+		uint32_t flags = mono_method_get_flags(mMethod, nullptr) & MONO_METHOD_ATTR_ACCESS_MASK;
+
+		if (flags == MONO_METHOD_ATTR_PRIVATE)
+			return MonoMemberVisibility::Private;
+		else if (flags == MONO_METHOD_ATTR_FAM_AND_ASSEM)
+			return MonoMemberVisibility::ProtectedInternal;
+		else if (flags == MONO_METHOD_ATTR_ASSEM)
+			return MonoMemberVisibility::Internal;
+		else if (flags == MONO_METHOD_ATTR_FAMILY)
+			return MonoMemberVisibility::Protected;
+		else if (flags == MONO_METHOD_ATTR_PUBLIC)
+			return MonoMemberVisibility::Public;
+
+		assert(false);
+		return MonoMemberVisibility::Private;
+	}
+
 	void MonoMethod::cacheSignature() const
 	{
 		MonoMethodSignature* methodSignature = mono_method_signature(mMethod);

+ 23 - 0
Source/BansheeMono/Source/BsMonoProperty.cpp

@@ -5,6 +5,7 @@
 #include "BsMonoManager.h"
 #include "BsMonoClass.h"
 #include <mono/jit/jit.h>
+#include <mono/metadata/class.h>
 
 namespace BansheeEngine
 {
@@ -98,6 +99,28 @@ namespace BansheeEngine
 		return foundAttr;
 	}
 
+	MonoMemberVisibility MonoProperty::getVisibility()
+	{
+		MonoMemberVisibility getterVisibility = MonoMemberVisibility::Public;
+		if(mGetMethod)
+		{
+			MonoMethod getterWrapper(mGetMethod);
+			getterVisibility = getterWrapper.getVisibility();
+		}
+
+		MonoMemberVisibility setterVisibility = MonoMemberVisibility::Public;
+		if (mSetMethod)
+		{
+			MonoMethod setterWrapper(mSetMethod);
+			setterVisibility = setterWrapper.getVisibility();
+		}
+
+		if (getterVisibility < setterVisibility)
+			return getterVisibility;
+
+		return setterVisibility;
+	}
+
 	void MonoProperty::initializeDeferred() const
 	{
 		if (mGetMethod != nullptr)

+ 57 - 1
Source/BansheeUtility/Include/BsFlags.h

@@ -231,5 +231,61 @@ namespace BansheeEngine
 		inline Flags<Enum, Storage> operator&(Enum a, Enum b) { Flags<Enum, Storage> r(a); r &= b; return r; } \
 		inline Flags<Enum, Storage> operator~(Enum a) { return ~Flags<Enum, Storage>(a); }
 
-	 /** @} */
+	/** @cond SPECIALIZATIONS */
+
+	/**
+	 * RTTIPlainType for Flags.
+	 * 			
+	 * @see		RTTIPlainType
+	 */
+	template<class Enum, class Storage> struct RTTIPlainType<Flags<Enum, Storage>>
+	{	
+		enum { id = TID_Pair }; enum { hasDynamicSize = 0 };
+
+		/** @copydoc RTTIPlainType::toMemory */
+		static void toMemory(const Flags<Enum, Storage>& data, char* memory)
+		{ 
+			UINT32 size = sizeof(UINT32);
+			char* memoryStart = memory;
+			memory += sizeof(UINT32);
+
+			Storage storageData = (Storage)data;
+
+			size += RTTIPlainType<Storage>::getDynamicSize(storageData);
+			RTTIPlainType<Storage>::toMemory(storageData, memory);
+
+			memcpy(memoryStart, &size, sizeof(UINT32));
+		}
+
+		/** @copydoc RTTIPlainType::fromMemory */
+		static UINT32 fromMemory(Flags<Enum, Storage>& data, char* memory)
+		{ 
+			UINT32 size = 0;
+			memcpy(&size, memory, sizeof(UINT32));
+			memory += sizeof(UINT32);
+
+			Storage storageData;
+			RTTIPlainType<Storage>::fromMemory(storageData, memory);
+
+			data = Flags<Enum, Storage>(storageData);
+
+			return size;
+		}
+
+		/** @copydoc RTTIPlainType::getDynamicSize */
+		static UINT32 getDynamicSize(const Flags<Enum, Storage>& data)
+		{ 
+			UINT64 dataSize = sizeof(UINT32);
+
+			Storage storageData = (Storage)data;
+			dataSize += RTTIPlainType<Storage>::getDynamicSize(storageData);
+
+			assert(dataSize <= std::numeric_limits<UINT32>::max());
+
+			return (UINT32)dataSize;
+		}	
+	}; 
+
+	/** @encond */
+	/** @} */
 }

+ 2 - 1
Source/BansheeUtility/Include/BsFwdDeclUtil.h

@@ -111,6 +111,7 @@ namespace BansheeEngine
 		TID_SerializedArrayEntry = 64,
 		TID_SerializedSubObject = 65,
 		TID_UnorderedSet = 66,
-		TID_SerializedDataBlock = 67
+		TID_SerializedDataBlock = 67,
+		TID_Flags = 68
 	};
 }

+ 1 - 1
Source/MBansheeEditor/Windows/Animation/GUIFieldSelector.cs

@@ -149,7 +149,7 @@ namespace BansheeEditor
             List<Element> elements = new List<Element>(); 
             foreach (var field in serializableObject.Fields)
             {
-                if (!field.Inspectable)
+                if (!field.Animable)
                     continue;
 
                 string propertyPath = parent.path + "/" + field.Name;

+ 0 - 1
Source/MBansheeEditor/Windows/Inspector/Style/InspectableFieldStepStyle.cs

@@ -8,7 +8,6 @@ namespace BansheeEditor
     /// </summary>
     public sealed class InspectableFieldStepStyle : InspectableFieldStyle
     {
-
         public InspectableFieldStepStyle(float step)
         {
             this.Step = step;

+ 6 - 5
Source/MBansheeEditor/Windows/Inspector/Style/InspectableFieldStyle.cs

@@ -1,6 +1,5 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-
 using BansheeEngine;
 
 namespace BansheeEditor
@@ -13,14 +12,16 @@ namespace BansheeEditor
         /// <summary>
         /// Creates all the relevant style information for a SerializableField.
         /// </summary>
-        /// <param name="field">A SerializableField.</param>
-        /// <returns>Style information.</returns>
+        /// <param name="field">Field to create the style info structure for.</param>
+        /// <returns>Style information retrieved from the field.</returns>
         public static InspectableFieldStyleInfo Create(SerializableField field)
         {
+            SerializableFieldStyle style = field.Style;
+
             var styleInfo = new InspectableFieldStyleInfo();
+            styleInfo.RangeStyle = style.HasRange ? new InspectableFieldRangeStyle(style.RangeMin, style.RangeMax, style.DisplayAsSlider) : null;
+            styleInfo.StepStyle = style.HasStep ? new InspectableFieldStepStyle(style.StepIncrement) : null;
 
-            styleInfo.RangeStyle = field.IsRanged? new InspectableFieldRangeStyle(field.RangeMinimum, field.RangeMaximum, field.IsSlider) : null;
-            styleInfo.StepStyle = field.IsStepped? new InspectableFieldStepStyle(field.Step) : null;
             return styleInfo;
         }
     }

+ 51 - 54
Source/MBansheeEngine/Serialization/SerializableField.cs

@@ -17,7 +17,8 @@ namespace BansheeEngine
         Serializable = 0x01,
         Inspectable = 0x02,
         Ranged = 0x04,
-        Stepped = 0x08
+        Stepped = 0x08,
+        Animable = 0x10
     }
 
     /// <summary>
@@ -72,67 +73,41 @@ namespace BansheeEngine
         }
 
         /// <summary>
-        /// Returns true if the field accepts a defined range.
-        /// </summary>
-        public bool IsRanged
-        {
-            get { return (flags & (byte)SerializableFieldAttributes.Ranged) != 0; }
-        }
-
-        /// <summary>
-        /// Returns the upper bound of the range.
-        /// </summary>
-        public float RangeMaximum
-        {
-            get { return IsRanged? Internal_GetRangeMaximum(mCachedPtr) : 0; }
-        }
-
-        /// <summary>
-        /// Returns the lower bound of the range.
-        /// </summary>
-        public float RangeMinimum
-        {
-            get { return IsRanged? Internal_GetRangeMinimum(mCachedPtr) : 0; }
-        }
-
-        /// <summary>
-        /// Whether the field is rendered as a slider.
-        /// </summary>
-        public bool IsSlider
-        {
-            get { return (IsRanged && Internal_RenderAsSlider(mCachedPtr)); }
-        }
-
-        /// <summary>
-        /// Whether the field has an associated step value.
+        /// Returns true if the field will be visible in the default inspector.
         /// </summary>
-        public bool IsStepped
+        public bool Inspectable
         {
-            get { return (flags & (byte)SerializableFieldAttributes.Stepped) != 0; }
+            get { return (flags & (byte)SerializableFieldAttributes.Inspectable) != 0; }
         }
 
         /// <summary>
-        /// Returns the step of the range
+        /// Returns true if the field will be automatically serialized.
         /// </summary>
-        public float Step
+        public bool Serializable
         {
-            get { return IsStepped? Internal_GetStep(mCachedPtr) : 0; }
+            get { return (flags & (byte)SerializableFieldAttributes.Serializable) != 0; }
         }
 
         /// <summary>
-        /// Returns true if the field will be visible in the default inspector.
+        /// Returns true if the field can be animated.
         /// </summary>
-        public bool Inspectable
+        public bool Animable
         {
-            get { return (flags & (byte)SerializableFieldAttributes.Inspectable) != 0; }
+            get { return (flags & (byte)SerializableFieldAttributes.Animable) != 0; }
         }
 
         /// <summary>
-        /// Returns true if the field will be automatically serialized.
+        /// Returns the requested style of the field, that may be used for controlling how the field is displayed and how
+        /// is its input filtered.
         /// </summary>
-        public bool Serializable
+        public SerializableFieldStyle Style
         {
-            get { return (flags & (byte)SerializableFieldAttributes.Serializable) != 0; }
+            get
+            {
+                SerializableFieldStyle style;
+                Internal_GetStyle(mCachedPtr, out style);
+                return style;
+            }
         }
 
         /// <summary>
@@ -181,16 +156,38 @@ namespace BansheeEngine
         private static extern void Internal_SetValue(IntPtr nativeInstance, object instance, object value);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern float Internal_GetRangeMaximum(IntPtr field);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern float Internal_GetRangeMinimum(IntPtr field);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern bool Internal_RenderAsSlider(IntPtr field);
+        private static extern void Internal_GetStyle(IntPtr nativeInstance, out SerializableFieldStyle style);
+    }
 
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern float Internal_GetStep(IntPtr field);
+    /// <summary>
+    /// Contains information about a style of a serializable field.
+    /// </summary>
+    public struct SerializableFieldStyle // Note: Must match C++ struct SerializableMemberStyle
+    {
+        /// <summary>
+        /// True if the range of the field is limited, false if unlimited.
+        /// </summary>
+        public bool HasRange;
+        /// <summary>
+        /// Returns the lower bound of the range. Only relevant if <see cref="HasRange"/> is true.
+        /// </summary>
+        public float RangeMin;
+        /// <summary>
+        /// Returns the upper bound of the range. Only relevant if <see cref="HasRange"/> is true.
+        /// </summary>
+        public float RangeMax;
+        /// <summary>
+        /// True if the field value can only be incremented in specific increments.
+        /// </summary>
+        public bool HasStep;
+        /// <summary>
+        /// Minimum increment the field value can be increment/decremented by. Only relevant if <see cref="HasStep"/> is true.
+        /// </summary>
+        public float StepIncrement;
+        /// <summary>
+        /// If true, number fields will be displayed as sliders instead of regular input boxes.
+        /// </summary>
+        public bool DisplayAsSlider;
     }
 
     /** @} */

+ 7 - 3
Source/SBansheeEngine/Include/BsManagedSerializableObjectInfo.h

@@ -60,14 +60,18 @@ namespace BansheeEngine
 	};
 
 	/**	Flags that are used to further define a field in a managed serializable object. */
-	enum class ScriptFieldFlags
+	enum class ScriptFieldFlag
 	{
 		Serializable = 0x01,
 		Inspectable = 0x02,
 		Range = 0x04,
-		Step = 0x08
+		Step = 0x08,
+		Animable = 0x10
 	};
 
+	typedef Flags<ScriptFieldFlag> ScriptFieldFlags;
+	BS_FLAGS_OPERATORS(ScriptFieldFlag);
+
 	/**	Contains information about a type of a managed serializable object. */
 	class BS_SCR_BE_EXPORT ManagedSerializableTypeInfo : public IReflectable
 	{
@@ -256,7 +260,7 @@ namespace BansheeEngine
 		ManagedSerializableMemberInfo();
 
 		/**	Determines should the member be serialized when serializing the parent object. */
-		bool isSerializable() const { return ((UINT32)mFlags & (UINT32)ScriptFieldFlags::Serializable) != 0; }
+		bool isSerializable() const { return mFlags.isSet(ScriptFieldFlag::Serializable); }
 
 		/** Returns the minimum value associated to a Range attribute. */
 		virtual float getRangeMinimum() const = 0;

+ 13 - 4
Source/SBansheeEngine/Include/BsScriptSerializableField.h

@@ -11,6 +11,18 @@ namespace BansheeEngine
 	 *  @{
 	 */
 
+	/** Contains information about a style of a serializable field. */
+    struct SerializableMemberStyle // Note: Must match C# struct SerializableFieldStyle
+    {
+        bool hasRange; /**< True if the range of the field is limited, false if unlimited. */
+        float rangeMin; /**< Returns the lower bound of the range. Only relevant if @see hasRange is true. */
+        float rangeMax; /**< Returns the upper bound of the range. Only relevant if @see hasRange is true. */
+        bool hasStep; /**< True if the field value can only be incremented in specific increments. */
+		/** Minimum increment the field value can be increment/decremented by. Only relevant if @see hasStep is true. */
+        float stepIncrement; 
+        bool displayAsSlider; /**< If true, number fields will be displayed as sliders instead of regular input boxes. */
+	};
+
 	/**	Interop class between C++ & CLR for ManagedSerializableFieldInfo. */
 	class BS_SCR_BE_EXPORT ScriptSerializableField : public ScriptObject<ScriptSerializableField>
 	{
@@ -36,10 +48,7 @@ namespace BansheeEngine
 		static MonoObject* internal_createProperty(ScriptSerializableField* nativeInstance);
 		static MonoObject* internal_getValue(ScriptSerializableField* nativeInstance, MonoObject* instance);
 		static void internal_setValue(ScriptSerializableField* nativeInstance, MonoObject* instance, MonoObject* value);
-		static float internal_getRangeMaximum(ScriptSerializableField* nativeInstance);
-		static float internal_getRangeMinimum(ScriptSerializableField* nativeInstance);
-		static bool internal_renderAsSlider(ScriptSerializableField* nativeInstance);
-		static float internal_getStep(ScriptSerializableField* nativeInstance);
+		static void internal_getStyle(ScriptSerializableField* nativeInstance, SerializableMemberStyle* style);
 	};
 
 	/** @} */

+ 13 - 15
Source/SBansheeEngine/Source/BsManagedSerializableObjectInfo.cpp

@@ -94,7 +94,7 @@ namespace BansheeEngine
 	}
 
 	ManagedSerializableMemberInfo::ManagedSerializableMemberInfo()
-		:mFieldId(0), mFlags((ScriptFieldFlags)0)
+		:mFieldId(0), mFlags(0)
 	{
 
 	}
@@ -117,9 +117,8 @@ namespace BansheeEngine
 
 	float ManagedSerializableFieldInfo::getRangeMinimum() const
 	{
-		if (((UINT32)mFlags & (UINT32)ScriptFieldFlags::Range) != 0)
+		if (mFlags.isSet(ScriptFieldFlag::Range))
 		{
-
 			MonoClass* range = ScriptAssemblyManager::instance().getRangeAttribute();
 			if (range != nullptr)
 			{
@@ -133,9 +132,8 @@ namespace BansheeEngine
 
 	float ManagedSerializableFieldInfo::getRangeMaximum() const
 	{
-		if (((UINT32)mFlags & (UINT32)ScriptFieldFlags::Range) != 0)
+		if (mFlags.isSet(ScriptFieldFlag::Range))
 		{
-
 			MonoClass* range = ScriptAssemblyManager::instance().getRangeAttribute();
 			if (range != nullptr)
 			{
@@ -149,7 +147,7 @@ namespace BansheeEngine
 
 	bool ManagedSerializableFieldInfo::renderAsSlider() const
 	{
-		if (((UINT32)mFlags & (UINT32)ScriptFieldFlags::Range) != 0)
+		if (mFlags.isSet(ScriptFieldFlag::Range))
 		{
 			MonoClass* range = ScriptAssemblyManager::instance().getRangeAttribute();
 			if (range != nullptr)
@@ -165,9 +163,8 @@ namespace BansheeEngine
 
 	float ManagedSerializableFieldInfo::getStep() const
 	{
-		if (((UINT32)mFlags & (UINT32)ScriptFieldFlags::Step) != 0)
+		if (mFlags.isSet(ScriptFieldFlag::Step))
 		{
-
 			MonoClass* step = ScriptAssemblyManager::instance().getStepAttribute();
 			if (step != nullptr)
 			{
@@ -207,9 +204,8 @@ namespace BansheeEngine
 
 	float ManagedSerializablePropertyInfo::getRangeMinimum() const
 	{
-		if (((UINT32)mFlags & (UINT32)ScriptFieldFlags::Range) != 0)
+		if (mFlags.isSet(ScriptFieldFlag::Range))
 		{
-
 			MonoClass* range = ScriptAssemblyManager::instance().getRangeAttribute();
 			if (range != nullptr)
 			{
@@ -218,14 +214,14 @@ namespace BansheeEngine
 				return min;
 			}
 		}
+
 		return 0;
 	}
 
 	float ManagedSerializablePropertyInfo::getRangeMaximum() const
 	{
-		if (((UINT32)mFlags & (UINT32)ScriptFieldFlags::Range) != 0)
+		if (mFlags.isSet(ScriptFieldFlag::Range))
 		{
-
 			MonoClass* range = ScriptAssemblyManager::instance().getRangeAttribute();
 			if (range != nullptr)
 			{
@@ -234,12 +230,13 @@ namespace BansheeEngine
 				return max;
 			}
 		}
+
 		return 0;
 	}
 
 	bool ManagedSerializablePropertyInfo::renderAsSlider() const
 	{
-		if (((UINT32)mFlags & (UINT32)ScriptFieldFlags::Range) != 0)
+		if (mFlags.isSet(ScriptFieldFlag::Range))
 		{
 			MonoClass* range = ScriptAssemblyManager::instance().getRangeAttribute();
 			if (range != nullptr)
@@ -249,15 +246,15 @@ namespace BansheeEngine
 				return slider;
 			}
 		}
+
 		return false;
 	}
 
 
 	float ManagedSerializablePropertyInfo::getStep() const
 	{
-		if (((UINT32)mFlags & (UINT32)ScriptFieldFlags::Step) != 0)
+		if (mFlags.isSet(ScriptFieldFlag::Step))
 		{
-
 			MonoClass* step = ScriptAssemblyManager::instance().getStepAttribute();
 			if (step != nullptr)
 			{
@@ -266,6 +263,7 @@ namespace BansheeEngine
 				return value;
 			}
 		}
+
 		return 0;
 	}
 

+ 18 - 12
Source/SBansheeEngine/Source/BsScriptAssemblyManager.cpp

@@ -126,29 +126,31 @@ namespace BansheeEngine
 				fieldInfo->mTypeInfo = typeInfo;
 				fieldInfo->mParentTypeId = objInfo->mTypeInfo->mTypeId;
 				
-				MonoFieldVisibility visibility = field->getVisibility();
-				if (visibility == MonoFieldVisibility::Public)
+				MonoMemberVisibility visibility = field->getVisibility();
+				if (visibility == MonoMemberVisibility::Public)
 				{
 					if (!field->hasAttribute(mDontSerializeFieldAttribute))
-						fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Serializable);
+						fieldInfo->mFlags |= ScriptFieldFlag::Serializable;
 
 					if (!field->hasAttribute(mHideInInspectorAttribute))
-						fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Inspectable);
+						fieldInfo->mFlags |= ScriptFieldFlag::Inspectable;
+
+					fieldInfo->mFlags |= ScriptFieldFlag::Animable;
 				}
 				else
 				{
 					if (field->hasAttribute(mSerializeFieldAttribute))
-						fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Serializable);
+						fieldInfo->mFlags |= ScriptFieldFlag::Serializable;
 
 					if (field->hasAttribute(mShowInInspectorAttribute))
-						fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Inspectable);
+						fieldInfo->mFlags |= ScriptFieldFlag::Inspectable;
 				}
 
 				if (field->hasAttribute(mRangeAttribute))
-					fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Range);
+					fieldInfo->mFlags |= ScriptFieldFlag::Range;
 
 				if (field->hasAttribute(mStepAttribute))
-					fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Step);
+					fieldInfo->mFlags |= ScriptFieldFlag::Step;
 
 				objInfo->mFieldNameToId[fieldInfo->mName] = fieldInfo->mFieldId;
 				objInfo->mFields[fieldInfo->mFieldId] = fieldInfo;
@@ -170,18 +172,22 @@ namespace BansheeEngine
 
 				if (!property->isIndexed())
 				{
+					MonoMemberVisibility visibility = property->getVisibility();
+					if (visibility == MonoMemberVisibility::Public)
+						propertyInfo->mFlags |= ScriptFieldFlag::Animable;
+
 					if (property->hasAttribute(mSerializeFieldAttribute))
-						propertyInfo->mFlags = (ScriptFieldFlags)((UINT32)propertyInfo->mFlags | (UINT32)ScriptFieldFlags::Serializable);
+						propertyInfo->mFlags |= ScriptFieldFlag::Serializable;
 
 					if (property->hasAttribute(mShowInInspectorAttribute))
-						propertyInfo->mFlags = (ScriptFieldFlags)((UINT32)propertyInfo->mFlags | (UINT32)ScriptFieldFlags::Inspectable);
+						propertyInfo->mFlags |= ScriptFieldFlag::Inspectable;
 				}
 
 				if (property->hasAttribute(mRangeAttribute))
-					propertyInfo->mFlags = (ScriptFieldFlags)((UINT32)propertyInfo->mFlags | (UINT32)ScriptFieldFlags::Range);
+					propertyInfo->mFlags |= ScriptFieldFlag::Range;
 
 				if (property->hasAttribute(mStepAttribute))
-					propertyInfo->mFlags = (ScriptFieldFlags)((UINT32)propertyInfo->mFlags | (UINT32)ScriptFieldFlags::Step);
+					propertyInfo->mFlags |= ScriptFieldFlag::Step;
 
 				objInfo->mFieldNameToId[propertyInfo->mName] = propertyInfo->mFieldId;
 				objInfo->mFields[propertyInfo->mFieldId] = propertyInfo;

+ 14 - 8
Source/SBansheeEngine/Source/BsScriptSerializableField.cpp

@@ -23,10 +23,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_CreateProperty", &ScriptSerializableField::internal_createProperty);
 		metaData.scriptClass->addInternalCall("Internal_GetValue", &ScriptSerializableField::internal_getValue);
 		metaData.scriptClass->addInternalCall("Internal_SetValue", &ScriptSerializableField::internal_setValue);
-		metaData.scriptClass->addInternalCall("Internal_GetRangeMaximum", &ScriptSerializableField::internal_getRangeMaximum);
-		metaData.scriptClass->addInternalCall("Internal_GetRangeMinimum", &ScriptSerializableField::internal_getRangeMinimum);
-		metaData.scriptClass->addInternalCall("Internal_RenderAsSlider", &ScriptSerializableField::internal_renderAsSlider);
-		metaData.scriptClass->addInternalCall("Internal_GetStep", &ScriptSerializableField::internal_getStep);
+		metaData.scriptClass->addInternalCall("Internal_GetStyle", &ScriptSerializableField::internal_getStyle);
 	}
 
 	ScriptSerializableField* ScriptSerializableField::create(MonoObject* parentObject, const SPtr<ManagedSerializableMemberInfo>& fieldInfo)
@@ -65,8 +62,17 @@ namespace BansheeEngine
 		else
 			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(); }
-	bool ScriptSerializableField::internal_renderAsSlider(ScriptSerializableField* nativeInstance) { return  nativeInstance->mFieldInfo->renderAsSlider(); }
-	float ScriptSerializableField::internal_getStep(ScriptSerializableField* nativeInstance) { return nativeInstance->mFieldInfo->getStep(); }
+	void ScriptSerializableField::internal_getStyle(ScriptSerializableField* nativeInstance, SerializableMemberStyle* style)
+	{
+		SPtr<ManagedSerializableMemberInfo> fieldInfo = nativeInstance->mFieldInfo;
+		*style = SerializableMemberStyle();
+
+		ScriptFieldFlags fieldFlags = fieldInfo->mFlags;
+		style->displayAsSlider = fieldInfo->renderAsSlider();
+		style->rangeMin = fieldInfo->getRangeMinimum();
+		style->rangeMax = fieldInfo->getRangeMaximum();
+		style->stepIncrement = fieldInfo->getStep();
+		style->hasStep = fieldFlags.isSet(ScriptFieldFlag::Step);
+		style->hasRange = fieldFlags.isSet(ScriptFieldFlag::Range);
+	}
 }