2
0

BsBinarySerializer.cpp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254
  1. #include "BsBinarySerializer.h"
  2. #include "BsException.h"
  3. #include "BsDebug.h"
  4. #include "BsIReflectable.h"
  5. #include "BsRTTIType.h"
  6. #include "BsRTTIField.h"
  7. #include "BsRTTIPlainField.h"
  8. #include "BsRTTIReflectableField.h"
  9. #include "BsRTTIReflectablePtrField.h"
  10. #include "BsRTTIManagedDataBlockField.h"
  11. #include "BsMemorySerializer.h"
  12. #include <unordered_set>
  13. /**
  14. * @brief A macro that represents a block of code that gets used a lot inside
  15. * encodeInternal. It checks if the buffer has enough space, and if it does
  16. * it copies the data from the specified location and increments the needed
  17. * pointers and counters. If there is not enough space the buffer is flushed
  18. * (hopefully to make some space). If there is still not enough space the entire
  19. * encoding process ends.
  20. *
  21. * @param dataPtr Pointer to data which to copy.
  22. * @param size Size of the data to copy
  23. */
  24. #define COPY_TO_BUFFER(dataIter, size) \
  25. if((*bytesWritten + size##) > bufferLength) \
  26. { \
  27. mTotalBytesWritten += *bytesWritten; \
  28. buffer = flushBufferCallback(buffer - *bytesWritten, *bytesWritten, bufferLength); \
  29. if(buffer == nullptr || bufferLength < size##) return nullptr; \
  30. *bytesWritten = 0; \
  31. } \
  32. \
  33. memcpy(buffer, dataIter##, size##); \
  34. buffer += size##; \
  35. *bytesWritten += size##;
  36. namespace BansheeEngine
  37. {
  38. BinarySerializer::BinarySerializer()
  39. :mLastUsedObjectId(1)
  40. {
  41. }
  42. void BinarySerializer::encode(IReflectable* object, UINT8* buffer, UINT32 bufferLength,
  43. UINT32* bytesWritten, std::function<UINT8*(UINT8*, UINT32, UINT32&)> flushBufferCallback, bool shallow)
  44. {
  45. mObjectsToEncode.clear();
  46. mObjectAddrToId.clear();
  47. mLastUsedObjectId = 1;
  48. *bytesWritten = 0;
  49. mTotalBytesWritten = 0;
  50. UINT8* bufferStart = buffer;
  51. Vector<std::shared_ptr<IReflectable>> encodedObjects;
  52. UINT32 objectId = findOrCreatePersistentId(object);
  53. // Encode primary object and its value types
  54. buffer = encodeInternal(object, objectId, buffer, bufferLength, bytesWritten, flushBufferCallback, shallow);
  55. if(buffer == nullptr)
  56. {
  57. BS_EXCEPT(InternalErrorException,
  58. "Destination buffer is null or not large enough.");
  59. }
  60. // Encode pointed to objects and their value types
  61. UnorderedSet<UINT32> serializedObjects;
  62. while(true)
  63. {
  64. auto iter = mObjectsToEncode.begin();
  65. bool foundObjectToProcess = false;
  66. for(iter; iter != mObjectsToEncode.end(); ++iter)
  67. {
  68. auto foundExisting = serializedObjects.find(iter->objectId);
  69. if(foundExisting != serializedObjects.end())
  70. continue; // Already processed
  71. std::shared_ptr<IReflectable> curObject = iter->object;
  72. UINT32 curObjectid = iter->objectId;
  73. serializedObjects.insert(curObjectid);
  74. mObjectsToEncode.erase(iter);
  75. buffer = encodeInternal(curObject.get(), curObjectid, buffer,
  76. bufferLength, bytesWritten, flushBufferCallback, shallow);
  77. if(buffer == nullptr)
  78. {
  79. BS_EXCEPT(InternalErrorException,
  80. "Destination buffer is null or not large enough.");
  81. }
  82. foundObjectToProcess = true;
  83. // Ensure we keep a reference to the object so it isn't released.
  84. // The system assigns unique IDs to IReflectable objects based on pointer
  85. // addresses but if objects get released then same address could be assigned twice.
  86. // Note: To get around this I could assign unique IDs to IReflectable objects
  87. encodedObjects.push_back(curObject);
  88. break; // Need to start over as mObjectsToSerialize was possibly modified
  89. }
  90. if(!foundObjectToProcess) // We're done
  91. break;
  92. }
  93. // Final flush
  94. if(*bytesWritten > 0)
  95. {
  96. mTotalBytesWritten += *bytesWritten;
  97. buffer = flushBufferCallback(buffer - *bytesWritten, *bytesWritten, bufferLength);
  98. }
  99. *bytesWritten = mTotalBytesWritten;
  100. encodedObjects.clear();
  101. mObjectsToEncode.clear();
  102. mObjectAddrToId.clear();
  103. }
  104. std::shared_ptr<IReflectable> BinarySerializer::decode(UINT8* data, UINT32 dataLength)
  105. {
  106. if (dataLength == 0)
  107. return nullptr;
  108. SPtr<SerializedObject> intermediateObject = _decodeIntermediate(data, dataLength);
  109. if (intermediateObject == nullptr)
  110. return nullptr;
  111. return _decodeIntermediate(intermediateObject);
  112. }
  113. SPtr<IReflectable> BinarySerializer::_decodeIntermediate(const SPtr<SerializedObject>& serializedObject)
  114. {
  115. mObjectMap.clear();
  116. SPtr<IReflectable> output;
  117. RTTITypeBase* type = IReflectable::_getRTTIfromTypeId(serializedObject->getRootTypeId());
  118. if (type != nullptr)
  119. {
  120. output = type->newRTTIObject();
  121. auto iterNewObj = mObjectMap.insert(std::make_pair(serializedObject, ObjectToDecode(output, serializedObject)));
  122. decodeInternal(output, serializedObject);
  123. iterNewObj.first->second.isDecoded = true;
  124. }
  125. // Go through the remaining objects (should be only ones with weak refs)
  126. for (auto iter = mObjectMap.begin(); iter != mObjectMap.end(); ++iter)
  127. {
  128. ObjectToDecode& objToDecode = iter->second;
  129. if (objToDecode.isDecoded)
  130. continue;
  131. decodeInternal(objToDecode.object, objToDecode.serializedObject);
  132. objToDecode.isDecoded = true;
  133. }
  134. mObjectMap.clear();
  135. return output;
  136. }
  137. UINT8* BinarySerializer::encodeInternal(IReflectable* object, UINT32 objectId, UINT8* buffer, UINT32& bufferLength,
  138. UINT32* bytesWritten, std::function<UINT8*(UINT8*, UINT32, UINT32&)> flushBufferCallback, bool shallow)
  139. {
  140. RTTITypeBase* si = object->getRTTI();
  141. bool isBaseClass = false;
  142. // If an object has base classes, we need to iterate through all of them
  143. do
  144. {
  145. si->onSerializationStarted(object);
  146. // Encode object ID & type
  147. ObjectMetaData objectMetaData = encodeObjectMetaData(objectId, si->getRTTIId(), isBaseClass);
  148. COPY_TO_BUFFER(&objectMetaData, sizeof(ObjectMetaData))
  149. int numFields = si->getNumFields();
  150. for(int i = 0; i < numFields; i++)
  151. {
  152. RTTIField* curGenericField = si->getField(i);
  153. // Copy field ID & other meta-data like field size and type
  154. int metaData = encodeFieldMetaData(curGenericField->mUniqueId, curGenericField->getTypeSize(),
  155. curGenericField->mIsVectorType, curGenericField->mType, curGenericField->hasDynamicSize(), false);
  156. COPY_TO_BUFFER(&metaData, META_SIZE)
  157. if(curGenericField->mIsVectorType)
  158. {
  159. UINT32 arrayNumElems = curGenericField->getArraySize(object);
  160. // Copy num vector elements
  161. COPY_TO_BUFFER(&arrayNumElems, NUM_ELEM_FIELD_SIZE)
  162. switch(curGenericField->mType)
  163. {
  164. case SerializableFT_ReflectablePtr:
  165. {
  166. RTTIReflectablePtrFieldBase* curField = static_cast<RTTIReflectablePtrFieldBase*>(curGenericField);
  167. for(UINT32 arrIdx = 0; arrIdx < arrayNumElems; arrIdx++)
  168. {
  169. std::shared_ptr<IReflectable> childObject;
  170. if (!shallow)
  171. childObject = curField->getArrayValue(object, arrIdx);
  172. UINT32 objId = registerObjectPtr(childObject);
  173. COPY_TO_BUFFER(&objId, sizeof(UINT32))
  174. }
  175. break;
  176. }
  177. case SerializableFT_Reflectable:
  178. {
  179. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  180. for(UINT32 arrIdx = 0; arrIdx < arrayNumElems; arrIdx++)
  181. {
  182. IReflectable& childObject = curField->getArrayValue(object, arrIdx);
  183. buffer = complexTypeToBuffer(&childObject, buffer, bufferLength,
  184. bytesWritten, flushBufferCallback, shallow);
  185. if(buffer == nullptr)
  186. {
  187. si->onSerializationEnded(object);
  188. return nullptr;
  189. }
  190. }
  191. break;
  192. }
  193. case SerializableFT_Plain:
  194. {
  195. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  196. for(UINT32 arrIdx = 0; arrIdx < arrayNumElems; arrIdx++)
  197. {
  198. UINT32 typeSize = 0;
  199. if(curField->hasDynamicSize())
  200. typeSize = curField->getArrayElemDynamicSize(object, arrIdx);
  201. else
  202. typeSize = curField->getTypeSize();
  203. if ((*bytesWritten + typeSize) > bufferLength)
  204. {
  205. UINT8* tempBuffer = (UINT8*)bs_stack_alloc(typeSize);
  206. curField->arrayElemToBuffer(object, arrIdx, tempBuffer);
  207. buffer = dataBlockToBuffer(tempBuffer, typeSize, buffer, bufferLength, bytesWritten, flushBufferCallback);
  208. if (buffer == nullptr || bufferLength == 0)
  209. {
  210. bs_stack_free(tempBuffer);
  211. si->onSerializationEnded(object);
  212. return nullptr;
  213. }
  214. bs_stack_free(tempBuffer);
  215. }
  216. else
  217. {
  218. curField->arrayElemToBuffer(object, arrIdx, buffer);
  219. buffer += typeSize;
  220. *bytesWritten += typeSize;
  221. }
  222. }
  223. break;
  224. }
  225. default:
  226. BS_EXCEPT(InternalErrorException,
  227. "Error encoding data. Encountered a type I don't know how to encode. Type: " + toString(UINT32(curGenericField->mType)) +
  228. ", Is array: " + toString(curGenericField->mIsVectorType));
  229. }
  230. }
  231. else
  232. {
  233. switch(curGenericField->mType)
  234. {
  235. case SerializableFT_ReflectablePtr:
  236. {
  237. RTTIReflectablePtrFieldBase* curField = static_cast<RTTIReflectablePtrFieldBase*>(curGenericField);
  238. std::shared_ptr<IReflectable> childObject;
  239. if (!shallow)
  240. childObject = curField->getValue(object);
  241. UINT32 objId = registerObjectPtr(childObject);
  242. COPY_TO_BUFFER(&objId, sizeof(UINT32))
  243. break;
  244. }
  245. case SerializableFT_Reflectable:
  246. {
  247. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  248. IReflectable& childObject = curField->getValue(object);
  249. buffer = complexTypeToBuffer(&childObject, buffer, bufferLength,
  250. bytesWritten, flushBufferCallback, shallow);
  251. if(buffer == nullptr)
  252. {
  253. si->onSerializationEnded(object);
  254. return nullptr;
  255. }
  256. break;
  257. }
  258. case SerializableFT_Plain:
  259. {
  260. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  261. UINT32 typeSize = 0;
  262. if(curField->hasDynamicSize())
  263. typeSize = curField->getDynamicSize(object);
  264. else
  265. typeSize = curField->getTypeSize();
  266. if ((*bytesWritten + typeSize) > bufferLength)
  267. {
  268. UINT8* tempBuffer = (UINT8*)bs_stack_alloc(typeSize);
  269. curField->toBuffer(object, tempBuffer);
  270. buffer = dataBlockToBuffer(tempBuffer, typeSize, buffer, bufferLength, bytesWritten, flushBufferCallback);
  271. if (buffer == nullptr || bufferLength == 0)
  272. {
  273. bs_stack_free(tempBuffer);
  274. si->onSerializationEnded(object);
  275. return nullptr;
  276. }
  277. bs_stack_free(tempBuffer);
  278. }
  279. else
  280. {
  281. curField->toBuffer(object, buffer);
  282. buffer += typeSize;
  283. *bytesWritten += typeSize;
  284. }
  285. break;
  286. }
  287. case SerializableFT_DataBlock:
  288. {
  289. RTTIManagedDataBlockFieldBase* curField = static_cast<RTTIManagedDataBlockFieldBase*>(curGenericField);
  290. ManagedDataBlock value = curField->getValue(object);
  291. // Data block size
  292. UINT32 dataBlockSize = value.getSize();
  293. COPY_TO_BUFFER(&dataBlockSize, sizeof(UINT32))
  294. // Data block data
  295. UINT8* dataToStore = value.getData();
  296. buffer = dataBlockToBuffer(dataToStore, dataBlockSize, buffer, bufferLength, bytesWritten, flushBufferCallback);
  297. if (buffer == nullptr || bufferLength == 0)
  298. {
  299. si->onSerializationEnded(object);
  300. return nullptr;
  301. }
  302. break;
  303. }
  304. default:
  305. BS_EXCEPT(InternalErrorException,
  306. "Error encoding data. Encountered a type I don't know how to encode. Type: " + toString(UINT32(curGenericField->mType)) +
  307. ", Is array: " + toString(curGenericField->mIsVectorType));
  308. }
  309. }
  310. }
  311. si->onSerializationEnded(object);
  312. si = si->getBaseClass();
  313. isBaseClass = true;
  314. } while(si != nullptr); // Repeat until we reach the top of the inheritance hierarchy
  315. return buffer;
  316. }
  317. SPtr<SerializedObject> BinarySerializer::_encodeIntermediate(IReflectable* object, bool shallow)
  318. {
  319. // TODO: This is a hacky way of generating an intermediate format to save development time and complexity.
  320. // It is hacky because it requires a full on encode to binary and then decode into intermediate. It should
  321. // be better to modify encoding process so it outputs the intermediate format directly (similar to how decoding works).
  322. // This also means that once you have an intermediate format you cannot use it to encode to binary.
  323. std::function<void*(UINT32)> allocator = &MemoryAllocator<GenAlloc>::allocate;
  324. MemorySerializer ms;
  325. UINT32 dataLength = 0;
  326. UINT8* data = ms.encode(object, dataLength, allocator, shallow);
  327. BinarySerializer bs;
  328. SPtr<SerializedObject> obj = bs._decodeIntermediate(data, dataLength, true);
  329. bs_free(data);
  330. return obj;
  331. }
  332. SPtr<SerializedObject> BinarySerializer::_decodeIntermediate(UINT8* data, UINT32 dataLength, bool copyData)
  333. {
  334. UINT32 bytesRead = 0;
  335. mInterimObjectMap.clear();
  336. SPtr<SerializedObject> rootObj;
  337. bool hasMore = decodeIntermediateInternal(data, dataLength, bytesRead, rootObj, copyData);
  338. while (hasMore)
  339. {
  340. UINT8* dataPtr = data + bytesRead;
  341. SPtr<SerializedObject> dummyObj;
  342. hasMore = decodeIntermediateInternal(dataPtr, dataLength, bytesRead, dummyObj, copyData);
  343. }
  344. return rootObj;
  345. }
  346. bool BinarySerializer::decodeIntermediateInternal(UINT8* data, UINT32 dataLength, UINT32& bytesRead, SPtr<SerializedObject>& output, bool copyData)
  347. {
  348. if ((bytesRead + sizeof(ObjectMetaData)) > dataLength)
  349. {
  350. BS_EXCEPT(InternalErrorException,
  351. "Error decoding data.");
  352. }
  353. ObjectMetaData objectMetaData;
  354. objectMetaData.objectMeta = 0;
  355. objectMetaData.typeId = 0;
  356. memcpy(&objectMetaData, data, sizeof(ObjectMetaData));
  357. data += sizeof(ObjectMetaData);
  358. bytesRead += sizeof(ObjectMetaData);
  359. UINT32 objectId = 0;
  360. UINT32 objectTypeId = 0;
  361. bool objectIsBaseClass = false;
  362. decodeObjectMetaData(objectMetaData, objectId, objectTypeId, objectIsBaseClass);
  363. if (objectIsBaseClass)
  364. {
  365. BS_EXCEPT(InternalErrorException, "Encountered a base-class object while looking for a new object. " \
  366. "Base class objects are only supposed to be parts of a larger object.");
  367. }
  368. RTTITypeBase* rtti = IReflectable::_getRTTIfromTypeId(objectTypeId);
  369. SerializedSubObject* serializedSubObject = nullptr;
  370. if (rtti != nullptr)
  371. {
  372. if (objectId > 0)
  373. {
  374. auto iterFind = mInterimObjectMap.find(objectId);
  375. if (iterFind == mInterimObjectMap.end())
  376. {
  377. output = bs_shared_ptr_new<SerializedObject>();
  378. mInterimObjectMap.insert(std::make_pair(objectId, output));
  379. }
  380. else
  381. output = iterFind->second;
  382. }
  383. else // Not a reflectable ptr referenced object
  384. output = bs_shared_ptr_new<SerializedObject>();
  385. output->subObjects.push_back(SerializedSubObject());
  386. serializedSubObject = &output->subObjects.back();
  387. serializedSubObject->typeId = objectTypeId;
  388. }
  389. while (bytesRead < dataLength)
  390. {
  391. int metaData = -1;
  392. if ((bytesRead + META_SIZE) > dataLength)
  393. {
  394. BS_EXCEPT(InternalErrorException,
  395. "Error decoding data.");
  396. }
  397. memcpy((void*)&metaData, data, META_SIZE);
  398. if (isObjectMetaData(metaData)) // We've reached a new object or a base class of the current one
  399. {
  400. if ((bytesRead + sizeof(ObjectMetaData)) > dataLength)
  401. {
  402. BS_EXCEPT(InternalErrorException,
  403. "Error decoding data.");
  404. }
  405. ObjectMetaData objMetaData;
  406. objMetaData.objectMeta = 0;
  407. objMetaData.typeId = 0;
  408. memcpy(&objMetaData, data, sizeof(ObjectMetaData));
  409. UINT32 objId = 0;
  410. UINT32 objTypeId = 0;
  411. bool objIsBaseClass = false;
  412. decodeObjectMetaData(objMetaData, objId, objTypeId, objIsBaseClass);
  413. // If it's a base class, get base class RTTI and handle that
  414. if (objIsBaseClass)
  415. {
  416. if (rtti != nullptr)
  417. rtti = rtti->getBaseClass();
  418. // Saved and current base classes don't match, so just skip over all that data
  419. if (rtti == nullptr || rtti->getRTTIId() != objTypeId)
  420. {
  421. rtti = nullptr;
  422. }
  423. if (rtti != nullptr)
  424. {
  425. output->subObjects.push_back(SerializedSubObject());
  426. serializedSubObject = &output->subObjects.back();
  427. serializedSubObject->typeId = objTypeId;
  428. }
  429. data += sizeof(ObjectMetaData);
  430. bytesRead += sizeof(ObjectMetaData);
  431. continue;
  432. }
  433. else
  434. {
  435. // Found new object, we're done
  436. return true;
  437. }
  438. }
  439. data += META_SIZE;
  440. bytesRead += META_SIZE;
  441. bool isArray;
  442. SerializableFieldType fieldType;
  443. UINT16 fieldId;
  444. UINT8 fieldSize;
  445. bool hasDynamicSize;
  446. bool terminator;
  447. decodeFieldMetaData(metaData, fieldId, fieldSize, isArray, fieldType, hasDynamicSize, terminator);
  448. if (terminator)
  449. {
  450. // We've processed the last field in this object, so return. Although we return false we don't actually know
  451. // if there is an object following this one. However it doesn't matter since terminator fields are only used
  452. // for embedded objects that are all processed within this method so we can compensate.
  453. return false;
  454. }
  455. RTTIField* curGenericField = nullptr;
  456. if (rtti != nullptr)
  457. curGenericField = rtti->findField(fieldId);
  458. if (curGenericField != nullptr)
  459. {
  460. if (!hasDynamicSize && curGenericField->getTypeSize() != fieldSize)
  461. {
  462. BS_EXCEPT(InternalErrorException,
  463. "Data type mismatch. Type size stored in file and actual type size don't match. ("
  464. + toString(curGenericField->getTypeSize()) + " vs. " + toString(fieldSize) + ")");
  465. }
  466. if (curGenericField->mIsVectorType != isArray)
  467. {
  468. BS_EXCEPT(InternalErrorException,
  469. "Data type mismatch. One is array, other is a single type.");
  470. }
  471. if (curGenericField->mType != fieldType)
  472. {
  473. BS_EXCEPT(InternalErrorException,
  474. "Data type mismatch. Field types don't match. " + toString(UINT32(curGenericField->mType)) + " vs. " + toString(UINT32(fieldType)));
  475. }
  476. }
  477. SPtr<SerializedInstance> serializedEntry;
  478. bool hasModification = false;
  479. int arrayNumElems = 1;
  480. if (isArray)
  481. {
  482. if ((bytesRead + NUM_ELEM_FIELD_SIZE) > dataLength)
  483. {
  484. BS_EXCEPT(InternalErrorException,
  485. "Error decoding data.");
  486. }
  487. memcpy((void*)&arrayNumElems, data, NUM_ELEM_FIELD_SIZE);
  488. data += NUM_ELEM_FIELD_SIZE;
  489. bytesRead += NUM_ELEM_FIELD_SIZE;
  490. SPtr<SerializedArray> serializedArray;
  491. if (curGenericField != nullptr)
  492. {
  493. serializedArray = bs_shared_ptr_new<SerializedArray>();
  494. serializedArray->numElements = arrayNumElems;
  495. serializedEntry = serializedArray;
  496. hasModification = true;
  497. }
  498. switch (fieldType)
  499. {
  500. case SerializableFT_ReflectablePtr:
  501. {
  502. RTTIReflectablePtrFieldBase* curField = static_cast<RTTIReflectablePtrFieldBase*>(curGenericField);
  503. for (int i = 0; i < arrayNumElems; i++)
  504. {
  505. if ((bytesRead + COMPLEX_TYPE_FIELD_SIZE) > dataLength)
  506. {
  507. BS_EXCEPT(InternalErrorException,
  508. "Error decoding data.");
  509. }
  510. int childObjectId = 0;
  511. memcpy(&childObjectId, data, COMPLEX_TYPE_FIELD_SIZE);
  512. data += COMPLEX_TYPE_FIELD_SIZE;
  513. bytesRead += COMPLEX_TYPE_FIELD_SIZE;
  514. if (curField != nullptr)
  515. {
  516. SPtr<SerializedObject> serializedArrayEntry = nullptr;
  517. if (childObjectId > 0)
  518. {
  519. auto findObj = mInterimObjectMap.find(childObjectId);
  520. if (findObj == mInterimObjectMap.end())
  521. {
  522. serializedArrayEntry = bs_shared_ptr_new<SerializedObject>();
  523. mInterimObjectMap.insert(std::make_pair(childObjectId, serializedArrayEntry));
  524. }
  525. else
  526. serializedArrayEntry = findObj->second;
  527. }
  528. SerializedArrayEntry arrayEntry;
  529. arrayEntry.serialized = serializedArrayEntry;
  530. arrayEntry.index = i;
  531. serializedArray->entries[i] = arrayEntry;
  532. }
  533. }
  534. break;
  535. }
  536. case SerializableFT_Reflectable:
  537. {
  538. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  539. for (int i = 0; i < arrayNumElems; i++)
  540. {
  541. if (curField != nullptr)
  542. {
  543. UINT32 bytesReadStart = bytesRead;
  544. SPtr<SerializedObject> serializedArrayEntry;
  545. decodeIntermediateInternal(data, dataLength, bytesRead, serializedArrayEntry, copyData);
  546. SerializedArrayEntry arrayEntry;
  547. arrayEntry.serialized = serializedArrayEntry;
  548. arrayEntry.index = i;
  549. serializedArray->entries[i] = arrayEntry;
  550. UINT32 complexTypeSize = bytesRead - bytesReadStart;
  551. data += complexTypeSize;
  552. }
  553. }
  554. break;
  555. }
  556. case SerializableFT_Plain:
  557. {
  558. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  559. for (int i = 0; i < arrayNumElems; i++)
  560. {
  561. UINT32 typeSize = fieldSize;
  562. if (hasDynamicSize)
  563. memcpy(&typeSize, data, sizeof(UINT32));
  564. if (curField != nullptr)
  565. {
  566. SPtr<SerializedField> serializedField = bs_shared_ptr_new<SerializedField>();
  567. if (copyData)
  568. {
  569. serializedField->value = (UINT8*)bs_alloc(typeSize);
  570. memcpy(serializedField->value, data, typeSize);
  571. serializedField->ownsMemory = true;
  572. }
  573. else
  574. serializedField->value = data;
  575. serializedField->size = typeSize;
  576. SerializedArrayEntry arrayEntry;
  577. arrayEntry.serialized = serializedField;
  578. arrayEntry.index = i;
  579. serializedArray->entries[i] = arrayEntry;
  580. }
  581. data += typeSize;
  582. bytesRead += typeSize;
  583. }
  584. break;
  585. }
  586. default:
  587. BS_EXCEPT(InternalErrorException,
  588. "Error decoding data. Encountered a type I don't know how to decode. Type: " + toString(UINT32(fieldType)) +
  589. ", Is array: " + toString(isArray));
  590. }
  591. }
  592. else
  593. {
  594. switch (fieldType)
  595. {
  596. case SerializableFT_ReflectablePtr:
  597. {
  598. RTTIReflectablePtrFieldBase* curField = static_cast<RTTIReflectablePtrFieldBase*>(curGenericField);
  599. if ((bytesRead + COMPLEX_TYPE_FIELD_SIZE) > dataLength)
  600. {
  601. BS_EXCEPT(InternalErrorException,
  602. "Error decoding data.");
  603. }
  604. int childObjectId = 0;
  605. memcpy(&childObjectId, data, COMPLEX_TYPE_FIELD_SIZE);
  606. data += COMPLEX_TYPE_FIELD_SIZE;
  607. bytesRead += COMPLEX_TYPE_FIELD_SIZE;
  608. if (curField != nullptr)
  609. {
  610. SPtr<SerializedObject> serializedField = nullptr;
  611. if (childObjectId > 0)
  612. {
  613. auto findObj = mInterimObjectMap.find(childObjectId);
  614. if (findObj == mInterimObjectMap.end())
  615. {
  616. serializedField = bs_shared_ptr_new<SerializedObject>();
  617. mInterimObjectMap.insert(std::make_pair(childObjectId, serializedField));
  618. }
  619. else
  620. serializedField = findObj->second;
  621. }
  622. serializedEntry = serializedField;
  623. hasModification = true;
  624. }
  625. break;
  626. }
  627. case SerializableFT_Reflectable:
  628. {
  629. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  630. if (curField != nullptr)
  631. {
  632. UINT32 bytesReadStart = bytesRead;
  633. SPtr<SerializedObject> serializedChildObj;
  634. decodeIntermediateInternal(data, dataLength, bytesRead, serializedChildObj, copyData);
  635. serializedEntry = serializedChildObj;
  636. hasModification = true;
  637. UINT32 complexTypeSize = bytesRead - bytesReadStart;
  638. data += complexTypeSize;
  639. }
  640. break;
  641. }
  642. case SerializableFT_Plain:
  643. {
  644. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  645. UINT32 typeSize = fieldSize;
  646. if (hasDynamicSize)
  647. memcpy(&typeSize, data, sizeof(UINT32));
  648. if (curField != nullptr)
  649. {
  650. SPtr<SerializedField> serializedField = bs_shared_ptr_new<SerializedField>();
  651. if (copyData)
  652. {
  653. serializedField->value = (UINT8*)bs_alloc(typeSize);
  654. memcpy(serializedField->value, data, typeSize);
  655. serializedField->ownsMemory = true;
  656. }
  657. else
  658. serializedField->value = data;
  659. serializedField->size = typeSize;
  660. serializedEntry = serializedField;
  661. hasModification = true;
  662. }
  663. data += typeSize;
  664. bytesRead += typeSize;
  665. break;
  666. }
  667. case SerializableFT_DataBlock:
  668. {
  669. RTTIManagedDataBlockFieldBase* curField = static_cast<RTTIManagedDataBlockFieldBase*>(curGenericField);
  670. if ((bytesRead + DATA_BLOCK_TYPE_FIELD_SIZE) > dataLength)
  671. {
  672. BS_EXCEPT(InternalErrorException,
  673. "Error decoding data.");
  674. }
  675. // Data block size
  676. UINT32 dataBlockSize = 0;
  677. memcpy(&dataBlockSize, data, DATA_BLOCK_TYPE_FIELD_SIZE);
  678. data += DATA_BLOCK_TYPE_FIELD_SIZE;
  679. bytesRead += DATA_BLOCK_TYPE_FIELD_SIZE;
  680. if ((bytesRead + dataBlockSize) > dataLength)
  681. {
  682. BS_EXCEPT(InternalErrorException,
  683. "Error decoding data.");
  684. }
  685. // Data block data
  686. if (curField != nullptr)
  687. {
  688. SPtr<SerializedField> serializedField = bs_shared_ptr_new<SerializedField>();
  689. if (copyData)
  690. {
  691. serializedField->value = (UINT8*)bs_alloc(dataBlockSize);
  692. memcpy(serializedField->value, data, dataBlockSize);
  693. serializedField->ownsMemory = true;
  694. }
  695. else
  696. serializedField->value = data;
  697. serializedField->size = dataBlockSize;
  698. serializedEntry = serializedField;
  699. hasModification = true;
  700. }
  701. data += dataBlockSize;
  702. bytesRead += dataBlockSize;
  703. break;
  704. }
  705. default:
  706. BS_EXCEPT(InternalErrorException,
  707. "Error decoding data. Encountered a type I don't know how to decode. Type: " + toString(UINT32(fieldType)) +
  708. ", Is array: " + toString(isArray));
  709. }
  710. }
  711. if (hasModification)
  712. {
  713. SerializedEntry entry;
  714. entry.fieldId = curGenericField->mUniqueId;
  715. entry.serialized = serializedEntry;
  716. serializedSubObject->entries.insert(std::make_pair(curGenericField->mUniqueId, entry));
  717. }
  718. }
  719. return false;
  720. }
  721. void BinarySerializer::decodeInternal(const SPtr<IReflectable>& object, const SPtr<SerializedObject>& serializableObject)
  722. {
  723. UINT32 numSubObjects = (UINT32)serializableObject->subObjects.size();
  724. Vector<RTTITypeBase*> rttiTypes;
  725. for (UINT32 subObjectIdx = 0; subObjectIdx < numSubObjects; subObjectIdx++)
  726. {
  727. const SerializedSubObject& subObject = serializableObject->subObjects[subObjectIdx];
  728. RTTITypeBase* rtti = IReflectable::_getRTTIfromTypeId(subObject.typeId);
  729. if (rtti == nullptr)
  730. continue;
  731. rtti->onDeserializationStarted(object.get());
  732. rttiTypes.push_back(rtti);
  733. UINT32 numFields = rtti->getNumFields();
  734. for (UINT32 fieldIdx = 0; fieldIdx < numFields; fieldIdx++)
  735. {
  736. RTTIField* curGenericField = rtti->getField(fieldIdx);
  737. auto iterFindFieldData = subObject.entries.find(curGenericField->mUniqueId);
  738. if (iterFindFieldData == subObject.entries.end())
  739. continue;
  740. SPtr<SerializedInstance> entryData = iterFindFieldData->second.serialized;
  741. if (curGenericField->isArray())
  742. {
  743. SPtr<SerializedArray> arrayData = std::static_pointer_cast<SerializedArray>(entryData);
  744. UINT32 arrayNumElems = (UINT32)arrayData->numElements;
  745. curGenericField->setArraySize(object.get(), arrayNumElems);
  746. switch (curGenericField->mType)
  747. {
  748. case SerializableFT_ReflectablePtr:
  749. {
  750. RTTIReflectablePtrFieldBase* curField = static_cast<RTTIReflectablePtrFieldBase*>(curGenericField);
  751. for (auto& arrayElem : arrayData->entries)
  752. {
  753. SPtr<SerializedObject> arrayElemData = std::static_pointer_cast<SerializedObject>(arrayElem.second.serialized);
  754. RTTITypeBase* childRtti = nullptr;
  755. if (arrayElemData != nullptr)
  756. childRtti = IReflectable::_getRTTIfromTypeId(arrayElemData->getRootTypeId());
  757. if (childRtti != nullptr)
  758. {
  759. auto findObj = mObjectMap.find(arrayElemData);
  760. if (findObj == mObjectMap.end())
  761. {
  762. SPtr<IReflectable> newObject = childRtti->newRTTIObject();
  763. findObj = mObjectMap.insert(std::make_pair(arrayElemData, ObjectToDecode(newObject, arrayElemData))).first;
  764. }
  765. ObjectToDecode& objToDecode = findObj->second;
  766. bool needsDecoding = (curField->getFlags() & RTTI_Flag_WeakRef) == 0 && !objToDecode.isDecoded;
  767. if (needsDecoding)
  768. {
  769. decodeInternal(objToDecode.object, objToDecode.serializedObject);
  770. objToDecode.isDecoded = true;
  771. }
  772. curField->setArrayValue(object.get(), arrayElem.first, objToDecode.object);
  773. }
  774. else
  775. {
  776. curField->setArrayValue(object.get(), arrayElem.first, nullptr);
  777. }
  778. }
  779. }
  780. break;
  781. case SerializableFT_Reflectable:
  782. {
  783. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  784. for (auto& arrayElem : arrayData->entries)
  785. {
  786. SPtr<SerializedObject> arrayElemData = std::static_pointer_cast<SerializedObject>(arrayElem.second.serialized);
  787. RTTITypeBase* childRtti = nullptr;
  788. if (arrayElemData != nullptr)
  789. childRtti = IReflectable::_getRTTIfromTypeId(arrayElemData->getRootTypeId());
  790. if (childRtti != nullptr)
  791. {
  792. SPtr<IReflectable> newObject = childRtti->newRTTIObject();
  793. decodeInternal(newObject, arrayElemData);
  794. curField->setArrayValue(object.get(), arrayElem.first, *newObject);
  795. }
  796. }
  797. break;
  798. }
  799. case SerializableFT_Plain:
  800. {
  801. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  802. for (auto& arrayElem : arrayData->entries)
  803. {
  804. SPtr<SerializedField> fieldData = std::static_pointer_cast<SerializedField>(arrayElem.second.serialized);
  805. if (fieldData != nullptr)
  806. {
  807. curField->arrayElemFromBuffer(object.get(), arrayElem.first, fieldData->value);
  808. }
  809. }
  810. }
  811. break;
  812. }
  813. }
  814. else
  815. {
  816. switch (curGenericField->mType)
  817. {
  818. case SerializableFT_ReflectablePtr:
  819. {
  820. RTTIReflectablePtrFieldBase* curField = static_cast<RTTIReflectablePtrFieldBase*>(curGenericField);
  821. SPtr<SerializedObject> fieldObjectData = std::static_pointer_cast<SerializedObject>(entryData);
  822. RTTITypeBase* childRtti = nullptr;
  823. if (fieldObjectData != nullptr)
  824. childRtti = IReflectable::_getRTTIfromTypeId(fieldObjectData->getRootTypeId());
  825. if (childRtti != nullptr)
  826. {
  827. auto findObj = mObjectMap.find(fieldObjectData);
  828. if (findObj == mObjectMap.end())
  829. {
  830. SPtr<IReflectable> newObject = childRtti->newRTTIObject();
  831. findObj = mObjectMap.insert(std::make_pair(fieldObjectData, ObjectToDecode(newObject, fieldObjectData))).first;
  832. }
  833. ObjectToDecode& objToDecode = findObj->second;
  834. bool needsDecoding = (curField->getFlags() & RTTI_Flag_WeakRef) == 0 && !objToDecode.isDecoded;
  835. if (needsDecoding)
  836. {
  837. decodeInternal(objToDecode.object, objToDecode.serializedObject);
  838. objToDecode.isDecoded = true;
  839. }
  840. curField->setValue(object.get(), objToDecode.object);
  841. }
  842. else
  843. {
  844. curField->setValue(object.get(), nullptr);
  845. }
  846. }
  847. break;
  848. case SerializableFT_Reflectable:
  849. {
  850. RTTIReflectableFieldBase* curField = static_cast<RTTIReflectableFieldBase*>(curGenericField);
  851. SPtr<SerializedObject> fieldObjectData = std::static_pointer_cast<SerializedObject>(entryData);
  852. RTTITypeBase* childRtti = nullptr;
  853. if (fieldObjectData != nullptr)
  854. childRtti = IReflectable::_getRTTIfromTypeId(fieldObjectData->getRootTypeId());
  855. if (childRtti != nullptr)
  856. {
  857. SPtr<IReflectable> newObject = childRtti->newRTTIObject();
  858. decodeInternal(newObject, fieldObjectData);
  859. curField->setValue(object.get(), *newObject);
  860. }
  861. break;
  862. }
  863. case SerializableFT_Plain:
  864. {
  865. RTTIPlainFieldBase* curField = static_cast<RTTIPlainFieldBase*>(curGenericField);
  866. SPtr<SerializedField> fieldData = std::static_pointer_cast<SerializedField>(entryData);
  867. if (fieldData != nullptr)
  868. {
  869. curField->fromBuffer(object.get(), fieldData->value);
  870. }
  871. }
  872. break;
  873. case SerializableFT_DataBlock:
  874. {
  875. RTTIManagedDataBlockFieldBase* curField = static_cast<RTTIManagedDataBlockFieldBase*>(curGenericField);
  876. SPtr<SerializedField> fieldData = std::static_pointer_cast<SerializedField>(entryData);
  877. if (fieldData != nullptr)
  878. {
  879. UINT8* dataCopy = curField->allocate(object.get(), fieldData->size); // TODO - Low priority. I need to read files better, so I
  880. memcpy(dataCopy, fieldData->value, fieldData->size); // can just pass the buffer pointer directly without copying (possibly large amounts of data)
  881. ManagedDataBlock value(dataCopy, fieldData->size); // Not managed because I assume the owner class will decide whether to delete the data or keep it
  882. curField->setValue(object.get(), value);
  883. }
  884. break;
  885. }
  886. }
  887. }
  888. }
  889. }
  890. for (auto iterFind = rttiTypes.rbegin(); iterFind != rttiTypes.rend(); ++iterFind)
  891. {
  892. (*iterFind)->onDeserializationEnded(object.get());
  893. }
  894. }
  895. UINT32 BinarySerializer::encodeFieldMetaData(UINT16 id, UINT8 size, bool array,
  896. SerializableFieldType type, bool hasDynamicSize, bool terminator)
  897. {
  898. // If O == 0 - Meta contains field information (Encoded using this method)
  899. //// Encoding: IIII IIII IIII IIII SSSS SSSS xTYP DCAO
  900. //// I - Id
  901. //// S - Size
  902. //// C - Complex
  903. //// A - Array
  904. //// D - Data block
  905. //// P - Complex ptr
  906. //// O - Object descriptor
  907. //// Y - Plain field has dynamic size
  908. //// T - Terminator (last field in an object)
  909. return (id << 16 | size << 8 |
  910. (array ? 0x02 : 0) |
  911. ((type == SerializableFT_DataBlock) ? 0x04 : 0) |
  912. ((type == SerializableFT_Reflectable) ? 0x08 : 0) |
  913. ((type == SerializableFT_ReflectablePtr) ? 0x10 : 0) |
  914. (hasDynamicSize ? 0x20 : 0) |
  915. (terminator ? 0x40 : 0)); // TODO - Low priority. Technically I could encode this much more tightly, and use var-ints for ID
  916. }
  917. void BinarySerializer::decodeFieldMetaData(UINT32 encodedData, UINT16& id, UINT8& size,
  918. bool& array, SerializableFieldType& type, bool& hasDynamicSize, bool& terminator)
  919. {
  920. if(isObjectMetaData(encodedData))
  921. {
  922. BS_EXCEPT(InternalErrorException,
  923. "Meta data represents an object description but is trying to be decoded as a field descriptor.");
  924. }
  925. terminator = (encodedData & 0x40) != 0;
  926. hasDynamicSize = (encodedData & 0x20) != 0;
  927. if((encodedData & 0x10) != 0)
  928. type = SerializableFT_ReflectablePtr;
  929. else if((encodedData & 0x08) != 0)
  930. type = SerializableFT_Reflectable;
  931. else if((encodedData & 0x04) != 0)
  932. type = SerializableFT_DataBlock;
  933. else
  934. type = SerializableFT_Plain;
  935. array = (encodedData & 0x02) != 0;
  936. size = (UINT8)((encodedData >> 8) & 0xFF);
  937. id = (UINT16)((encodedData >> 16) & 0xFFFF);
  938. }
  939. BinarySerializer::ObjectMetaData BinarySerializer::encodeObjectMetaData(UINT32 objId, UINT32 objTypeId, bool isBaseClass)
  940. {
  941. // If O == 1 - Meta contains object instance information (Encoded using encodeObjectMetaData)
  942. //// Encoding: SSSS SSSS SSSS SSSS xxxx xxxx xxxx xxBO
  943. //// S - Size of the object identifier
  944. //// O - Object descriptor
  945. //// B - Base class indicator
  946. if(objId > 1073741823)
  947. {
  948. BS_EXCEPT(InvalidParametersException, "Object ID is larger than we can store (max 30 bits): " + toString(objId));
  949. }
  950. ObjectMetaData metaData;
  951. metaData.objectMeta = (objId << 2) | (isBaseClass ? 0x02 : 0) | 0x01;
  952. metaData.typeId = objTypeId;
  953. return metaData;
  954. }
  955. void BinarySerializer::decodeObjectMetaData(BinarySerializer::ObjectMetaData encodedData, UINT32& objId, UINT32& objTypeId, bool& isBaseClass)
  956. {
  957. if(!isObjectMetaData(encodedData.objectMeta))
  958. {
  959. BS_EXCEPT(InternalErrorException,
  960. "Meta data represents a field description but is trying to be decoded as an object descriptor.");
  961. }
  962. objId = (encodedData.objectMeta >> 2) & 0x3FFFFFFF;
  963. isBaseClass = (encodedData.objectMeta & 0x02) != 0;
  964. objTypeId = encodedData.typeId;
  965. }
  966. bool BinarySerializer::isObjectMetaData(UINT32 encodedData)
  967. {
  968. return ((encodedData & 0x01) != 0);
  969. }
  970. UINT8* BinarySerializer::complexTypeToBuffer(IReflectable* object, UINT8* buffer, UINT32& bufferLength,
  971. UINT32* bytesWritten, std::function<UINT8*(UINT8*, UINT32, UINT32&)> flushBufferCallback, bool shallow)
  972. {
  973. if (object != nullptr)
  974. {
  975. buffer = encodeInternal(object, 0, buffer, bufferLength, bytesWritten, flushBufferCallback, shallow);
  976. // Encode terminator field
  977. // Complex types require terminator fields because they can be embedded within other complex types and we need
  978. // to know when their fields end and parent's resume
  979. int metaData = encodeFieldMetaData(0, 0, false, SerializableFT_Plain, false, true);
  980. COPY_TO_BUFFER(&metaData, META_SIZE)
  981. }
  982. return buffer;
  983. }
  984. UINT8* BinarySerializer::dataBlockToBuffer(UINT8* data, UINT32 size, UINT8* buffer, UINT32& bufferLength, UINT32* bytesWritten,
  985. std::function<UINT8*(UINT8* buffer, UINT32 bytesWritten, UINT32& newBufferSize)> flushBufferCallback)
  986. {
  987. UINT32 remainingSize = size;
  988. while (remainingSize > 0)
  989. {
  990. UINT32 remainingSpaceInBuffer = bufferLength - *bytesWritten;
  991. if (remainingSize <= remainingSpaceInBuffer)
  992. {
  993. COPY_TO_BUFFER(data, remainingSize);
  994. remainingSize = 0;
  995. }
  996. else
  997. {
  998. memcpy(buffer, data, remainingSpaceInBuffer);
  999. buffer += remainingSpaceInBuffer;
  1000. *bytesWritten += remainingSpaceInBuffer;
  1001. data += remainingSpaceInBuffer;
  1002. remainingSize -= remainingSpaceInBuffer;
  1003. mTotalBytesWritten += *bytesWritten;
  1004. buffer = flushBufferCallback(buffer - *bytesWritten, *bytesWritten, bufferLength);
  1005. if (buffer == nullptr || bufferLength == 0)
  1006. return nullptr;
  1007. *bytesWritten = 0;
  1008. }
  1009. }
  1010. return buffer;
  1011. }
  1012. UINT32 BinarySerializer::findOrCreatePersistentId(IReflectable* object)
  1013. {
  1014. void* ptrAddress = (void*)object;
  1015. auto findIter = mObjectAddrToId.find(ptrAddress);
  1016. if(findIter != mObjectAddrToId.end())
  1017. return findIter->second;
  1018. UINT32 objId = mLastUsedObjectId++;
  1019. mObjectAddrToId.insert(std::make_pair(ptrAddress, objId));
  1020. return objId;
  1021. }
  1022. UINT32 BinarySerializer::registerObjectPtr(std::shared_ptr<IReflectable> object)
  1023. {
  1024. if(object == nullptr)
  1025. return 0;
  1026. void* ptrAddress = (void*)object.get();
  1027. auto iterFind = mObjectAddrToId.find(ptrAddress);
  1028. if(iterFind == mObjectAddrToId.end())
  1029. {
  1030. UINT32 objId = findOrCreatePersistentId(object.get());
  1031. mObjectsToEncode.push_back(ObjectToEncode(objId, object));
  1032. mObjectAddrToId.insert(std::make_pair(ptrAddress, objId));
  1033. return objId;
  1034. }
  1035. return iterFind->second;
  1036. }
  1037. }
  1038. #undef COPY_TO_BUFFER