Overview of classed types.
GblClass
Base struct for all type classes.
A class represents a collection of data that is shared among all instances of a given type. This data is typically in the form of function pointers for modeling overridable methods or regular data for modeling static member variables.
GblClass is the base structure which is to be inherited by all class structures within the meta type system. This means placing it or a type "inheriting" from it as the first member of a class struct, when using C.
- See also
- GblInstance, GblType
Floating Classes
Typically, when you wish to override virtual methods on a class to provide custom functionality, you would need to register a new, derived static type inheriting from the existing type and overriding the desired methods within the class constructor.
This is good for when you need to implement lots of custom state and logic or for when this logic is to be applied to all instances of a class... However, this can be extremely inconvenient and cumbersome when you simply wish to quickly override one or two methods on a single instance.
This is where libGimbal's floating classes come into play. Lets say you wish to quickly create a new GblObject with a custom event handler:
GblIEventHandler* pHandler = GBL_EVENT_HANDLER(pMyObj);
GblIEventHandler_eventNotify(pHandler, NULL);
GblInstance * GblInstance_create(GblType type, size_t publicSize, GblClass *pClass)
Creates and returns an instance, optionally with an extended size and/or non-default class.
#define GBL_OBJECT_TYPE
GblType UUID for GblObject.
Main Object-Oriented Instance with Properties, EventHandlers, and Parenting.
By creating a separate "floating" class, we are able to perform ad-hoc method overriding for a single instance:
pClass->iEventHandlerIFace.pFnEventNotify = my_event_notifier_function_;
GblIEventHandler_eventNotify(GBL_IEVENT_HANDLER(pObj), NULL);
GblClass * GblClass_createFloating(GblType type, size_t size)
Creates a standalone, unowned, "floating" class for the given type, which can override defaults.
GblRefCount GblInstance_destroy(GblInstance *pSelf)
Destructs and deallocates an instance. It must have been created with GblInstance_create().
#define GBL_INSTANCE(self)
Casts GblInstance-compatible to GblInstance.
#define GBL_OBJECT(self)
Casts a GblInstance to a GblObject.
#define GBL_OBJECT_CLASS(klass)
Casts a GblClass to a GblObjectClass.
GblClass structure for GblObject.
- Note
- If we do not "sink" the floating class, then we have to destory it manually, because its lifetime will not yet be bound to the instance. This can actually be useful for allowing you to manually manage the class's lifetime as it's shared among multiple instances.
For extra credit, we can do the same trick with stack-allocated types as well:
pClass->iEventHandlerIFace.pFnEventNotify = my_event_notifier_function_;
GblInstance_constructWithClass(
GBL_INSTANCE(&
object), &klass);
GblIEventHandler_eventNotify(GBL_IEVENT_HANDLER(&object), NULL);
GBL_RESULT GblClass_constructFloating(GblClass *pSelf, GblType type)
Constructs a standalone, unowned, overridable, "floating" class for the given type in-place.
GblRefCount GblInstance_destruct(GblInstance *pSelf)
Destructs but doesn't deallocate an instance. It must have been created with GblInstance_construct().
Class Swizzling
Sometimes you would like to do something similar to the previous example, with ad-hoc virtual method overriding, but the creation of the object is not actually under your control. This is a time for libGimbal's class swizzling, inspired by Objective-C's "is-a" swizzling:
"name", "MyObject",
"userdata", (void*)0xdeadbabe,
NULL);
assert(GblClass_isDefault(GBL_CLASS(pClass));
assert(!GblClass_isOverridden(GBL_CLASS(pClass));
assert(!GblClass_isFloating(GBL_CLASS(pClass));
pClass2->iEventHandlerIFace.pFnEvent = [](GblIEventHandler* pSelf,
GblEvent* pEvent) {
GBL_CTX_BEGIN(NULL);
GBL_CTX_VERBOSE("So %s just sent a %s to a C++ lambda...",
GblEvent_accept(pEvent);
GBL_CTX_END();
};
assert(!GblClass_isDefault(pClass2));
assert(GblClass_isOverridden(pClass2));
assert(!GblClass_isOwned(pClass2));
GblInstance_swizzleClass(
GBL_INSTANCE(pObj), GBL_CLASS(pClass2));
GblIEventHandler_eventNotify(GBL_IEVENT_HANDLER(pObj), pSomeEventObject);
#define GBL_EVENT_TYPE
Returns the GblType for GblEvent.
GBL_RESULT GblInstance_construct(GblInstance *pSelf, GblType type, GblClass *pClass)
Constructs an instance, optionally with a non-default class, returning a result code.
#define GBL_OBJECT_GET_CLASS(self)
Gets a GblObjectClass from a GblInstance.
GblObject * GblObject_create(GblType type,...)
Creates an object-derived type on the heap, intializing it with a NULL-terminated K,...
const char * GblType_name(GblType self)
Returns the type name string associated with the given GblType.
Event base class for use with the event system.