CmRTTIType.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. #pragma once
  2. #include <string>
  3. #include <algorithm>
  4. #include <unordered_map>
  5. #include <boost/function.hpp>
  6. #include <boost/bind.hpp>
  7. #include <boost/type_traits.hpp>
  8. #include <boost/static_assert.hpp>
  9. #include "CmPrerequisitesUtil.h"
  10. #include "CmManagedDataBlock.h"
  11. #include "CmRTTIField.h"
  12. #include "CmRTTIPlainField.h"
  13. #include "CmRTTIReflectableField.h"
  14. #include "CmRTTIReflectablePtrField.h"
  15. #include "CmRTTIManagedDataBlockField.h"
  16. #include "CmIReflectable.h"
  17. namespace CamelotEngine
  18. {
  19. #define CM_SETGET_MEMBER(name, type, parentType) \
  20. type##& get##name(parentType##* obj) { return obj->##name; } \
  21. void set##name(parentType##* obj, type##& val) { obj->##name = val; }
  22. #define CM_ADD_PLAINFIELD(name, id, parentType) \
  23. addPlainField(#name, id##, &##parentType##::get##name, &##parentType##::set##name);
  24. /**
  25. * @brief Provides an interface for accessing fields of a certain class.
  26. * Data can be easily accessed by getter and setter methods.
  27. *
  28. * Supported data types:
  29. * - Plain types - All types defined in CmRTTIField.h, mostly native types and POD (plain old data) structs. Data is parsed byte by byte.
  30. * No pointers to plain types are supported. Data is passed around by value.
  31. * - Reflectable types - Any class deriving from IReflectable. Data is parsed based on fields in its ReflectionInterface. Can be pointer or value type.
  32. * - Arrays of both plain and reflectable types are supported
  33. * - Data blocks - A managed or unmanaged block of data. See CmManagedDataBlock.h
  34. */
  35. class CM_UTILITY_EXPORT RTTITypeBase
  36. {
  37. public:
  38. RTTITypeBase();
  39. virtual ~RTTITypeBase();
  40. virtual vector<RTTITypeBase*>::type& getDerivedClasses() = 0;
  41. virtual void registerDerivedClass(RTTITypeBase* derivedClass) = 0;
  42. virtual std::shared_ptr<IReflectable> newRTTIObject() = 0;
  43. virtual const String& getRTTIName() = 0;
  44. virtual UINT32 getRTTIId() = 0;
  45. template <class ObjectType, class DataType>
  46. void setPlainValue(ObjectType* object, const std::string& name, DataType& value)
  47. {
  48. RTTIField* genericField = findField(name);
  49. genericField->checkIsSimple(false);
  50. RTTIPlainFieldBase* field = static_cast<RTTIPlainFieldBase*>(genericField);
  51. field->setValue(object, value);
  52. }
  53. template <class ObjectType, class DataType>
  54. void setPlainArrayValue(ObjectType* object, const std::string& name, UINT32 index, DataType& value)
  55. {
  56. RTTIField* genericField = findField(name);
  57. genericField->checkIsSimple(true);
  58. RTTIPlainFieldBase* field = static_cast<RTTIPlainFieldBase*>(genericField);
  59. field->setArrayValue(object, index, value);
  60. }
  61. template <class ObjectType, class DataType>
  62. void setReflectableValue(ObjectType* object, const std::string& name, DataType& value)
  63. {
  64. BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotEngine::IReflectable, DataType>::value),
  65. "Invalid data type for complex field. It needs to derive from CamelotEngine::IReflectable.");
  66. RTTIField* genericField = findField(name);
  67. genericField->checkIsComplex(false);
  68. RTTIReflectableFieldBase* field = static_cast<RTTIReflectableFieldBase*>(genericField);
  69. field->setValue(object, value);
  70. }
  71. template <class ObjectType, class DataType>
  72. void setReflectableArrayValue(ObjectType* object, const std::string& name, UINT32 index, DataType& value)
  73. {
  74. BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotEngine::IReflectable, DataType>::value),
  75. "Invalid data type for complex field. It needs to derive from CamelotEngine::IReflectable.");
  76. RTTIField* genericField = findField(name);
  77. genericField->checkIsComplex(true);
  78. RTTIReflectableFieldBase* field = static_cast<RTTIReflectableFieldBase*>(genericField);
  79. field->setArrayValue(object, index, value);
  80. }
  81. template <class ObjectType>
  82. void setDataBlockValue(ObjectType* object, const std::string& name, ManagedDataBlock value)
  83. {
  84. RTTIField* genericField = findField(name);
  85. genericField->checkIsDataBlock();
  86. RTTIManagedDataBlockFieldBase* field = static_cast<RTTIManagedDataBlockFieldBase*>(genericField);
  87. field->setValue(object, value);
  88. }
  89. template <class ObjectType, class DataType>
  90. void setReflectablePtrValue(ObjectType* object, const std::string& name, std::shared_ptr<DataType> value)
  91. {
  92. BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotEngine::IReflectable, DataType>::value),
  93. "Invalid data type for complex field. It needs to derive from CamelotEngine::IReflectable.");
  94. RTTIField* genericField = findField(name);
  95. genericField->checkIsComplexPtr(false);
  96. RTTIReflectablePtrFieldBase* field = static_cast<RTTIReflectablePtrFieldBase*>(genericField);
  97. field->setValue(object, value);
  98. }
  99. template <class ObjectType, class DataType>
  100. void setReflectablePtrArrayValue(ObjectType* object, const std::string& name, UINT32 index, std::shared_ptr<DataType> value)
  101. {
  102. BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotEngine::IReflectable, DataType>::value),
  103. "Invalid data type for complex field. It needs to derive from CamelotEngine::IReflectable.");
  104. RTTIField* genericField = findField(name);
  105. genericField->checkIsComplexPtr(true);
  106. RTTIReflectablePtrFieldBase* field = static_cast<RTTIReflectablePtrFieldBase*>(genericField);
  107. field->setArrayValue(object, index, value);
  108. }
  109. template <class ObjectType, class DataType>
  110. void getPlainValue(ObjectType* object, const std::string& name, DataType& value)
  111. {
  112. RTTIField* genericField = findField(name);
  113. genericField->checkIsSimple(false);
  114. RTTIPlainFieldBase* field = static_cast<RTTIPlainFieldBase*>(genericField);
  115. field->getValue(object, value);
  116. }
  117. template <class ObjectType, class DataType>
  118. void getPlainArrayValue(ObjectType* object, const std::string& name, UINT32 index, DataType& value)
  119. {
  120. RTTIField* genericField = findField(name);
  121. genericField->checkIsSimple(true);
  122. RTTIPlainFieldBase* field = static_cast<RTTIPlainFieldBase*>(genericField);
  123. field->getArrayValue(object, index, value);
  124. }
  125. template <class ObjectType>
  126. IReflectable& getReflectableValue(ObjectType* object, const std::string& name)
  127. {
  128. RTTIField* genericField = findField(name);
  129. genericField->checkIsComplex(false);
  130. RTTIReflectableFieldBase* field = static_cast<RTTIReflectableFieldBase*>(genericField);
  131. return field->getValue(object);
  132. }
  133. template <class ObjectType>
  134. IReflectable& getReflectableArrayValue(ObjectType* object, const std::string& name, UINT32 index)
  135. {
  136. RTTIField* genericField = findField(name);
  137. genericField->checkIsComplex(true);
  138. RTTIReflectableFieldBase* field = static_cast<RTTIReflectableFieldBase*>(genericField);
  139. return field->getArrayValue(object, index);
  140. }
  141. template <class ObjectType>
  142. ManagedDataBlock getDataBlockValue(ObjectType* object, const std::string& name)
  143. {
  144. RTTIField* genericField = findField(name);
  145. genericField->checkIsDataBlock();
  146. RTTIManagedDataBlockFieldBase* field = static_cast<RTTIManagedDataBlockFieldBase*>(genericField);
  147. return field->getValue(object);
  148. }
  149. template <class ObjectType>
  150. std::shared_ptr<IReflectable> getReflectablePtrValue(ObjectType* object, const std::string& name)
  151. {
  152. RTTIField* genericField = findField(name);
  153. genericField->checkIsComplexPtr(false);
  154. RTTIReflectablePtrFieldBase* field = static_cast<RTTIReflectablePtrFieldBase*>(genericField);
  155. return field->getValue(object);
  156. }
  157. template <class ObjectType>
  158. std::shared_ptr<IReflectable> getReflectablePtrArrayValue(ObjectType* object, const std::string& name, UINT32 index)
  159. {
  160. RTTIField* genericField = findField(name);
  161. genericField->checkIsComplexPtr(true);
  162. RTTIReflectablePtrFieldBase* field = static_cast<RTTIReflectablePtrFieldBase*>(genericField);
  163. return field->getArrayValue(object, index);
  164. }
  165. template <class ObjectType>
  166. UINT32 getArraySize(ObjectType* object, const std::string& name)
  167. {
  168. RTTIField* field = findField(name);
  169. return field->getArraySize(object);
  170. }
  171. template <class ObjectType>
  172. void setArraySize(ObjectType* object, const std::string& name, UINT32 size)
  173. {
  174. RTTIField* field = findField(name);
  175. field->setArraySize(object, size);
  176. }
  177. UINT32 getNumFields() { return mFields.size(); }
  178. RTTIField* getField(UINT32 idx) { return mFields.at(idx); }
  179. /**
  180. * @brief Tries to find a field with the specified name. Throws an exception if it can't.
  181. *
  182. * @param name The name of the field.
  183. */
  184. RTTIField* findField(const std::string& name);
  185. /**
  186. * @brief Tries to find a field with the specified unique ID. Doesn't throw an exception
  187. * if it can't find the field (Unlike findField(name)).
  188. *
  189. * @param uniqueFieldId Unique identifier for the field.
  190. *
  191. * @return nullptr if it can't find the field.
  192. */
  193. RTTIField* findField(int uniqueFieldId);
  194. protected:
  195. /**
  196. * @brief Tries to add a new field to the fields array, and throws an exception
  197. * if a field with the same name or id already exists.
  198. *
  199. * @param [in] field Field, must be non-null.
  200. */
  201. void addNewField(RTTIField* field);
  202. private:
  203. std::vector<RTTIField*> mFields;
  204. };
  205. /**
  206. * @brief Used for initializing a certain type as soon as the program is loaded.
  207. */
  208. template<typename Type, typename BaseType>
  209. struct InitRTTIOnStart
  210. {
  211. public:
  212. InitRTTIOnStart()
  213. {
  214. BaseType::getRTTIStatic()->registerDerivedClass(Type::getRTTIStatic());
  215. }
  216. void makeSureIAmInstantiated() { }
  217. };
  218. /**
  219. * @brief Specialization for root class of RTTI hierarchy - IReflectable
  220. */
  221. template<typename Type>
  222. struct InitRTTIOnStart<Type, IReflectable>
  223. {
  224. public:
  225. InitRTTIOnStart()
  226. {
  227. IReflectable::registerDerivedClass(Type::getRTTIStatic());
  228. }
  229. void makeSureIAmInstantiated() { }
  230. };
  231. /**
  232. * @brief Pretty much just an extension of RTTITypeBase. Feel free to derive from this class and return
  233. * the derived class from IReflectable::getRTTI. This way you can separate serialization logic from
  234. * the actual class you're serializing.
  235. */
  236. template <typename Type, typename BaseType, typename MyRTTIType>
  237. class RTTIType : public RTTITypeBase
  238. {
  239. protected:
  240. /************************************************************************/
  241. /* RTTI CLASS META DATA */
  242. /************************************************************************/
  243. static InitRTTIOnStart<Type, BaseType> initOnStart;
  244. public:
  245. RTTIType()
  246. {
  247. // Templates only actually generate code for stuff that is directly used, including static data members,
  248. // so we fool it here like we're using the class directly. Otherwise compiler won't generate the code for the member
  249. // and our type won't get initialized on start (Actual behavior is a bit more random)
  250. initOnStart.makeSureIAmInstantiated();
  251. }
  252. virtual ~RTTIType() {}
  253. static MyRTTIType* instance()
  254. {
  255. static MyRTTIType inst;
  256. return &inst;
  257. }
  258. virtual vector<RTTITypeBase*>::type& getDerivedClasses()
  259. {
  260. static vector<RTTITypeBase*>::type mRTTIDerivedClasses;
  261. return mRTTIDerivedClasses;
  262. }
  263. virtual void registerDerivedClass(RTTITypeBase* derivedClass)
  264. {
  265. if(IReflectable::isTypeIdDuplicate(derivedClass->getRTTIId()))
  266. {
  267. CM_EXCEPT(InternalErrorException, "RTTI type \"" + derivedClass->getRTTIName() +
  268. "\" has a duplicate ID: " + toString(derivedClass->getRTTIId()));
  269. }
  270. getDerivedClasses().push_back(derivedClass);
  271. }
  272. /************************************************************************/
  273. /* FIELDS OPERATING DIRECTLY ON SERIALIZABLE OBJECT */
  274. /************************************************************************/
  275. template<class ObjectType, class DataType>
  276. void addPlainField(const std::string& name, UINT32 uniqueId, DataType& (ObjectType::*getter)(), void (ObjectType::*setter)(DataType&) = nullptr)
  277. {
  278. addPlainField<ObjectType, DataType>(name, uniqueId,
  279. boost::function<DataType&(ObjectType*)>(getter),
  280. boost::function<void(ObjectType*, DataType&)>(setter));
  281. }
  282. template<class ObjectType, class DataType>
  283. void addReflectableField(const std::string& name, UINT32 uniqueId, DataType& (ObjectType::*getter)(), void (ObjectType::*setter)(DataType&) = nullptr)
  284. {
  285. addReflectableField<ObjectType, DataType>(name, uniqueId,
  286. boost::function<DataType&(ObjectType*)>(getter),
  287. boost::function<void(ObjectType*, DataType&)>(setter));
  288. }
  289. template<class ObjectType, class DataType>
  290. void addReflectablePtrField(const std::string& name, UINT32 uniqueId, std::shared_ptr<DataType> (ObjectType::*getter)(), void (ObjectType::*setter)(std::shared_ptr<DataType>) = nullptr)
  291. {
  292. addReflectablePtrField<ObjectType, DataType>(name, uniqueId,
  293. boost::function<std::shared_ptr<DataType>(ObjectType*)>(getter),
  294. boost::function<void(ObjectType*, std::shared_ptr<DataType>)>(setter));
  295. }
  296. template<class ObjectType, class DataType>
  297. void addPlainArrayField(const std::string& name, UINT32 uniqueId, DataType& (ObjectType::*getter)(UINT32), UINT32 (ObjectType::*getSize)(),
  298. void (ObjectType::*setter)(UINT32, DataType&) = nullptr, void(ObjectType::*setSize)(UINT32) = nullptr)
  299. {
  300. addPlainArrayField<ObjectType, DataType>(name, uniqueId,
  301. boost::function<DataType&(ObjectType*, UINT32)>(getter),
  302. boost::function<UINT32(ObjectType*)>(getSize),
  303. boost::function<void(ObjectType*, UINT32, DataType&)>(setter),
  304. boost::function<void(ObjectType*, UINT32)>(setSize));
  305. }
  306. template<class ObjectType, class DataType>
  307. void addReflectableArrayField(const std::string& name, UINT32 uniqueId, DataType& (ObjectType::*getter)(UINT32), UINT32 (ObjectType::*getSize)(),
  308. void (ObjectType::*setter)(UINT32, DataType&) = nullptr, void(ObjectType::*setSize)(UINT32) = nullptr)
  309. {
  310. addReflectableArrayField<ObjectType, DataType>(name, uniqueId,
  311. boost::function<DataType&(ObjectType*, UINT32)>(getter),
  312. boost::function<UINT32(ObjectType*)>(getSize),
  313. boost::function<void(ObjectType*, UINT32, DataType&)>(setter),
  314. boost::function<void(ObjectType*, UINT32)>(setSize));
  315. }
  316. template<class ObjectType, class DataType>
  317. void addReflectablePtrArrayField(const std::string& name, UINT32 uniqueId, std::shared_ptr<DataType> (ObjectType::*getter)(UINT32), UINT32 (ObjectType::*getSize)(),
  318. void (ObjectType::*setter)(UINT32, std::shared_ptr<DataType>) = nullptr, void(ObjectType::*setSize)(UINT32) = nullptr)
  319. {
  320. addReflectablePtrArrayField<ObjectType, DataType>(name, uniqueId,
  321. boost::function<std::shared_ptr<DataType>(ObjectType*, UINT32)>(getter),
  322. boost::function<UINT32(ObjectType*)>(getSize),
  323. boost::function<void(ObjectType*, UINT32, std::shared_ptr<DataType>)>(setter),
  324. boost::function<void(ObjectType*, UINT32)>(setSize));
  325. }
  326. template<class ObjectType>
  327. void addDataBlockField(const std::string& name, UINT32 uniqueId, ManagedDataBlock (ObjectType::*getter)(),
  328. void (ObjectType::*setter)(ManagedDataBlock) = nullptr)
  329. {
  330. addDataBlockField<ObjectType>(name, uniqueId,
  331. boost::function<ManagedDataBlock(ObjectType*)>(getter),
  332. boost::function<void(ObjectType*, ManagedDataBlock)>(setter));
  333. }
  334. protected:
  335. virtual void initSerializableFields() {}
  336. /************************************************************************/
  337. /* FIELDS OPERATING ON DERIVED SERIALIZATION INTERFACE */
  338. /* (Needs an extra pointer to the actual object) */
  339. /************************************************************************/
  340. template<class InterfaceType, class ObjectType, class DataType>
  341. void addPlainField(const std::string& name, UINT32 uniqueId,
  342. DataType& (InterfaceType::*getter)(ObjectType*),
  343. void (InterfaceType::*setter)(ObjectType*, DataType&) = nullptr)
  344. {
  345. BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotEngine::RTTIType<Type, BaseType, MyRTTIType>, InterfaceType>::value),
  346. "Class with the get/set methods must derive from CamelotEngine::SerializationInterface.");
  347. addPlainField<ObjectType, DataType>(name, uniqueId,
  348. boost::function<DataType&(ObjectType*)>(boost::bind(getter, static_cast<InterfaceType*>(this), _1)),
  349. boost::function<void(ObjectType*, DataType&)>(boost::bind(setter, static_cast<InterfaceType*>(this), _1, _2)));
  350. }
  351. template<class InterfaceType, class ObjectType, class DataType>
  352. void addReflectableField(const std::string& name, UINT32 uniqueId,
  353. DataType& (InterfaceType::*getter)(ObjectType*),
  354. void (InterfaceType::*setter)(ObjectType*, DataType&) = nullptr)
  355. {
  356. addReflectableField<ObjectType, DataType>(name, uniqueId,
  357. boost::function<DataType&(ObjectType*)>(boost::bind(getter, static_cast<InterfaceType*>(this), _1)),
  358. boost::function<void(ObjectType*, DataType&)>(boost::bind(setter, static_cast<InterfaceType*>(this), _1, _2)));
  359. }
  360. template<class InterfaceType, class ObjectType, class DataType>
  361. void addReflectablePtrField(const std::string& name, UINT32 uniqueId,
  362. std::shared_ptr<DataType> (InterfaceType::*getter)(ObjectType*),
  363. void (InterfaceType::*setter)(ObjectType*, std::shared_ptr<DataType>) = nullptr)
  364. {
  365. addReflectablePtrField<ObjectType, DataType>(name, uniqueId,
  366. boost::function<std::shared_ptr<DataType>(ObjectType*)>(boost::bind(getter, static_cast<InterfaceType*>(this), _1)),
  367. boost::function<void(ObjectType*, std::shared_ptr<DataType>)>(boost::bind(setter, static_cast<InterfaceType*>(this), _1, _2)));
  368. }
  369. template<class InterfaceType, class ObjectType, class DataType>
  370. void addPlainArrayField(const std::string& name, UINT32 uniqueId,
  371. DataType& (InterfaceType::*getter)(ObjectType*, UINT32),
  372. UINT32 (InterfaceType::*getSize)(ObjectType*),
  373. void (InterfaceType::*setter)(ObjectType*, UINT32, DataType&) = nullptr,
  374. void(InterfaceType::*setSize)(ObjectType*, UINT32) = nullptr)
  375. {
  376. addPlainArrayField<ObjectType, DataType>(name, uniqueId,
  377. boost::function<DataType&(ObjectType*, UINT32)>(boost::bind(getter, static_cast<InterfaceType*>(this), _1, _2)),
  378. boost::function<UINT32(ObjectType*)>(boost::bind(getSize, static_cast<InterfaceType*>(this), _1)),
  379. boost::function<void(ObjectType*, UINT32, DataType&)>(boost::bind(setter, static_cast<InterfaceType*>(this), _1, _2, _3)),
  380. boost::function<void(ObjectType*, UINT32)>(boost::bind(setSize, static_cast<InterfaceType*>(this), _1, _2)));
  381. }
  382. template<class InterfaceType, class ObjectType, class DataType>
  383. void addReflectableArrayField(const std::string& name, UINT32 uniqueId,
  384. DataType& (InterfaceType::*getter)(ObjectType*, UINT32),
  385. UINT32 (InterfaceType::*getSize)(ObjectType*),
  386. void (InterfaceType::*setter)(ObjectType*, UINT32, DataType&) = nullptr,
  387. void(InterfaceType::*setSize)(ObjectType*, UINT32) = nullptr)
  388. {
  389. addReflectableArrayField<ObjectType, DataType>(name, uniqueId,
  390. boost::function<DataType&(ObjectType*, UINT32)>(boost::bind(getter, static_cast<InterfaceType*>(this), _1, _2)),
  391. boost::function<UINT32(ObjectType*)>(boost::bind(getSize, static_cast<InterfaceType*>(this), _1)),
  392. boost::function<void(ObjectType*, UINT32, DataType&)>(boost::bind(setter, static_cast<InterfaceType*>(this), _1, _2, _3)),
  393. boost::function<void(ObjectType*, UINT32)>(boost::bind(setSize, static_cast<InterfaceType*>(this), _1, _2)));
  394. }
  395. template<class InterfaceType, class ObjectType, class DataType>
  396. void addReflectablePtrArrayField(const std::string& name, UINT32 uniqueId,
  397. std::shared_ptr<DataType> (InterfaceType::*getter)(ObjectType*, UINT32),
  398. UINT32 (InterfaceType::*getSize)(ObjectType*),
  399. void (InterfaceType::*setter)(ObjectType*, UINT32, std::shared_ptr<DataType>) = nullptr,
  400. void(InterfaceType::*setSize)(ObjectType*, UINT32) = nullptr)
  401. {
  402. addReflectablePtrArrayField<ObjectType, DataType>(name, uniqueId,
  403. boost::function<std::shared_ptr<DataType>(ObjectType*, UINT32)>(boost::bind(getter, static_cast<InterfaceType*>(this), _1, _2)),
  404. boost::function<UINT32(ObjectType*)>(boost::bind(getSize, static_cast<InterfaceType*>(this), _1)),
  405. boost::function<void(ObjectType*, UINT32, std::shared_ptr<DataType>)>(boost::bind(setter, static_cast<InterfaceType*>(this), _1, _2, _3)),
  406. boost::function<void(ObjectType*, UINT32)>(boost::bind(setSize, static_cast<InterfaceType*>(this), _1, _2)));
  407. }
  408. template<class InterfaceType, class ObjectType>
  409. void addDataBlockField(const std::string& name, UINT32 uniqueId, ManagedDataBlock (InterfaceType::*getter)(ObjectType*),
  410. void (InterfaceType::*setter)(ObjectType*, ManagedDataBlock) = nullptr)
  411. {
  412. addDataBlockField<ObjectType>(name, uniqueId,
  413. boost::function<ManagedDataBlock(ObjectType*)>(boost::bind(getter, static_cast<InterfaceType*>(this), _1)),
  414. boost::function<void(ObjectType*, ManagedDataBlock)>(boost::bind(setter, static_cast<InterfaceType*>(this), _1, _2)));
  415. }
  416. private:
  417. template<class ObjectType, class DataType>
  418. void addPlainField(const std::string& name, UINT32 uniqueId, boost::any getter, boost::any setter = nullptr)
  419. {
  420. RTTIPlainField<DataType, ObjectType>* newField = new RTTIPlainField<DataType, ObjectType>();
  421. newField->initSingle(name, uniqueId, getter, setter);
  422. addNewField(newField);
  423. }
  424. template<class ObjectType, class DataType>
  425. void addReflectableField(const std::string& name, UINT32 uniqueId, boost::any getter, boost::any setter = nullptr)
  426. {
  427. BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotEngine::IReflectable, DataType>::value),
  428. "Invalid data type for complex field. It needs to derive from CamelotEngine::IReflectable.");
  429. RTTIReflectableField<DataType, ObjectType>* newField = new RTTIReflectableField<DataType, ObjectType>();
  430. newField->initSingle(name, uniqueId, getter, setter);
  431. addNewField(newField);
  432. }
  433. template<class ObjectType, class DataType>
  434. void addReflectablePtrField(const std::string& name, UINT32 uniqueId, boost::any getter, boost::any setter = nullptr)
  435. {
  436. BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotEngine::IReflectable, DataType>::value),
  437. "Invalid data type for complex field. It needs to derive from CamelotEngine::IReflectable.");
  438. RTTIReflectablePtrField<DataType, ObjectType>* newField = new RTTIReflectablePtrField<DataType, ObjectType>();
  439. newField->initSingle(name, uniqueId, getter, setter);
  440. addNewField(newField);
  441. }
  442. template<class ObjectType, class DataType>
  443. void addPlainArrayField(const std::string& name, UINT32 uniqueId, boost::any getter, boost::any getSize,
  444. boost::any setter = nullptr, boost::any setSize = nullptr)
  445. {
  446. RTTIPlainField<DataType, ObjectType>* newField = new RTTIPlainField<DataType, ObjectType>();
  447. newField->initArray(name, uniqueId, getter, getSize, setter, setSize);
  448. addNewField(newField);
  449. }
  450. template<class ObjectType, class DataType>
  451. void addReflectableArrayField(const std::string& name, UINT32 uniqueId, boost::any getter, boost::any getSize,
  452. boost::any setter = nullptr, boost::any setSize = nullptr)
  453. {
  454. BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotEngine::IReflectable, DataType>::value),
  455. "Invalid data type for complex field. It needs to derive from CamelotEngine::IReflectable.");
  456. RTTIReflectableField<DataType, ObjectType>* newField = new RTTIReflectableField<DataType, ObjectType>();
  457. newField->initArray(name, uniqueId, getter, getSize, setter, setSize);
  458. addNewField(newField);
  459. }
  460. template<class ObjectType, class DataType>
  461. void addReflectablePtrArrayField(const std::string& name, UINT32 uniqueId, boost::any getter, boost::any getSize,
  462. boost::any setter = nullptr, boost::any setSize = nullptr)
  463. {
  464. BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotEngine::IReflectable, DataType>::value),
  465. "Invalid data type for complex field. It needs to derive from CamelotEngine::IReflectable.");
  466. RTTIReflectablePtrField<DataType, ObjectType>* newField = new RTTIReflectablePtrField<DataType, ObjectType>();
  467. newField->initArray(name, uniqueId, getter, getSize, setter, setSize);
  468. addNewField(newField);
  469. }
  470. template<class ObjectType>
  471. void addDataBlockField(const std::string& name, UINT32 uniqueId, boost::any getter, boost::any setter = nullptr)
  472. {
  473. RTTIManagedDataBlockField<ManagedDataBlock, ObjectType>* newField = new RTTIManagedDataBlockField<ManagedDataBlock, ObjectType>();
  474. newField->initSingle(name, uniqueId, getter, setter);
  475. addNewField(newField);
  476. }
  477. };
  478. template <typename Type, typename BaseType, typename MyRTTIType>
  479. InitRTTIOnStart<Type, BaseType> RTTIType<Type, BaseType, MyRTTIType>::initOnStart;
  480. }