JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
fobject.h
Go to the documentation of this file.
1 //------------------------------------------------------------------------
2// Project : SDK Base
3// Version : 1.0
4//
5// Category : Helpers
6// Filename : base/source/fobject.h
7// Created by : Steinberg, 2008
8// Description : Basic Object implementing FUnknown
9//
10//-----------------------------------------------------------------------------
11// LICENSE
12// (c) 2023, 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
38//------------------------------------------------------------------------
41//------------------------------------------------------------------------
42#pragma once
43
46#include "base/source/fdebug.h" // use of NEW
47
48#define SMTG_DEPENDENCY_COUNT DEVELOPMENT
49
50namespace Steinberg {
51
52//----------------------------------
53
54using FClassID = FIDString;
55
56//------------------------------------------------------------------------
57// Basic FObject - implements FUnknown + IDependent
58//------------------------------------------------------------------------
82//------------------------------------------------------------------------
83class FObject : public IDependent
84{
85public:
86 //------------------------------------------------------------------------
87 FObject () = default;
88 FObject (const FObject&)
89 : refCount (1)
90#if SMTG_DEPENDENCY_COUNT
91 , dependencyCount (0)
92#endif
93 {}
94 FObject& operator= (const FObject&) { return *this; }
95 virtual ~FObject ();
96
97 // OBJECT_METHODS
98 static inline FClassID getFClassID () {return "FObject";}
99 virtual FClassID isA () const {return FObject::getFClassID ();}
100 virtual bool isA (FClassID s) const {return isTypeOf (s, false);}
101 virtual bool isTypeOf (FClassID s, bool /*askBaseClass*/ = true) const {return classIDsEqual (s, FObject::getFClassID ());}
103 int32 getRefCount () {return refCount;}
104 FUnknown* unknownCast () {return this;}
105
106 // FUnknown
107 tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) SMTG_OVERRIDE;
108 uint32 PLUGIN_API addRef () SMTG_OVERRIDE;
109 uint32 PLUGIN_API release () SMTG_OVERRIDE;
110
111 // IDependent
112 void PLUGIN_API update (FUnknown* /*changedUnknown*/, int32 /*message*/) SMTG_OVERRIDE {}
114 // IDependency
115 virtual void addDependent (IDependent* dep);
116 virtual void removeDependent (IDependent* dep);
117 virtual void changed (int32 msg = kChanged);
118 virtual void deferUpdate (int32 msg = kChanged);
119 virtual void updateDone (int32 /* msg */) {}
120 virtual bool isEqualInstance (FUnknown* d) {return this == d;}
121
122 static void setUpdateHandler (IUpdateHandler* handler) {gUpdateHandler = handler;}
123 static IUpdateHandler* getUpdateHandler () {return gUpdateHandler;}
124
125 // static helper functions
126 static inline bool classIDsEqual (FClassID ci1, FClassID ci2);
127 static inline FObject* unknownToObject (FUnknown* unknown);
128
130 static const FUID iid;
131
132//------------------------------------------------------------------------
133protected:
134 int32 refCount = 1;
135#if SMTG_DEPENDENCY_COUNT
136 int16 dependencyCount = 0;
137#endif
138 static IUpdateHandler* gUpdateHandler;
139};
140
141
142//------------------------------------------------------------------------
143// conversion from FUnknown to FObject
144//------------------------------------------------------------------------
146{
147 FObject* object = nullptr;
148 if (unknown)
149 {
150 unknown->queryInterface (FObject::iid, (void**)&object);
151 if (object)
152 object->release (); // queryInterface has added ref
153 }
154 return object;
155}
156
157//------------------------------------------------------------------------
158inline bool FObject::classIDsEqual (FClassID ci1, FClassID ci2)
159{
160 return (ci1 && ci2) ? (strcmp (ci1, ci2) == 0) : false;
161}
162
163//-----------------------------------------------------------------------
165//-----------------------------------------------------------------------
166template <class C>
167inline C* FCast (const FObject* object)
168{
169 if (object && object->isTypeOf (C::getFClassID (), true))
170 return (C*) object;
171 return 0;
172}
173
174//-----------------------------------------------------------------------
176//-----------------------------------------------------------------------
177template <class C>
178inline C* FCast (FUnknown* unknown)
179{
180 FObject* object = FObject::unknownToObject (unknown);
181 return FCast<C> (object);
182}
183
184//-----------------------------------------------------------------------
186//-----------------------------------------------------------------------
187template <class C>
188inline C* FUCast (FObject* object)
189{
190 return FUnknownPtr<C> (object ? object->unknownCast () : nullptr);
191}
192
193template <class C>
194inline C* FUCast (FUnknown* object)
195{
196 return FUnknownPtr<C> (object);
197}
198
199//------------------------------------------------------------------------
219
220//-----------------------------------------------------------------------
221template <class I>
222inline void SafeRelease (I *& ptr)
223{
224 if (ptr)
225 {
226 ptr->release ();
227 ptr = 0;
228 }
229}
230
231//-----------------------------------------------------------------------
232template <class I>
233inline void SafeRelease (IPtr<I> & ptr)
234{
235 ptr = 0;
236}
237
238
239//-----------------------------------------------------------------------
240template <class T>
241inline void SafeDelete (T *& ptr)
242{
243 if (ptr)
244 {
245 delete ptr;
246 ptr = 0;
247 }
248}
250
251//-----------------------------------------------------------------------
252template <class T>
253inline void AssignShared (T*& dest, T* newPtr)
254{
255 if (dest == newPtr)
256 return;
257
258 if (dest)
259 dest->release ();
260 dest = newPtr;
261 if (dest)
262 dest->addRef ();
263}
264
265//-----------------------------------------------------------------------
266template <class T>
267inline void AssignSharedDependent (IDependent* _this, T*& dest, T* newPtr)
268{
269 if (dest == newPtr)
270 return;
271
272 if (dest)
273 dest->removeDependent (_this);
274 AssignShared (dest, newPtr);
275 if (dest)
276 dest->addDependent (_this);
277}
278
279//-----------------------------------------------------------------------
280template <class T>
281inline void AssignSharedDependent (IDependent* _this, IPtr<T>& dest, T* newPtr)
282{
283 if (dest == newPtr)
284 return;
285
286 if (dest)
287 dest->removeDependent (_this);
288 dest = newPtr;
289 if (dest)
290 dest->addDependent (_this);
291}
292
293//-----------------------------------------------------------------------
294template <class T>
295inline void SafeReleaseDependent (IDependent* _this, T*& dest)
296{
297 if (dest)
298 dest->removeDependent (_this);
299 SafeRelease (dest);
300}
301
302//-----------------------------------------------------------------------
303template <class T>
304inline void SafeReleaseDependent (IDependent* _this, IPtr<T>& dest)
305{
306 if (dest)
307 dest->removeDependent (_this);
308 SafeRelease (dest);
309}
310
311
312//------------------------------------------------------------------------
314namespace Singleton {
316 void registerInstance (FObject** o);
317
319 bool isTerminated ();
320
322 void lockRegister ();
323 void unlockRegister ();
324}
325
326//------------------------------------------------------------------------
327} // namespace Steinberg
328
329//-----------------------------------------------------------------------
330#define SINGLETON(ClassName) \
331 static ClassName* instance (bool create = true) \
332 { \
333 static Steinberg::FObject* inst = nullptr; \
334 if (inst == nullptr && create && Steinberg::Singleton::isTerminated () == false) \
335 { \
336 Steinberg::Singleton::lockRegister (); \
337 if (inst == nullptr) \
338 { \
339 inst = NEW ClassName; \
340 Steinberg::Singleton::registerInstance (&inst); \
341 } \
342 Steinberg::Singleton::unlockRegister (); \
343 } \
344 return (ClassName*)inst; \
345 }
346
347//-----------------------------------------------------------------------
348#define OBJ_METHODS(className, baseClass) \
349 static inline Steinberg::FClassID getFClassID () {return (#className);} \
350 virtual Steinberg::FClassID isA () const SMTG_OVERRIDE {return className::getFClassID ();} \
351 virtual bool isA (Steinberg::FClassID s) const SMTG_OVERRIDE {return isTypeOf (s, false);} \
352 virtual bool isTypeOf (Steinberg::FClassID s, bool askBaseClass = true) const SMTG_OVERRIDE \
353 { return (FObject::classIDsEqual (s, #className) ? true : (askBaseClass ? baseClass::isTypeOf (s, true) : false)); }
354
355//------------------------------------------------------------------------
359//------------------------------------------------------------------------
360#define REFCOUNT_METHODS(BaseClass) \
361virtual Steinberg::uint32 PLUGIN_API addRef ()SMTG_OVERRIDE{ return BaseClass::addRef (); } \
362virtual Steinberg::uint32 PLUGIN_API release ()SMTG_OVERRIDE{ return BaseClass::release (); }
363
364//------------------------------------------------------------------------
383
384//------------------------------------------------------------------------
386//------------------------------------------------------------------------
387#define DEFINE_INTERFACES \
388Steinberg::tresult PLUGIN_API queryInterface (const Steinberg::TUID iid, void** obj) SMTG_OVERRIDE \
389{
390
391//------------------------------------------------------------------------
393//------------------------------------------------------------------------
394#define DEF_INTERFACE(InterfaceName) \
395 QUERY_INTERFACE (iid, obj, InterfaceName::iid, InterfaceName)
396
397//------------------------------------------------------------------------
399//------------------------------------------------------------------------
400#define END_DEFINE_INTERFACES(BaseClass) \
401 return BaseClass::queryInterface (iid, obj); \
402}
404
405//------------------------------------------------------------------------
418
419//------------------------------------------------------------------------
420#define DEF_INTERFACES_1(InterfaceName,BaseClass) \
421DEFINE_INTERFACES \
422DEF_INTERFACE (InterfaceName) \
423END_DEFINE_INTERFACES (BaseClass)
424
425//------------------------------------------------------------------------
426#define DEF_INTERFACES_2(InterfaceName1,InterfaceName2,BaseClass) \
427DEFINE_INTERFACES \
428DEF_INTERFACE (InterfaceName1) \
429DEF_INTERFACE (InterfaceName2) \
430END_DEFINE_INTERFACES (BaseClass)
431
432//------------------------------------------------------------------------
433#define DEF_INTERFACES_3(InterfaceName1,InterfaceName2,InterfaceName3,BaseClass) \
434DEFINE_INTERFACES \
435DEF_INTERFACE (InterfaceName1) \
436DEF_INTERFACE (InterfaceName2) \
437DEF_INTERFACE (InterfaceName3) \
438END_DEFINE_INTERFACES (BaseClass)
439
440//------------------------------------------------------------------------
441#define DEF_INTERFACES_4(InterfaceName1,InterfaceName2,InterfaceName3,InterfaceName4,BaseClass) \
442 DEFINE_INTERFACES \
443 DEF_INTERFACE (InterfaceName1) \
444 DEF_INTERFACE (InterfaceName2) \
445 DEF_INTERFACE (InterfaceName3) \
446 DEF_INTERFACE (InterfaceName4) \
447 END_DEFINE_INTERFACES (BaseClass)
449
450//------------------------------------------------------------------------
462
463#define FUNKNOWN_METHODS(InterfaceName,BaseClass) \
464DEF_INTERFACES_1(InterfaceName,BaseClass) \
465REFCOUNT_METHODS(BaseClass)
466
467#define FUNKNOWN_METHODS2(InterfaceName1,InterfaceName2,BaseClass) \
468DEF_INTERFACES_2(InterfaceName1,InterfaceName2,BaseClass) \
469REFCOUNT_METHODS(BaseClass)
470
471#define FUNKNOWN_METHODS3(InterfaceName1,InterfaceName2,InterfaceName3,BaseClass) \
472DEF_INTERFACES_3(InterfaceName1,InterfaceName2,InterfaceName3,BaseClass) \
473REFCOUNT_METHODS(BaseClass)
474
475#define FUNKNOWN_METHODS4(InterfaceName1,InterfaceName2,InterfaceName3,InterfaceName4,BaseClass) \
476DEF_INTERFACES_4(InterfaceName1,InterfaceName2,InterfaceName3,InterfaceName4,BaseClass) \
477REFCOUNT_METHODS(BaseClass)
479
480
481//------------------------------------------------------------------------
482//------------------------------------------------------------------------
483#if COM_COMPATIBLE
484//------------------------------------------------------------------------
496
497//------------------------------------------------------------------------
498#define IUNKNOWN_REFCOUNT_METHODS(BaseClass) \
499STDMETHOD_ (ULONG, AddRef) (void) {return BaseClass::addRef ();} \
500STDMETHOD_ (ULONG, Release) (void) {return BaseClass::release ();}
501
502//------------------------------------------------------------------------
503#define COM_QUERY_INTERFACE(iid, obj, InterfaceName) \
504if (riid == __uuidof(InterfaceName)) \
505{ \
506 addRef (); \
507 *obj = (InterfaceName*)this; \
508 return kResultOk; \
509}
510
511//------------------------------------------------------------------------
512#define COM_OBJECT_QUERY_INTERFACE(InterfaceName,BaseClass) \
513STDMETHOD (QueryInterface) (REFIID riid, void** object) \
514{ \
515 COM_QUERY_INTERFACE (riid, object, InterfaceName) \
516 return BaseClass::queryInterface ((FIDString)&riid, object); \
517}
518
519//------------------------------------------------------------------------
520#define COM_UNKNOWN_METHODS(InterfaceName,BaseClass) \
521COM_OBJECT_QUERY_INTERFACE(InterfaceName,BaseClass) \
522IUNKNOWN_REFCOUNT_METHODS(BaseClass)
524
525#endif // COM_COMPATIBLE
Implements FUnknown and IDependent.
Definition fobject.h:84
virtual void addDependent(IDependent *dep)
adds dependency to the object
Definition fobject.cpp:141
FObject()=default
default constructor...
virtual void removeDependent(IDependent *dep)
removes dependency from the object
Definition fobject.cpp:153
virtual void changed(int32 msg=kChanged)
Inform all dependents, that the object has changed.
Definition fobject.cpp:193
static bool classIDsEqual(FClassID ci1, FClassID ci2)
compares (evaluates) 2 class IDs
Definition fobject.h:158
static void setUpdateHandler(IUpdateHandler *handler)
set method for the local attribute
Definition fobject.h:122
static const FUID iid
Special UID that is used to cast an FUnknown pointer to a FObject.
Definition fobject.h:130
uint32 PLUGIN_API addRef() SMTG_OVERRIDE
please refer to FUnknown::addref ()
Definition fobject.cpp:113
virtual void deferUpdate(int32 msg=kChanged)
Similar to triggerUpdates, except only delivered in idle (usefull in collecting updates).
Definition fobject.cpp:202
static FObject * unknownToObject(FUnknown *unknown)
pointer conversion from FUnknown to FObject
Definition fobject.h:145
FObject & operator=(const FObject &)
overloads operator "=" as the reference assignment
Definition fobject.h:94
virtual ~FObject()
destructor...
Definition fobject.cpp:68
tresult PLUGIN_API queryInterface(const TUID _iid, void **obj) SMTG_OVERRIDE
please refer to FUnknown::queryInterface ()
Definition fobject.cpp:131
static IUpdateHandler * getUpdateHandler()
get method for the local attribute
Definition fobject.h:123
virtual void updateDone(int32)
empty virtual method that should be overridden by derived classes
Definition fobject.h:119
int32 refCount
COM-model local reference count.
Definition fobject.h:134
virtual bool isTypeOf(FClassID s, bool=true) const
evaluates if the passed ID is of the FObject type
Definition fobject.h:101
uint32 PLUGIN_API release() SMTG_OVERRIDE
please refer to FUnknown::release ()
Definition fobject.cpp:119
int32 getRefCount()
returns the current interface reference count
Definition fobject.h:103
void PLUGIN_API update(FUnknown *, int32) SMTG_OVERRIDE
empty virtual method that should be overridden by derived classes for data updates upon changes
Definition fobject.h:112
virtual FClassID isA() const
a local alternative to getFClassID ()
Definition fobject.h:99
static FClassID getFClassID()
return Class ID as an ASCII string (statically)
Definition fobject.h:98
FUnknown * unknownCast()
get FUnknown interface from object
Definition fobject.h:104
virtual bool isA(FClassID s) const
evaluates if the passed ID is of the FObject type
Definition fobject.h:100
Handling 16 Byte Globally Unique Identifiers.
Definition funknown.h:241
FUnknownPtr - automatic interface conversion and smart pointer in one.
Definition funknown.h:417
The basic interface of all interfaces.
Definition funknown.h:375
virtual tresult PLUGIN_API queryInterface(const TUID _iid, void **obj)=0
Query for a pointer to the specified interface.
A dependent will get notified about changes of a model.
Host implements dependency handling for plugins.
Debugging tools.
C * FCast(const FObject *object)
FCast overload 1 - FObject to FObject.
Definition fobject.h:167
C * FUCast(FObject *object)
FUCast - casting from FUnknown to Interface.
Definition fobject.h:188
bool isTerminated()
Returns true when singleton instances were already released.
Definition fobject.cpp:219
void lockRegister()
lock and unlock the singleton registration for multi-threading safety
Definition fobject.cpp:224
void registerInstance(FObject **o)
registers an instance (type FObject)
Definition fobject.cpp:236
strcmp