2
0

BsCoreObjectManager.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #include "BsCoreObjectManager.h"
  2. #include "BsCoreObject.h"
  3. #include "BsCoreObjectCore.h"
  4. #include "BsException.h"
  5. #include "BsMath.h"
  6. #include "BsFrameAlloc.h"
  7. #include "BsCoreThread.h"
  8. namespace BansheeEngine
  9. {
  10. CoreObjectManager::CoreObjectManager()
  11. :mNextAvailableID(1)
  12. {
  13. }
  14. CoreObjectManager::~CoreObjectManager()
  15. {
  16. #if BS_DEBUG_MODE
  17. BS_LOCK_MUTEX(mObjectsMutex);
  18. if(mObjects.size() > 0)
  19. {
  20. // All objects MUST be destroyed at this point, otherwise there might be memory corruption.
  21. // (Reason: This is called on application shutdown and at that point we also unload any dynamic libraries,
  22. // which will invalidate any pointers to objects created from those libraries. Therefore we require of the user to
  23. // clean up all objects manually before shutting down the application).
  24. BS_EXCEPT(InternalErrorException, "Core object manager shut down, but not all objects were released. Application must release ALL " \
  25. "engine objects before shutdown.");
  26. }
  27. #endif
  28. }
  29. UINT64 CoreObjectManager::registerObject(CoreObject* object)
  30. {
  31. assert(object != nullptr);
  32. BS_LOCK_MUTEX(mObjectsMutex);
  33. mObjects[mNextAvailableID] = object;
  34. return mNextAvailableID++;
  35. }
  36. void CoreObjectManager::unregisterObject(CoreObject* object)
  37. {
  38. assert(object != nullptr);
  39. BS_LOCK_MUTEX(mObjectsMutex);
  40. UINT64 internalId = object->getInternalID();
  41. mObjects.erase(internalId);
  42. for (auto& syncData : mCoreSyncData)
  43. {
  44. auto iterFind = syncData.entries.find(internalId);
  45. if (iterFind != syncData.entries.end())
  46. {
  47. UINT8* data = iterFind->second.syncData.getBuffer();
  48. if (data != nullptr && syncData.alloc != nullptr)
  49. syncData.alloc->dealloc(data);
  50. syncData.entries.erase(iterFind);
  51. }
  52. }
  53. }
  54. void CoreObjectManager::syncToCore(CoreAccessor& accessor)
  55. {
  56. syncDownload(gCoreThread().getFrameAlloc());
  57. accessor.queueCommand(std::bind(&CoreObjectManager::syncUpload, this));
  58. }
  59. void CoreObjectManager::syncDownload(FrameAlloc* allocator)
  60. {
  61. BS_LOCK_MUTEX(mObjectsMutex);
  62. mCoreSyncData.push_back(CoreStoredSyncData());
  63. CoreStoredSyncData& syncData = mCoreSyncData.back();
  64. syncData.alloc = allocator;
  65. for (auto& objectData : mObjects)
  66. {
  67. CoreObject* object = objectData.second;
  68. SPtr<CoreObjectCore> objectCore = object->getCore();
  69. if (objectCore != nullptr && object->isCoreDirty())
  70. {
  71. CoreSyncData objSyncData = object->syncToCore(allocator);
  72. object->markCoreClean();
  73. syncData.entries[object->getInternalID()] = CoreStoredSyncObjData(objectCore.get(), objSyncData);
  74. }
  75. }
  76. }
  77. void CoreObjectManager::syncUpload()
  78. {
  79. BS_LOCK_MUTEX(mObjectsMutex);
  80. if (mCoreSyncData.size() == 0)
  81. return;
  82. CoreStoredSyncData& syncData = mCoreSyncData.front();
  83. for (auto& objectData : syncData.entries)
  84. {
  85. const CoreStoredSyncObjData& objSyncData = objectData.second;
  86. objSyncData.destinationObj->syncToCore(objSyncData.syncData);
  87. UINT8* data = objSyncData.syncData.getBuffer();
  88. if (data != nullptr)
  89. syncData.alloc->dealloc(data);
  90. }
  91. syncData.entries.clear();
  92. mCoreSyncData.pop_front();
  93. }
  94. }