Przeglądaj źródła

Refactored RTTI macros so they don't require two separate definitions for a single field

BearishSun 9 lat temu
rodzic
commit
16c1bf808d
27 zmienionych plików z 569 dodań i 557 usunięć
  1. 45 0
      Documentation/Manuals/Native/rtti.md
  2. 6 7
      Source/BansheeCore/Include/BsAudioClipImportOptionsRTTI.h
  3. 9 13
      Source/BansheeCore/Include/BsAudioClipRTTI.h
  4. 5 5
      Source/BansheeCore/Include/BsCBoxColliderRTTI.h
  5. 7 8
      Source/BansheeCore/Include/BsCCapsuleColliderRTTI.h
  6. 15 24
      Source/BansheeCore/Include/BsCCharacterControllerRTTI.h
  7. 13 21
      Source/BansheeCore/Include/BsCColliderRTTI.h
  8. 27 49
      Source/BansheeCore/Include/BsCD6JointRTTI.h
  9. 10 14
      Source/BansheeCore/Include/BsCDistanceJointRTTI.h
  10. 15 24
      Source/BansheeCore/Include/BsCHingeJointRTTI.h
  11. 12 15
      Source/BansheeCore/Include/BsCJointRTTI.h
  12. 5 5
      Source/BansheeCore/Include/BsCMeshColliderRTTI.h
  13. 6 6
      Source/BansheeCore/Include/BsCPlaneColliderRTTI.h
  14. 18 31
      Source/BansheeCore/Include/BsCRigidbodyRTTI.h
  15. 11 17
      Source/BansheeCore/Include/BsCSliderJointRTTI.h
  16. 5 5
      Source/BansheeCore/Include/BsCSphereColliderRTTI.h
  17. 11 17
      Source/BansheeCore/Include/BsCSphericalJointRTTI.h
  18. 12 19
      Source/BansheeCore/Include/BsMeshImportOptionsRTTI.h
  19. 10 9
      Source/BansheeCore/Include/BsPhysicsMeshRTTI.h
  20. 31 44
      Source/BansheeCore/Include/BsPrefabDiffRTTI.h
  21. 19 39
      Source/BansheeEditor/Include/BsEditorSettingsRTTI.h
  22. 15 19
      Source/BansheeEditor/Include/BsProjectResourceMetaRTTI.h
  23. 5 5
      Source/BansheeEditor/Include/BsProjectSettingsRTTI.h
  24. 8 11
      Source/BansheeEditor/Include/BsSettingsRTTI.h
  25. 57 74
      Source/BansheeEditor/Source/BsEditorTestSuite.cpp
  26. 5 4
      Source/BansheeEngine/Include/BsResourceMappingRTTI.h
  27. 187 72
      Source/BansheeUtility/Include/BsRTTIType.h

+ 45 - 0
Documentation/Manuals/Native/rtti.md

@@ -232,6 +232,51 @@ If possible you should prefer implementing an @ref BansheeEngine::IReflectable "
  - @ref BansheeEngine::rttiWriteElem "rttiWriteElem" - Serializes an object into the provided buffer and returns offset into the buffer after the written data
  - @ref BansheeEngine::rttiGetElemSize "rttiGetElemSize" - Returns a size an object
 
+## RTTI field macros  {#rtti_b_f} 
+In order to make definitions for fields in an RTTI type simpler, Banshee provides a set of macros you can use. These macros will automatically create getter/setter methods, and register the field. The macros are:
+ - BS_RTTI_MEMBER_PLAIN(name, id) - Registers a new plain field for the variable `name` with a unique id `id`. 
+ - BS_RTTI_MEMBER_PLAIN_NAMED(name, field, id) - Registers a new plain field for the variable `field` with a unique id `id`, and name `name`. Useful when the variable name cannot be used for the field name as it's done in BS_RTTI_MEMBER_PLAIN (e.g. if it is nested within another structure).
+ - BS_RTTI_MEMBER_PLAIN_ARRAY(name, id) - Registers a new plain field for the variable `field` with a unique id `id`. The field contains a `Vector` of plain values.
+ - BS_RTTI_MEMBER_REFL(name, id) - Same as BS_RTTI_MEMBER_PLAIN but for reflectable fields.
+ - BS_RTTI_MEMBER_REFL_NAMED(name, field, id) - Same as BS_RTTI_MEMBER_PLAIN_NAMED but for reflectable fields.
+ - BS_RTTI_MEMBER_REFL_ARRAY(name, id) - Same as BS_RTTI_MEMBER_PLAIN_ARRAY but for reflectable fields.
+ - BS_RTTI_MEMBER_REFLPTR(name, id) - Same as BS_RTTI_MEMBER_PLAIN but for reflectable pointer fields.
+ - BS_RTTI_MEMBER_REFLPTR_NAMED(name, field, id) - Same as BS_RTTI_MEMBER_PLAIN_NAMED but for reflectable pointer fields.
+ - BS_RTTI_MEMBER_REFLPTR_ARRAY(name, id) - Same as BS_RTTI_MEMBER_PLAIN_ARRAY but for reflectable pointer fields.
+ 
+Before you use any of those macros you must first call @ref BS_BEGIN_RTTI_MEMBERS() "BS_BEGIN_RTTI_MEMBERS" macro, and follow it with @ref BS_END_RTTI_MEMBERS() "BS_END_RTTI_MEMBERS" macro. These macros will define a new field `mInitMembers` in the @ref BansheeEngine::RTTITypeBase "RTTIType", which you need to initialize in the constructor with the `this` pointer.
+
+If we refactor our `TextureRTTI` example from above to use macros, it would look like so:
+~~~~~~~~~~~~~{.cpp}
+class TextureRTTI : public RTTIType<Texture, IReflectable, TextureRTTI>
+{
+	BS_BEGIN_RTTI_MEMBERS
+		BS_RTTI_MEMBER_PLAIN(width, 0)
+		BS_RTTI_MEMBER_PLAIN(height, 1)
+	BS_END_RTTI_MEMBERS
+	
+	TextureRTTI ()
+		:mInitMembers(this)
+	{ }
+
+	const String& getRTTIName() override
+	{
+		static String name = "Texture";
+		return name;
+	}
+
+	UINT32 getRTTIId() override
+	{
+		return TID_Texture;
+	}
+
+	SPtr<IReflectable> newRTTIObject() override
+	{
+		return bs_shared_ptr_new<Texture>();
+	}
+};
+~~~~~~~~~~~~~
+ 
 # Advanced serialization  {#rtti_c}
 Implementations of @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType> "RTTIType" can optionally override @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType>::onSerializationStarted "RTTIType::onSerializationStarted", @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType>::onSerializationEnded "RTTIType::onSerializationEnded", @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType>::onDeserializationStarted "RTTIType::onDeserializationStarted" and @ref BansheeEngine::RTTIType<Type, BaseType, MyRTTIType>::onDeserializationEnded "RTTIType::onDeserializationEnded" methods. As their names imply they will get called during serialization/deserialization and allow you to do any pre- or post-processing of the data. Most other systems (other than serialization) that access field data will also call these functions before reading, and after writing field data.
 

+ 6 - 7
Source/BansheeCore/Include/BsAudioClipImportOptionsRTTI.h

@@ -16,15 +16,14 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT AudioClipImportOptionsRTTI : public RTTIType<AudioClipImportOptions, ImportOptions, AudioClipImportOptionsRTTI>
 	{
 	private:
-		BS_PLAIN_MEMBER(mFormat);
-		BS_PLAIN_MEMBER(mReadMode);
-
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(mFormat, 0)
+			BS_RTTI_MEMBER_PLAIN(mReadMode, 1)
+		BS_END_RTTI_MEMBERS
 	public:
 		AudioClipImportOptionsRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mFormat, 0);
-			BS_ADD_PLAIN_FIELD(mReadMode, 1);
-		}
+			:mInitMembers(this)
+		{ }
 
 		/** @copydoc RTTIType::getRTTIName */
 		const String& getRTTIName() override

+ 9 - 13
Source/BansheeCore/Include/BsAudioClipRTTI.h

