BsScriptManagedResource.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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::newWeakGCHandle(instance);
  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::newWeakGCHandle(instance);
  39. return instance;
  40. }
  41. void ScriptManagedResource::_clearManagedInstance()
  42. {
  43. mGCHandle = 0;
  44. }
  45. ScriptObjectBackup ScriptManagedResource::beginRefresh()
  46. {
  47. ScriptResourceBase::beginRefresh();
  48. ScriptObjectBackup backupData;
  49. backupData.data = mResource->backup(true);
  50. return backupData;
  51. }
  52. void ScriptManagedResource::endRefresh(const ScriptObjectBackup& backupData)
  53. {
  54. MonoObject* instance = MonoUtil::getObjectFromGCHandle(mGCHandle);
  55. ResourceBackupData resourceBackup = any_cast<ResourceBackupData>(backupData.data);
  56. mResource->restore(instance, resourceBackup);
  57. // If we could not find resource type after refresh, treat it as if it was destroyed
  58. if (instance == nullptr)
  59. _onManagedInstanceDeleted();
  60. ScriptResourceBase::endRefresh(backupData);
  61. }
  62. void ScriptManagedResource::_onManagedInstanceDeleted()
  63. {
  64. mGCHandle = 0;
  65. if (!mRefreshInProgress)
  66. {
  67. // The only way this method should be reachable is when Resource::unload is called, which means the resource
  68. // has had to been already freed. Even if all managed instances are released ManagedResource itself holds the last
  69. // instance which is only freed on unload().
  70. // Note: During domain unload this could get called even if not all instances are released, but ManagedResourceManager
  71. // should make sure all instances are unloaded before that happens.
  72. BS_ASSERT(mResource == nullptr || !mResource.isLoaded());
  73. ScriptResourceManager::instance().destroyScriptResource(this);
  74. }
  75. }
  76. void ScriptManagedResource::setResource(const HResource& resource)
  77. {
  78. mResource = static_resource_cast<ManagedResource>(resource);
  79. }
  80. }