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 * \author 2023 Falco Girgis
10 * \copyright MIT License
11 */
12#ifndef GIMBAL_PROPERTY_H
13#define GIMBAL_PROPERTY_H
14
15#include "../instances/gimbal_box.h"
16
17/*! \name Type System
18 * \brief UUID and Cast Operators
19 * @{
20 */
21#define GBL_PROPERTY_TYPE (GBL_TYPEID(GblProperty)) //!< Type UUID for GblProperty
22#define GBL_PROPERTY(self) (GBL_CAST(GblProperty, self)) //!< Casts a GblInstance to GblProperty
23#define GBL_PROPERTY_CLASS(klass) (GBL_CLASS_CAST(GblProperty, klass)) //!< Casts a GblClass to GblPropertyClass
24#define GBL_PROPERTY_GET_CLASS(self) (GBL_CLASSOF(GblProperty, self)) //!< Gets a GblPropertyClass from GblInstance
25//! @}
26
27//! Alternate type identifier for GblProperty
28#define GBL_GENERIC_PROPERTY_TYPE GBL_PROPERTY_TYPE
29
30/*! \name Helper DSL
31 * \brief Helper macros for declaration and registration
32 * @{
33 */
34//! Declares a list of properties for the given object/instance structure
35#define GBL_PROPERTIES(object, ...) GBL_PROPERTIES_(object, __VA_ARGS__)
36//! Registeres the list of properties which were declared with GBL_PROPERTIES()
37#define GBL_PROPERTIES_REGISTER(/*object,*/ ...) GBL_PROPERTIES_REGISTER_(__VA_ARGS__)
38//! @}
39
40#define GBL_SELF_TYPE GblProperty
41
43
45
46//! Function signature used as an iterator with GblProperty_foreach()
47typedef GblBool (*GblPropertyIterFn)(const GblProperty* pProp, void* pClosure);
48
49/*! \enum GBL_PROPERTY_FLAG
50 * \brief Flags used to denote property attributes
51 */
53 GBL_PROPERTY_FLAG_CONSTRUCT = 0x1, //!< Property must be given to the constructor
54 GBL_PROPERTY_FLAG_READ = 0x2, //!< Property value can be read
55 GBL_PROPERTY_FLAG_WRITE = 0x4, //!< Property value can be modified
56 GBL_PROPERTY_FLAG_SAVE = 0x8, //!< Property is serialized when saving
57 GBL_PROPERTY_FLAG_LOAD = 0x10, //!< Property is deserialized when loading
58 GBL_PROPERTY_FLAG_ABSTRACT = 0x20, //!< Property must be implemented by deriving type
59 GBL_PROPERTY_FLAG_OVERRIDE = 0x40, //!< Property overrides an existing property
60 GBL_PROPERTY_FLAG_READ_WRITE = 0x6, //!< Property is both readable and writable
61 GBL_PROPERTY_FLAG_SAVE_LOAD = 0x18, //!< Property is both savable and loadable
62 GBL_PROPERTY_FLAG_ALL = 0xffff //!< Mask for all property flags
63};
64
65/*! \struct GblPropertyClass
66 * \extends GblBoxClass
67 * \brief GblClass VTable structure for GblProperty
68 *
69 * GblPropertyClass provides overridable virtual methods which
70 * allow for a derived type to implement type-specific functionality
71 * for a property. This functionality includes:
72 * - additional constructor argument handling
73 * - default value handling
74 * - type checking
75 * - value validation
76 * - (fuzzy) comparisons
77 *
78 * \sa GblProperty
79 */
80GBL_CLASS_DERIVE(GblProperty, GblBox)
81 //! Virtual method invoked during constructor to manage additional, non-default arguments
82 GBL_RESULT (*pFnInitOptionalArgs)(GBL_SELF, size_t argCount, va_list* pVaList);
83 //! Virtual method returning the default value for the property
84 GBL_RESULT (*pFnDefaultValue) (GBL_CSELF, GblVariant* pValue);
85 //! Checks whether a variant is of the right type or can even be accepted as the new property value
86 GBL_RESULT (*pFnCheckValue) (GBL_CSELF, const GblVariant* pValue);
87 //! Updates the variant's value to be within range and a valid value for the given property
88 GBL_RESULT (*pFnValidateValue) (GBL_CSELF, GblVariant* pValue);
89 //! Compares the values of the two given variants to see if they're even different
90 GBL_RESULT (*pFnCompareValues) (GBL_CSELF, const GblVariant* pV1, const GblVariant* pV2, int* pResult);
92
93/*! \struct GblProperty
94 * \extends GblBox
95 * \ingroup meta
96 * \brief Represents a string-indexed member of a GblObject
97 *
98 * GblProperty rerpesents a single GblObject member which can be
99 * dynamically looked-up by a string key, passed to the Gblobject
100 * constructor, or which can be programmatically iterated over.
101 *
102 * \sa GblPropertyClass
103 */
106 GblProperty* pNext;
107 GblType objectType;
109 GblQuark name;
110 size_t id;
111 GblFlags flags;
112 GblType valueType;
114
115GBL_EXPORT GblType GblProperty_type (void) GBL_NOEXCEPT;
116GBL_EXPORT size_t GblProperty_totalCount (void) GBL_NOEXCEPT;
117
118GBL_EXPORT GBL_RESULT GblProperty_install (GblType objType, GblProperty* pProp) GBL_NOEXCEPT;
119GBL_EXPORT GblBool GblProperty_uninstall (GblType objType, const char* pName) GBL_NOEXCEPT;
120GBL_EXPORT GblBool GblProperty_uninstallQuark (GblType objType, GblQuark name) GBL_NOEXCEPT;
121GBL_EXPORT GblBool GblProperty_uninstallAll (GblType objType) GBL_NOEXCEPT;
122
123GBL_EXPORT size_t GblProperty_count (GblType objectType) GBL_NOEXCEPT;
124GBL_EXPORT GblFlags GblProperty_combinedFlags (GblType objectType) GBL_NOEXCEPT;
125
126GBL_EXPORT const GblProperty*
127 GblProperty_find (GblType objectType, const char* pName) GBL_NOEXCEPT;
128GBL_EXPORT const GblProperty*
129 GblProperty_findQuark (GblType objectType, GblQuark name) GBL_NOEXCEPT;
130GBL_EXPORT const GblProperty*
131 GblProperty_next (GblType objectType,
132 const GblProperty* pPrev,
134
135GBL_EXPORT GblBool GblProperty_foreach (GblType objectType,
136 GBL_PROPERTY_FLAG flags,
137 GblPropertyIterFn pFnIt,
138 void* pClosure) GBL_NOEXCEPT;
139// ===== INSTANCE =====
140
141GBL_EXPORT GblProperty* GblProperty_create (GblType derivedType,
142 const char* pName,
143 size_t id,
144 GblFlags flags,
145 size_t optionalArgCount,
146 ...) GBL_NOEXCEPT;
147
148GBL_EXPORT GblProperty* GblProperty_createVaList (GblType derivedType,
149 const char* pName,
150 size_t id,
151 GblFlags flags,
152 size_t optionalArgCount,
153 va_list* pList) GBL_NOEXCEPT;
154
155GBL_EXPORT GBL_RESULT GblProperty_construct (GBL_SELF,
156 GblType derivedType,
157 const char* pName,
158 size_t id,
159 GblFlags flags,
160 size_t optionalArgCount,
161 ...) GBL_NOEXCEPT;
162
163GBL_EXPORT GBL_RESULT GblProperty_constructVaList(GBL_SELF,
164 GblType derivedType,
165 const char* pName,
166 size_t id,
167 GblFlags flags,
168 size_t optionalArgCount,
169 va_list* pList) GBL_NOEXCEPT;
170
171GBL_EXPORT GBL_RESULT GblProperty_createOrConstruct(GblProperty** ppSelf,
172 GblType derivedType,
173 const char* pName,
174 size_t id,
175 GblFlags flags,
176 size_t optionalArgCount,
177 ...) GBL_NOEXCEPT;
178
179GBL_EXPORT GblType GblProperty_objectType (GBL_CSELF) GBL_NOEXCEPT;
180GBL_EXPORT const char* GblProperty_nameString (GBL_CSELF) GBL_NOEXCEPT;
181
182GBL_EXPORT GBL_RESULT GblProperty_defaultValue (GBL_CSELF, GblVariant* pValue) GBL_NOEXCEPT;
183GBL_EXPORT GblBool GblProperty_checkValue (GBL_CSELF, const GblVariant* pValue) GBL_NOEXCEPT;
184GBL_EXPORT GBL_RESULT GblProperty_validateValue (GBL_CSELF, GblVariant* pValue) GBL_NOEXCEPT;
185
186GBL_EXPORT int GblProperty_compareValues (GBL_CSELF,
187 const GblVariant* pV1,
188 const GblVariant* pV2) GBL_NOEXCEPT;
190
191//! \cond
192#define GBL_PROPERTIES_(object, ...)
193 GBL_PROPERTIES_IDS_(object, __VA_ARGS__)
194 GBL_PROPERTIES_REGISTER_DEFINE_(object, __VA_ARGS__)
195
196#define GBL_PROPERTIES_REGISTER_(...)
198
199#define GBL_PROPERTIES_REGISTER_1(object)
200 GBL_PROPERTIES_REGISTER_2(object, NULL)
201
202#define GBL_PROPERTIES_REGISTER_2(object, list)
204 for(size_t p = 0; p < object##_Property_Id_count; ++p) {
205 object##_registerProperty_(p,
206 list? &list[p] : GBL_NULL);
207 }
209
210#define GBL_PROPERTIES_IDS_(object, ...)
211 typedef enum object##_Property_Id_ {
212 GBL_TUPLE_FOREACH(GBL_PROPERTY_ID_, object, (__VA_ARGS__))
213 object##_Property_Id_count
214 } object##_Property_Id_;
215
216#define GBL_PROPERTY_ID_(object, property)
217 GBL_PROPERTY_ID__(object, GBL_EVAL property)
218
219#define GBL_PROPERTY_ID__(...)
220 GBL_PROPERTY_ID___(__VA_ARGS__)
221
222#define GBL_PROPERTY_ID___(object, name, type, flags, ...)
223 object##_Property_Id_##name,
224
225#define GBL_PROPERTIES_REGISTER_DEFINE_(object, ...)
226 GBL_EXPORT GblType object##_type(void) GBL_NOEXCEPT;
227 GBL_INLINE GBL_RESULT object##_registerProperty_(GblEnum id,
228 GblProperty** ppProp) GBL_NOEXCEPT
229 {
230 GBL_CTX_BEGIN(NULL);
231 GblProperty* pProp = ppProp? *ppProp : GBL_NULL;
232 switch(id) {
233 GBL_TUPLE_FOREACH(GBL_PROPERTY_REGISTER_, object, (__VA_ARGS__))
234 default: GBL_CTX_VERIFY(GBL_FALSE, GBL_RESULT_ERROR_INVALID_PROPERTY);
235 }
236 if(pProp) {
237 GBL_CTX_CALL(GblProperty_install(object##_type(), pProp));
238 if(ppProp) *ppProp = pProp;
239 }
240 GBL_CTX_END();
241 }
242
243#define GBL_PROPERTY_REGISTER_(object, property)
244 GBL_PROPERTY_REGISTER__(object, GBL_EVAL property)
245
246#define GBL_PROPERTY_REGISTER__(...)
247 GBL_PROPERTY_REGISTER___(__VA_ARGS__)
248
249#define GBL_PROPERTY_REGISTER___(object, name, type, ...)
250 case object##_Property_Id_##name:
251 GBL_CTX_VERIFY_CALL(GblProperty_createOrConstruct(&pProp,
252 type##_PROPERTY_TYPE,
253 GblQuark_internStatic(GBL_STRINGIFY(name)),
254 id,
255 GBL_PROPERTY_FLAGS_MASK_ GBL_TUPLE_FIRST(__VA_ARGS__),
256 GBL_PROPERTY_VARARGS_((__VA_ARGS__))));
257 break;
258
259#define GBL_PROPERTY_VARARGS_(...)
260 GBL_VA_OVERLOAD_CALL(GBL_PROPERTY_VARARGS_, GBL_VA_OVERLOAD_SUFFIXER_1_N, __VA_ARGS__)
261
262#define GBL_PROPERTY_VARARGS__1(flags)
263 0
264
265#define GBL_PROPERTY_VARARGS__N(...)
266 GBL_NARG __VA_ARGS__ - 1, GBL_TUPLE_REST __VA_ARGS__
267
268#define GBL_PROPERTY_FLAGS_MASK_(...)
269 GBL_MAP(GBL_PROPERTY_FLAGS_MASK__, __VA_ARGS__)0
270
271#define GBL_PROPERTY_FLAGS_MASK__(suffix)
272 GBL_PROPERTY_FLAG_##suffix |
273//! \endcond
274
275#undef GBL_SELF_TYPE
276
277#endif // GIMBAL_PROPERTY_H
#define GBL_CLASS_CAST(cType, klass)
#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:539
#define GBL_CTX_CALL(...)
Definition gimbal_ctx.h:533
#define GBL_CTX_BEGIN(...)
Definition gimbal_ctx.h:561
#define GBL_CTX_END()
Definition gimbal_ctx.h:574
#define GBL_CTX_VERIFY(...)
Definition gimbal_ctx.h:97
#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_CLASSOF(cType, self)
#define GBL_CAST(cType, self)
#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_WRITE
Property value can be modified.
@ GBL_PROPERTY_FLAG_LOAD
Property is deserialized when loading.
@ 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.
#define GBL_PROPERTY_TYPE
Type UUID for GblProperty.
#define GBL_PROPERTIES_REGISTER(...)
Registeres the list of properties which were declared with GBL_PROPERTIES()
#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:51
uintptr_t GblQuark
Uniquely identifiable interned string type.
Represents a string-indexed member of a GblObject.