libGimbal 0.1.0
C17-Based Extended Standard Library and Cross-Language Runtime Framework
Loading...
Searching...
No Matches
gimbal_property.h
Go to the documentation of this file.
1/*! \file
2 * \ingroup meta
3 * \brief GblProperty instance, DSL, and management API
4 *
5 * This file contains the type declarations and methods
6 * for GblProperty, the root property instance from
7 * which all other properties are derived.
8 *
9 * Properties are string-keyed values of any data type
10 * which can be added to a GblObject.
11 *
12 * \author 2023, 2025 Falco Girgis
13 * \copyright MIT License
14 */
15#ifndef GIMBAL_PROPERTY_H
16#define GIMBAL_PROPERTY_H
17
18#include "../instances/gimbal_box.h"
19
20/*! \name Type System
21 * \brief UUID and Cast Operators
22 * @{
23 */
24#define GBL_PROPERTY_TYPE (GBL_TYPEID(GblProperty)) //!< Type UUID for GblProperty
25#define GBL_PROPERTY(self) (GBL_CAST(GblProperty, self)) //!< Casts a GblInstance to GblProperty
26#define GBL_PROPERTY_CLASS(klass) (GBL_CLASS_CAST(GblProperty, klass)) //!< Casts a GblClass to GblPropertyClass
27#define GBL_PROPERTY_GET_CLASS(self) (GBL_CLASSOF(GblProperty, self)) //!< Gets a GblPropertyClass from GblInstance
28//! @}
29
30//! Alternate type identifier for GblProperty
31#define GBL_GENERIC_PROPERTY_TYPE GBL_PROPERTY_TYPE
32
33/*! \name Helper DSL
34 * \brief Helper macros for declaration and registration
35 * @{
36 */
37//! Declares a list of properties for the given object/instance structure
38#define GBL_PROPERTIES(object, ...) GBL_PROPERTIES_(object, __VA_ARGS__)
39//! Registers the list of properties which were declared with GBL_PROPERTIES()
40#define GBL_PROPERTIES_REGISTER(/*object,*/ ...) GBL_PROPERTIES_REGISTER_(__VA_ARGS__)
41//! @}
42
43#define GBL_SELF_TYPE GblProperty
44
46
48
49//! Function signature used as an iterator with GblProperty_foreach(), returns GBL_FALSE when iteration should cease.
50typedef GblBool (*GblPropertyIterFn)(const GblProperty* pProp, void* pClosure);
51
52/*! \enum GBL_PROPERTY_FLAG
53 * \brief Flags used to denote property attributes.
54 */
56 GBL_PROPERTY_FLAG_CONSTRUCT = 0x001, //!< Property must be given to the constructor.
57 GBL_PROPERTY_FLAG_READ = 0x002, //!< Property value can be read.
58 GBL_PROPERTY_FLAG_WRITE = 0x004, //!< Property value can be modified.
59 GBL_PROPERTY_FLAG_IN = 0x008, //!< Property assumes ownership of data when writing.
60 GBL_PROPERTY_FLAG_OUT = 0x010, //!< Property releases ownership of data when reading.
61 GBL_PROPERTY_FLAG_SAVE = 0x020, //!< Property is serialized when saving.
62 GBL_PROPERTY_FLAG_LOAD = 0x040, //!< Property is deserialized when loading.
63 GBL_PROPERTY_FLAG_ABSTRACT = 0x080, //!< Property must be implemented by deriving type.
64 GBL_PROPERTY_FLAG_OVERRIDE = 0x100, //!< Property overrides an existing property.
65 GBL_PROPERTY_FLAG_READ_WRITE = 0x006, //!< Property is both readable and writable.
66 GBL_PROPERTY_FLAG_SAVE_LOAD = 0x060, //!< Property is both savable and loadable.
67 GBL_PROPERTY_FLAG_ALL = 0xfff //!< Mask for all property flags combined.
68};
69
70/*! \struct GblPropertyClass
71 * \extends GblBoxClass
72 * \brief GblClass VTable structure for GblProperty
73 *
74 * GblPropertyClass provides overridable virtual methods which
75 * allow for a derived type to implement type-specific functionality
76 * for a property. This functionality includes:
77 * - additional constructor argument handling
78 * - default value handling
79 * - type checking
80 * - value validation
81 * - (fuzzy) comparisons
82 *
83 * \sa GblProperty
84 */
85GBL_CLASS_DERIVE(GblProperty, GblBox)
86 //! Virtual method invoked during constructor to manage additional, non-default arguments
87 GBL_RESULT (*pFnInitOptionalArgs)(GBL_SELF, size_t argCount, va_list* pVaList);
88 //! Virtual method returning the default value for the property
89 GBL_RESULT (*pFnDefaultValue) (GBL_CSELF, GblVariant* pValue);
90 //! Checks whether a variant is of the right type or can even be accepted as the new property value
91 GBL_RESULT (*pFnCheckValue) (GBL_CSELF, const GblVariant* pValue);
92 //! Updates the variant's value to be within range and a valid value for the given property
93 GBL_RESULT (*pFnValidateValue) (GBL_CSELF, GblVariant* pValue);
94 //! Compares the values of the two given variants to see if they're even different
95 GBL_RESULT (*pFnCompareValues) (GBL_CSELF, const GblVariant* pV1, const GblVariant* pV2, int* pResult);
97
98/*! \struct GblProperty
99 * \extends GblBox
100 * \ingroup meta
101 * \brief Represents a string-indexed member of a GblObject
102 *
103 * GblProperty represents a single GblObject member which can be
104 * dynamically looked-up by a string key, passed to the Gblobject
105 * constructor, or which can be programmatically iterated over.
106 *
107 * \sa GblPropertyClass
108 */
111 GblProperty* pNext; //!< Pointer to next property contained by the same type.
112 GblType objectType; //!< UUID of the owning type.
114 GblQuark name; //!< Interned string name of property.
115 size_t id; //!< Integer ID of property.
116 GblFlags flags; //!< Combined flags of property.
117 GblType valueType; //!< Type of the value represented by the property.
119
120//! Returns the UUID associated with the GblProperty type, registering it if it hasn't been already.
122
123/*! \name Management
124 \brief Routines for installing and uninstalling properties.
125 @{
126*/
127//! Installs the given property onto the given type (which must be GblObject compatible).
128GBL_EXPORT GBL_RESULT GblProperty_install (GblType objType, GblProperty* pProp) GBL_NOEXCEPT;
129//! Uninstalls the property with the given name from the given object type.
131//! Uninstalls the property with the given name quark from the given object type.
133//! Uninstalls all properties which were previously installed onto the given object type.
135//! @}
136
137/*! \name Info
138 \brief Querying for miscellaneous property info.
139 @{
140*/
141//! Returns the total number of properties which have been registered onto any GblType.
143//! Returns the number of properties which were explicitly registered to the given type (not including inherited properties).
145//! Returns the combined, bitwise OR'd flags from all properties registered onto the given type.
147//! @}
148
149/*! \name Querying
150 \brief Routines for looking up installed properties.
151 @{
152*/
153//! Looks up the given property by string name which was previously installed onto the given GblObject type.
154GBL_EXPORT const GblProperty* GblProperty_find (GblType objectType, const char* pName) GBL_NOEXCEPT;
155//! Looks up the given property by GblQuark name which was previously installed onto the given GblObject type.
156GBL_EXPORT const GblProperty* GblProperty_findQuark (GblType objectType, GblQuark name) GBL_NOEXCEPT;
157//! @}
158
159/*! \name Iterating
160 \brief Routines for iterating over installed properties.
161 @{
162*/
163//! Returns the next property installed onto the given type, given the current property (or NULL for the first) and the flag mask for which properties to include.
164GBL_EXPORT const GblProperty* GblProperty_next (GblType objectType,
165 const GblProperty* pPrev,
167//! Iterates over the properties installed onto the given type containing any of the given flags, calling the given callback, which gets passed back an optional closure. Returns false if the callback returns false to end iteration.
169 GBL_PROPERTY_FLAG flags,
170 GblPropertyIterFn pFnIt,
171 void* pClosure) GBL_NOEXCEPT;
172//! @}
173
174/*! \name Initializing
175 \brief Routines for creating and constructing new properties.
176 @{
177*/
178//! Creates a new property on the heap with the given type, name, id, flags, and any optional arguments handled by its optional argument initializer.
179GBL_EXPORT GblProperty* GblProperty_create (GblType derivedType,
180 const char* pName,
181 size_t id,
182 GblFlags flags,
183 size_t optionalArgCount,
184 ...) GBL_NOEXCEPT;
185//! Equivalent to GblProperty_create(), except taking a va_list rather than variadic argument list.
187 const char* pName,
188 size_t id,
189 GblFlags flags,
190 size_t optionalArgCount,
191 va_list* pList) GBL_NOEXCEPT;
192//! Constructs a preallocated property with the given type, name, id, flags, and any optional arguments handled by its optional argument initializer.
194 GblType derivedType,
195 const char* pName,
196 size_t id,
197 GblFlags flags,
198 size_t optionalArgCount,
199 ...) GBL_NOEXCEPT;
200//! Equivalent to GblProperty_construct(), except taking a va_list rather than variadic argument list.
202 GblType derivedType,
203 const char* pName,
204 size_t id,
205 GblFlags flags,
206 size_t optionalArgCount,
207 va_list* pList) GBL_NOEXCEPT;
208//! Either calls GblProperty_create() or GblProperty_construct() based on whether ppSelf points to an existing property or not. If not, it will point to a newly created property, upon success, after the function returns.
209GBL_EXPORT GBL_RESULT GblProperty_createOrConstruct (GblProperty** ppSelf,
210 GblType derivedType,
211 const char* pName,
212 size_t id,
213 GblFlags flags,
214 size_t optionalArgCount,
215 ...) GBL_NOEXCEPT;
216//! @}
217
218/*! \name Accessors
219 \brief Routines for accessing internal property data.
220 @{
221*/
222//! Returns the UUID of the type associated with the given property.
224//! Returns the string name of the given property.
226//! @}
227
228/*! \name Methods
229 \brief Routines for calling class methods on properties.
230 @{
231*/
232//! Sets the given variant to contain the default value of the given property, calling GblPropertyClass::pFnDefaultValue().
234//! Checks whether the value contained by the given variant is valid for the given property, calling GblPropertyClass::pFnCeckValue().
236//! Modifies the value contained within the given variant to be a valid value, if possible, calling GblPropertyClass::pFnValidateValue().
238//! Compares the values contained by the given variants, based on the rules of the given property, calling GblPropertyClass::pFnCompareValues().
240 const GblVariant* pV1,
241 const GblVariant* pV2) GBL_NOEXCEPT;
242//! @}
243
245
246//! \cond PRIVATE MACRO IMPLEMENTATIONS
247#define GBL_PROPERTIES_(object, ...)
248 GBL_PROPERTIES_IDS_(object, __VA_ARGS__)
249 GBL_PROPERTIES_REGISTER_DEFINE_(object, __VA_ARGS__)
250
251#define GBL_PROPERTIES_REGISTER_(...)
253
254#define GBL_PROPERTIES_REGISTER_1(object)
255 GBL_PROPERTIES_REGISTER_2(object, NULL)
256
257#define GBL_PROPERTIES_REGISTER_2(object, list)
259 for(size_t p = 0; p < object##_Property_Id_count; ++p) {
260 object##_registerProperty_(p,
261 list? &list[p] : GBL_NULL);
262 }
264
265#define GBL_PROPERTIES_IDS_(object, ...)
266 typedef enum object##_Property_Id_ {
267 GBL_TUPLE_FOREACH(GBL_PROPERTY_ID_, object, (__VA_ARGS__))
268 object##_Property_Id_count
269 } object##_Property_Id_;
270
271#define GBL_PROPERTY_ID_(object, property)
272 GBL_PROPERTY_ID__(object, GBL_EVAL property)
273
274#define GBL_PROPERTY_ID__(...)
275 GBL_PROPERTY_ID___(__VA_ARGS__)
276
277#define GBL_PROPERTY_ID___(object, name, type, flags, ...)
278 object##_Property_Id_##name,
279
280#define GBL_PROPERTIES_REGISTER_DEFINE_(object, ...)
281 GBL_EXPORT GblType object##_type(void) GBL_NOEXCEPT;
282 GBL_INLINE GBL_RESULT object##_registerProperty_(GblEnum id,
283 GblProperty** ppProp) GBL_NOEXCEPT
284 {
285 GBL_CTX_BEGIN(NULL);
286 GblProperty* pProp = ppProp? *ppProp : GBL_NULL;
287 switch(id) {
288 GBL_TUPLE_FOREACH(GBL_PROPERTY_REGISTER_, object, (__VA_ARGS__))
289 default: GBL_CTX_VERIFY(GBL_FALSE, GBL_RESULT_ERROR_INVALID_PROPERTY);
290 }
291 if(pProp) {
292 GBL_CTX_CALL(GblProperty_install(object##_type(), pProp));
293 if(ppProp) *ppProp = pProp;
294 }
295 GBL_CTX_END();
296 }
297
298#define GBL_PROPERTY_REGISTER_(object, property)
299 GBL_PROPERTY_REGISTER__(object, GBL_EVAL property)
300
301#define GBL_PROPERTY_REGISTER__(...)
302 GBL_PROPERTY_REGISTER___(__VA_ARGS__)
303
304#define GBL_PROPERTY_REGISTER___(object, name, type, ...)
305 case object##_Property_Id_##name:
306 GBL_CTX_VERIFY_CALL(GblProperty_createOrConstruct(&pProp,
307 type##_PROPERTY_TYPE,
308 GblQuark_internStatic(GBL_STRINGIFY(name)),
309 id,
310 GBL_PROPERTY_FLAGS_MASK_ GBL_TUPLE_FIRST(__VA_ARGS__),
311 GBL_PROPERTY_VARARGS_((__VA_ARGS__))));
312 break;
313
314#define GBL_PROPERTY_VARARGS_(...)
315 GBL_VA_OVERLOAD_CALL(GBL_PROPERTY_VARARGS_, GBL_VA_OVERLOAD_SUFFIXER_1_N, __VA_ARGS__)
316
317#define GBL_PROPERTY_VARARGS__1(flags)
318 0
319
320#define GBL_PROPERTY_VARARGS__N(...)
321 GBL_NARG __VA_ARGS__ - 1, GBL_TUPLE_REST __VA_ARGS__
322
323#define GBL_PROPERTY_FLAGS_MASK_(...)
324 GBL_MAP(GBL_PROPERTY_FLAGS_MASK__, __VA_ARGS__)0
325
326#define GBL_PROPERTY_FLAGS_MASK__(suffix)
327 GBL_PROPERTY_FLAG_##suffix |
328//! \endcond
329
330#undef GBL_SELF_TYPE
331
332#endif // GIMBAL_PROPERTY_H
#define GBL_STMT_START
#define GBL_NULL
#define GBL_NOEXCEPT
#define GBL_INLINE
#define GBL_STMT_END
#define GBL_CTX_VERIFY_CALL(...)
Definition gimbal_ctx.h:541
#define GBL_CTX_CALL(...)
Definition gimbal_ctx.h:535
#define GBL_CTX_BEGIN(...)
Definition gimbal_ctx.h:563
#define GBL_CTX_END()
Definition gimbal_ctx.h:576
#define GBL_CTX_VERIFY(...)
Definition gimbal_ctx.h:99
#define GBL_DECLS_BEGIN
#define GBL_FORWARD_DECLARE_STRUCT(S)
#define GBL_TYPEID(instanceStruct)
#define GBL_INSTANCE_DERIVE(derivedInstance, baseInstance)
#define GBL_PRIVATE_BEGIN
#define GBL_DECLARE_ENUM(E)
#define GBL_CLASS_DERIVE(...)
#define GBL_INSTANCE_END
#define GBL_EXPORT
#define GBL_CLASS_END
#define GBL_PRIVATE_END
Private data structure.
#define GBL_VA_OVERLOAD_CALL(BASE, SUFFIXER,...)
#define GBL_TUPLE_REST(X,...)
#define GBL_STRINGIFY(a)
#define GBL_TUPLE_FIRST(...)
#define GBL_NARG(...)
#define GBL_TUPLE_FOREACH(MACRO_, DATA_, TUPLE_)
#define GBL_VA_OVERLOAD_SUFFIXER_1_N(...)
#define GBL_VA_OVERLOAD_SUFFIXER_ARGC(...)
#define GBL_MAP(f,...)
Applies the function macro f to each of the remaining parameters.
#define GBL_EVAL(...)
GBL_PROPERTY_FLAG
Flags used to denote property attributes.
@ GBL_PROPERTY_FLAG_READ
Property value can be read.
@ GBL_PROPERTY_FLAG_SAVE_LOAD
Property is both savable and loadable.
@ GBL_PROPERTY_FLAG_ABSTRACT
Property must be implemented by deriving type.
@ GBL_PROPERTY_FLAG_OUT
Property releases ownership of data when reading.
@ GBL_PROPERTY_FLAG_WRITE
Property value can be modified.
@ GBL_PROPERTY_FLAG_LOAD
Property is deserialized when loading.
@ GBL_PROPERTY_FLAG_IN
Property assumes ownership of data when writing.
@ GBL_PROPERTY_FLAG_SAVE
Property is serialized when saving.
@ GBL_PROPERTY_FLAG_CONSTRUCT
Property must be given to the constructor.
@ GBL_PROPERTY_FLAG_OVERRIDE
Property overrides an existing property.
@ GBL_PROPERTY_FLAG_READ_WRITE
Property is both readable and writable.
@ GBL_PROPERTY_FLAG_ALL
Mask for all property flags combined.
GblProperty * GblProperty_create(GblType derivedType, const char *pName, size_t id, GblFlags flags, size_t optionalArgCount,...)
Creates a new property on the heap with the given type, name, id, flags, and any optional arguments h...
#define GBL_PROPERTY_TYPE
Type UUID for GblProperty.
const GblProperty * GblProperty_find(GblType objectType, const char *pName)
Looks up the given property by string name which was previously installed onto the given GblObject ty...
GblFlags GblProperty_combinedFlags(GblType objectType)
Returns the combined, bitwise OR'd flags from all properties registered onto the given type.
GblBool GblProperty_uninstall(GblType objType, const char *pName)
Uninstalls the property with the given name from the given object type.
GblBool GblProperty_uninstallQuark(GblType objType, GblQuark name)
Uninstalls the property with the given name quark from the given object type.
GBL_RESULT GblProperty_defaultValue(const GblProperty *pSelf, GblVariant *pValue)
Sets the given variant to contain the default value of the given property, calling GblPropertyClass::...
GblType GblProperty_objectType(const GblProperty *pSelf)
Returns the UUID of the type associated with the given property.
const GblProperty * GblProperty_next(GblType objectType, const GblProperty *pPrev, GblFlags mask)
Returns the next property installed onto the given type, given the current property (or NULL for the ...
GblBool GblProperty_foreach(GblType objectType, GBL_PROPERTY_FLAG flags, GblPropertyIterFn pFnIt, void *pClosure)
Iterates over the properties installed onto the given type containing any of the given flags,...
GblBool GblProperty_checkValue(const GblProperty *pSelf, const GblVariant *pValue)
Checks whether the value contained by the given variant is valid for the given property,...
int GblProperty_compareValues(const GblProperty *pSelf, const GblVariant *pV1, const GblVariant *pV2)
Compares the values contained by the given variants, based on the rules of the given property,...
GBL_RESULT GblProperty_validateValue(const GblProperty *pSelf, GblVariant *pValue)
Modifies the value contained within the given variant to be a valid value, if possible,...
GblType GblProperty_type(void)
Returns the UUID associated with the GblProperty type, registering it if it hasn't been already.
size_t GblProperty_totalCount(void)
Returns the total number of properties which have been registered onto any GblType.
GBL_RESULT GblProperty_createOrConstruct(GblProperty **ppSelf, GblType derivedType, const char *pName, size_t id, GblFlags flags, size_t optionalArgCount,...)
Either calls GblProperty_create() or GblProperty_construct() based on whether ppSelf points to an exi...
GBL_RESULT GblProperty_constructVaList(GblProperty *pSelf, GblType derivedType, const char *pName, size_t id, GblFlags flags, size_t optionalArgCount, va_list *pList)
Equivalent to GblProperty_construct(), except taking a va_list rather than variadic argument list.
const GblProperty * GblProperty_findQuark(GblType objectType, GblQuark name)
Looks up the given property by GblQuark name which was previously installed onto the given GblObject ...
GBL_RESULT GblProperty_install(GblType objType, GblProperty *pProp)
Installs the given property onto the given type (which must be GblObject compatible).
const char * GblProperty_name(const GblProperty *pSelf)
Returns the string name of the given property.
size_t GblProperty_count(GblType objectType)
Returns the number of properties which were explicitly registered to the given type (not including in...
#define GBL_PROPERTIES_REGISTER(...)
Registers the list of properties which were declared with GBL_PROPERTIES()
GblBool GblProperty_uninstallAll(GblType objType)
Uninstalls all properties which were previously installed onto the given object type.
GblProperty * GblProperty_createVaList(GblType derivedType, const char *pName, size_t id, GblFlags flags, size_t optionalArgCount, va_list *pList)
Equivalent to GblProperty_create(), except taking a va_list rather than variadic argument list.
GBL_RESULT GblProperty_construct(GblProperty *pSelf, GblType derivedType, const char *pName, size_t id, GblFlags flags, size_t optionalArgCount,...)
Constructs a preallocated property with the given type, name, id, flags, and any optional arguments h...
#define GBL_FALSE
uint32_t GblFlags
Standard-sized flags type, 32-bits across platforms.
uint8_t GblBool
Basic boolean type, standardized to sizeof(char)
uintptr_t GblType
Meta Type UUID.
Definition gimbal_type.h:52
uintptr_t GblQuark
Uniquely identifiable interned string type.
Represents a string-indexed member of a GblObject.
GblFlags flags
Combined flags of property.
GblProperty * pNext
Pointer to next property contained by the same type.
GblQuark name
Interned string name of property.
GblType objectType
UUID of the owning type.
GblType valueType
Type of the value represented by the property.
size_t id
Integer ID of property.