BsScriptResource.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. #include "BsScriptRRefBase.h"
  8. namespace bs
  9. {
  10. /** @addtogroup ScriptInteropEngine
  11. * @{
  12. */
  13. /** Base class for all resource interop objects. */
  14. class BS_SCR_BE_EXPORT ScriptResourceBase : public PersistentScriptObjectBase
  15. {
  16. public:
  17. /** Returns a generic handle to the internal wrapped resource. */
  18. virtual HResource getGenericHandle() const = 0;
  19. /** Sets the internal resource this object wraps. */
  20. virtual void setResource(const HResource& resource) = 0;
  21. /** Returns the managed version of this resource. */
  22. MonoObject* getManagedInstance() const;
  23. /**
  24. * Returns a reference wrapper for the provided resource.
  25. *
  26. * @param[in] resource Handle to the resource to retrieve the reference wrapper for.
  27. * @param[in] rttiId Type ID for the resource type to create a RRef for.
  28. */
  29. static MonoObject* getRRef(const HResource& resource, UINT32 rttiId);
  30. /**
  31. * Maps a RTTI ID to a class representing the specified resource type in managed code. Returns null if the ID
  32. * cannot be mapped to a managed resource class.
  33. */
  34. static ::MonoClass* getManagedResourceClass(UINT32 rttiId);
  35. /**
  36. * Returns a RRef<T> type that can be used for wrapping a resource of the type represeented by the provided
  37. * RTTI ID.
  38. */
  39. static ::MonoClass* getRRefClass(UINT32 rttiId);
  40. protected:
  41. friend class ScriptResourceManager;
  42. ScriptResourceBase(MonoObject* instance);
  43. virtual ~ScriptResourceBase();
  44. /**
  45. * Makes the object reference the specific managed instance. Internally this allocates a GC handle that keeps a
  46. * reference to the object and allows getManagedInstance to retrieve the managed instance when requested. Should
  47. * be called on initial creation and whenever the managed instance changes (e.g. after assembly refresh). This
  48. * creates a strong reference to the managed instance, and you need to make sure to release it with
  49. * freeManagedInstance() when no longer required.
  50. */
  51. void setManagedInstance(MonoObject* instance);
  52. /**
  53. * Frees a managed instace assigned with setManagedInstance(). Should be called before the object is destroyed or
  54. * when you changing the managed instance it points to (in order to release the previous instance).
  55. */
  56. void freeManagedInstance();
  57. /**
  58. * Triggered by the script resource managed when the native resource handle this object point to has been destroyed.
  59. */
  60. virtual void notifyResourceDestroyed() { }
  61. /** Destroys the interop object, unless refresh is in progress in which case it is just prepared for re-creation. */
  62. void destroy();
  63. UINT32 mGCHandle;
  64. };
  65. /** Base class for a specific resource's interop object. */
  66. template<class ScriptClass, class ResType, class BaseType = ScriptResourceBase>
  67. class BS_SCR_BE_EXPORT TScriptResource : public ScriptObject <ScriptClass, BaseType>
  68. {
  69. public:
  70. /** Returns a generic handle to the internal wrapped resource. */
  71. HResource getGenericHandle() const override { return mResource; }
  72. /** Sets the internal resource this object wraps. */
  73. void setResource(const HResource& resource) override { mResource = static_resource_cast<ResType>(resource); }
  74. /** Returns a handle to the internal wrapped resource. */
  75. const ResourceHandle<ResType>& getHandle() const { return mResource; }
  76. /** Returns a reference wrapper for this resource. */
  77. MonoObject* getRRef() const
  78. {
  79. return ScriptResourceBase::getRRef(mResource, ResType::getRTTIStatic()->getRTTIId());
  80. }
  81. protected:
  82. friend class ScriptResourceManager;
  83. TScriptResource(MonoObject* instance, const ResourceHandle<ResType>& resource)
  84. :ScriptObject<ScriptClass, BaseType>(instance), mResource(resource)
  85. {
  86. this->setManagedInstance(instance);
  87. }
  88. virtual ~TScriptResource() {}
  89. /** @copydoc ScriptObject::_createManagedInstance */
  90. MonoObject* _createManagedInstance(bool construct) override
  91. {
  92. MonoObject* managedInstance = ScriptClass::metaData.scriptClass->createInstance(construct);
  93. this->setManagedInstance(managedInstance);
  94. return managedInstance;
  95. }
  96. /** @copydoc ScriptObjectBase::_clearManagedInstance */
  97. void _clearManagedInstance() override
  98. {
  99. this->freeManagedInstance();
  100. }
  101. /**
  102. * Triggered by the script resource managed when the native resource handle this object point to has been destroyed.
  103. */
  104. void notifyResourceDestroyed() override
  105. {
  106. this->freeManagedInstance();
  107. }
  108. /** Called when the managed instance gets finalized by the CLR. */
  109. void _onManagedInstanceDeleted(bool assemblyRefresh) override
  110. {
  111. this->freeManagedInstance();
  112. this->destroy();
  113. }
  114. ResourceHandle<ResType> mResource;
  115. };
  116. /** Interop class between C++ & CLR for Resource. */
  117. class BS_SCR_BE_EXPORT ScriptResource : public ScriptObject<ScriptResource, ScriptResourceBase>
  118. {
  119. public:
  120. SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "Resource")
  121. private:
  122. ScriptResource(MonoObject* instance)
  123. :ScriptObject(instance)
  124. { }
  125. /************************************************************************/
  126. /* CLR HOOKS */
  127. /************************************************************************/
  128. static MonoString* internal_getName(ScriptResourceBase* nativeInstance);
  129. static void internal_getUUID(ScriptResourceBase* nativeInstance, UUID* uuid);
  130. static void internal_release(ScriptResourceBase* nativeInstance);
  131. };
  132. /** Interop class between C++ & CLR for UUID. */
  133. class BS_SCR_BE_EXPORT ScriptUUID : public ScriptObject<ScriptUUID>
  134. {
  135. public:
  136. SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "UUID")
  137. /** Unboxes a boxed managed UUID struct and returns the native version of the structure. */
  138. static UUID unbox(MonoObject* obj);
  139. /** Boxes a native UUID struct and returns a managed object containing it. */
  140. static MonoObject* box(const UUID& value);
  141. private:
  142. ScriptUUID(MonoObject* instance);
  143. };
  144. /** @} */
  145. }