BsScriptResource.h 5.2 KB

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