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
funknown.h
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2// Project : SDK Core
3//
4// Category : SDK Core Interfaces
5// Filename : pluginterfaces/base/funknown.h
6// Created by : Steinberg, 01/2004
7// Description : Basic Interface
8//
9//-----------------------------------------------------------------------------
10// This file is part of a Steinberg SDK. It is subject to the license terms
11// in the LICENSE file found in the top-level directory of this distribution
12// and at www.steinberg.net/sdklicenses.
13// No part of the SDK, including this file, may be copied, modified, propagated,
14// or distributed except according to the terms contained in the LICENSE file.
15//-----------------------------------------------------------------------------
16
17#pragma once
18
22#include <cstring>
23
24#if SMTG_CPP11_STDLIBSUPPORT
25#include <type_traits>
26#endif
27
28//------------------------------------------------------------------------
32//------------------------------------------------------------------------
33// Unique Identifier macros
34//------------------------------------------------------------------------
35
36#if COM_COMPATIBLE
37#define INLINE_UID(l1, l2, l3, l4) \
38{ \
39 (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x000000FF) ), (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x0000FF00) >> 8), \
40 (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x00FF0000) >> 16), (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0xFF000000) >> 24), \
41 (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x00FF0000) >> 16), (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0xFF000000) >> 24), \
42 (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x000000FF) ), (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x0000FF00) >> 8), \
43 (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x00FF0000) >> 16), \
44 (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x000000FF) ), \
45 (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x00FF0000) >> 16), \
46 (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x000000FF) ) \
47}
48#else
49#define INLINE_UID(l1, l2, l3, l4) \
50{ \
51 (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x00FF0000) >> 16), \
52 (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l1) & 0x000000FF) ), \
53 (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x00FF0000) >> 16), \
54 (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l2) & 0x000000FF) ), \
55 (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x00FF0000) >> 16), \
56 (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l3) & 0x000000FF) ), \
57 (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0xFF000000) >> 24), (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x00FF0000) >> 16), \
58 (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x0000FF00) >> 8), (::Steinberg::int8)(((::Steinberg::uint32)(l4) & 0x000000FF) ) \
59}
60#endif
61
62//------------------------------------------------------------------------
63#define DECLARE_UID(name, l1, l2, l3, l4) SMTG_CONSTEXPR14 ::Steinberg::TUID name = INLINE_UID (l1, l2, l3, l4);
64
65//------------------------------------------------------------------------
66#define EXTERN_UID(name) extern const ::Steinberg::TUID name;
67
68#ifdef INIT_CLASS_IID
69#define DECLARE_CLASS_IID(ClassName, l1, l2, l3, l4) \
70 static SMTG_CONSTEXPR14 const ::Steinberg::TUID ClassName##_iid = INLINE_UID (l1, l2, l3, l4); \
71 const ::Steinberg::FUID ClassName::iid (ClassName##_iid);
72#else
73#define DECLARE_CLASS_IID(ClassName, l1, l2, l3, l4) \
74 static SMTG_CONSTEXPR14 const ::Steinberg::TUID ClassName##_iid = INLINE_UID (l1, l2, l3, l4);
75#endif
76
77#define DEF_CLASS_IID(ClassName) const ::Steinberg::FUID ClassName::iid (ClassName##_iid);
78
79#define INLINE_UID_OF(ClassName) ClassName##_iid
80
81#define INLINE_UID_FROM_FUID(x) \
82 INLINE_UID (x.getLong1 (), x.getLong2 (), x.getLong3 (), x.getLong4 ())
83
84//------------------------------------------------------------------------
85// FUnknown implementation macros
86//------------------------------------------------------------------------
87
88#define DECLARE_FUNKNOWN_METHODS \
89public: \
90 virtual ::Steinberg::tresult PLUGIN_API queryInterface (const ::Steinberg::TUID _iid, void** obj) SMTG_OVERRIDE; \
91 virtual ::Steinberg::uint32 PLUGIN_API addRef () SMTG_OVERRIDE; \
92 virtual ::Steinberg::uint32 PLUGIN_API release () SMTG_OVERRIDE; \
93protected : \
94 ::Steinberg::int32 __funknownRefCount; \
95public:
96
97//------------------------------------------------------------------------
98
99#define DELEGATE_REFCOUNT(ClassName) \
100public: \
101 virtual ::Steinberg::uint32 PLUGIN_API addRef () SMTG_OVERRIDE { return ClassName::addRef (); } \
102 virtual ::Steinberg::uint32 PLUGIN_API release () SMTG_OVERRIDE { return ClassName::release (); }
103
104//------------------------------------------------------------------------
105#define IMPLEMENT_REFCOUNT(ClassName) \
106::Steinberg::uint32 PLUGIN_API ClassName::addRef () \
107{ \
108 return ::Steinberg::FUnknownPrivate::atomicAdd (__funknownRefCount, 1); \
109} \
110::Steinberg::uint32 PLUGIN_API ClassName::release () \
111{ \
112 if (::Steinberg::FUnknownPrivate::atomicAdd (__funknownRefCount, -1) == 0) \
113 { \
114 delete this; \
115 return 0; \
116 } \
117 return __funknownRefCount; \
118}
119
120//------------------------------------------------------------------------
121#define FUNKNOWN_CTOR { __funknownRefCount = 1; }
122#if SMTG_FUNKNOWN_DTOR_ASSERT
123#include <cassert>
124#define FUNKNOWN_DTOR { assert (__funknownRefCount == 0); }
125#else
126#define FUNKNOWN_DTOR
127#endif
128
129//------------------------------------------------------------------------
130#define QUERY_INTERFACE(iid, obj, InterfaceIID, InterfaceName) \
131if (::Steinberg::FUnknownPrivate::iidEqual (iid, InterfaceIID)) \
132{ \
133 addRef (); \
134 *obj = static_cast< InterfaceName* >(this); \
135 return ::Steinberg::kResultOk; \
136}
137
138//------------------------------------------------------------------------
139#define IMPLEMENT_QUERYINTERFACE(ClassName, InterfaceName, ClassIID) \
140::Steinberg::tresult PLUGIN_API ClassName::queryInterface (const ::Steinberg::TUID _iid, void** obj)\
141{ \
142 QUERY_INTERFACE (_iid, obj, ::Steinberg::FUnknown::iid, InterfaceName) \
143 QUERY_INTERFACE (_iid, obj, ClassIID, InterfaceName) \
144 *obj = nullptr; \
145 return ::Steinberg::kNoInterface; \
146}
147
148//------------------------------------------------------------------------
149#define IMPLEMENT_FUNKNOWN_METHODS(ClassName,InterfaceName,ClassIID) \
150 IMPLEMENT_REFCOUNT (ClassName) \
151 IMPLEMENT_QUERYINTERFACE (ClassName, InterfaceName, ClassIID)
152
153//------------------------------------------------------------------------
154// Result Codes
155//------------------------------------------------------------------------
156
157namespace Steinberg {
158
159//------------------------------------------------------------------------
160#if COM_COMPATIBLE
161#if SMTG_OS_WINDOWS
162enum
163{
164 kNoInterface = static_cast<tresult>(0x80004002L), // E_NOINTERFACE
165 kResultOk = static_cast<tresult>(0x00000000L), // S_OK
166 kResultTrue = kResultOk,
167 kResultFalse = static_cast<tresult>(0x00000001L), // S_FALSE
168 kInvalidArgument = static_cast<tresult>(0x80070057L), // E_INVALIDARG
169 kNotImplemented = static_cast<tresult>(0x80004001L), // E_NOTIMPL
170 kInternalError = static_cast<tresult>(0x80004005L), // E_FAIL
171 kNotInitialized = static_cast<tresult>(0x8000FFFFL), // E_UNEXPECTED
172 kOutOfMemory = static_cast<tresult>(0x8007000EL) // E_OUTOFMEMORY
173};
174#else
175enum
176{
177 kNoInterface = static_cast<tresult>(0x80000004L), // E_NOINTERFACE
178 kResultOk = static_cast<tresult>(0x00000000L), // S_OK
179 kResultTrue = kResultOk,
180 kResultFalse = static_cast<tresult>(0x00000001L), // S_FALSE
181 kInvalidArgument = static_cast<tresult>(0x80000003L), // E_INVALIDARG
182 kNotImplemented = static_cast<tresult>(0x80000001L), // E_NOTIMPL
183 kInternalError = static_cast<tresult>(0x80000008L), // E_FAIL
184 kNotInitialized = static_cast<tresult>(0x8000FFFFL), // E_UNEXPECTED
185 kOutOfMemory = static_cast<tresult>(0x80000002L) // E_OUTOFMEMORY
186};
187#endif
188#else
189enum
190{
191 kNoInterface = -1,
192 kResultOk,
193 kResultTrue = kResultOk,
194 kResultFalse,
195 kInvalidArgument,
196 kNotImplemented,
197 kInternalError,
198 kNotInitialized,
199 kOutOfMemory
200};
201#endif
202
203//------------------------------------------------------------------------
204typedef int64 LARGE_INT; // obsolete
205
206//------------------------------------------------------------------------
207// FUID class declaration
208//------------------------------------------------------------------------
209typedef char TUID[16];
210
211#if SMTG_CPP14
212//------------------------------------------------------------------------
213inline SMTG_CONSTEXPR14 void copyTUID (char* dst, const char* src)
214{
215 for (auto i = 0; i < 16; ++i)
216 dst[i] = src[i];
217}
218#endif
219
220//------------------------------------------------------------------------
221/* FUnknown private */
222namespace FUnknownPrivate {
223SMTG_ALWAYS_INLINE bool iidEqual (const void* iid1, const void* iid2)
224{
225 const uint64* p1 = reinterpret_cast<const uint64*> (iid1);
226 const uint64* p2 = reinterpret_cast<const uint64*> (iid2);
227 return p1[0] == p2[0] && p1[1] == p2[1];
228}
229
230int32 PLUGIN_API atomicAdd (int32& value, int32 amount);
231}
232
233//------------------------------------------------------------------------
240class FUID
241{
242public:
243//------------------------------------------------------------------------
244 FUID ();
245 FUID (uint32 l1, uint32 l2, uint32 l3, uint32 l4);
246 FUID (const FUID&);
247 virtual ~FUID () {}
248
249#if SMTG_CPP11_STDLIBSUPPORT
250 FUID (FUID&& other);
251 FUID& operator= (FUID&& other);
252#endif
253
257 bool generate ();
258
261 bool isValid () const;
262
263 FUID& operator = (const FUID& f);
264 bool operator == (const FUID& f) const { return ::Steinberg::FUnknownPrivate::iidEqual (data, f.data); }
265 bool operator < (const FUID& f) const { return memcmp (data, f.data, sizeof (TUID)) < 0; }
266 bool operator != (const FUID& f) const { return !::Steinberg::FUnknownPrivate::iidEqual (data, f.data); }
267
268 uint32 getLong1 () const;
269 uint32 getLong2 () const;
270 uint32 getLong3 () const;
271 uint32 getLong4 () const;
272
273 void from4Int (uint32 d1, uint32 d2, uint32 d3, uint32 d4);
274 void to4Int (uint32& d1, uint32& d2, uint32& d3, uint32& d4) const;
275
276 typedef char8 String[33];
277
290 void toString (char8* string) const;
291
295 bool fromString (const char8* string);
296
299 void toRegistryString (char8* string) const;
300
302 bool fromRegistryString (const char8* string);
303
315 void print (int32 style, char8* string = nullptr, size_t stringBufferSize = 0) const;
316
317#if SMTG_CPP17
318 [[deprecated ("Use the print method with the buffer size")]]
319#endif
320 void print (char8* string = nullptr, int32 style = kINLINE_UID) const;
321
322 template <size_t N>
323 inline explicit FUID (const char (&uid)[N])
324 {
325#if SMTG_CPP11_STDLIBSUPPORT
326 static_assert (N == sizeof (TUID), "only TUID allowed");
327#endif
328 memcpy (data, uid, sizeof (TUID));
329 }
330 inline void toTUID (TUID result) const { memcpy (result, data, sizeof (TUID)); }
331 inline operator const TUID& () const { return data; }
332 inline const TUID& toTUID () const { return data; }
333
334 static FUID fromTUID (const TUID uid)
335 {
336 FUID res;
337 if (uid)
338 memcpy (res.data, uid, sizeof (TUID));
339 return res;
340 }
341
342//------------------------------------------------------------------------
343protected:
344 TUID data;
345};
346
347#if SMTG_CPP11_STDLIBSUPPORT
348template <typename T>
349inline bool operator== (const FUID& f1, T f2)
350{
351 static_assert (
353 "Do not compare a FUID with a TUID directly. Either convert the TUID to a FUID and compare them or use FUnknownPrivate::iidEqual");
354 return f1.operator== (f2);
355}
356#endif
357
358//------------------------------------------------------------------------
359// FUnknown
360//------------------------------------------------------------------------
375{
376public:
377
378//------------------------------------------------------------------------
384 virtual tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) = 0;
385
389 virtual uint32 PLUGIN_API addRef () = 0;
390
393 virtual uint32 PLUGIN_API release () = 0;
394
395//------------------------------------------------------------------------
396 static const FUID iid;
397//------------------------------------------------------------------------
398};
399
400
401DECLARE_CLASS_IID (FUnknown, 0x00000000, 0x00000000, 0xC0000000, 0x00000046)
402
403//------------------------------------------------------------------------
404// FUnknownPtr
405//------------------------------------------------------------------------
415template <class I>
416class FUnknownPtr : public IPtr<I>
417{
418public:
419//------------------------------------------------------------------------
420 inline FUnknownPtr (FUnknown* unknown); // query interface
421 inline FUnknownPtr (const FUnknownPtr& p) : IPtr<I> (p) {}
422 inline FUnknownPtr () {}
423
424 inline FUnknownPtr& operator= (const FUnknownPtr& p)
425 {
427 return *this;
428 }
429 inline I* operator= (FUnknown* unknown);
430 inline I* getInterface () { return this->ptr; }
431
432#if SMTG_CPP11_STDLIBSUPPORT
433 inline FUnknownPtr (FUnknownPtr&& p) SMTG_NOEXCEPT : IPtr<I> (std::move (p)) {}
434 inline FUnknownPtr& operator= (FUnknownPtr&& p) SMTG_NOEXCEPT
435 {
436 IPtr<I>::operator= (std::move (p));
437 return *this;
438 }
439#endif
440};
441
442#if SMTG_CPP11_STDLIBSUPPORT
443
444//------------------------------------------------------------------------
445namespace FUnknownPrivate {
446
447template <typename T>
448struct Void : std::false_type
449{
450 using Type = void;
451};
452
453template <typename T>
454using VoidT = typename Void<T>::Type;
455
456//------------------------------------------------------------------------
461template <typename T, typename U = void>
462struct HasIIDType : std::false_type
463{
464};
465
466//------------------------------------------------------------------------
467template <typename T>
468struct HasIIDType<T, FUnknownPrivate::VoidT<typename T::IID>> : std::true_type
469{
470};
471
472//------------------------------------------------------------------------
473} // FUnknownPrivate
474
475//------------------------------------------------------------------------
477template <typename T,
479const TUID& getTUID ()
480{
481 return T::IID::toTUID ();
482}
483
484//------------------------------------------------------------------------
486template <typename T,
488const TUID& getTUID ()
489{
490 return T::iid.toTUID ();
491}
492
493#else // SMTG_CPP11_STDLIBSUPPORT
494
495template<typename T>
496const TUID& getTUID ()
497{
498 return T::iid.toTUID ();
499}
500
501#endif // SMTG_CPP11_STDLIBSUPPORT
502
503//------------------------------------------------------------------------
504template <class I>
505inline FUnknownPtr<I>::FUnknownPtr (FUnknown* unknown)
506{
507 if (unknown && unknown->queryInterface (getTUID<I> (), (void**)&this->ptr) != kResultOk)
508 this->ptr = 0;
509}
510
511//------------------------------------------------------------------------
512template <class I>
513inline I* FUnknownPtr<I>::operator= (FUnknown* unknown)
514{
515 I* newPtr = 0;
516 if (unknown && unknown->queryInterface (getTUID<I> (), (void**)&newPtr) == kResultOk)
517 {
518 OPtr<I> rel (newPtr);
519 return IPtr<I>::operator= (newPtr);
520 }
521
522 return IPtr<I>::operator= (0);
523}
524
525//------------------------------------------------------------------------
526// FReleaser (obsolete)
527//------------------------------------------------------------------------
553{
554 FReleaser (FUnknown* u) : u (u) {}
555 ~FReleaser ()
556 {
557 if (u)
558 u->release ();
559 }
560 FUnknown* u;
561};
562
563//------------------------------------------------------------------------
564} // namespace Steinberg
Handling 16 Byte Globally Unique Identifiers.
Definition funknown.h:241
void toString(char8 *string) const
Converts UID to a string.
Definition funknown.cpp:296
bool fromRegistryString(const char8 *string)
Sets the UID data from a string in Microsoft(R) OLE format.
Definition funknown.cpp:345
bool fromString(const char8 *string)
Sets the UID data from a string.
Definition funknown.cpp:314
bool isValid() const
Checks if the UID data is valid.
Definition funknown.cpp:192
void toRegistryString(char8 *string) const
Converts UID to a string in Microsoft(R) OLE format.
Definition funknown.cpp:383
void print(int32 style, char8 *string=nullptr, size_t stringBufferSize=0) const
Prints the UID to a string (or debug output if string is NULL).
Definition funknown.cpp:420
@ kCLASS_UID
"DECLARE_CLASS_IID (Interface, 0x00000000, 0x00000000, 0x00000000, 0x00000000)"
Definition funknown.h:309
@ kDECLARE_UID
"DECLARE_UID (0x00000000, 0x00000000, 0x00000000, 0x00000000)"
Definition funknown.h:307
@ kINLINE_UID
"INLINE_UID (0x00000000, 0x00000000, 0x00000000, 0x00000000)"
Definition funknown.h:306
@ kFUID
"FUID (0x00000000, 0x00000000, 0x00000000, 0x00000000)"
Definition funknown.h:308
bool generate()
Generates a new Unique Identifier (UID).
Definition funknown.cpp:151
FUnknownPtr - automatic interface conversion and smart pointer in one.
Definition funknown.h:417
The basic interface of all interfaces.
Definition funknown.h:375
virtual uint32 PLUGIN_API addRef()=0
Adds a reference and returns the new reference count.
virtual uint32 PLUGIN_API release()=0
Releases a reference and returns the new reference count.
virtual tresult PLUGIN_API queryInterface(const TUID _iid, void **obj)=0
Query for a pointer to the specified interface.
IPtr - Smart pointer template class.
char TUID[16]
plain UID type
Definition funknown.h:209
memcmp
memcpy
Release an interface using automatic object (obsolete).
Definition funknown.h:553