@@ -16,12 +16,14 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT AudioClipRTTI : public RTTIType <AudioClip, Resource, AudioClipRTTI>
 	{
 	private:
-		BS_PLAIN_MEMBER_NAMED(readMode, mDesc.readMode);
-		BS_PLAIN_MEMBER_NAMED(format, mDesc.format);
-		BS_PLAIN_MEMBER_NAMED(frequency, mDesc.frequency);
-		BS_PLAIN_MEMBER_NAMED(bitDepth, mDesc.bitDepth);
-		BS_PLAIN_MEMBER_NAMED(numChannels, mDesc.numChannels);
-		BS_PLAIN_MEMBER(mNumSamples);
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN_NAMED(readMode, mDesc.readMode, 0)
+			BS_RTTI_MEMBER_PLAIN_NAMED(format, mDesc.format, 1)
+			BS_RTTI_MEMBER_PLAIN_NAMED(frequency, mDesc.frequency, 2)
+			BS_RTTI_MEMBER_PLAIN_NAMED(bitDepth, mDesc.bitDepth, 3)
+			BS_RTTI_MEMBER_PLAIN_NAMED(numChannels, mDesc.numChannels, 4)
+			BS_RTTI_MEMBER_PLAIN(mNumSamples, 5)
+		BS_END_RTTI_MEMBERS
 
 		ManagedDataBlock getData(AudioClip* obj)
 		{
@@ -43,14 +45,8 @@ namespace BansheeEngine
 
 	public:
 		AudioClipRTTI()
+			:mInitMembers(this)
 		{
-			BS_ADD_PLAIN_FIELD(readMode, 0);
-			BS_ADD_PLAIN_FIELD(format, 1);
-			BS_ADD_PLAIN_FIELD(frequency, 2);
-			BS_ADD_PLAIN_FIELD(bitDepth, 3);
-			BS_ADD_PLAIN_FIELD(numChannels, 4);
-			BS_ADD_PLAIN_FIELD(mNumSamples, 5);
-
 			addDataBlockField("mData", 6, &AudioClipRTTI::getData, &AudioClipRTTI::setData, 
 				0, &AudioClipRTTI::allocateData);
 		}

+ 5 - 5
Source/BansheeCore/Include/BsCBoxColliderRTTI.h

@@ -17,13 +17,13 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT CBoxColliderRTTI : public RTTIType<CBoxCollider, CCollider, CBoxColliderRTTI>
 	{
 	private:
-		BS_PLAIN_MEMBER(mExtents)
-
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(mExtents, 0)
+		BS_END_RTTI_MEMBERS
 	public:
 		CBoxColliderRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mExtents, 0);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 7 - 8
Source/BansheeCore/Include/BsCCapsuleColliderRTTI.h

@@ -17,16 +17,15 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT CCapsuleColliderRTTI : public RTTIType<CCapsuleCollider, CCollider, CCapsuleColliderRTTI>
 	{
 	private:
-		BS_PLAIN_MEMBER(mNormal)
-		BS_PLAIN_MEMBER(mRadius)
-		BS_PLAIN_MEMBER(mHalfHeight)
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(mNormal, 0)
+			BS_RTTI_MEMBER_PLAIN(mRadius, 1)
+			BS_RTTI_MEMBER_PLAIN(mHalfHeight, 2)
+		BS_END_RTTI_MEMBERS
 	public:
 		CCapsuleColliderRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mNormal, 0);
-			BS_ADD_PLAIN_FIELD(mRadius, 1);
-			BS_ADD_PLAIN_FIELD(mHalfHeight, 2);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 15 - 24
Source/BansheeCore/Include/BsCCharacterControllerRTTI.h

@@ -17,33 +17,24 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT CCharacterControllerRTTI : public RTTIType<CCharacterController, Component, CCharacterControllerRTTI>
 	{
 	private:
-		BS_PLAIN_MEMBER_NAMED(mPosition, mDesc.position)
-		BS_PLAIN_MEMBER_NAMED(mContactOffset, mDesc.contactOffset)
-		BS_PLAIN_MEMBER_NAMED(mStepOffset, mDesc.stepOffset)
-		BS_PLAIN_MEMBER_NAMED(mSlopeLimit, mDesc.slopeLimit)
-		BS_PLAIN_MEMBER_NAMED(mMinMoveDistance, mDesc.minMoveDistance)
-		BS_PLAIN_MEMBER_NAMED(mHeight, mDesc.height)
-		BS_PLAIN_MEMBER_NAMED(mRadius, mDesc.radius)
-		BS_PLAIN_MEMBER_NAMED(mUp, mDesc.up)
-		BS_PLAIN_MEMBER_NAMED(mClimbingMode, mDesc.climbingMode)
-		BS_PLAIN_MEMBER_NAMED(mNonWalkableMode, mDesc.nonWalkableMode)
-		BS_PLAIN_MEMBER(mLayer)
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN_NAMED(mPosition, mDesc.position, 0)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mContactOffset, mDesc.contactOffset, 1)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mStepOffset, mDesc.stepOffset, 2)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mSlopeLimit, mDesc.slopeLimit, 3)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mMinMoveDistance, mDesc.minMoveDistance, 4)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mHeight, mDesc.height, 5)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mRadius, mDesc.radius, 6)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mUp, mDesc.up, 7)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mClimbingMode, mDesc.climbingMode, 8)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mNonWalkableMode, mDesc.nonWalkableMode, 9)
+			BS_RTTI_MEMBER_PLAIN(mLayer, 10)
+		BS_END_RTTI_MEMBERS
 
 	public:
 		CCharacterControllerRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mPosition, 0);
-			BS_ADD_PLAIN_FIELD(mContactOffset, 1);
-			BS_ADD_PLAIN_FIELD(mStepOffset, 2);
-			BS_ADD_PLAIN_FIELD(mSlopeLimit, 3);
-			BS_ADD_PLAIN_FIELD(mMinMoveDistance, 4);
-			BS_ADD_PLAIN_FIELD(mHeight, 5);
-			BS_ADD_PLAIN_FIELD(mRadius, 6);
-			BS_ADD_PLAIN_FIELD(mUp, 7);
-			BS_ADD_PLAIN_FIELD(mClimbingMode, 8);
-			BS_ADD_PLAIN_FIELD(mNonWalkableMode, 9);
-			BS_ADD_PLAIN_FIELD(mLayer, 10);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 13 - 21
Source/BansheeCore/Include/BsCColliderRTTI.h

@@ -15,29 +15,21 @@ namespace BansheeEngine
 
 	class BS_CORE_EXPORT CColliderRTTI : public RTTIType<CCollider, Component, CColliderRTTI>
 	{
-		BS_PLAIN_MEMBER(mLayer)
-		BS_PLAIN_MEMBER(mRestOffset)
-		BS_PLAIN_MEMBER(mContactOffset)
-		BS_REFL_MEMBER(mMaterial)
-		BS_PLAIN_MEMBER(mMass)
-		BS_PLAIN_MEMBER(mIsTrigger)
-		BS_PLAIN_MEMBER(mLocalPosition)
-		BS_PLAIN_MEMBER(mLocalRotation)
-		BS_PLAIN_MEMBER(mCollisionReportMode)
-
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(mLayer, 0)
+			BS_RTTI_MEMBER_PLAIN(mRestOffset, 1)
+			BS_RTTI_MEMBER_PLAIN(mContactOffset, 2)
+			BS_RTTI_MEMBER_REFL(mMaterial, 3)
+			BS_RTTI_MEMBER_PLAIN(mMass, 4)
+			BS_RTTI_MEMBER_PLAIN(mIsTrigger, 5)
+			BS_RTTI_MEMBER_PLAIN(mLocalPosition, 6)
+			BS_RTTI_MEMBER_PLAIN(mLocalRotation, 7)
+			BS_RTTI_MEMBER_PLAIN(mCollisionReportMode, 8)
+		BS_END_RTTI_MEMBERS
 	public:
 		CColliderRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mLayer, 0);
-			BS_ADD_PLAIN_FIELD(mRestOffset, 1);
-			BS_ADD_PLAIN_FIELD(mContactOffset, 2);
-			BS_ADD_REFL_FIELD(mMaterial, 3);
-			BS_ADD_PLAIN_FIELD(mMass, 4);
-			BS_ADD_PLAIN_FIELD(mIsTrigger, 5);
-			BS_ADD_PLAIN_FIELD(mLocalPosition, 6);
-			BS_ADD_PLAIN_FIELD(mLocalRotation, 7);
-			BS_ADD_PLAIN_FIELD(mCollisionReportMode, 8);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 27 - 49
Source/BansheeCore/Include/BsCD6JointRTTI.h

@@ -36,33 +36,36 @@ namespace BansheeEngine
 		UINT32 getDriveCount(CD6Joint* obj) { return (UINT32)D6Joint::DriveType::Count; }
 		void setDriveCount(CD6Joint* obj, UINT32 size) { /* Do nothing */ }
 
-		BS_PLAIN_MEMBER_NAMED(mLimitLinearExtent, mDesc.limitLinear.extent)
-		BS_PLAIN_MEMBER_NAMED(mLimitLinearContactDist, mDesc.limitTwist.contactDist)
-		BS_PLAIN_MEMBER_NAMED(mLimitLinearRestitution, mDesc.limitTwist.restitution)
-		BS_PLAIN_MEMBER_NAMED(mLimitLinearSpringDamping, mDesc.limitTwist.spring.damping)
-		BS_PLAIN_MEMBER_NAMED(mLimitLinearSpringStiffness, mDesc.limitTwist.spring.stiffness)
-
-		BS_PLAIN_MEMBER_NAMED(mLimitTwistLower, mDesc.limitTwist.lower)
-		BS_PLAIN_MEMBER_NAMED(mLimitTwistUpper, mDesc.limitTwist.upper)
-		BS_PLAIN_MEMBER_NAMED(mLimitTwistContactDist, mDesc.limitTwist.contactDist)
-		BS_PLAIN_MEMBER_NAMED(mLimitTwistRestitution, mDesc.limitTwist.restitution)
-		BS_PLAIN_MEMBER_NAMED(mLimitTwistSpringDamping, mDesc.limitTwist.spring.damping)
-		BS_PLAIN_MEMBER_NAMED(mLimitTwistSpringStiffness, mDesc.limitTwist.spring.stiffness)
-
-		BS_PLAIN_MEMBER_NAMED(mLimitSwingYLimitAngle, mDesc.limitSwing.yLimitAngle)
-		BS_PLAIN_MEMBER_NAMED(mLimitSwingZLimitAngle, mDesc.limitSwing.zLimitAngle)
-		BS_PLAIN_MEMBER_NAMED(mLimitSwingContactDist, mDesc.limitSwing.contactDist)
-		BS_PLAIN_MEMBER_NAMED(mLimitSwingRestitution, mDesc.limitSwing.restitution)
-		BS_PLAIN_MEMBER_NAMED(mLimitSwingSpringDamping, mDesc.limitSwing.spring.damping)
-		BS_PLAIN_MEMBER_NAMED(mLimitSwingSpringStiffness, mDesc.limitSwing.spring.stiffness)
-
-		BS_PLAIN_MEMBER_NAMED(mDrivePosition, mDesc.drivePosition)
-		BS_PLAIN_MEMBER_NAMED(mDriveRotation, mDesc.driveRotation)
-		BS_PLAIN_MEMBER_NAMED(mDriveLinearVelocity, mDesc.driveLinearVelocity)
-		BS_PLAIN_MEMBER_NAMED(mDriveAngularVelocity, mDesc.driveAngularVelocity)
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitLinearExtent, mDesc.limitLinear.extent, 5)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitLinearContactDist, mDesc.limitTwist.contactDist, 6)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitLinearRestitution, mDesc.limitTwist.restitution, 7)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitLinearSpringDamping, mDesc.limitTwist.spring.damping, 8)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitLinearSpringStiffness, mDesc.limitTwist.spring.stiffness, 9)
+
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitTwistLower, mDesc.limitTwist.lower, 10)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitTwistUpper, mDesc.limitTwist.upper, 11)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitTwistContactDist, mDesc.limitTwist.contactDist, 12)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitTwistRestitution, mDesc.limitTwist.restitution, 13)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitTwistSpringDamping, mDesc.limitTwist.spring.damping, 14)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitTwistSpringStiffness, mDesc.limitTwist.spring.stiffness, 15)
+
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitSwingYLimitAngle, mDesc.limitSwing.yLimitAngle, 16)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitSwingZLimitAngle, mDesc.limitSwing.zLimitAngle, 17)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitSwingContactDist, mDesc.limitSwing.contactDist, 18)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitSwingRestitution, mDesc.limitSwing.restitution, 19)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitSwingSpringDamping, mDesc.limitSwing.spring.damping, 20)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitSwingSpringStiffness, mDesc.limitSwing.spring.stiffness, 21)
+
+			BS_RTTI_MEMBER_PLAIN_NAMED(mDrivePosition, mDesc.drivePosition, 22)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mDriveRotation, mDesc.driveRotation, 23)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mDriveLinearVelocity, mDesc.driveLinearVelocity, 24)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mDriveAngularVelocity, mDesc.driveAngularVelocity, 25)
+		BS_END_RTTI_MEMBERS
 
 	public:
 		CD6JointRTTI()
