Browse Source

RTTI checks for duplicate type IDs

Marko Pintera 13 years ago
parent
commit
305a01e545

+ 3 - 5
CamelotUtility/Include/CmIReflectable.h

@@ -33,11 +33,9 @@ namespace CamelotEngine
 		 * @brief	INTERNAL USE. Called by each type deriving from IReflectable,
 		 * 			on program load.
 		 */
-		static void registerDerivedClass(RTTITypeBase* derivedClass)
-		{
-			getDerivedClasses().push_back(derivedClass);
-		}
-
+		static void registerDerivedClass(RTTITypeBase* derivedClass);
 		static std::shared_ptr<IReflectable> createInstanceFromTypeId(UINT32 rttiTypeId);
+		static RTTITypeBase* getRTTIfromTypeId(UINT32 rttiTypeId);
+		static bool isTypeIdDuplicate(UINT32 typeId);
 	};
 }

+ 6 - 0
CamelotUtility/Include/CmRTTIType.h

@@ -321,6 +321,12 @@ namespace CamelotEngine
 
 		virtual void registerDerivedClass(RTTITypeBase* derivedClass)
 		{
+			if(IReflectable::isTypeIdDuplicate(derivedClass->getRTTIId()))
+			{
+				CM_EXCEPT(InternalErrorException, "RTTI type \"" + derivedClass->getRTTIName() + 
+					"\" has a duplicate ID: " + toString(derivedClass->getRTTIId()));
+			}
+
 			getDerivedClasses().push_back(derivedClass);
 		}
 

+ 27 - 1
CamelotUtility/Source/CmIReflectable.cpp

@@ -4,7 +4,28 @@
 
 namespace CamelotEngine
 {
+	void IReflectable::registerDerivedClass(RTTITypeBase* derivedClass)
+	{
+		if(isTypeIdDuplicate(derivedClass->getRTTIId()))
+		{
+			CM_EXCEPT(InternalErrorException, "RTTI type \"" + derivedClass->getRTTIName() + 
+				"\" has a duplicate ID: " + toString(derivedClass->getRTTIId()));
+		}
+
+		getDerivedClasses().push_back(derivedClass);
+	}
+
 	std::shared_ptr<IReflectable> IReflectable::createInstanceFromTypeId(UINT32 rttiTypeId)
+	{
+		RTTITypeBase* type = getRTTIfromTypeId(rttiTypeId);
+
+		if(type != nullptr)
+			return type->newRTTIObject();
+		
+		return nullptr;
+	}
+
+	RTTITypeBase* IReflectable::getRTTIfromTypeId(UINT32 rttiTypeId)
 	{
 		stack<RTTITypeBase*>::type todo;
 		vector<RTTITypeBase*>::type& rootClasses = getDerivedClasses();
@@ -18,7 +39,7 @@ namespace CamelotEngine
 			todo.pop();
 
 			if(curType->getRTTIId() == rttiTypeId)
-				return curType->newRTTIObject();
+				return curType;
 
 			vector<RTTITypeBase*>::type& derivedClasses = curType->getDerivedClasses();
 			for(auto iter = derivedClasses.begin(); iter != derivedClasses.end(); ++iter)
@@ -27,4 +48,9 @@ namespace CamelotEngine
 
 		return nullptr;
 	}
+
+	bool IReflectable::isTypeIdDuplicate(UINT32 typeId)
+	{
+		return IReflectable::getRTTIfromTypeId(typeId) != nullptr;
+	}
 }