LMMS
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) 2021, 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
48namespace Steinberg {
49
50//----------------------------------
51
53
54//------------------------------------------------------------------------
55// Basic FObject - implements FUnknown + IDependent
56//------------------------------------------------------------------------
80//------------------------------------------------------------------------
81class FObject : public IDependent
82{
83public:
84 //------------------------------------------------------------------------
85 FObject () : refCount (1) {}
86 FObject (const FObject&) : refCount (1) {}
87 virtual ~FObject () {}
88 FObject& operator = (const FObject&) { return *this; }
89
90 // OBJECT_METHODS
91 static inline FClassID getFClassID () {return "FObject";}
92 virtual FClassID isA () const {return FObject::getFClassID ();}
93 virtual bool isA (FClassID s) const {return isTypeOf (s, false);}
94 virtual bool isTypeOf (FClassID s, bool /*askBaseClass*/ = true) const {return classIDsEqual (s, FObject::getFClassID ());}
97 FUnknown* unknownCast () {return this;}
98
99 // FUnknown
100 tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) SMTG_OVERRIDE;
101 uint32 PLUGIN_API addRef () SMTG_OVERRIDE;
102 uint32 PLUGIN_API release () SMTG_OVERRIDE;
103
104 // IDependent
105 void PLUGIN_API update (FUnknown* /*changedUnknown*/, int32 /*message*/) SMTG_OVERRIDE {}
107 // IDependency
108 virtual void addDependent (IDependent* dep);
109 virtual void removeDependent (IDependent* dep);
110 virtual void changed (int32 msg = kChanged);
111 virtual void deferUpdate (int32 msg = kChanged);
112 virtual void updateDone (int32 /* msg */) {}
113 virtual bool isEqualInstance (FUnknown* d) {return this == d;}
114
117
118 // static helper functions
119 static inline bool classIDsEqual (FClassID ci1, FClassID ci2);
120 static inline FObject* unknownToObject (FUnknown* unknown);
121
123 static const FUID iid;
124
125//------------------------------------------------------------------------
126protected:
128
130};
131
132
133//------------------------------------------------------------------------
134// conversion from FUnknown to FObject
135//------------------------------------------------------------------------
137{
138 FObject* object = nullptr;
139 if (unknown)
140 {
141 unknown->queryInterface (FObject::iid, (void**)&object);
142 if (object)
143 object->release (); // queryInterface has added ref
144 }
145 return object;
146}
147
148//------------------------------------------------------------------------
150{
151 return (ci1 && ci2) ? (strcmp (ci1, ci2) == 0) : false;
152}
153
154//-----------------------------------------------------------------------
156//-----------------------------------------------------------------------
157template <class C>
158inline C* FCast (const FObject* object)
159{
160 if (object && object->isTypeOf (C::getFClassID (), true))
161 return (C*) object;
162 return 0;
163}
164
165//-----------------------------------------------------------------------
167//-----------------------------------------------------------------------
168template <class C>
169inline C* FCast (FUnknown* unknown)
170{
171 FObject* object = FObject::unknownToObject (unknown);
172 return FCast<C> (object);
173}
174
175//-----------------------------------------------------------------------
177//-----------------------------------------------------------------------
178template <class C>
179inline C* FUCast (FObject* object)
180{
181 return FUnknownPtr<C> (object ? object->unknownCast () : nullptr);
182}
183
184template <class C>
185inline C* FUCast (FUnknown* object)
186{
187 return FUnknownPtr<C> (object);
188}
189
190//------------------------------------------------------------------------
211//-----------------------------------------------------------------------
212template <class I>
213inline void SafeRelease (I *& ptr)
214{
215 if (ptr)
216 {
217 ptr->release ();
218 ptr = 0;
219 }
220}
221
222//-----------------------------------------------------------------------
223template <class I>
224inline void SafeRelease (IPtr<I> & ptr)
225{
226 ptr = 0;
227}
228
229
230//-----------------------------------------------------------------------
231template <class T>
232inline void SafeDelete (T *& ptr)
233{
234 if (ptr)
235 {
236 delete ptr;
237 ptr = 0;
238 }
239}
240
241
242//-----------------------------------------------------------------------
243template <class T>
244inline void AssignShared (T*& dest, T* newPtr)
245{
246 if (dest == newPtr)
247 return;
248
249 if (dest)
250 dest->release ();
251 dest = newPtr;
252 if (dest)
253 dest->addRef ();
254}
255
256//-----------------------------------------------------------------------
257template <class T>
258inline void AssignSharedDependent (IDependent* _this, T*& dest, T* newPtr)
259{
260 if (dest == newPtr)
261 return;
262
263 if (dest)
264 dest->removeDependent (_this);
265 AssignShared (dest, newPtr);
266 if (dest)
267 dest->addDependent (_this);
268}
269
270//-----------------------------------------------------------------------
271template <class T>
272inline void AssignSharedDependent (IDependent* _this, IPtr<T>& dest, T* newPtr)
273{
274 if (dest == newPtr)
275 return;
276
277 if (dest)
278 dest->removeDependent (_this);
279 dest = newPtr;
280 if (dest)
281 dest->addDependent (_this);
282}
283
284//-----------------------------------------------------------------------
285template <class T>
286inline void SafeReleaseDependent (IDependent* _this, T*& dest)
287{
288 if (dest)
289 dest->removeDependent (_this);
290 SafeRelease (dest);
291}
292
293//-----------------------------------------------------------------------
294template <class T>
295inline void SafeReleaseDependent (IDependent* _this, IPtr<T>& dest)
296{
297 if (dest)
298 dest->removeDependent (_this);
299 SafeRelease (dest);
300}
301
302
303//------------------------------------------------------------------------
305namespace Singleton {
307 void registerInstance (FObject** o);
308
310 bool isTerminated ();
311
313 void lockRegister ();
314 void unlockRegister ();
315}
316
317//------------------------------------------------------------------------
318} // namespace Steinberg
319
320//-----------------------------------------------------------------------
321#define SINGLETON(ClassName) \
322 static ClassName* instance (bool create = true) \
323 { \
324 static Steinberg::FObject* inst = nullptr; \
325 if (inst == nullptr && create && Steinberg::Singleton::isTerminated () == false) \
326 { \
327 Steinberg::Singleton::lockRegister (); \
328 if (inst == nullptr) \
329 { \
330 inst = NEW ClassName; \
331 Steinberg::Singleton::registerInstance (&inst); \
332 } \
333 Steinberg::Singleton::unlockRegister (); \
334 } \
335 return (ClassName*)inst; \
336 }
337
338//-----------------------------------------------------------------------
339#define OBJ_METHODS(className, baseClass) \
340 static inline Steinberg::FClassID getFClassID () {return (#className);} \
341 virtual Steinberg::FClassID isA () const SMTG_OVERRIDE {return className::getFClassID ();} \
342 virtual bool isA (Steinberg::FClassID s) const SMTG_OVERRIDE {return isTypeOf (s, false);} \
343 virtual bool isTypeOf (Steinberg::FClassID s, bool askBaseClass = true) const SMTG_OVERRIDE \
344 { return (classIDsEqual (s, #className) ? true : (askBaseClass ? baseClass::isTypeOf (s, true) : false)); }
345
346//------------------------------------------------------------------------
350//------------------------------------------------------------------------
351#define REFCOUNT_METHODS(BaseClass) \
352virtual Steinberg::uint32 PLUGIN_API addRef ()SMTG_OVERRIDE{ return BaseClass::addRef (); } \
353virtual Steinberg::uint32 PLUGIN_API release ()SMTG_OVERRIDE{ return BaseClass::release (); }
354
355//------------------------------------------------------------------------
375//------------------------------------------------------------------------
377//------------------------------------------------------------------------
378#define DEFINE_INTERFACES \
379Steinberg::tresult PLUGIN_API queryInterface (const Steinberg::TUID iid, void** obj) SMTG_OVERRIDE \
380{
381
382//------------------------------------------------------------------------
384//------------------------------------------------------------------------
385#define DEF_INTERFACE(InterfaceName) \
386 QUERY_INTERFACE (iid, obj, InterfaceName::iid, InterfaceName)
387
388//------------------------------------------------------------------------
390//------------------------------------------------------------------------
391#define END_DEFINE_INTERFACES(BaseClass) \
392 return BaseClass::queryInterface (iid, obj); \
393}
394
395
396//------------------------------------------------------------------------
410//------------------------------------------------------------------------
411#define DEF_INTERFACES_1(InterfaceName,BaseClass) \
412DEFINE_INTERFACES \
413DEF_INTERFACE (InterfaceName) \
414END_DEFINE_INTERFACES (BaseClass)
415
416//------------------------------------------------------------------------
417#define DEF_INTERFACES_2(InterfaceName1,InterfaceName2,BaseClass) \
418DEFINE_INTERFACES \
419DEF_INTERFACE (InterfaceName1) \
420DEF_INTERFACE (InterfaceName2) \
421END_DEFINE_INTERFACES (BaseClass)
422
423//------------------------------------------------------------------------
424#define DEF_INTERFACES_3(InterfaceName1,InterfaceName2,InterfaceName3,BaseClass) \
425DEFINE_INTERFACES \
426DEF_INTERFACE (InterfaceName1) \
427DEF_INTERFACE (InterfaceName2) \
428DEF_INTERFACE (InterfaceName3) \
429END_DEFINE_INTERFACES (BaseClass)
430
431//------------------------------------------------------------------------
432#define DEF_INTERFACES_4(InterfaceName1,InterfaceName2,InterfaceName3,InterfaceName4,BaseClass) \
433 DEFINE_INTERFACES \
434 DEF_INTERFACE (InterfaceName1) \
435 DEF_INTERFACE (InterfaceName2) \
436 DEF_INTERFACE (InterfaceName3) \
437 DEF_INTERFACE (InterfaceName4) \
438 END_DEFINE_INTERFACES (BaseClass)
439
440
441//------------------------------------------------------------------------
454#define FUNKNOWN_METHODS(InterfaceName,BaseClass) \
455DEF_INTERFACES_1(InterfaceName,BaseClass) \
456REFCOUNT_METHODS(BaseClass)
457
458#define FUNKNOWN_METHODS2(InterfaceName1,InterfaceName2,BaseClass) \
459DEF_INTERFACES_2(InterfaceName1,InterfaceName2,BaseClass) \
460REFCOUNT_METHODS(BaseClass)
461
462#define FUNKNOWN_METHODS3(InterfaceName1,InterfaceName2,InterfaceName3,BaseClass) \
463DEF_INTERFACES_3(InterfaceName1,InterfaceName2,InterfaceName3,BaseClass) \
464REFCOUNT_METHODS(BaseClass)
465
466#define FUNKNOWN_METHODS4(InterfaceName1,InterfaceName2,InterfaceName3,InterfaceName4,BaseClass) \
467DEF_INTERFACES_4(InterfaceName1,InterfaceName2,InterfaceName3,InterfaceName4,BaseClass) \
468REFCOUNT_METHODS(BaseClass)
469
470
471
472//------------------------------------------------------------------------
473//------------------------------------------------------------------------
474#if COM_COMPATIBLE
475//------------------------------------------------------------------------
488//------------------------------------------------------------------------
489#define IUNKNOWN_REFCOUNT_METHODS(BaseClass) \
490STDMETHOD_ (ULONG, AddRef) (void) {return BaseClass::addRef ();} \
491STDMETHOD_ (ULONG, Release) (void) {return BaseClass::release ();}
492
493//------------------------------------------------------------------------
494#define COM_QUERY_INTERFACE(iid, obj, InterfaceName) \
495if (riid == __uuidof(InterfaceName)) \
496{ \
497 addRef (); \
498 *obj = (InterfaceName*)this; \
499 return kResultOk; \
500}
501
502//------------------------------------------------------------------------
503#define COM_OBJECT_QUERY_INTERFACE(InterfaceName,BaseClass) \
504STDMETHOD (QueryInterface) (REFIID riid, void** object) \
505{ \
506 COM_QUERY_INTERFACE (riid, object, InterfaceName) \
507 return BaseClass::queryInterface ((FIDString)&riid, object); \
508}
509
510//------------------------------------------------------------------------
511#define COM_UNKNOWN_METHODS(InterfaceName,BaseClass) \
512COM_OBJECT_QUERY_INTERFACE(InterfaceName,BaseClass) \
513IUNKNOWN_REFCOUNT_METHODS(BaseClass)
515
516#endif // COM_COMPATIBLE
Definition fobject.h:82
virtual void addDependent(IDependent *dep)
adds dependency to the object
Definition fobject.cpp:92
virtual void removeDependent(IDependent *dep)
removes dependency from the object
Definition fobject.cpp:99
virtual void changed(int32 msg=kChanged)
Inform all dependents, that the object has changed.
Definition fobject.cpp:106
FObject()
default constructor...
Definition fobject.h:85
static bool classIDsEqual(FClassID ci1, FClassID ci2)
compares (evaluates) 2 class IDs
Definition fobject.h:149
static void setUpdateHandler(IUpdateHandler *handler)
set method for the local attribute
Definition fobject.h:115
static const FUID iid
Definition fobject.h:123
uint32 PLUGIN_API addRef() SMTG_OVERRIDE
please refer to FUnknown::addref ()
Definition fobject.cpp:64
virtual void deferUpdate(int32 msg=kChanged)
Similar to triggerUpdates, except only delivered in idle (usefull in collecting updates).
Definition fobject.cpp:115
virtual bool isEqualInstance(FUnknown *d)
Definition fobject.h:113
static FObject * unknownToObject(FUnknown *unknown)
pointer conversion from FUnknown to FObject
Definition fobject.h:136
FObject & operator=(const FObject &)
overloads operator "=" as the reference assignment
Definition fobject.h:88
virtual ~FObject()
destructor...
Definition fobject.h:87
tresult PLUGIN_API queryInterface(const TUID _iid, void **obj) SMTG_OVERRIDE
please refer to FUnknown::queryInterface ()
Definition fobject.cpp:82
static IUpdateHandler * getUpdateHandler()
get method for the local attribute
Definition fobject.h:116
virtual void updateDone(int32)
empty virtual method that should be overridden by derived classes
Definition fobject.h:112
int32 refCount
COM-model local reference count.
Definition fobject.h:127
virtual bool isTypeOf(FClassID s, bool=true) const
evaluates if the passed ID is of the FObject type
Definition fobject.h:94
uint32 PLUGIN_API release() SMTG_OVERRIDE
please refer to FUnknown::release ()
Definition fobject.cpp:70
FObject(const FObject &)
overloaded constructor...
Definition fobject.h:86
int32 getRefCount()
returns the current interface reference count
Definition fobject.h:96
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:105
virtual FClassID isA() const
a local alternative to getFClassID ()
Definition fobject.h:92
static FClassID getFClassID()
return Class ID as an ASCII string (statically)
Definition fobject.h:91
static IUpdateHandler * gUpdateHandler
Definition fobject.h:129
FUnknown * unknownCast()
get FUnknown interface from object
Definition fobject.h:97
virtual bool isA(FClassID s) const
evaluates if the passed ID is of the FObject type
Definition fobject.h:93
Definition funknown.h:233
Definition funknown.h:361
Definition funknown.h:403
Definition iupdatehandler.h:76
@ kChanged
Definition iupdatehandler.h:85
Definition smartpointer.h:44
Definition iupdatehandler.h:41
unsigned d
Definition inflate.c:940
unsigned s
Definition inflate.c:1555
#define SMTG_OVERRIDE
Definition fplatform.h:241
void * object
Definition jmemsys.h:50
const char * msg
Definition missing_descriptor.c:20
void unlockRegister()
Definition fobject.cpp:141
bool isTerminated()
Definition fobject.cpp:133
void lockRegister()
Definition fobject.cpp:135
void registerInstance(FObject **o)
Definition fobject.cpp:146
Definition baseiids.cpp:43
void AssignShared(T *&dest, T *newPtr)
Definition fobject.h:244
void SafeReleaseDependent(IDependent *_this, T *&dest)
Definition fobject.h:286
void SafeDelete(T *&ptr)
Definition fobject.h:232
C * FCast(const FObject *object)
Definition fobject.h:158
int int32
Definition ftypes.h:50
void AssignSharedDependent(IDependent *_this, T *&dest, T *newPtr)
Definition fobject.h:258
int8 TUID[16]
plain UID type
Definition funknown.h:210
void SafeRelease(I *&ptr)
Definition fobject.h:213
const char8 * FIDString
Definition ftypes.h:117
C * FUCast(FObject *object)
Definition fobject.h:179
int32 tresult
Definition ftypes.h:76
FIDString FClassID
Definition fobject.h:52
unsigned int uint32
Definition ftypes.h:51
void handler(int signal)
Definition fileio.c:1632