+			:mInitMembers(this)
 		{
 			addPlainArrayField("mMotion", 0, &CD6JointRTTI::getMotion, &CD6JointRTTI::getMotionCount, 
 				&CD6JointRTTI::setMotion, &CD6JointRTTI::setMotionCount);
@@ -74,31 +77,6 @@ namespace BansheeEngine
 				&CD6JointRTTI::setDriveForceLimit, &CD6JointRTTI::setDriveCount);
 			addPlainArrayField("mDriveAcceleartion", 4, &CD6JointRTTI::getDriveAcceleration, &CD6JointRTTI::getDriveCount, 
 				&CD6JointRTTI::setDriveAcceleration, &CD6JointRTTI::setDriveCount);
-
-			BS_ADD_PLAIN_FIELD(mLimitLinearExtent, 5);
-			BS_ADD_PLAIN_FIELD(mLimitLinearContactDist, 6);
-			BS_ADD_PLAIN_FIELD(mLimitLinearRestitution, 7);
-			BS_ADD_PLAIN_FIELD(mLimitLinearSpringDamping, 8);
-			BS_ADD_PLAIN_FIELD(mLimitLinearSpringStiffness, 9);
-
-			BS_ADD_PLAIN_FIELD(mLimitTwistLower, 10);
-			BS_ADD_PLAIN_FIELD(mLimitTwistUpper, 11);
-			BS_ADD_PLAIN_FIELD(mLimitTwistContactDist, 12);
-			BS_ADD_PLAIN_FIELD(mLimitTwistRestitution, 13);
-			BS_ADD_PLAIN_FIELD(mLimitTwistSpringDamping, 14);
-			BS_ADD_PLAIN_FIELD(mLimitTwistSpringStiffness, 15);
-
-			BS_ADD_PLAIN_FIELD(mLimitSwingYLimitAngle, 16);
-			BS_ADD_PLAIN_FIELD(mLimitSwingZLimitAngle, 17);
-			BS_ADD_PLAIN_FIELD(mLimitSwingContactDist, 18);
-			BS_ADD_PLAIN_FIELD(mLimitSwingRestitution, 19);
-			BS_ADD_PLAIN_FIELD(mLimitSwingSpringDamping, 20);
-			BS_ADD_PLAIN_FIELD(mLimitSwingSpringStiffness, 21);
-
-			BS_ADD_PLAIN_FIELD(mDrivePosition, 22);
-			BS_ADD_PLAIN_FIELD(mDriveRotation, 23);
-			BS_ADD_PLAIN_FIELD(mDriveLinearVelocity, 24);
-			BS_ADD_PLAIN_FIELD(mDriveAngularVelocity, 25);
 		}
 
 		const String& getRTTIName() override

+ 10 - 14
Source/BansheeCore/Include/BsCDistanceJointRTTI.h

@@ -16,23 +16,19 @@ namespace BansheeEngine
 
 	class BS_CORE_EXPORT CDistanceJointRTTI : public RTTIType<CDistanceJoint, CJoint, CDistanceJointRTTI>
 	{
-		BS_PLAIN_MEMBER_NAMED(mFlag, mDesc.flag)
-		BS_PLAIN_MEMBER_NAMED(mMinDistance, mDesc.minDistance)
-		BS_PLAIN_MEMBER_NAMED(mMaxDistance, mDesc.maxDistance)
-		BS_PLAIN_MEMBER_NAMED(mTolerance, mDesc.tolerance)
-		BS_PLAIN_MEMBER_NAMED(mSpringDamping, mDesc.spring.damping)
-		BS_PLAIN_MEMBER_NAMED(mSpringStiffness, mDesc.spring.stiffness)
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN_NAMED(mFlag, mDesc.flag, 0)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mMinDistance, mDesc.minDistance, 1)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mMaxDistance, mDesc.maxDistance, 2)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mTolerance, mDesc.tolerance, 3)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mSpringDamping, mDesc.spring.damping, 4)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mSpringStiffness, mDesc.spring.stiffness, 5)
+		BS_END_RTTI_MEMBERS
 
 	public:
 		CDistanceJointRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mFlag, 0);
-			BS_ADD_PLAIN_FIELD(mMinDistance, 1);
-			BS_ADD_PLAIN_FIELD(mMaxDistance, 2);
-			BS_ADD_PLAIN_FIELD(mTolerance, 3);
-			BS_ADD_PLAIN_FIELD(mSpringDamping, 4);
-			BS_ADD_PLAIN_FIELD(mSpringStiffness, 5);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 15 - 24
Source/BansheeCore/Include/BsCHingeJointRTTI.h

@@ -16,33 +16,24 @@ namespace BansheeEngine
 
 	class BS_CORE_EXPORT CHingeJointRTTI : public RTTIType<CHingeJoint, CJoint, CHingeJointRTTI>
 	{
-		BS_PLAIN_MEMBER_NAMED(mFlag, mDesc.flag)
-		BS_PLAIN_MEMBER_NAMED(mDriveSpeed, mDesc.drive.speed)
-		BS_PLAIN_MEMBER_NAMED(mDriveForceLimit, mDesc.drive.forceLimit)
-		BS_PLAIN_MEMBER_NAMED(mDriveGearRatio, mDesc.drive.gearRatio)
-		BS_PLAIN_MEMBER_NAMED(mDriveFreeSpin, mDesc.drive.freeSpin)
-		BS_PLAIN_MEMBER_NAMED(mLimitLower, mDesc.limit.lower)
-		BS_PLAIN_MEMBER_NAMED(mLimitUpper, mDesc.limit.upper)
-		BS_PLAIN_MEMBER_NAMED(mLimitContactDist, mDesc.limit.contactDist)
-		BS_PLAIN_MEMBER_NAMED(mLimitRestitution, mDesc.limit.restitution)
-		BS_PLAIN_MEMBER_NAMED(mSpringDamping, mDesc.limit.spring.damping)
-		BS_PLAIN_MEMBER_NAMED(mSpringStiffness, mDesc.limit.spring.stiffness)
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN_NAMED(mFlag, mDesc.flag, 0)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mDriveSpeed, mDesc.drive.speed, 1)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mDriveForceLimit, mDesc.drive.forceLimit, 2)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mDriveGearRatio, mDesc.drive.gearRatio, 3)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mDriveFreeSpin, mDesc.drive.freeSpin, 4)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitLower, mDesc.limit.lower, 5)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitUpper, mDesc.limit.upper, 6)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitContactDist, mDesc.limit.contactDist, 7)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitRestitution, mDesc.limit.restitution, 8)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mSpringDamping, mDesc.limit.spring.damping, 9)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mSpringStiffness, mDesc.limit.spring.stiffness, 10)
+		BS_END_RTTI_MEMBERS
 
 	public:
 		CHingeJointRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mFlag, 0);
-			BS_ADD_PLAIN_FIELD(mDriveSpeed, 1);
-			BS_ADD_PLAIN_FIELD(mDriveForceLimit, 2);
-			BS_ADD_PLAIN_FIELD(mDriveGearRatio, 3);
-			BS_ADD_PLAIN_FIELD(mDriveFreeSpin, 4);
-			BS_ADD_PLAIN_FIELD(mLimitLower, 5);
-			BS_ADD_PLAIN_FIELD(mLimitUpper, 6);
-			BS_ADD_PLAIN_FIELD(mLimitContactDist, 7);
-			BS_ADD_PLAIN_FIELD(mLimitRestitution, 8);
-			BS_ADD_PLAIN_FIELD(mSpringDamping, 9);
-			BS_ADD_PLAIN_FIELD(mSpringStiffness, 10);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 12 - 15
Source/BansheeCore/Include/BsCJointRTTI.h

@@ -15,14 +15,16 @@ namespace BansheeEngine
 
 	class BS_CORE_EXPORT CJointRTTI : public RTTIType<CJoint, Component, CJointRTTI>
 	{
-		BS_REFL_MEMBER_NAMED(mBodyA, mBodies[0]);
-		BS_REFL_MEMBER_NAMED(mBodyB, mBodies[1]);
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_REFL_NAMED(mBodyA, mBodies[0], 0)
+			BS_RTTI_MEMBER_REFL_NAMED(mBodyB, mBodies[1], 1)
 
-		BS_PLAIN_MEMBER_NAMED(mPositionA, mPositions[0]);
-		BS_PLAIN_MEMBER_NAMED(mPositionB, mPositions[1]);
+			BS_RTTI_MEMBER_PLAIN_NAMED(mPositionA, mPositions[0], 2)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mPositionB, mPositions[1], 3)
 
-		BS_PLAIN_MEMBER_NAMED(mRotationA, mRotations[0]);
-		BS_PLAIN_MEMBER_NAMED(mRotationB, mRotations[1]);
+			BS_RTTI_MEMBER_PLAIN_NAMED(mRotationA, mRotations[0], 4)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mRotationB, mRotations[1], 5)
+		BS_END_RTTI_MEMBERS
 
 		float& getBreakForce(OwnerType* obj) { return obj->mDesc.breakForce; }	
 		void setBreakForce(OwnerType* obj, float& val) { obj->mDesc.breakForce = val; }
@@ -35,16 +37,11 @@ namespace BansheeEngine
 
 	public:
 		CJointRTTI()
