BsCoreObjectManager.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include "BsCoreObjectManager.h"
  2. #include "BsCoreObject.h"
  3. #include "BsCoreObjectCore.h"
  4. #include "BsException.h"
  5. #include "BsFrameAlloc.h"
  6. namespace BansheeEngine
  7. {
  8. CoreObjectManager::CoreObjectManager()
  9. :mNextAvailableID(1), mSimSyncIdx(0), mSimSyncCount(0),
  10. mCoreSyncIdx(0), mCoreSyncCount(0)
  11. {
  12. }
  13. CoreObjectManager::~CoreObjectManager()
  14. {
  15. #if BS_DEBUG_MODE
  16. BS_LOCK_MUTEX(mObjectsMutex);
  17. if(mObjects.size() > 0)
  18. {
  19. // All objects MUST be destroyed at this point, otherwise there might be memory corruption.
  20. // (Reason: This is called on application shutdown and at that point we also unload any dynamic libraries,
  21. // which will invalidate any pointers to objects created from those libraries. Therefore we require of the user to
  22. // clean up all objects manually before shutting down the application).
  23. BS_EXCEPT(InternalErrorException, "Core object manager shut down, but not all objects were released. Application must release ALL " \
  24. "engine objects before shutdown.");
  25. }
  26. #endif
  27. }
  28. UINT64 CoreObjectManager::registerObject(CoreObject* object)
  29. {
  30. assert(object != nullptr);
  31. BS_LOCK_MUTEX(mObjectsMutex);
  32. mObjects[mNextAvailableID] = object;
  33. return mNextAvailableID++;
  34. }
  35. void CoreObjectManager::unregisterObject(CoreObject* object)
  36. {
  37. assert(object != nullptr);
  38. BS_LOCK_MUTEX(mObjectsMutex);
  39. UINT64 internalId = object->getInternalID();
  40. mObjects.erase(internalId);
  41. {
  42. for (UINT32 i = 0; i < mSimSyncCount; i++)
  43. {
  44. UINT32 idx = (mSimSyncIdx + i - mSimSyncCount - 1) % mSimSyncCount;
  45. SimStoredSyncData& syncData = mSimSyncData[idx];
  46. auto iterFind = syncData.entries.find(internalId);
  47. if (iterFind != syncData.entries.end())
  48. {
  49. UINT8* data = iterFind->second.syncData.getBuffer();
  50. if (data != nullptr && syncData.alloc != nullptr)
  51. syncData.alloc->dealloc(data);
  52. syncData.entries.erase(iterFind);
  53. }
  54. }
  55. }
  56. {
  57. for (UINT32 i = 0; i < mCoreSyncCount; i++)
  58. {
  59. UINT32 idx = (mCoreSyncIdx + i - mCoreSyncCount - 1) % mCoreSyncCount;
  60. CoreStoredSyncData& syncData = mCoreSyncData[idx];
  61. auto iterFind = syncData.entries.find(internalId);
  62. if (iterFind != syncData.entries.end())
  63. {
  64. UINT8* data = iterFind->second.syncData.getBuffer();
  65. if (data != nullptr && syncData.alloc != nullptr)
  66. syncData.alloc->dealloc(data);
  67. syncData.entries.erase(iterFind);
  68. }
  69. }
  70. }
  71. }
  72. void CoreObjectManager::syncDownload(CoreObjectSync type, FrameAlloc* allocator)
  73. {
  74. BS_LOCK_MUTEX(mObjectsMutex);
  75. if (type == CoreObjectSync::Sim)
  76. {
  77. mCoreSyncCount++;
  78. if (mCoreSyncCount > (UINT32)mCoreSyncData.size())
  79. mCoreSyncData.push_back(CoreStoredSyncData());
  80. mCoreSyncIdx = (mCoreSyncIdx + 1) % mCoreSyncCount;
  81. CoreStoredSyncData& syncData = mCoreSyncData[mCoreSyncIdx];
  82. syncData.alloc = allocator;
  83. for (auto& objectData : mObjects)
  84. {
  85. CoreObject* object = objectData.second;
  86. SPtr<CoreObjectCore> objectCore = object->getCore();
  87. if (objectCore != nullptr && object->isCoreDirty())
  88. {
  89. CoreSyncData objSyncData = object->syncToCore(allocator);
  90. object->markCoreClean();
  91. syncData.entries[object->getInternalID()] = CoreStoredSyncObjData(objectCore.get(), objSyncData);
  92. }
  93. }
  94. }
  95. else
  96. {
  97. mSimSyncCount++;
  98. if (mSimSyncCount > (UINT32)mSimSyncData.size())
  99. mSimSyncData.push_back(SimStoredSyncData());
  100. mSimSyncIdx = (mSimSyncIdx + 1) % mSimSyncCount;
  101. SimStoredSyncData& syncData = mSimSyncData[mSimSyncIdx];
  102. syncData.alloc = allocator;
  103. for (auto& objectData : mObjects)
  104. {
  105. CoreObject* object = objectData.second;
  106. SPtr<CoreObjectCore> objectCore = object->getCore();
  107. if (objectCore != nullptr && objectCore->isCoreDirty())
  108. {
  109. CoreSyncData objSyncData = objectCore->syncFromCore(allocator);
  110. objectCore->markCoreClean();
  111. syncData.entries[object->getInternalID()] = SimStoredSyncObjData(object, objSyncData);
  112. }
  113. }
  114. }
  115. }
  116. void CoreObjectManager::syncUpload(CoreObjectSync type)
  117. {
  118. BS_LOCK_MUTEX(mObjectsMutex);
  119. if (type == CoreObjectSync::Sim)
  120. {
  121. if (mCoreSyncCount == 0)
  122. return;
  123. mCoreSyncCount--;
  124. UINT32 idx = mCoreSyncIdx - mCoreSyncCount;
  125. CoreStoredSyncData& syncData = mCoreSyncData[idx];
  126. for (auto& objectData : syncData.entries)
  127. {
  128. const CoreStoredSyncObjData& objSyncData = objectData.second;
  129. objSyncData.destinationObj->syncToCore(objSyncData.syncData);
  130. UINT8* data = objSyncData.syncData.getBuffer();
  131. if (data != nullptr)
  132. syncData.alloc->dealloc(data);
  133. }
  134. syncData.entries.clear();
  135. }
  136. else
  137. {
  138. if (mSimSyncCount == 0)
  139. return;
  140. mSimSyncCount--;
  141. UINT32 idx = mSimSyncIdx - mSimSyncCount;
  142. SimStoredSyncData& syncData = mSimSyncData[idx];
  143. for (auto& objectData : syncData.entries)
  144. {
  145. const SimStoredSyncObjData& objSyncData = objectData.second;
  146. objSyncData.destinationObj->syncFromCore(objSyncData.syncData);
  147. UINT8* data = objSyncData.syncData.getBuffer();
  148. if (data != nullptr)
  149. syncData.alloc->dealloc(data);
  150. }
  151. syncData.entries.clear();
  152. }
  153. }
  154. }