BsScriptManagedResource.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Wrappers/BsScriptManagedResource.h"
  4. #include "BsScriptResourceManager.h"
  5. #include "Serialization/BsScriptAssemblyManager.h"
  6. #include "BsScriptMeta.h"
  7. #include "BsMonoField.h"
  8. #include "BsMonoClass.h"
  9. #include "BsMonoManager.h"
  10. #include "BsManagedResource.h"
  11. #include "Resources/BsResources.h"
  12. #include "Error/BsException.h"
  13. #include "BsMonoUtil.h"
  14. namespace bs
  15. {
  16. ScriptManagedResource::ScriptManagedResource(MonoObject* instance, const HManagedResource& resource)
  17. :ScriptObject(instance), mResource(resource)
  18. {
  19. BS_ASSERT(instance != nullptr);
  20. MonoUtil::getClassName(instance, mNamespace, mType);
  21. mGCHandle = MonoUtil::newGCHandle(instance, false);
  22. }
  23. void ScriptManagedResource::initRuntimeData()
  24. {
  25. metaData.scriptClass->addInternalCall("Internal_CreateInstance", (void*)&ScriptManagedResource::internal_createInstance);
  26. }
  27. void ScriptManagedResource::internal_createInstance(MonoObject* instance)
  28. {
  29. HManagedResource resource = ManagedResource::create(instance);
  30. }
  31. MonoObject* ScriptManagedResource::_createManagedInstance(bool construct)
  32. {
  33. SPtr<ManagedSerializableObjectInfo> currentObjInfo = nullptr;
  34. // See if this type even still exists
  35. if (!ScriptAssemblyManager::instance().getSerializableObjectInfo(mNamespace, mType, currentObjInfo))
  36. return nullptr;
  37. MonoObject* instance = currentObjInfo->mMonoClass->createInstance(construct);
  38. mGCHandle = MonoUtil::newGCHandle(instance, false);
  39. return instance;
  40. }
  41. void ScriptManagedResource::_clearManagedInstance()
  42. {
  43. freeManagedInstance();
  44. }
  45. ScriptObjectBackup ScriptManagedResource::beginRefresh()
  46. {
  47. ScriptObjectBackup backupData;
  48. backupData.data = mResource->backup();
  49. return backupData;
  50. }
  51. void ScriptManagedResource::endRefresh(const ScriptObjectBackup& backupData)
  52. {
  53. MonoObject* instance = MonoUtil::getObjectFromGCHandle(mGCHandle);
  54. ResourceBackupData resourceBackup = any_cast<ResourceBackupData>(backupData.data);
  55. mResource->restore(resourceBackup);
  56. // If we could not find resource type after refresh, treat it as if it was destroyed
  57. if (instance == nullptr)
  58. _onManagedInstanceDeleted(false);
  59. }
  60. void ScriptManagedResource::_onManagedInstanceDeleted(bool assemblyRefresh)
  61. {
  62. mGCHandle = 0;
  63. if (!assemblyRefresh || mResource->isDestroyed())
  64. {
  65. // The only way this method should be reachable is when Resource::unload is called, which means the resource
  66. // has had to been already freed. Even if all managed instances are released ManagedResource itself holds the last
  67. // instance which is only freed on unload().
  68. // Note: During domain unload this could get called even if not all instances are released, but ManagedResourceManager
  69. // should make sure all instances are unloaded before that happens.
  70. BS_ASSERT(mResource == nullptr || !mResource.isLoaded());
  71. ScriptResourceManager::instance().destroyScriptResource(this);
  72. }
  73. }
  74. void ScriptManagedResource::_notifyDestroyed()
  75. {
  76. freeManagedInstance();
  77. }
  78. void ScriptManagedResource::setResource(const HResource& resource)
  79. {
  80. mResource = static_resource_cast<ManagedResource>(resource);
  81. }
  82. }