+			:mInitMembers(this)
 		{
-			BS_ADD_REFL_FIELD(mBodyA, 0);
-			BS_ADD_REFL_FIELD(mBodyB, 1);
-			BS_ADD_PLAIN_FIELD(mPositionA, 2);
-			BS_ADD_PLAIN_FIELD(mPositionB, 3);
-			BS_ADD_PLAIN_FIELD(mRotationA, 4);
-			BS_ADD_PLAIN_FIELD(mRotationB, 5);
-			BS_ADD_PLAIN_FIELD(BreakForce, 6);
-			BS_ADD_PLAIN_FIELD(BreakTorque, 7);
-			BS_ADD_PLAIN_FIELD(EnableCollision, 8);
+			addPlainField("BreakForce", 6, &CJointRTTI::getBreakForce, &CJointRTTI::setBreakForce);
+			addPlainField("BreakTorque", 7, &CJointRTTI::getBreakTorque, &CJointRTTI::setBreakTorque);
+			addPlainField("EnableCollision", 8, &CJointRTTI::getEnableCollision, &CJointRTTI::setEnableCollision);
 		}
 
 		const String& getRTTIName() override

+ 5 - 5
Source/BansheeCore/Include/BsCMeshColliderRTTI.h

@@ -17,13 +17,13 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT CMeshColliderRTTI : public RTTIType<CMeshCollider, CCollider, CMeshColliderRTTI>
 	{
 	private:
-		BS_REFL_MEMBER(mMesh)
-
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_REFL(mMesh, 0)
+		BS_END_RTTI_MEMBERS
 	public:
 		CMeshColliderRTTI()
-		{
-			BS_ADD_REFL_FIELD(mMesh, 0);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 6 - 6
Source/BansheeCore/Include/BsCPlaneColliderRTTI.h

@@ -17,14 +17,14 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT CPlaneColliderRTTI : public RTTIType<CPlaneCollider, CCollider, CPlaneColliderRTTI>
 	{
 	private:
-		BS_PLAIN_MEMBER(mNormal)
-		BS_PLAIN_MEMBER(mDistance)
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(mNormal, 0)
+			BS_RTTI_MEMBER_PLAIN(mDistance, 1)
+		BS_END_RTTI_MEMBERS
 	public:
 		CPlaneColliderRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mNormal, 0);
-			BS_ADD_PLAIN_FIELD(mDistance, 1);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 18 - 31
Source/BansheeCore/Include/BsCRigidbodyRTTI.h

@@ -17,39 +17,26 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT CRigidbodyRTTI : public RTTIType<CRigidbody, Component, CRigidbodyRTTI>
 	{
 	private:
-		BS_PLAIN_MEMBER(mPositionSolverCount);
-		BS_PLAIN_MEMBER(mVelocitySolverCount);
-		BS_PLAIN_MEMBER(mFlags);
-		BS_PLAIN_MEMBER(mCMassPosition);
-		BS_PLAIN_MEMBER(mCMassRotation);
-		BS_PLAIN_MEMBER(mInertiaTensor);
-		BS_PLAIN_MEMBER(mMass);
-		BS_PLAIN_MEMBER(mMaxAngularVelocity);
-		BS_PLAIN_MEMBER(mLinearDrag);
-		BS_PLAIN_MEMBER(mAngularDrag);
-		BS_PLAIN_MEMBER(mSleepThreshold);
-		BS_PLAIN_MEMBER(mUseGravity);
-		BS_PLAIN_MEMBER(mIsKinematic);
-		BS_PLAIN_MEMBER(mCollisionReportMode);
-
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(mPositionSolverCount, 0)
+			BS_RTTI_MEMBER_PLAIN(mVelocitySolverCount, 1)
+			BS_RTTI_MEMBER_PLAIN(mFlags, 2)
+			BS_RTTI_MEMBER_PLAIN(mCMassPosition, 3)
+			BS_RTTI_MEMBER_PLAIN(mCMassRotation, 4)
+			BS_RTTI_MEMBER_PLAIN(mInertiaTensor, 5)
+			BS_RTTI_MEMBER_PLAIN(mMass, 6)
+			BS_RTTI_MEMBER_PLAIN(mMaxAngularVelocity, 7)
+			BS_RTTI_MEMBER_PLAIN(mLinearDrag, 8)
+			BS_RTTI_MEMBER_PLAIN(mAngularDrag, 9)
+			BS_RTTI_MEMBER_PLAIN(mSleepThreshold, 10)
+			BS_RTTI_MEMBER_PLAIN(mUseGravity, 11)
+			BS_RTTI_MEMBER_PLAIN(mIsKinematic, 12)
+			BS_RTTI_MEMBER_PLAIN(mCollisionReportMode, 14)
+		BS_END_RTTI_MEMBERS
 	public:
 		CRigidbodyRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mPositionSolverCount, 0);
-			BS_ADD_PLAIN_FIELD(mVelocitySolverCount, 1);
-			BS_ADD_PLAIN_FIELD(mFlags, 2);
-			BS_ADD_PLAIN_FIELD(mCMassPosition, 3);
-			BS_ADD_PLAIN_FIELD(mCMassRotation, 4);
-			BS_ADD_PLAIN_FIELD(mInertiaTensor, 5);
-			BS_ADD_PLAIN_FIELD(mMass, 6);
-			BS_ADD_PLAIN_FIELD(mMaxAngularVelocity, 7);
-			BS_ADD_PLAIN_FIELD(mLinearDrag, 8);
-			BS_ADD_PLAIN_FIELD(mAngularDrag, 9);
-			BS_ADD_PLAIN_FIELD(mSleepThreshold, 10);
-			BS_ADD_PLAIN_FIELD(mUseGravity, 11);
-			BS_ADD_PLAIN_FIELD(mIsKinematic, 12);
-			BS_ADD_PLAIN_FIELD(mCollisionReportMode, 14);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 11 - 17
Source/BansheeCore/Include/BsCSliderJointRTTI.h

@@ -16,25 +16,19 @@ namespace BansheeEngine
 
 	class BS_CORE_EXPORT CSliderJointRTTI : public RTTIType<CSliderJoint, CJoint, CSliderJointRTTI>
 	{
-		BS_PLAIN_MEMBER_NAMED(mFlag, mDesc.flag)
-		BS_PLAIN_MEMBER_NAMED(mLimitLower, mDesc.limit.lower)
-		BS_PLAIN_MEMBER_NAMED(mLimitUpper, mDesc.limit.upper)
-		BS_PLAIN_MEMBER_NAMED(mLimitContactDist, mDesc.limit.contactDist)
-		BS_PLAIN_MEMBER_NAMED(mLimitRestitution, mDesc.limit.restitution)
-		BS_PLAIN_MEMBER_NAMED(mSpringDamping, mDesc.limit.spring.damping)
-		BS_PLAIN_MEMBER_NAMED(mSpringStiffness, mDesc.limit.spring.stiffness)
-
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN_NAMED(mFlag, mDesc.flag, 0)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitLower, mDesc.limit.lower, 1)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitUpper, mDesc.limit.upper, 2)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitContactDist, mDesc.limit.contactDist, 3)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitRestitution, mDesc.limit.restitution, 4)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mSpringDamping, mDesc.limit.spring.damping, 5)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mSpringStiffness, mDesc.limit.spring.stiffness, 6)
+		BS_END_RTTI_MEMBERS
 	public:
 		CSliderJointRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mFlag, 0);
-			BS_ADD_PLAIN_FIELD(mLimitLower, 1);
-			BS_ADD_PLAIN_FIELD(mLimitUpper, 2);
-			BS_ADD_PLAIN_FIELD(mLimitContactDist, 3);
-			BS_ADD_PLAIN_FIELD(mLimitRestitution, 4);
-			BS_ADD_PLAIN_FIELD(mSpringDamping, 5);
-			BS_ADD_PLAIN_FIELD(mSpringStiffness, 6);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 5 - 5
Source/BansheeCore/Include/BsCSphereColliderRTTI.h

@@ -17,13 +17,13 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT CSphereColliderRTTI : public RTTIType<CSphereCollider, CCollider, CSphereColliderRTTI>
 	{
 	private:
-		BS_PLAIN_MEMBER(mRadius)
-
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(mRadius, 0)
+		BS_END_RTTI_MEMBERS
 	public:
 		CSphereColliderRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mRadius, 0);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 11 - 17
Source/BansheeCore/Include/BsCSphericalJointRTTI.h

@@ -16,25 +16,19 @@ namespace BansheeEngine
 
 	class BS_CORE_EXPORT CSphericalJointRTTI : public RTTIType<CSphericalJoint, CJoint, CSphericalJointRTTI>
 	{
-		BS_PLAIN_MEMBER_NAMED(mFlag, mDesc.flag)
-		BS_PLAIN_MEMBER_NAMED(mYLimitAngle, mDesc.limit.yLimitAngle)
-		BS_PLAIN_MEMBER_NAMED(mZLimitAngle, mDesc.limit.zLimitAngle)
-		BS_PLAIN_MEMBER_NAMED(mLimitContactDist, mDesc.limit.contactDist)
-		BS_PLAIN_MEMBER_NAMED(mLimitRestitution, mDesc.limit.restitution)
-		BS_PLAIN_MEMBER_NAMED(mSpringDamping, mDesc.limit.spring.damping)
-		BS_PLAIN_MEMBER_NAMED(mSpringStiffness, mDesc.limit.spring.stiffness)
-
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN_NAMED(mFlag, mDesc.flag, 0)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mYLimitAngle, mDesc.limit.yLimitAngle, 1)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mZLimitAngle, mDesc.limit.zLimitAngle, 2)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitContactDist, mDesc.limit.contactDist, 3)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mLimitRestitution, mDesc.limit.restitution, 4)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mSpringDamping, mDesc.limit.spring.damping, 5)
+			BS_RTTI_MEMBER_PLAIN_NAMED(mSpringStiffness, mDesc.limit.spring.stiffness, 6)
+		BS_END_RTTI_MEMBERS
 	public:
 		CSphericalJointRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mFlag, 0);
-			BS_ADD_PLAIN_FIELD(mYLimitAngle, 1);
-			BS_ADD_PLAIN_FIELD(mZLimitAngle, 2);
-			BS_ADD_PLAIN_FIELD(mLimitContactDist, 3);
-			BS_ADD_PLAIN_FIELD(mLimitRestitution, 4);
-			BS_ADD_PLAIN_FIELD(mSpringDamping, 5);
-			BS_ADD_PLAIN_FIELD(mSpringStiffness, 6);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 12 - 19
Source/BansheeCore/Include/BsMeshImportOptionsRTTI.h

