libGimbal 0.1.0
C17-Based Extended Standard Library and Cross-Language Runtime Framework
Loading...
Searching...
No Matches
gimbal_box.h
Go to the documentation of this file.
1/*! \file
2 * \brief GblBox (reference-counted, opaque userdata), and related functions
3 * \ingroup meta
4 *
5 * GblBox represents the most minimal type within the type
6 * system that is still runtime extensible and still offers
7 * everything typically required for an object to have
8 * bindings to another language.
9 *
10 * A GblBox extends GblInstance with:
11 * - Reference counting/shared pointer semantics
12 * - Arbitrary userdata storage corresponding destructors
13 *
14 * \author 2023, 2025 Falco Girgis
15 * \copyright MIT License
16 *
17 * \todo
18 * - GblBoxClass_destructing()?
19 */
20#ifndef GIMBAL_BOX_H
21#define GIMBAL_BOX_H
22
24#include "../ifaces/gimbal_ivariant.h"
25#include "../../containers/gimbal_array_map.h"
26#include "../signals/gimbal_signal.h"
27
28/*! \name Type System
29 * \brief Type UUID and Cast operators.
30 * @{
31 */
32#define GBL_BOX_TYPE GBL_TYPEID(GblBox) //!< GblType UUID of a GblBox
33#define GBL_BOX(self) GBL_CAST(GblBox, self) //!< Casts a GblInstance to GblBox
34#define GBL_BOX_CLASS(klass) GBL_CLASS_CAST(GblBox, klass) //!< Casts a GblClass to GblBoxClass
35#define GBL_BOX_GET_CLASS(self) GBL_CLASSOF(GblBox, self) //!< Gets a GblBoxClass from a GblInstance
36//! @}
37
38/*! \name Reference Management
39 * \brief Macros for convenient lifetime control.
40 * @{
41 */
42#define GBL_REF(box) GblBox_ref(GBL_BOX(box)) //!< Auto-casting convenience macro around GblBox_ref()
43#define GBL_UNREF(box) GblBox_unref(GBL_AS(GblBox, box)) //!< Auto-casting convenience macro around GblBox_unref()
44//! @}
45
46#define GBL_SELF_TYPE GblBox
47
49
51
52/*! \struct GblBoxClass
53 * \extends GblClass
54 * \implements GblIVariantClass
55 * \ingroup meta
56 * \brief GblClass VTable/static data structure for GblBox
57 *
58 * GblBoxClass extends GblClass and implements the GblIVariant
59 * interface for GblVariant container support. It also provides
60 * arbitrary userdata storage at the class-level.
61 *
62 * \sa GblBox
63 */
64GBL_CLASS_BASE(GblBox, GblIVariant)
66 GblArrayMap* pFields; //!< PRIVATE: Internal storage for userdata fields
68
69 //! Virtual method invoked when a GblBox is being destroyed.
70 GBL_RESULT (*pFnDestructor)(GBL_SELF);
72
73/*! \struct GblBox
74 * \extends GblInstance
75 * \implements GblIVariant
76 * \ingroup meta
77 * \brief Minimally bindable GblInstance with reference semantics and opaque userdata
78 *
79 * A GblBox is a GblInstance-derived type which simply adds the bare minimal set of
80 * functionality that is typically required for language bindings and interop. This
81 * includes:
82 * - destructors
83 * - reference counting semantics
84 * - a dictionary for storing arbitrary associated userdata
85 * - interop with GblVariant types
86 * - arbitrary flag bits
87 *
88 * \note
89 * A GblBox is 12 or 20 bytes total (32 or 64 bit respectively).
90 *
91 * \sa GblBoxClass
92 */
93GBL_INSTANCE_BASE(GblBox) // Size (32/64 bit)
94 GBL_PRIVATE_BEGIN // 12/20 Bytes Total
95 GblArrayMap* pFields; //!< PRIVATE: Storage for extended userdata fields
96 volatile uint16_t refCounter; //!< PRIVATE: Atomic reference counter
98 uint16_t contextType : 1, //!< PRIVATE: GblContext type flag \deprecated
99 uint16_t constructedInPlace : 1, //!< PRIVATE: Flag for whether memory is deallocated upon destruction
100 uint16_t finalizing : 1, //!< PRIVATE: Flag for whether the GblBox is being finalized or scheduled to be destructed.
101 uint16_t destructing : 1, //!< PRIVATE: Flag for whether the GblBox's destructor chain has begun to be called.
102 uint16_t derivedFlags : 12 //!< PRIVATE: Extra flags for use in derived classes
103 )
106
107//! \cond
108GBL_SIGNALS(GblBox,
109 (finalize, (GBL_INSTANCE_TYPE, pReceiver)) //!< Emitted just before a box is destroyed.
110)
111//! \endcond
112
113/*! \name Floating Classes
114 * \brief Methods for managing floating classes
115 * @{
116 */
117//! Creates an extended floating class, setting its properties to the given values. Has default values.
118GBL_EXPORT GblBoxClass* GblBoxClass_createFloating (GblType derivedType,
119 size_t size /*=DEFAULT*/,
120 void* pUserdata/*=NULL*/,
121 GblArrayMapDtorFn pFnUdDtor/*=NULL*/) GBL_NOEXCEPT;
122//! Constructs an extended floating class in-place, setting its properties to the given values. Has default values.
123GBL_EXPORT GBL_RESULT GblBoxClass_constructFloating (GBL_KLASS,
124 GblType derivedType,
125 void* pUserdata /*=NULL*/,
126 GblArrayMapDtorFn pFnUdDtor /*=NULL*/) GBL_NOEXCEPT;
127//! @}
128
129/*! \name Userdata
130 * \brief Methods for setting and destroying userdata
131 * \relatesalso GblBoxClass
132 * @{
133 */
134//! Returns the void* userdata pointer that has been associated with the given GblBoxClass
135GBL_EXPORT void* GblBoxClass_userdata (GBL_CKLASS) GBL_NOEXCEPT;
136//! Sets the void* userdata pointer, associating it with the given GblBoxClass
137GBL_EXPORT GBL_RESULT GblBoxClass_setUserdata (GBL_KLASS, void* pUserdata) GBL_NOEXCEPT;
138//! Adds an extra destructor callback to the field list, passing the given class back as the destructed value
139GBL_EXPORT GBL_RESULT GblBoxClass_setUserDestructor (GBL_KLASS,
140 GblArrayMapDtorFn pFnUdDtor) GBL_NOEXCEPT;
141//! @}
142
143/*! \name Fields
144 * \brief Methods for managing extended userdata fields
145 * \relatesalso GblBoxClass
146 * @{
147 */
148//! Returns the generic userdata field value associated with the given key on the class, or 0 if there isn't one
149GBL_EXPORT uintptr_t GblBoxClass_field (GBL_CKLASS, GblQuark key) GBL_NOEXCEPT;
150//! Extracts the generic userdata field value associated with the given key on the class, without destroying it
151GBL_EXPORT uintptr_t GblBoxClass_takeField (GBL_KLASS, GblQuark key) GBL_NOEXCEPT;
152//! Destroys the generic userdata field value associated with the given key on the class, returning GBL_TRUE upon success
153GBL_EXPORT GblBool GblBoxClass_clearField (GBL_KLASS, GblQuark key) GBL_NOEXCEPT;
154//! Returns GBL_TRUE if the given class has generic userdata field value associated with the given key
155GBL_EXPORT GblBool GblBoxClass_hasField (GBL_CKLASS, GblQuark key) GBL_NOEXCEPT;
156//! Sets the generic userdata value and its optional destructor for the given key on the class, destroying the previous value if there was one
157GBL_EXPORT GBL_RESULT GblBoxClass_setField (GBL_KLASS,
158 GblQuark key,
159 uintptr_t ud,
160 GblArrayMapDtorFn pFnDtor/*=NULL*/) GBL_NOEXCEPT;
161//! @}
162
163//! Returns the GblType UUID associated with GblBox
164GBL_EXPORT GblType GblBox_type (void) GBL_NOEXCEPT;
165
166/*! \name Constructors
167 * \brief Overloaded constructors for GblBox
168 * @{
169 */
170//! Creates a GblBox instance of the derived type and returns a pointer to it. Has default arguments.
171GBL_EXPORT GblBox* GblBox_create (GblType derived,
172 size_t size /*=DEFAULT*/,
173 void* pUserdata/*=NULL*/,
174 GblArrayMapDtorFn pFnUdDtor/*=NULL*/,
175 GblBoxClass* pClass /*=NULL*/) GBL_NOEXCEPT;
176//! Constructs a GblBox instance of the derived type in-place, returning a result status code
177GBL_EXPORT GBL_RESULT GblBox_construct (GBL_SELF,
178 GblType derived,
179 void* pUserdata/*=NULL*/,
180 GblArrayMapDtorFn pFnUdDtor/*=NULL*/,
181 GblBoxClass* pClass /*=NULL*/) GBL_NOEXCEPT;
182//! @}
183
184/*! \name Reference Counting
185 * \brief Methods for managing shared reference lifetime
186 * \relatesalso GblBox
187 * @{
188 */
189//! Increments the given GblBox's reference count by 1, returning a pointer to it
190GBL_EXPORT GblBox* GblBox_ref (GBL_SELF) GBL_NOEXCEPT;
191//! Decrements the given GblBox's reference count by 1, destructing it when it hits 0
193//! Returns the number of active references held to the given GblBox
195//! @}
196
197/*! \name Lifetime Management
198 * \brief Methods for querying information about the Box's lifetime.
199 * \relatesalso GblBox
200 * @{
201 */
202//! Returns true of the box's reference count has hit zero and it is going to be destroyed.
203GBL_EXPORT GblBool GblBox_isFinalizing (GBL_CSELF) GBL_NOEXCEPT;
204//! Returns true if the box's destructor chain has already begun to be called, and destruction is in-progress.
205GBL_EXPORT GblBool GblBox_isDestructing (GBL_CSELF) GBL_NOEXCEPT;
206//! @}
207
208/*! \name Userdata
209 * \brief Methods for managing and destroying userdata
210 * \relatesalso GblBox
211 * @{
212 */
213//! Returns the userdata pointer stored within the given GblBox
214GBL_EXPORT void* GblBox_userdata (GBL_CSELF) GBL_NOEXCEPT;
215//! Stores the untyped userdata pointer within the GblBox
216GBL_EXPORT GBL_RESULT GblBox_setUserdata (GBL_SELF, void* pUserdata) GBL_NOEXCEPT;
217//! Sets an additional user destructor to be invoked with the GblBox passed back to it when its being destructed
218GBL_EXPORT GBL_RESULT GblBox_setUserDestructor (GBL_SELF,
219 GblArrayMapDtorFn pFnUdDtor) GBL_NOEXCEPT;
220//! @}
221
222/*! \name Fields
223 * \brief Methods for managing extended userdata fields
224 * \relatesalso GblBox
225 * @{
226 */
227//! Returns the generic userdata field value for the given GblBox associated with the key
228GBL_EXPORT uintptr_t GblBox_field (GBL_CSELF, GblQuark key) GBL_NOEXCEPT;
229//! Extracts the generic userdata field value for the given key, without destroying it
230GBL_EXPORT uintptr_t GblBox_takeField (GBL_SELF, GblQuark key) GBL_NOEXCEPT;
231//! Clears the field value for the given key, if it exists, calling its destructor (if it has one) and returning GBL_TRUE
232GBL_EXPORT GblBool GblBox_clearField (GBL_SELF, GblQuark key) GBL_NOEXCEPT;
233//! Returns GBL_TRUE if there is a field value on the given GblBox corresponding to the key
234GBL_EXPORT GblBool GblBox_hasField (GBL_CSELF, GblQuark key) GBL_NOEXCEPT;
235//! Inserts \p ud into the the GblBox with the given \p key and optional destructor, destroying any overwritten value
236GBL_EXPORT GBL_RESULT GblBox_setField (GBL_SELF,
237 GblQuark key,
238 uintptr_t ud,
239 GblArrayMapDtorFn pFnDtor/*=NULL*/) GBL_NOEXCEPT;
240//! @}
241
242//! \cond
243#define GblBoxClass_createFloating(...)
244 GblBoxClass_createFloatingDefault_(__VA_ARGS__)
245#define GblBoxClass_createFloatingDefault_(...)
246 GblBoxClass_createFloatingDefault__(__VA_ARGS__, 0, GBL_NULL, GBL_NULL)
247#define GblBoxClass_createFloatingDefault__(type, size, ud, dtor, ...)
248 (GblBoxClass_createFloating)(type, size, ud, dtor)
249
250#define GblBoxClass_constructFloating(...)
251 GblBoxClass_constructFloatingDefault_(__VA_ARGS__)
252#define GblBoxClass_constructFloatingDefault_(...)
253 GblBoxClass_constructFloatingDefault__(__VA_ARGS__, GBL_NULL, GBL_NULL)
254#define GblBoxClass_constructFloatingDefault__(klass, type, ud, dtor, ...)
255 (GblBoxClass_constructFloating)(klass, type, ud, dtor)
256
257#define GblBoxClass_setField(...)
258 GblBoxClass_setFieldDefault_(__VA_ARGS__)
259#define GblBoxClass_setFieldDefault_(...)
260 GblBoxClass_setFieldDefault__(__VA_ARGS__, GBL_NULL)
261#define GblBoxClass_setFieldDefault__(klass, key, value, dtor, ...)
262 (GblBoxClass_setField)(klass, key, value, dtor)
263
264#define GblBox_create(...)
265 GblBox_createDefault_(__VA_ARGS__)
266#define GblBox_createDefault_(...)
267 GblBox_createDefault__(__VA_ARGS__, 0, GBL_NULL, GBL_NULL, GBL_NULL)
268#define GblBox_createDefault__(type, size, ud, dtor, klass, ...)
269 (GblBox_create)(type, size, ud, dtor, klass)
270
271#define GblBox_construct(...)
272 GblBox_constructDefault_(__VA_ARGS__)
273#define GblBox_constructDefault_(...)
274 GblBox_constructDefault__(__VA_ARGS__, GBL_NULL, GBL_NULL, GBL_NULL)
275#define GblBox_constructDefault__(self, type, ud, dtor, klass, ...)
276 (GblBox_construct)(self, type, ud, dtor, klass)
277
278#define GblBox_setField(...)
279 GblBox_setFieldDefault_(__VA_ARGS__)
280#define GblBox_setFieldDefault_(...)
281 GblBox_setFieldDefault__(__VA_ARGS__, GBL_NULL)
282#define GblBox_setFieldDefault__(self, key, value, dtor, ...)
283 (GblBox_setField)(self, key, value, dtor)
284//! \endcond
285
287
288#undef GBL_SELF_TYPE
289
290#endif // GIMBAL_BOX_H
#define GBL_BOX(self)
Casts a GblInstance to GblBox.
Definition gimbal_box.h:33
#define GBL_NULL
#define GBL_NOEXCEPT
#define GBL_DECLS_BEGIN
#define GBL_FORWARD_DECLARE_STRUCT(S)
#define GBL_INSTANCE_BASE(instance)
#define GBL_TYPEID(instanceStruct)
#define GBL_CLASS_BASE(...)
#define GBL_PRIVATE_BEGIN
#define GBL_INSTANCE_END
#define GBL_EXPORT
#define GBL_CLASS_END
#define GBL_PRIVATE_END
Private data structure.
#define GBL_BIT_FIELDS(...)
Used to declare an endian-independent group of bitfields.
#define GBL_SIGNALS(instanceStruct,...)
Declares a list of signals to be associated with the given instanceStruct.
uint8_t GblBool
Basic boolean type, standardized to sizeof(char)
uint16_t GblRefCount
Type able to hold a reference counter across the codebase.
uintptr_t GblType
Meta Type UUID.
Definition gimbal_type.h:52
uintptr_t GblQuark
Uniquely identifiable interned string type.
GblArrayMap * pFields
PRIVATE: Internal storage for userdata fields.
Definition gimbal_box.h:66