Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

185 lines
6.0KB

  1. //------------------------------------------------------------------------
  2. // Project : SDK Base
  3. // Version : 1.0
  4. //
  5. // Category : Helpers
  6. // Filename : base/source/fobject.cpp
  7. // Created by : Steinberg, 2008
  8. // Description : Basic Object implementing FUnknown
  9. //
  10. //-----------------------------------------------------------------------------
  11. // LICENSE
  12. // (c) 2019, Steinberg Media Technologies GmbH, All Rights Reserved
  13. //-----------------------------------------------------------------------------
  14. // Redistribution and use in source and binary forms, with or without modification,
  15. // are permitted provided that the following conditions are met:
  16. //
  17. // * Redistributions of source code must retain the above copyright notice,
  18. // this list of conditions and the following disclaimer.
  19. // * Redistributions in binary form must reproduce the above copyright notice,
  20. // this list of conditions and the following disclaimer in the documentation
  21. // and/or other materials provided with the distribution.
  22. // * Neither the name of the Steinberg Media Technologies nor the names of its
  23. // contributors may be used to endorse or promote products derived from this
  24. // software without specific prior written permission.
  25. //
  26. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  27. // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  28. // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  29. // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  30. // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  31. // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  32. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  33. // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  34. // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  35. // OF THE POSSIBILITY OF SUCH DAMAGE.
  36. //-----------------------------------------------------------------------------
  37. #include "base/source/fobject.h"
  38. #include "base/thread/include/flock.h"
  39. #include <vector>
  40. namespace Steinberg {
  41. IUpdateHandler* FObject::gUpdateHandler = 0;
  42. //------------------------------------------------------------------------
  43. const FUID FObject::iid;
  44. //------------------------------------------------------------------------
  45. struct FObjectIIDInitializer
  46. {
  47. // the object iid is always generated so that different components
  48. // only can cast to their own objects
  49. // this initializer must be after the definition of FObject::iid, otherwise
  50. // the default constructor of FUID will clear the generated iid
  51. FObjectIIDInitializer ()
  52. {
  53. const_cast<FUID&> (FObject::iid).generate ();
  54. }
  55. } gFObjectIidInitializer;
  56. //------------------------------------------------------------------------
  57. uint32 PLUGIN_API FObject::addRef ()
  58. {
  59. return FUnknownPrivate::atomicAdd (refCount, 1);
  60. }
  61. //------------------------------------------------------------------------
  62. uint32 PLUGIN_API FObject::release ()
  63. {
  64. if (FUnknownPrivate::atomicAdd (refCount, -1) == 0)
  65. {
  66. refCount = -1000;
  67. delete this;
  68. return 0;
  69. }
  70. return refCount;
  71. }
  72. //------------------------------------------------------------------------
  73. tresult PLUGIN_API FObject::queryInterface (const TUID _iid, void** obj)
  74. {
  75. QUERY_INTERFACE (_iid, obj, FUnknown::iid, FUnknown)
  76. QUERY_INTERFACE (_iid, obj, IDependent::iid, IDependent)
  77. QUERY_INTERFACE (_iid, obj, FObject::iid, FObject)
  78. *obj = 0;
  79. return kNoInterface;
  80. }
  81. //------------------------------------------------------------------------
  82. void FObject::addDependent (IDependent* dep)
  83. {
  84. if (gUpdateHandler)
  85. gUpdateHandler->addDependent (unknownCast (), dep);
  86. }
  87. //------------------------------------------------------------------------
  88. void FObject::removeDependent (IDependent* dep)
  89. {
  90. if (gUpdateHandler)
  91. gUpdateHandler->removeDependent (unknownCast (), dep);
  92. }
  93. //------------------------------------------------------------------------
  94. void FObject::changed (int32 msg)
  95. {
  96. if (gUpdateHandler)
  97. gUpdateHandler->triggerUpdates (unknownCast (), msg);
  98. else
  99. updateDone (msg);
  100. }
  101. //------------------------------------------------------------------------
  102. void FObject::deferUpdate (int32 msg)
  103. {
  104. if (gUpdateHandler)
  105. gUpdateHandler->deferUpdates (unknownCast (), msg);
  106. else
  107. updateDone (msg);
  108. }
  109. //------------------------------------------------------------------------
  110. /** Automatic creation and destruction of singleton instances. */
  111. //------------------------------------------------------------------------
  112. namespace Singleton
  113. {
  114. typedef std::vector<FObject**> ObjectVector;
  115. ObjectVector* singletonInstances = 0;
  116. bool singletonsTerminated = false;
  117. Steinberg::Base::Thread::FLock* singletonsLock;
  118. bool isTerminated () {return singletonsTerminated;}
  119. void lockRegister ()
  120. {
  121. if (!singletonsLock) // assume first call not from multiple threads
  122. singletonsLock = NEW Steinberg::Base::Thread::FLock;
  123. singletonsLock->lock ();
  124. }
  125. void unlockRegister ()
  126. {
  127. singletonsLock->unlock ();
  128. }
  129. void registerInstance (FObject** o)
  130. {
  131. SMTG_ASSERT (singletonsTerminated == false)
  132. if (singletonsTerminated == false)
  133. {
  134. if (singletonInstances == 0)
  135. singletonInstances = NEW std::vector<FObject**>;
  136. singletonInstances->push_back (o);
  137. }
  138. }
  139. struct Deleter
  140. {
  141. ~Deleter ()
  142. {
  143. singletonsTerminated = true;
  144. if (singletonInstances)
  145. {
  146. for (ObjectVector::iterator it = singletonInstances->begin (),
  147. end = singletonInstances->end ();
  148. it != end; ++it)
  149. {
  150. FObject** obj = (*it);
  151. (*obj)->release ();
  152. *obj = 0;
  153. obj = 0;
  154. }
  155. delete singletonInstances;
  156. singletonInstances = 0;
  157. }
  158. delete singletonsLock;
  159. singletonsLock = 0;
  160. }
  161. } deleter;
  162. }
  163. //------------------------------------------------------------------------
  164. } // namespace Steinberg