@@ -16,27 +16,20 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT MeshImportOptionsRTTI : public RTTIType <MeshImportOptions, ImportOptions, MeshImportOptionsRTTI>
 	{
 	private:
-		BS_PLAIN_MEMBER(mCPUReadable)
-		BS_PLAIN_MEMBER(mImportNormals)
-		BS_PLAIN_MEMBER(mImportTangents)
-		BS_PLAIN_MEMBER(mImportBlendShapes)
-		BS_PLAIN_MEMBER(mImportSkin)
-		BS_PLAIN_MEMBER(mImportAnimation)
-		BS_PLAIN_MEMBER(mImportScale)
-		BS_PLAIN_MEMBER(mCollisionMeshType)
-
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(mCPUReadable, 0)
+			BS_RTTI_MEMBER_PLAIN(mImportNormals, 1)
+			BS_RTTI_MEMBER_PLAIN(mImportTangents, 2)
+			BS_RTTI_MEMBER_PLAIN(mImportBlendShapes, 3)
+			BS_RTTI_MEMBER_PLAIN(mImportSkin, 4)
+			BS_RTTI_MEMBER_PLAIN(mImportAnimation, 5)
+			BS_RTTI_MEMBER_PLAIN(mImportScale, 6)
+			BS_RTTI_MEMBER_PLAIN(mCollisionMeshType, 7)
+		BS_END_RTTI_MEMBERS
 	public:
 		MeshImportOptionsRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mCPUReadable, 0);
-			BS_ADD_PLAIN_FIELD(mImportNormals, 1);
-			BS_ADD_PLAIN_FIELD(mImportTangents, 2);
-			BS_ADD_PLAIN_FIELD(mImportBlendShapes, 3);
-			BS_ADD_PLAIN_FIELD(mImportSkin, 4);
-			BS_ADD_PLAIN_FIELD(mImportAnimation, 5);
-			BS_ADD_PLAIN_FIELD(mImportScale, 6);
-			BS_ADD_PLAIN_FIELD(mCollisionMeshType, 7);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 10 - 9
Source/BansheeCore/Include/BsPhysicsMeshRTTI.h

