BsScriptResource.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsScriptEnginePrerequisites.h"
  5. #include "BsScriptObject.h"
  6. #include "BsMonoUtil.h"
  7. namespace bs
  8. {
  9. /** @addtogroup ScriptInteropEngine
  10. * @{
  11. */
  12. /** Base class for all resource interop objects. */
  13. class BS_SCR_BE_EXPORT ScriptResourceBase : public PersistentScriptObjectBase
  14. {
  15. public:
  16. /** Returns a generic handle to the internal wrapped resource. */
  17. virtual HResource getGenericHandle() const = 0;
  18. /** Sets the internal resource this object wraps. */
  19. virtual void setResource(const HResource& resource) = 0;
  20. /** Returns the managed version of this resource. */
  21. MonoObject* getManagedInstance() const;
  22. /** @copydoc ScriptObjectBase::beginRefresh */
  23. ScriptObjectBackup beginRefresh() override;
  24. /** @copydoc ScriptObjectBase::endRefresh */
  25. void endRefresh(const ScriptObjectBackup& backupData) override;
  26. protected:
  27. friend class ScriptResourceManager;
  28. ScriptResourceBase(MonoObject* instance);
  29. virtual ~ScriptResourceBase();
  30. /**
  31. * Makes the object reference the specific managed instance. Internally this allocates a GC handle that keeps a
  32. * reference to the object and allows getManagedInstance to retrieve the managed instance when requested. Should
  33. * be called on initial creation and whenever the managed instance changes (e.g. after assembly refresh). This
  34. * creates a strong reference to the managed instance, and you need to make sure to release it with
  35. * freeManagedInstance() when no longer required.
  36. */
  37. void setManagedInstance(MonoObject* instance);
  38. /**
  39. * Frees a managed instace assigned with setManagedInstance(). Should be called before the object is destroyed or
  40. * when you changing the managed instance it points to (in order to release the previous instance).
  41. */
  42. void freeManagedInstance();
  43. /**
  44. * Triggered by the script resource managed when the native resource handle this object point to has been destroyed.
  45. */
  46. virtual void notifyResourceDestroyed() { }
  47. /** Destroys the interop object, unless refresh is in progress in which case it is just prepared for re-creation. */
  48. void destroy();
  49. bool mRefreshInProgress;
  50. UINT32 mGCHandle;
  51. };
  52. /** Base class for a specific resource's interop object. */
  53. template<class ScriptClass, class ResType, class BaseType = ScriptResourceBase>
  54. class BS_SCR_BE_EXPORT TScriptResource : public ScriptObject <ScriptClass, BaseType>
  55. {
  56. public:
  57. /** Returns a generic handle to the internal wrapped resource. */
  58. HResource getGenericHandle() const override { return mResource; }
  59. /** Sets the internal resource this object wraps. */
  60. void setResource(const HResource& resource) override { mResource = static_resource_cast<ResType>(resource); }
  61. /** Returns a handle to the internal wrapped resource. */
  62. const ResourceHandle<ResType>& getHandle() const { return mResource; }
  63. protected:
  64. friend class ScriptResourceManager;
  65. TScriptResource(MonoObject* instance, const ResourceHandle<ResType>& resource)
  66. :ScriptObject<ScriptClass, BaseType>(instance), mResource(resource)
  67. {
  68. this->setManagedInstance(instance);
  69. }
  70. virtual ~TScriptResource() {}
  71. /** @copydoc ScriptObject::_createManagedInstance */
  72. MonoObject* _createManagedInstance(bool construct) override
  73. {
  74. MonoObject* managedInstance = ScriptClass::metaData.scriptClass->createInstance(construct);
  75. this->setManagedInstance(managedInstance);
  76. return managedInstance;
  77. }
  78. /** @copydoc ScriptObjectBase::_clearManagedInstance */
  79. void _clearManagedInstance() override
  80. {
  81. this->mGCHandle = 0;
  82. }
  83. /**
  84. * Triggered by the script resource managed when the native resource handle this object point to has been destroyed.
  85. */
  86. void notifyResourceDestroyed() override
  87. {
  88. this->freeManagedInstance();
  89. }
  90. /** Called when the managed instance gets finalized by the CLR. */
  91. void _onManagedInstanceDeleted() override
  92. {
  93. this->freeManagedInstance();
  94. this->destroy();
  95. }
  96. ResourceHandle<ResType> mResource;
  97. };
  98. /** Interop class between C++ & CLR for Resource. */
  99. class BS_SCR_BE_EXPORT ScriptResource : public ScriptObject<ScriptResource, ScriptResourceBase>
  100. {
  101. public:
  102. SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "Resource")
  103. private:
  104. ScriptResource(MonoObject* instance)
  105. :ScriptObject(instance)
  106. { }
  107. /************************************************************************/
  108. /* CLR HOOKS */
  109. /************************************************************************/
  110. static MonoString* internal_getName(ScriptResourceBase* nativeInstance);
  111. static void internal_getUUID(ScriptResourceBase* nativeInstance, UUID* uuid);
  112. static void internal_release(ScriptResourceBase* nativeInstance);
  113. };
  114. /** Interop class between C++ & CLR for UUID. */
  115. class BS_SCR_BE_EXPORT ScriptUUID : public ScriptObject<ScriptUUID>
  116. {
  117. public:
  118. SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "UUID")
  119. /** Unboxes a boxed managed UUID struct and returns the native version of the structure. */
  120. static UUID unbox(MonoObject* obj);
  121. /** Boxes a native UUID struct and returns a managed object containing it. */
  122. static MonoObject* box(const UUID& value);
  123. private:
  124. ScriptUUID(MonoObject* instance);
  125. };
  126. /** @} */
  127. }