@@ -17,13 +17,14 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT PhysicsMeshRTTI : public RTTIType<PhysicsMesh, Resource, PhysicsMeshRTTI>
 	{
 	private:
-		BS_REFLPTR_MEMBER(mInternal)
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_REFLPTR(mInternal, 0)
+		BS_END_RTTI_MEMBERS
 
 	public:
 		PhysicsMeshRTTI()
-		{
-			BS_ADD_REFLPTR_FIELD(mInternal, 0)
-		}
+			:mInitMembers(this)
+		{ }
 
 		void onDeserializationEnded(IReflectable* obj) override
 		{
@@ -54,13 +55,13 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT FPhysicsMeshRTTI : public RTTIType<FPhysicsMesh, IReflectable, FPhysicsMeshRTTI>
 	{
 	private:
-		BS_PLAIN_MEMBER(mType)
-
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(mType, 0)
+		BS_END_RTTI_MEMBERS
 	public:
 		FPhysicsMeshRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mType, 0)
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 31 - 44
Source/BansheeCore/Include/BsPrefabDiffRTTI.h

@@ -19,14 +19,14 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT PrefabComponentDiffRTTI : public RTTIType < PrefabComponentDiff, IReflectable, PrefabComponentDiffRTTI >
 	{
 	private:
-		BS_PLAIN_MEMBER(id)
-		BS_REFLPTR_MEMBER(data);
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(id, 0)
+			BS_RTTI_MEMBER_REFLPTR(data, 1)
+		BS_END_RTTI_MEMBERS
 	public:
 		PrefabComponentDiffRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(id, 0);
-			BS_ADD_REFLPTR_FIELD(data, 1);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{
@@ -48,42 +48,28 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT PrefabObjectDiffRTTI : public RTTIType < PrefabObjectDiff, IReflectable, PrefabObjectDiffRTTI >
 	{
 	private:
-		BS_PLAIN_MEMBER(id)
-
-		BS_PLAIN_MEMBER(name)
-		BS_PLAIN_MEMBER(position);
-		BS_PLAIN_MEMBER(rotation);
-		BS_PLAIN_MEMBER(scale);
-		BS_PLAIN_MEMBER(isActive);
-		BS_PLAIN_MEMBER(soFlags);
-
-		BS_REFLPTR_MEMBER_VEC(componentDiffs)
-		BS_PLAIN_MEMBER_VEC(removedComponents)
-		BS_REFLPTR_MEMBER_VEC(addedComponents)
-
-		BS_REFLPTR_MEMBER_VEC(childDiffs)
-		BS_PLAIN_MEMBER_VEC(removedChildren)
-		BS_REFLPTR_MEMBER_VEC(addedChildren)
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(id, 0)
+			BS_RTTI_MEMBER_PLAIN(name, 1)
+
+			BS_RTTI_MEMBER_REFLPTR_ARRAY(componentDiffs, 2)
+			BS_RTTI_MEMBER_PLAIN_ARRAY(removedComponents, 3)
+			BS_RTTI_MEMBER_REFLPTR_ARRAY(addedComponents, 4)
+			BS_RTTI_MEMBER_REFLPTR_ARRAY(childDiffs, 5)
+
+			BS_RTTI_MEMBER_PLAIN_ARRAY(removedChildren, 6)
+			BS_RTTI_MEMBER_REFLPTR_ARRAY(addedChildren, 7)
+
+			BS_RTTI_MEMBER_PLAIN(position, 8)
+			BS_RTTI_MEMBER_PLAIN(rotation, 9)
+			BS_RTTI_MEMBER_PLAIN(scale, 10)
+			BS_RTTI_MEMBER_PLAIN(isActive, 11)
+			BS_RTTI_MEMBER_PLAIN(soFlags, 12)
+		BS_END_RTTI_MEMBERS
 	public:
 		PrefabObjectDiffRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(id, 0);
-			BS_ADD_PLAIN_FIELD(name, 1);
-
-			BS_ADD_REFLPTR_FIELD_ARR(componentDiffs, 2);
-			BS_ADD_PLAIN_FIELD_ARR(removedComponents, 3);
-			BS_ADD_REFLPTR_FIELD_ARR(addedComponents, 4);
-			BS_ADD_REFLPTR_FIELD_ARR(childDiffs, 5);
-
-			BS_ADD_PLAIN_FIELD_ARR(removedChildren, 6);
-			BS_ADD_REFLPTR_FIELD_ARR(addedChildren, 7);
-
-			BS_ADD_PLAIN_FIELD(position, 8);
-			BS_ADD_PLAIN_FIELD(rotation, 9);
-			BS_ADD_PLAIN_FIELD(scale, 10);
-			BS_ADD_PLAIN_FIELD(isActive, 11);
-			BS_ADD_PLAIN_FIELD(soFlags, 12);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{
@@ -112,12 +98,13 @@ namespace BansheeEngine
 		};
 
 	private:
-		BS_REFLPTR_MEMBER(mRoot);
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_REFLPTR(mRoot, 0)
+		BS_END_RTTI_MEMBERS
 	public:
 		PrefabDiffRTTI()
-		{
-			BS_ADD_REFLPTR_FIELD(mRoot, 0);
-		}
+			:mInitMembers(this)
+		{ }
 
 		void onDeserializationStarted(IReflectable* obj) override
 		{

+ 19 - 39
Source/BansheeEditor/Include/BsEditorSettingsRTTI.h

@@ -16,53 +16,33 @@ namespace BansheeEngine
 	class EditorSettingsRTTI : public RTTIType <EditorSettings, Settings, EditorSettingsRTTI>
 	{
 	private:
-		BS_PLAIN_MEMBER(mMoveSnapActive);
-		BS_PLAIN_MEMBER(mRotateSnapActive);
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(mMoveSnapActive, 0)
+			BS_RTTI_MEMBER_PLAIN(mRotateSnapActive, 1)
 
-		BS_PLAIN_MEMBER(mMoveSnap);
-		BS_PLAIN_MEMBER(mRotationSnap);
+			BS_RTTI_MEMBER_PLAIN(mMoveSnap, 2)
+			BS_RTTI_MEMBER_PLAIN(mRotationSnap, 3)
 
-		BS_PLAIN_MEMBER(mGridSize);
-		BS_PLAIN_MEMBER(mGridAxisSpacing);
+			BS_RTTI_MEMBER_PLAIN(mGridSize, 4)
+			BS_RTTI_MEMBER_PLAIN(mGridAxisSpacing, 5)
 
-		BS_PLAIN_MEMBER(mActiveSceneTool);
-		BS_PLAIN_MEMBER(mActiveCoordinateMode);
-		BS_PLAIN_MEMBER(mActivePivotMode);
+			BS_RTTI_MEMBER_PLAIN(mActiveSceneTool, 6)
+			BS_RTTI_MEMBER_PLAIN(mActiveCoordinateMode, 7)
+			BS_RTTI_MEMBER_PLAIN(mActivePivotMode, 8)
 
-		BS_PLAIN_MEMBER(mHandleSize);
+			BS_RTTI_MEMBER_PLAIN(mHandleSize, 9)
 
-		BS_PLAIN_MEMBER(mLastOpenProject);
-		BS_PLAIN_MEMBER(mAutoLoadLastProject);
-		BS_PLAIN_MEMBER(mRecentProjects);
-
-		BS_PLAIN_MEMBER(mFPSLimit);
-		BS_PLAIN_MEMBER(mMouseSensitivity);
+			BS_RTTI_MEMBER_PLAIN(mLastOpenProject, 10)
+			BS_RTTI_MEMBER_PLAIN(mAutoLoadLastProject, 11)
+			BS_RTTI_MEMBER_PLAIN(mRecentProjects, 12)
 
+			BS_RTTI_MEMBER_PLAIN(mFPSLimit, 13)
+			BS_RTTI_MEMBER_PLAIN(mMouseSensitivity, 14)
+		BS_END_RTTI_MEMBERS
 	public:
 		EditorSettingsRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mMoveSnapActive, 0);
-			BS_ADD_PLAIN_FIELD(mRotateSnapActive, 1);
-
-			BS_ADD_PLAIN_FIELD(mMoveSnap, 2);
-			BS_ADD_PLAIN_FIELD(mRotationSnap, 3);
-
-			BS_ADD_PLAIN_FIELD(mGridSize, 4);
-			BS_ADD_PLAIN_FIELD(mGridAxisSpacing, 5);
-
-			BS_ADD_PLAIN_FIELD(mActiveSceneTool, 6);
-			BS_ADD_PLAIN_FIELD(mActiveCoordinateMode, 7);
-			BS_ADD_PLAIN_FIELD(mActivePivotMode, 8);
-
-			BS_ADD_PLAIN_FIELD(mHandleSize, 9);
-
-			BS_ADD_PLAIN_FIELD(mLastOpenProject, 10);
-			BS_ADD_PLAIN_FIELD(mAutoLoadLastProject, 11);
-			BS_ADD_PLAIN_FIELD(mRecentProjects, 12);
-
-			BS_ADD_PLAIN_FIELD(mFPSLimit, 13);
-			BS_ADD_PLAIN_FIELD(mMouseSensitivity, 14);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 15 - 19
Source/BansheeEditor/Include/BsProjectResourceMetaRTTI.h

@@ -18,19 +18,16 @@ namespace BansheeEngine
 	class ProjectResourceMetaRTTI : public RTTIType<ProjectResourceMeta, IReflectable, ProjectResourceMetaRTTI>
 	{
 	private:
-		BS_PLAIN_MEMBER(mName)
-		BS_PLAIN_MEMBER(mUUID)
-		BS_PLAIN_MEMBER(mTypeId)
-		BS_REFLPTR_MEMBER(mResourceMeta)
-			
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(mName, 0)
+			BS_RTTI_MEMBER_PLAIN(mUUID, 1)
+			BS_RTTI_MEMBER_PLAIN(mTypeId, 2)
+			BS_RTTI_MEMBER_REFLPTR(mResourceMeta, 3)
+		BS_END_RTTI_MEMBERS
 	public:
 		ProjectResourceMetaRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mName, 0);
-			BS_ADD_PLAIN_FIELD(mUUID, 1);
-			BS_ADD_PLAIN_FIELD(mTypeId, 2);
-			BS_ADD_REFLPTR_FIELD(mResourceMeta, 3);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{
@@ -52,17 +49,16 @@ namespace BansheeEngine
 	class ProjectFileMetaRTTI : public RTTIType<ProjectFileMeta, IReflectable, ProjectFileMetaRTTI>
 	{
 	private:
-		BS_REFLPTR_MEMBER(mImportOptions)
-		BS_PLAIN_MEMBER(mIncludeInBuild)
-		BS_REFLPTR_MEMBER_VEC(mResourceMetaData)
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_REFLPTR(mImportOptions, 1)
+			BS_RTTI_MEMBER_PLAIN(mIncludeInBuild, 4)
+			BS_RTTI_MEMBER_REFLPTR_ARRAY(mResourceMetaData, 5)
+		BS_END_RTTI_MEMBERS
 
 	public:
 		ProjectFileMetaRTTI()
-		{
-			BS_ADD_REFLPTR_FIELD(mImportOptions, 1);
-			BS_ADD_PLAIN_FIELD(mIncludeInBuild, 4);
-			BS_ADD_REFLPTR_FIELD_ARR(mResourceMetaData, 5);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 5 - 5
Source/BansheeEditor/Include/BsProjectSettingsRTTI.h

@@ -16,13 +16,13 @@ namespace BansheeEngine
 	class ProjectSettingsRTTI : public RTTIType <ProjectSettings, Settings, ProjectSettingsRTTI>
 	{
 	private:
-		BS_PLAIN_MEMBER(mLastOpenScene);
-
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(mLastOpenScene, 0)
+		BS_END_RTTI_MEMBERS
 	public:
 		ProjectSettingsRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mLastOpenScene, 0);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 8 - 11
Source/BansheeEditor/Include/BsSettingsRTTI.h

@@ -16,19 +16,16 @@ namespace BansheeEngine
 	class SettingsRTTI : public RTTIType <Settings, IReflectable, SettingsRTTI>
 	{
 	private:
-		BS_PLAIN_MEMBER(mFloatProperties);
-		BS_PLAIN_MEMBER(mIntProperties);
-		BS_PLAIN_MEMBER(mBoolProperties);
-		BS_PLAIN_MEMBER(mStringProperties);
-
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(mFloatProperties, 13)
+			BS_RTTI_MEMBER_PLAIN(mIntProperties, 14)
+			BS_RTTI_MEMBER_PLAIN(mBoolProperties, 15)
+			BS_RTTI_MEMBER_PLAIN(mStringProperties, 16)
+		BS_END_RTTI_MEMBERS
 	public:
 		SettingsRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mFloatProperties, 13);
-			BS_ADD_PLAIN_FIELD(mIntProperties, 14);
-			BS_ADD_PLAIN_FIELD(mBoolProperties, 15);
-			BS_ADD_PLAIN_FIELD(mStringProperties, 16);
-		}
+			:mInitMembers(this)
+		{ }
 
 		virtual const String& getRTTIName() override
 		{

+ 57 - 74
Source/BansheeEditor/Source/BsEditorTestSuite.cpp

@@ -34,18 +34,18 @@ namespace BansheeEngine
 			addReflectableField("ref2", 1, &TestComponentARTTI::getRef2, &TestComponentARTTI::setRef2);
 		}
 
-		virtual const String& getRTTIName() override
+		const String& getRTTIName() override
 		{
 			static String name = "TestComponentA";
 			return name;
 		}
 
-		virtual UINT32 getRTTIId() override
+		UINT32 getRTTIId() override
 		{
 			return TID_TestComponentA;
 		}
 
-		virtual SPtr<IReflectable> newRTTIObject() override
+		SPtr<IReflectable> newRTTIObject() override
 		{
 			return GameObjectRTTI::createGameObject<TestComponentA>();
 		}
@@ -67,18 +67,18 @@ namespace BansheeEngine
 			addPlainField("val1", 1, &TestComponentBRTTI::getVal1, &TestComponentBRTTI::setVal1);
 		}
 
-		virtual const String& getRTTIName() override
+		const String& getRTTIName() override
 		{
 			static String name = "TestComponentB";
 			return name;
 		}
 
-		virtual UINT32 getRTTIId() override
+		UINT32 getRTTIId() override
 		{
 			return TID_TestComponentB;
 		}
 
-		virtual SPtr<IReflectable> newRTTIObject() override
+		SPtr<IReflectable> newRTTIObject() override
 		{
 			return GameObjectRTTI::createGameObject<TestComponentB>();
 		}
@@ -123,7 +123,7 @@ namespace BansheeEngine
 	public:
 		friend class TestObjectBRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	struct TestObjectA : IReflectable
@@ -169,72 +169,53 @@ namespace BansheeEngine
 	public:
 		friend class TestObjectARTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 	};
 
 	class TestObjectARTTI : public RTTIType < TestObjectA, IReflectable, TestObjectARTTI >
 	{
 	private:
-		BS_PLAIN_MEMBER(intA);
-		BS_PLAIN_MEMBER(strA);
-		BS_PLAIN_MEMBER(strB);
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(intA, 0)
+			BS_RTTI_MEMBER_PLAIN(strA, 1)
+			BS_RTTI_MEMBER_PLAIN(strB, 2)
 
-		BS_REFL_MEMBER(objA);
-		BS_REFL_MEMBER(objB);
+			BS_RTTI_MEMBER_REFL(objA, 3)
+			BS_RTTI_MEMBER_REFL(objB, 4)
 
-		BS_REFLPTR_MEMBER(objPtrA);
-		BS_REFLPTR_MEMBER(objPtrB);
-		BS_REFLPTR_MEMBER(objPtrC);
-		BS_REFLPTR_MEMBER(objPtrD);
+			BS_RTTI_MEMBER_REFLPTR(objPtrA, 5)
+			BS_RTTI_MEMBER_REFLPTR(objPtrB, 6)
+			BS_RTTI_MEMBER_REFLPTR(objPtrC, 7)
+			BS_RTTI_MEMBER_REFLPTR(objPtrD, 8)
 
-		BS_PLAIN_MEMBER_VEC(arrStrA);
-		BS_PLAIN_MEMBER_VEC(arrStrB);
-		BS_PLAIN_MEMBER_VEC(arrStrC);
+			BS_RTTI_MEMBER_PLAIN_ARRAY(arrStrA, 9)
+			BS_RTTI_MEMBER_PLAIN_ARRAY(arrStrB, 10)
+			BS_RTTI_MEMBER_PLAIN_ARRAY(arrStrC, 11)
 
-		BS_REFL_MEMBER_VEC(arrObjA);
-		BS_REFL_MEMBER_VEC(arrObjB);
+			BS_RTTI_MEMBER_REFL_ARRAY(arrObjA, 12)
+			BS_RTTI_MEMBER_REFL_ARRAY(arrObjB, 13)
 
-		BS_REFLPTR_MEMBER_VEC(arrObjPtrA);
-		BS_REFLPTR_MEMBER_VEC(arrObjPtrB);
+			BS_RTTI_MEMBER_REFLPTR_ARRAY(arrObjPtrA, 14)
+			BS_RTTI_MEMBER_REFLPTR_ARRAY(arrObjPtrB, 15)
+		BS_END_RTTI_MEMBERS
 
 	public:
 		TestObjectARTTI()
-		{
-			BS_ADD_PLAIN_FIELD(intA, 0);
-			BS_ADD_PLAIN_FIELD(strA, 1);
-			BS_ADD_PLAIN_FIELD(strB, 2);
-
-			BS_ADD_REFL_FIELD(objA, 3);
-			BS_ADD_REFL_FIELD(objB, 4);
-
-			BS_ADD_REFLPTR_FIELD(objPtrA, 5);
-			BS_ADD_REFLPTR_FIELD(objPtrB, 6);
-			BS_ADD_REFLPTR_FIELD(objPtrC, 7);
-			BS_ADD_REFLPTR_FIELD(objPtrD, 8);
-
-			BS_ADD_PLAIN_FIELD_ARR(arrStrA, 9);
-			BS_ADD_PLAIN_FIELD_ARR(arrStrB, 10);
-			BS_ADD_PLAIN_FIELD_ARR(arrStrC, 11);
-
-			BS_ADD_REFL_FIELD_ARR(arrObjA, 12);
-			BS_ADD_REFL_FIELD_ARR(arrObjB, 13);
-
-			BS_ADD_REFLPTR_FIELD_ARR(arrObjPtrA, 14);
-			BS_ADD_REFLPTR_FIELD_ARR(arrObjPtrB, 15);
-		}
+			:mInitMembers(this)
+		{ }
 
-		virtual const String& getRTTIName() override
+		const String& getRTTIName() override
 		{
 			static String name = "TestObjectA";
 			return name;
 		}
 
-		virtual UINT32 getRTTIId() override
+		UINT32 getRTTIId() override
 		{
 			return TID_TestObjectA;
 		}
 
-		virtual SPtr<IReflectable> newRTTIObject() override
+		SPtr<IReflectable> newRTTIObject() override
 		{
 			return bs_shared_ptr_new<TestObjectA>();
 		}
@@ -243,28 +224,28 @@ namespace BansheeEngine
 	class TestObjectBRTTI : public RTTIType < TestObjectB, IReflectable, TestObjectBRTTI >
 	{
 	private:
-		BS_PLAIN_MEMBER(intA);
-		BS_PLAIN_MEMBER(strA);
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(intA, 0)
+			BS_RTTI_MEMBER_PLAIN(strA, 1)
+		BS_END_RTTI_MEMBERS
 
 	public:
 		TestObjectBRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(intA, 0);
-			BS_ADD_PLAIN_FIELD(strA, 1);
-		}
+			:mInitMembers(this)
+		{ }
 
-		virtual const String& getRTTIName() override
+		const String& getRTTIName() override
 		{
 			static String name = "TestObjectB";
 			return name;
 		}
 
-		virtual UINT32 getRTTIId() override
+		UINT32 getRTTIId() override
 		{
 			return TID_TestObjectB;
 		}
 
-		virtual SPtr<IReflectable> newRTTIObject() override
+		SPtr<IReflectable> newRTTIObject() override
 		{
 			return bs_shared_ptr_new<TestObjectB>();
 		}
@@ -312,7 +293,7 @@ namespace BansheeEngine
 	public:
 		friend class TestComponentCRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 
 	protected:
 		TestComponentC() {} // Serialization only
@@ -349,26 +330,27 @@ namespace BansheeEngine
 	class TestComponentCRTTI : public RTTIType < TestComponentC, Component, TestComponentCRTTI >
 	{
 	private:
-		BS_REFL_MEMBER(obj)
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_REFL(obj, 0)
+		BS_END_RTTI_MEMBERS
 
 	public:
 		TestComponentCRTTI()
-		{
-			BS_ADD_REFL_FIELD(obj, 0);
-		}
+			:mInitMembers(this)
+		{ }
 
-		virtual const String& getRTTIName() override
+		const String& getRTTIName() override
 		{
 			static String name = "TestComponentC";
 			return name;
 		}
 
-		virtual UINT32 getRTTIId() override
+		UINT32 getRTTIId() override
 		{
 			return TID_TestComponentC;
 		}
 
-		virtual SPtr<IReflectable> newRTTIObject() override
+		SPtr<IReflectable> newRTTIObject() override
 		{
 			return GameObjectRTTI::createGameObject<TestComponentC>();
 		}
@@ -377,26 +359,27 @@ namespace BansheeEngine
 	class TestComponentDRTTI : public RTTIType < TestComponentD, Component, TestComponentDRTTI >
 	{
 	private:
-		BS_REFL_MEMBER(obj)
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_REFL(obj, 0)
+		BS_END_RTTI_MEMBERS
 
 	public:
 		TestComponentDRTTI()
-		{
-			BS_ADD_REFL_FIELD(obj, 0);
-		}
+			:mInitMembers(this)
+		{ }
 
-		virtual const String& getRTTIName() override
+		const String& getRTTIName() override
 		{
 			static String name = "TestComponentD";
 			return name;
 		}
 
-		virtual UINT32 getRTTIId() override
+		UINT32 getRTTIId() override
 		{
 			return TID_TestComponentD;
 		}
 
-		virtual SPtr<IReflectable> newRTTIObject() override
+		SPtr<IReflectable> newRTTIObject() override
 		{
 			return GameObjectRTTI::createGameObject<TestComponentD>();
 		}

+ 5 - 4
Source/BansheeEngine/Include/BsResourceMappingRTTI.h

@@ -16,13 +16,14 @@ namespace BansheeEngine
 	class BS_EXPORT ResourceMappingRTTI : public RTTIType<ResourceMapping, IReflectable, ResourceMappingRTTI>
 	{
 	private:
-		BS_PLAIN_MEMBER(mMapping)
+		BS_BEGIN_RTTI_MEMBERS
+			BS_RTTI_MEMBER_PLAIN(mMapping, 0)
+		BS_END_RTTI_MEMBERS
 
 	public:
 		ResourceMappingRTTI()
-		{
-			BS_ADD_PLAIN_FIELD(mMapping, 0);
-		}
+			:mInitMembers(this)
+		{ }
 
 		const String& getRTTIName() override
 		{

+ 187 - 72
Source/BansheeUtility/Include/BsRTTIType.h

@@ -22,83 +22,198 @@ namespace BansheeEngine
 	 *  @{
 	 */
 
-	/** Similar to BS_PLAIN_MEMBER but allows you to specify name of the field and the variable it's referencing separately. */
-#define BS_PLAIN_MEMBER_NAMED(name, field)														\
-	decltype(OwnerType::field)& get##name(OwnerType* obj) { return obj->field; }				\
-	void set##name(OwnerType* obj, decltype(OwnerType::field)& val) { obj->field = val; } 
-
-	/** Similar to BS_REFL_MEMBER but allows you to specify name of the field and the variable it's referencing separately. */
-#define BS_REFL_MEMBER_NAMED(name, field)														\
-	decltype(OwnerType::field)& get##name(OwnerType* obj) { return obj->field; }				\
-	void set##name(OwnerType* obj, decltype(OwnerType::field)& val) { obj->field = val; } 
-
-	/** Similar to BS_REFLPTR_MEMBER but allows you to specify name of the field and the variable it's referencing separately. */
-#define BS_REFLPTR_MEMBER_NAMED(name, field)													\
-	decltype(OwnerType::field) get##name(OwnerType* obj) { return obj->field; }					\
-	void set##name(OwnerType* obj, decltype(OwnerType::field) val) { obj->field = val; } 
-
-	/** Shortcut for defining getter/setter methods for a RTTI plain field. */
-#define BS_PLAIN_MEMBER(name)																	\
-	decltype(OwnerType::name)& get##name(OwnerType* obj) { return obj->name; }					\
-	void set##name(OwnerType* obj, decltype(OwnerType::name)& val) { obj->name = val; } 
-
-	/** Shortcut for defining getter/setter methods for a RTTI reflectable field. */
-#define BS_REFL_MEMBER(name)																	\
+	 /**
+	  * Starts definitions for member fields within a RTTI type. Follow this with calls to BS_RTTI_MEMBER* calls, and finish by
+	  * calling BS_END_RTTI_MEMBERS. You must also initialize mInitMembers field in the parent class' constructor.
+	  */
+#define BS_BEGIN_RTTI_MEMBERS																	\
+	struct META_FirstEntry {};																	\
+	void META_InitPrevEntry(META_FirstEntry typeId) { }											\
+																								\
+	typedef META_FirstEntry
+
+	  /**
+	   * Registers a new member field in the RTTI type. The field references the @p name member in the owner class.
+	   * The type of the member must be a valid plain type. Each field must specify a unique ID for @p id.
+	   */
+#define BS_RTTI_MEMBER_PLAIN(name, id)															\
+	META_Entry_##name;																			\
+																								\
 	decltype(OwnerType::name)& get##name(OwnerType* obj) { return obj->name; }					\
-	void set##name(OwnerType* obj, decltype(OwnerType::name)& val) { obj->name = val; } 
-
-	/** Shortcut for defining getter/setter methods for a RTTI reflectable pointer field. */
-#define BS_REFLPTR_MEMBER(name)								\
-	decltype(OwnerType::name) get##name(OwnerType* obj) { return obj->name; }				\
-	void set##name(OwnerType* obj, decltype(OwnerType::name) val) { obj->name = val; } 
-
-	/** Registers a plain field defined with BS_PLAIN_MEMBER or BS_PLAIN_MEMBER_NAMED with the RTTI object. */
-#define BS_ADD_PLAIN_FIELD(name, id) \
-	addPlainField(#name, id, &MyType::get##name, &MyType::set##name);
-
-	/** Registers a plain field defined with BS_REFL_MEMBER or BS_REFL_MEMBER_NAMED with the RTTI object. */
-#define BS_ADD_REFL_FIELD(name, id) \
-	addReflectableField(#name, id, &MyType::get##name, &MyType::set##name);
-
-	/** Registers a plain field defined with BS_REFLPTR_MEMBER or BS_REFLPTR_MEMBER_NAMED with the RTTI object. */
-#define BS_ADD_REFLPTR_FIELD(name, id) \
-	addReflectablePtrField(#name, id, &MyType::get##name, &MyType::set##name);
-
-	/** Shortcut for defining getter/setter methods for a RTTI plain Vector<T> field. */
-#define BS_PLAIN_MEMBER_VEC(name)								\
-	std::common_type<decltype(OwnerType::name)>::type::value_type& get##name(OwnerType* obj, UINT32 idx) { return obj->name[idx]; }				\
+	void set##name(OwnerType* obj, decltype(OwnerType::name)& val) { obj->name = val; }			\
+																								\
+	struct META_NextEntry_##name{};																\
+	void META_InitPrevEntry(META_NextEntry_##name typeId)										\
+	{																							\
+		addPlainField(#name, id, &MyType::get##name, &MyType::set##name);						\
+		META_InitPrevEntry(META_Entry_##name());												\
+	}																							\
+																								\
+	typedef META_NextEntry_##name
+
+	   /** Same as BS_RTTI_MEMBER_PLAIN, but allows you to specify separate names for the field name and the member variable. */
+#define BS_RTTI_MEMBER_PLAIN_NAMED(name, field, id)												\
+	META_Entry_##name;																			\
+																								\
+	decltype(OwnerType::field)& get##name(OwnerType* obj) { return obj->field; }				\
+	void set##name(OwnerType* obj, decltype(OwnerType::field)& val) { obj->field = val; }		\
+																								\
+	struct META_NextEntry_##name{};																\
+	void META_InitPrevEntry(META_NextEntry_##name typeId)										\
+	{																							\
+		addPlainField(#name, id, &MyType::get##name, &MyType::set##name);						\
+		META_InitPrevEntry(META_Entry_##name());												\
+	}																							\
+																								\
+	typedef META_NextEntry_##name
+
+/**
+ * Registers a new member field in the RTTI type. The field references the @p name member in the owner class.
+ * The type of the member must be an array of valid plain types. Each field must specify a unique ID for @p id.
+ */
+#define BS_RTTI_MEMBER_PLAIN_ARRAY(name, id)													\
+	META_Entry_##name;																			\
+																								\
+	std::common_type<decltype(OwnerType::name)>::type::value_type& get##name(OwnerType* obj, UINT32 idx) { return obj->name[idx]; }					\
 	void set##name(OwnerType* obj, UINT32 idx, std::common_type<decltype(OwnerType::name)>::type::value_type& val) { obj->name[idx] = val; }		\
-	UINT32 getSize##name(OwnerType* obj) { return (UINT32)obj->name.size(); }	\
-	void setSize##name(OwnerType* obj, UINT32 val) { obj->name.resize(val); }
-
-	/** Shortcut for defining getter/setter methods for a RTTI reflectable Vector<T> field. */
-#define BS_REFL_MEMBER_VEC(name)								\
-	std::common_type<decltype(OwnerType::name)>::type::value_type& get##name(OwnerType* obj, UINT32 idx) { return obj->name[idx]; }				\
+	UINT32 getSize##name(OwnerType* obj) { return (UINT32)obj->name.size(); }																		\
+	void setSize##name(OwnerType* obj, UINT32 val) { obj->name.resize(val); }																		\
+																								\
+	struct META_NextEntry_##name{};																\
+	void META_InitPrevEntry(META_NextEntry_##name typeId)										\
+	{																							\
+		addPlainArrayField(#name, id, &MyType::get##name, &MyType::getSize##name, &MyType::set##name, &MyType::setSize##name);						\
+		META_InitPrevEntry(META_Entry_##name());												\
+	}																							\
+																								\
+	typedef META_NextEntry_##name
+
+/**
+ * Registers a new member field in the RTTI type. The field references the @p name member in the owner class. 
+ * The type of the member must be a valid reflectable (non-pointer) type. Each field must specify a unique ID for @p id.
+ */
+#define BS_RTTI_MEMBER_REFL(name, id)															\
+	META_Entry_##name;																			\
+																								\
+	decltype(OwnerType::name)& get##name(OwnerType* obj) { return obj->name; }					\
+	void set##name(OwnerType* obj, decltype(OwnerType::name)& val) { obj->name = val; }			\
+																								\
+	struct META_NextEntry_##name{};																\
+	void META_InitPrevEntry(META_NextEntry_##name typeId)										\
+	{																							\
+		addReflectableField(#name, id, &MyType::get##name, &MyType::set##name);					\
+		META_InitPrevEntry(META_Entry_##name());												\
+	}																							\
+																								\
+	typedef META_NextEntry_##name
+
+/** Same as BS_RTTI_MEMBER_REFL, but allows you to specify separate names for the field name and the member variable. */
+#define BS_RTTI_MEMBER_REFL_NAMED(name, field, id)												\
+	META_Entry_##name;																			\
+																								\
+	decltype(OwnerType::field)& get##name(OwnerType* obj) { return obj->field; }				\
+	void set##name(OwnerType* obj, decltype(OwnerType::field)& val) { obj->field = val; }		\
+																								\
+	struct META_NextEntry_##name{};																\
+	void META_InitPrevEntry(META_NextEntry_##name typeId)										\
+	{																							\
+		addReflectableField(#name, id, &MyType::get##name, &MyType::set##name);					\
+		META_InitPrevEntry(META_Entry_##name());												\
+	}																							\
+																								\
+	typedef META_NextEntry_##name
+
+/**
+ * Registers a new member field in the RTTI type. The field references the @p name member in the owner class. 
+ * The type of the member must be an array of valid reflectable (non-pointer) types. Each field must specify a unique ID for
+ * @p id.
+ */
+#define BS_RTTI_MEMBER_REFL_ARRAY(name, id)														\
+	META_Entry_##name;																			\
+																								\
+	std::common_type<decltype(OwnerType::name)>::type::value_type& get##name(OwnerType* obj, UINT32 idx) { return obj->name[idx]; }					\
 	void set##name(OwnerType* obj, UINT32 idx, std::common_type<decltype(OwnerType::name)>::type::value_type& val) { obj->name[idx] = val; }		\
-	UINT32 getSize##name(OwnerType* obj) { return (UINT32)obj->name.size(); }	\
-	void setSize##name(OwnerType* obj, UINT32 val) { obj->name.resize(val); }
-
-	/** Shortcut for defining getter/setter methods for a RTTI reflectable pointer Vector<T> field. */
-#define BS_REFLPTR_MEMBER_VEC(name)								\
+	UINT32 getSize##name(OwnerType* obj) { return (UINT32)obj->name.size(); }					\
+	void setSize##name(OwnerType* obj, UINT32 val) { obj->name.resize(val); }					\
+																								\
+	struct META_NextEntry_##name{};																\
+	void META_InitPrevEntry(META_NextEntry_##name typeId)										\
+	{																							\
+		addReflectableArrayField(#name, id, &MyType::get##name, &MyType::getSize##name, &MyType::set##name, &MyType::setSize##name);				\
+		META_InitPrevEntry(META_Entry_##name());												\
+	}																							\
+																								\
+	typedef META_NextEntry_##name
+
+/**
+ * Registers a new member field in the RTTI type. The field references the @p name member in the owner class. 
+ * The type of the member must be a valid reflectable pointer type. Each field must specify a unique ID for @p id.
+ */
+#define BS_RTTI_MEMBER_REFLPTR(name, id)														\
+	META_Entry_##name;																			\
+																								\
+	decltype(OwnerType::name) get##name(OwnerType* obj) { return obj->name; }					\
+	void set##name(OwnerType* obj, decltype(OwnerType::name) val) { obj->name = val; }			\
+																								\
+	struct META_NextEntry_##name{};																\
+	void META_InitPrevEntry(META_NextEntry_##name typeId)										\
+	{																							\
+		addReflectablePtrField(#name, id, &MyType::get##name, &MyType::set##name);				\
+		META_InitPrevEntry(META_Entry_##name());												\
+	}																							\
+																								\
+	typedef META_NextEntry_##name
+
+/** Same as BS_RTTI_MEMBER_REFLPTR, but allows you to specify separate names for the field name and the member variable. */
+#define BS_RTTI_MEMBER_REFLPTR_NAMED(name, field, id)											\
+	META_Entry_##name;																			\
+																								\
+	decltype(OwnerType::field) get##name(OwnerType* obj) { return obj->field; }					\
+	void set##name(OwnerType* obj, decltype(OwnerType::field) val) { obj->field = val; }		\
+																								\
+	struct META_NextEntry_##name{};																\
+	void META_InitPrevEntry(META_NextEntry_##name typeId)										\
+	{																							\
+		addReflectablePtrField(#name, id, &MyType::get##name, &MyType::set##name);				\
+		META_InitPrevEntry(META_Entry_##name());												\
+	}																							\
+																								\
+	typedef META_NextEntry_##name
+
+/**
+ * Registers a new member field in the RTTI type. The field references the @p name member in the owner class. 
+ * The type of the member must be a valid reflectable pointer type. Each field must specify a unique ID for @p id.
+ */
+#define BS_RTTI_MEMBER_REFLPTR_ARRAY(name, id)													\
+	META_Entry_##name;																			\
+																								\
 	std::common_type<decltype(OwnerType::name)>::type::value_type get##name(OwnerType* obj, UINT32 idx) { return obj->name[idx]; }				\
 	void set##name(OwnerType* obj, UINT32 idx, std::common_type<decltype(OwnerType::name)>::type::value_type val) { obj->name[idx] = val; }		\
-	UINT32 getSize##name(OwnerType* obj) { return (UINT32)obj->name.size(); }	\
-	void setSize##name(OwnerType* obj, UINT32 val) { obj->name.resize(val); }
-
-	/** Registers a plain array field defined with BS_PLAIN_MEMBER_VEC with the RTTI object. */
-#define BS_ADD_PLAIN_FIELD_ARR(name, id) \
-	addPlainArrayField(#name, id, &MyType::get##name, &MyType::getSize##name, \
-	&MyType::set##name, &MyType::setSize##name);
-
-	/** Registers a reflectable object array field defined with BS_PLAIN_MEMBER_VEC with the RTTI object. */
-#define BS_ADD_REFL_FIELD_ARR(name, id) \
-	addReflectableArrayField(#name, id, &MyType::get##name, &MyType::getSize##name, \
-	&MyType::set##name, &MyType::setSize##name);
-
-	/** Registers a reflectable pointer array field defined with BS_PLAIN_MEMBER_VEC with the RTTI object. */
-#define BS_ADD_REFLPTR_FIELD_ARR(name, id) \
-	addReflectablePtrArrayField(#name, id, &MyType::get##name, &MyType::getSize##name, \
-	&MyType::set##name, &MyType::setSize##name);
+	UINT32 getSize##name(OwnerType* obj) { return (UINT32)obj->name.size(); }					\
+	void setSize##name(OwnerType* obj, UINT32 val) { obj->name.resize(val); }					\
+																								\
+	struct META_NextEntry_##name{};																\
+	void META_InitPrevEntry(META_NextEntry_##name typeId)										\
+	{																							\
+		addReflectablePtrArrayField(#name, id, &MyType::get##name, &MyType::getSize##name, &MyType::set##name, &MyType::setSize##name);			\
+		META_InitPrevEntry(META_Entry_##name());												\
+	}																							\
+																								\
+	typedef META_NextEntry_##name
+
+/** Ends definitions for member fields with a RTTI type. Must follow BS_BEGIN_RTTI_MEMBERS. */
+#define BS_END_RTTI_MEMBERS																		\
+	META_LastEntry;																				\
+																								\
+	struct META_InitAllMembers																	\
+	{																							\
+		META_InitAllMembers(MyType* owner)														\
+		{																						\
+			owner->META_InitPrevEntry(META_LastEntry());										\
+		}																						\
+	};																							\
+																								\
+	META_InitAllMembers mInitMembers;
 
 	/** @} */