GSP
Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Support
Contact Us
Online Help
Handbooks
Domain Status
Man Pages

FAQ
Virtual Servers
Pricing
Billing
Technical

Network
Facilities
Connectivity
Topology Map

Miscellaneous
Server Agreement
Year 2038
Credits
 

USA Flag

 

 

Man Pages
AG_OBJECT(3) FreeBSD Library Functions Manual AG_OBJECT(3)

AG_Objectagar object system

#include <agar/core.h>

The Agar object system provides object-oriented programming capabilities (inheritance and virtual functions) as well as serialization, managed timers, abstracted data types and a virtual filesystem (VFS).

Agar objects are organized in a tree structure, which we refer to as the VFS. Any AG_Object can become the root of a VFS. A VFS can be made persistent to the degree required by the application. Agar objects can be serialized to a machine-independent binary format with AG_DataSource(3).

AG_Object *
(AG_Object *parent, const char *name, AG_ObjectClass *classInfo);


void
(AG_Object *obj, AG_ObjectClass *classInfo);


void
(AG_Object *newParent, AG_Object *child);


void
(AG_Object *child);


void
(AG_Object *obj);


void
(AG_Object *obj);


void
(AG_Object *obj);


void
(AG_Object *obj);


void
(AG_Object *obj);


AG_Object *
(AG_Object *obj);


AG_Object *
(AG_Object *obj);


AG_Object *
(AG_Object *vfsRoot, const char *format, ...);


AG_Object *
(AG_Object *vfsRoot, const char *name);


AG_Object *
(AG_Object *obj, const char *name, const char *type);


AG_Object *
(AG_Object *obj, const char *name);


char *
(AG_Object *obj);


int
(AG_Object *obj, char *buf, AG_Size bufSize);


void
(AG_Object *obj, const char *fmt, ...);


void
(AG_Object *obj, const char *name);


void
(AG_Object *obj, AG_ObjectClass *classInfo, char *name, AG_Size nameSize);


void
(AG_Object *obj, const char *prefix, char *name, AG_Size nameSize);


(AG_Object *child, AG_Object *parent, TYPE type);

The () function allocates and initializes a new object instance of the class described by classInfo. The object is attached to parent (unless parent is NULL). If insufficient memory is available, or parent and name are both specified and a child object of the given name already exists then AG_ObjectNew() fails and return NULL.

() initializes an already-allocated instance of the class described by classInfo. It invokes the init() method over each class in the inheritance hierarchy.

The name argument to () and AG_ObjectInit() may be NULL, in which case a unique name (e.g., "object0") will be generated. name may not exceed AG_OBJECT_NAME_MAX characters and must not contain ‘/’. The classInfo argument must point to an initialized AG_ObjectClass structure (see OBJECT CLASSES).

() attaches an object child to another object newParent, raising an ‘attached’ event. It's a no-op if newParent is NULL.

() removes an object child from its parent (if any), cancelling scheduled AG_Timer(3) expirations before raising ‘detached’.

(), AG_ObjectMoveDown(), AG_ObjectMoveToHead() and AG_ObjectMoveToTail() move the object in the parent object's list of child objects. This is useful when the ordering of objects is important.

() calls AG_ObjectDetach() followed by AG_ObjectDestroy().

() returns a pointer to the root of the VFS which the given object is attached to. AG_ObjectParent() returns the object's parent.

The () function returns the object corresponding to the specified path name. If there is no such object it returns NULL.

() returns the first ancestor of the object matching either the name of the object (if name is non-NULL) or the class of the object (if type is non-NULL).

() searches the child objects directly under obj for an object called name. It returns a pointer to the object if found or NULL.

() returns an autoallocated string containing the full pathname of an object (relative to the root of its VFS). If insufficient memory is available to construct the path, it fails and returns NULL.

() copies the object's full pathname (relative to its VFS root) to a fixed-size buffer buf of size bufSize in bytes. Components of the path are separated by the path separator AG_PATHSEP ("/" or "\"). The returned pathname is guaranteed to begin and to end with the path separator. AG_ObjectCopyName() returns 0 on success or -1 if buf is too small to contain the complete path.

() updates the name of the given object. If the object is attached to a VFS then the VFS must be locked.

() generates a unique name for a child object of obj. The class name (converted to lowercase) is used as prefix followed by an integer (starting from 0 and counting up). The generated string is copied to the fixed-size buffer name of size nameSize in bytes. The AG_ObjectGenNamePfx() variant generates a name using the specified prefix instead of the class name.

The () macro iterates child over every child object of parent. The child pointer is cast to type. In Debug builds, an object validity and class-membership test is performed.

void
AG_RegisterClass(AG_ObjectClass *classInfo);


void
(AG_ObjectClass *classInfo);


AG_ObjectClass *
(const char *classSpec, AG_Size objectSize, AG_Size classSize, Uint major, Uint minor);


AG_ObjectInitFn
(AG_ObjectClass *cl, AG_ObjectInitFn fn);


AG_ObjectResetFn
(AG_ObjectClass *cl, AG_ObjectResetFn fn);


AG_ObjectDestroyFn
(AG_ObjectClass *cl, AG_ObjectDestroyFn fn);


AG_ObjectLoadFn
(AG_ObjectClass *cl, AG_ObjectLoadFn fn);


AG_ObjectSaveFn
(AG_ObjectClass *cl, AG_ObjectSaveFn fn);


AG_ObjectEditFn
(AG_ObjectClass *cl, AG_ObjectEditFn fn);


void
(AG_ObjectClass *cl);


void
(const char *name, const char *prefix, const char *url);


void
(const char *name);


AG_ObjectClass *
(const char *classSpec);


AG_ObjectClass *
(const char *classSpec);


void
(const char *path);


void
(const char *path);


int
(AG_Object *obj, const char *pattern);


char *
(const AG_Object *obj, int full);


AG_ObjectClass *
(const AG_Object *obj);


int
(AG_Object *obj, AG_ObjectClass **pHier, int *nHier);


(AG_Object *child, AG_Object *parent, TYPE type, const char *pattern);

The () function registers a new object class. classInfo should be an initialized AG_ObjectClass structure:

typedef struct ag_object_class {
	char hier[AG_OBJECT_HIER_MAX];	/* Full inheritance hierarchy */
	AG_Size size;             	/* Size of instance structure */
	AG_Version ver;          	/* Version numbers */
	void (*init)(void *obj);
	void (*reset)(void *obj);
	void (*destroy)(void *obj);
	int  (*load)(void *obj, AG_DataSource *ds, const AG_Version *ver);
	int  (*save)(void *obj, AG_DataSource *ds);
	void *(*edit)(void *obj);
} AG_ObjectClass;

New methods (and other class-specific data) can be added by overloading AG_ObjectClass. For example, AG_WidgetClass adds GUI-specific methods:

typedef struct ag_widget_class {
	struct ag_object_class _inherit;

	void (*draw)(void *);
	void (*size_request)(void *, AG_SizeReq *);
	/* ... */
} AG_WidgetClass;

The first field hier describes the full inheritance hierarchy. The string "Agar(Widget:Button)" (or "AG_Widget:AG_Button") says that AG_Button is a direct subclass of AG_Widget.

If a class requires dynamically loadable modules (see AG_DSO(3)), the list of modules can be indicated in the hier string by appending "@" and a comma-separated list of library names. For example:

"AG_Widget:MY_Widget@myLib,myOtherLib"

The size member specifies the size in bytes of the object instance structure. ver is an optional datafile version number (see AG_Version(3)).

The () method initializes a new object instance. It's called by AG_ObjectInit() (and AG_ObjectNew() after a successful allocation).

The () method is an optional cleanup routine. It's called by AG_ObjectLoad() before load() and by AG_ObjectDestroy() before destroy().

The () method frees all resources allocated by the object.

The () method reads the serialized state of object obj from data source ds. () saves the state of obj to data source ds. load() and save() must both return 0 on success or -1 on failure. See AG_DataSource(3) and the SERIALIZATION section.

() is an application-specific method. In a typical Agar GUI application edit() may generate and return an AG_Window(3) or an AG_Box(3).

() removes the specified object class.

() provides an alternative interface to the passing of a statically-initialized AG_ObjectClass structure to AG_RegisterClass(). AG_CreateClass() allocates and initializes an AG_ObjectClass structure (or derivative thereof). AG_ClassSetInit(), AG_ClassSetReset(), AG_ClassSetDestroy(), AG_ClassSetLoad(), AG_ClassSetSave() and AG_ClassSetEdit() set the function pointer for the respective method (returning the previous one).

() unregisters and frees an auto-allocated AG_ObjectClass (or derivative thereof).

() registers a new namespace with the specified name, prefix and informational URL. For example, Agar registers its own using:

AG_RegisterNamespace("Agar", "AG_", "https://libagar.org/");

Once the namespace is registered, it is possible to specify inheritance hierarchies using the partitioned format:

Agar(Widget:Button):MyLib(MyButton)

which is equivalent to the conventional format:

AG_Widget:AG_Button:MY_Button

() deletes the specified namespace.

The () function searches for the AG_ObjectClass structure corresponding to the given class The classSpec string can be in conventional or partitioned namespace format (see AG_RegisterNamespace()). If the search is unsuccessful, it returns NULL.

() ensures that the class specified by the classSpec string is registered, possibly loading dynamic libraries if needed. If the class description string includes libraries (e.g., "@lib1,lib2") then the registered modules directories (see AG_RegisterModuleDirectory()) will be scanned and the needed modules loaded automatically.

Library names in class description strings should be bare, without prefix or suffix (the actual filename on disk being platform-dependent). Valid libraries are loaded via AG_DSO(3). The first library must define a ‘myFooClass’ symbol (where ‘myFoo’ is the name of the class transformed from ‘MY_Foo’), which should be a pointer to the AG_ObjectClass describing the object class.

() unregisters the specified class and also decrements the reference count of any dynamically-located module associated with it. If this reference count reaches zero, the module is removed from the current process's address space.

The () function adds the specified directory to the module search path. AG_UnregisterModuleDirectory() removes the specified directory from the search path.

The () function tests whether obj is an instance of the class described by pattern and returns 1 if the object belongs to that class. pattern is a class description string which may include "*" wildcards. For example, "AG_Widget:AG_Button:*" would match the "AG_Button" class or any subclass thereof. The pattern "AG_Widget:AG_Button" would match only the "AG_Button" class but not its subclasses. Fast paths are provided for patterns such as "Super:Sub:*" and "Super:Sub", but general patterns such as "Super:*:Sub:*" are also supported.

() returns a newly-allocated string containing the name of the class of an object obj. If full is 1, return the complete inheritance hierarchy (e.g., "AG_Widget:AG_Button"). Otherwise, return only the subclass (e.g., "AG_Button").

() returns a pointer to the class description structure of the superclass of obj. If obj is an instance of the base AG_Object class then the base class (i.e., agObjectClass returned).

The () function returns into pHier an array of AG_ObjectClass pointers describing the inheritance hierarchy of an object. The size of the array is returned into nHier. If the returned item count is > 0, the returned array should be freed when no longer in use. AG_ObjectGetInheritHier() returns 0 on success or -1 if there is insufficient memory.

The () macro iterates child over every child object of parent which is an instance of the class specified in pattern. The pattern argument is a class description string (that may include "*"). The child variable is cast to type with type checking in Debug builds (and no checking in Release builds).

int
AG_ObjectLoad(AG_Object *obj);


int
(AG_Object *obj, const char *file);


int
(AG_Object *obj, AG_Db *db, const AG_Dbt *key);


int
(AG_Object *obj);


int
(AG_Object *obj, const char *file);


int
(AG_Object *obj);


int
(AG_Object *obj, const char *file);


int
(AG_Object *obj);


int
(AG_Object *obj);


int
(AG_Object *obj, const char *path);


int
(AG_Object *obj, AG_Db *db, const AG_Dbt *key);


int
(AG_Object *obj, AG_DataSource *ds);


int
(AG_Object *obj, AG_DataSource *ds);


int
(AG_DataSource *ds, AG_ObjectHeader *header);

These functions implement serialization, or archiving of the state of an AG_Object to a flat, machine-independent binary format.

The () family of functions load the state of an Agar object from some binary data source. The generic AG_Object part of the object is loaded first, followed by any class-specific serialized data (which is read by invoking the load() function over every class in the inheritance hierarchy).

The (), AG_ObjectLoadGeneric() and AG_ObjectLoadData() functions look for an archive file in the default search path (using the AG_CONFIG_PATH_DATA of AG_Config(3)).

The (), AG_ObjectLoadGenericFromFile() and AG_ObjectLoadDataFromFile() variants attempt to load the object state from a specific file. The AG_ObjectLoadFromDB() variant loads the object state from the given AG_Db(3) database entry.

The () family of functions serialize and save the state of the given object. The generic AG_Object state is written first, followed by the object's serialized data (which is written by invoking the () function of every class in the inheritance hierarchy).

() creates an archive of the object in the default location (the AG_CONFIG_PATH_DATA of AG_Config(3)). The AG_ObjectSaveAll() variant saves the object's children as well as the object itself. AG_ObjectSaveToFile() archives the object to the specified file. AG_ObjectSaveToDB() archives the object to the given AG_Db(3) entry.

The () function writes an archive of the given object to the specified AG_DataSource(3), and AG_ObjectUnserialize() reads an archive of the given object.

The () routine attempts to read the header of a serialized Agar object from a AG_DataSource(3) and returns 0 on success or -1 if no valid header could be read. On success, header information is returned into the header structure:

typedef struct ag_object_header {
	char hier[AG_OBJECT_HIER_MAX];	    /* Inheritance hierarchy */
	char libs[AG_OBJECT_LIBS_MAX];	    /* Library list */
	char classSpec[AG_OBJECT_HIER_MAX]; /* Full class string */
	Uint32 dataOffs;                    /* Dataset offset */
	AG_Version ver;                     /* AG_Object version */
	Uint flags;                         /* Object flags */
} AG_ObjectHeader;

void
AG_ObjectDestroy(AG_Object *obj);


void
(AG_Object *obj);


void
(AG_Object *obj);


void
(AG_Object *obj);


void
(AG_Object *obj);


void
(AG_Object *obj, const char *pattern);


void
(AG_Object *obj, const char *pattern);

() restores the state of an object to some initial state. It invokes the object's reset(), which is expected to bring the object to a consistent state prior to deserialization (before load()).

() frees all resources allocated by an object. It invokes the reset() and destroy() methods over each class in the inheritance hierarchy. AG_ObjectDestroy() also cancels any scheduled AG_Timer(3) expiration. AG_ObjectDestroy() implies AG_ObjectFreeEvents(), AG_ObjectFreeVariables() and AG_ObjectFreeChildren(). Unless AG_OBJECT_STATIC is set, AG_ObjectDestroy() also implies free(3).

() clears all configured event handlers (also cancelling any scheduled timer expirations).

() clears the AG_Variable(3) table of the object.

The () routine invokes AG_ObjectDetach() and AG_ObjectDestroy() over every child object under parent.

() invokes AG_ObjectDetach() and AG_ObjectDestroy() on every child object under parent which is an instance of the class described by pattern (see AG_OfClass(3)). The AG_ObjectFreeChildrenOfTypeLockless() variant assumes obj is locked.

void
AG_ObjectLock(AG_Object *obj);


void
(AG_Object *obj);


void
(AG_Object *obj);


void
(AG_Object *obj);


void
(AG_Object *child);


void
(AG_Object *obj);

() and AG_ObjectUnlock() acquire or release the locking device associated with the given object. This is a mutex protecting all read/write members of the AG_Object structure, except parent, root and the list of child objects cobjs which are all considered part of the virtual filesystem and are instead protected by AG_LockVFS().

The () mutex can be used as a general-purpose locking device which is guaranteed to be held during processing of all events posted to the object as well as during object method such as load() and save().

() and AG_UnlockVFS() acquire or release the lock which protects the layout of the entire VFS which obj is a part of.

Agar is compiled without threads support ("--disable-threads") then (), AG_ObjectUnlock(), AG_LockVFS() and AG_UnlockVFS() are no-ops.

The () call is a variant of AG_ObjectDetach() which assumes that parent and child are locked.

The () call is a variant of AG_ObjectFreeChildren() which assumes that parent and child are locked.

The following public AG_Object flags are defined:

AG_OBJECT_INDESTRUCTIBLE
Application-specific advisory flag.
AG_OBJECT_STATIC
Object is statically allocated (or allocated via a facility other than malloc(3)). Disable use of free(3) by AG_ObjectDestroy().
AG_OBJECT_READONLY
Application-specific advisory flag.
AG_OBJECT_DEBUG
Application-specific debugging flag.
AG_OBJECT_NAME_ONATTACH
Automatically generate a unique name for the object as soon as AG_ObjectAttach() occurs.

The AG_Object mechanism generates the following events:

(AG_Object *parent)
The object has been attached to a new parent.
(AG_Object *parent)
The object has been detached from its parent.
(void)
The object's name has changed.
(const char *path)
Invoked by AG_ObjectLoadData(), on success. If the object was loaded from file, path is the pathname of the file.
(AG_Variable *V)
A new variable binding has been created, or the value of an existing binding has been updated; see AG_Variable(3) for details.

For the AG_ObjectClass structure (see OBJECT CLASSES section):

char *hier
Full inheritance hierarchy.
AG_Size size
Size of instance structure (in bytes).
AG_Version ver
Versioning information (see AG_Version(3)).
void (*init)
Initialization routine.
void (*reset)
Cleanup routine (for ()).
void (*destroy)
Final cleanup routine.
int (*load)
Deserialization routine.
int (*save)
Serialization routine.
void *(*edit)
Application-specific entry point.

The following read-only members are initialized internally:

char *name
The name for this class only.
char *libs
Comma-separated list of DSO modules.
AG_ObjectClass *super
Pointer to the superclass.
TAILQ(AG_ObjectClass) sub
Direct subclasses of this class.

For the AG_Object structure:

char name[AG_OBJECT_NAME_MAX]
Unique (in parent) identifier for this object instance. May not contain ‘/’.
AG_ObjectClass *cls
A pointer to the AG_ObjectClass for this object's class (see OBJECT CLASSES).
Uint flags
Option flags for this object instance (see FLAGS section).
TAILQ(AG_Event) events
Table of registered event handlers (set by AG_SetEvent(3)) and virtual functions (set by ()).
TAILQ(AG_Timer) timers
Active timers (see AG_Timer(3)).
TAILQ(AG_Variable) vars
Named variables (see AG_Variable(3)).
TAILQ(AG_Object) children
Child objects.

The following code initializes a stack-allocated object, prints a message on the debug console and finally destroys the object:

AG_Object myObject;

AG_ObjectInit(&obj, "myObject", &agObjectClass);
Debug(&obj, "Hello, world!\n");
AG_ObjectDestroy(&obj);

The following code creates a VFS representing a document, searches for an element by name and finally destroys the VFS:

AG_Object *doc, *head, *title, *body, *p;
AG_Object *result;

doc   = AG_ObjectNew(NULL, "doc",   &agObjectClass);
head  = AG_ObjectNew(doc,  "head",  &agObjectClass);
title = AG_ObjectNew(head, "title", &agObjectClass);
body  = AG_ObjectNew(doc,  "body",  &agObjectClass);
p     = AG_ObjectNew(body, "p",     &agObjectClass);

result = AG_ObjectFindS(doc, "/doc/head/title");
if (result != NULL) {
	AG_Verbose("Title = %s\n", result->name);
}
AG_ObjectDestroy(doc);

The following code transforms an object's name to upper-case:

void
ObjectNameToUpper(AG_Object *obj)
{
	char name[AG_OBJECT_NAME_MAX], *c;

	if (AG_ObjectCopyName(obj, name,
	    sizeof(name)) == -1) {
		return;
	}
	for (c = name; *c != '\0'; c++) {
		*c = toupper(*c);
	}
	AG_ObjectSetNameS(obj, name);
}

The following code attaches an object to a parent, detaches it and then reattaches it to a different parent:

AG_Object parent1, parent2, child;

AG_ObjectInit(&parent1, NULL, &agObjectClass);
AG_ObjectInit(&parent2, NULL, &agObjectClass);
AG_ObjectInit(&child, NULL, &agObjectClass);

AG_ObjectAttach(&parent1, &child);
AG_ObjectDetach(&child);
AG_ObjectAttach(&parent2, &child);

The following code uses AGOBJECT_FOREACH_CLASS to iterate child over every child object of the parent object which is an instance of "MyClass":

struct my_class *chld;

AGOBJECT_FOREACH_CLASS(chld, parent, my_class, "MyClass") {
	printf("Child %s is an instance of MyClass.\n",
	    AGOBJECT(chld)->name);
}

The following code performs a class-membership test with a pattern:

AG_Button *btn = AG_ButtonNew(NULL, 0, NULL);

if (AG_OfClass(btn, "AG_Widget:AG_Button")) {
	/*
	 * btn is an instance of AG_Button,
	 * and NOT a subclass thereof.
	 */
}
if (AG_OfClass(btn, "AG_Widget:AG_Button:*")) {
	/*
	 * btn is an instance of AG_Button,
	 * OR a subclass thereof.
	 */
}

The following code performs the same class-membership test using the numerical class identifier (as opposed to an AG_OfClass() pattern):

AG_Button *btn = AG_ButtonNew(NULL, 0, NULL);

if (OBJECT(btn)->cid == AGC_BUTTON) {
	/*
	 * btn is an instance of AG_Button,
	 * and NOT a subclass thereof.
	 */
}
if (AG_BUTTON_ISA(btn)) {
	/*
	 * btn is an instance of AG_Button
	 * OR a subclass thereof.
	 */
}

The following code registers a new class "MyClass" and instantiates it:

AG_ObjectClass myClass = {
	"MY_Class",
	sizeof(AG_Object),
	{ 1,0, 1234, 0xE03A },
	NULL,    /* init */
	NULL,    /* reset */
	NULL,    /* destroy */
	NULL,    /* load */
	NULL,    /* save */
	NULL     /* edit */
};

AG_Object *obj;

AG_RegisterClass(&myClass);

obj = AG_ObjectNew(NULL, NULL, &myClass);
Debug(obj, "Hello, world!\n");

AG_ObjectDestroy(obj);

The following code implements a new class "MY_Dummy" which overloads AG_Object with new structure members. It also handles serialization and provides a public interface in C. The public header file follows:

/*
 * Public header file for MY_Dummy (my_dummy.h).
 */
typedef struct my_dummy {
	struct ag_object _inherit; /* AG_Object ->
	                              MY_Dummy */
	Uint flags;
#define MY_DUMMY_OPT1 0x01  /* Some option */
#define MY_DUMMY_OPT2 0x02  /* Another option */
	int x,y;            /* Some integers */
	void *myData;       /* Allocated data */
} MY_Dummy;

extern AG_ObjectClass myDummyClass;
MY_Dummy *_Nullable MY_DummyNew(int, int, Uint);

The implementation follows:

/*
 * Implementation of MY_Dummy (my_dummy.c).
 */
#define MYDATASIZE 1024

MY_Dummy *
MY_DummyNew(int x, int y, Uint flags)
{
	MY_Dummy *d;

	d = AG_TryMalloc(sizeof(MY_Dummy));
	if (d == NULL) {
		return (NULL);
	}
	AG_ObjectInit(d, &mdDummyClass);
	d->x = x;
	d->y = y;
	d->flags = flags;
	return (d);
}

static void
Init(void *_Nonnull obj)
{
	MY_Dummy *d = obj;

	d->flags = 0;
	d->x = 0;
	d->y = 0;
	d->myData = Malloc(MYDATASIZE);
	memset(d->myData, 0, MYDATASIZE);
}

static void
Destroy(void *_Nonnull obj)
{
	MY_Dummy *d = obj;

	free(d->myData);
}

static int
Load(void *_Nonnull obj, AG_DataSource *_Nonnull ds,
    const AG_Version *_Nonnull ver)
{
	MY_Dummy *d = obj;

	d->flags = AG_ReadUint8(ds);
	d->x = (int)AG_ReadUint16(ds);
	d->y = (int)AG_ReadUint16(ds);
	return AG_Read(ds, d->myData, MYDATASIZE);
}

static int
Save(void *_Nonnull obj, AG_DataSource *_Nonnull ds)
{
	MY_Dummy *d = obj;

	AG_WriteUint8(ds, (Uint8)(d->flags));
	AG_WriteUint16(ds, (Uint16)d->x);
	AG_WriteUint16(ds, (Uint16)d->y);
	return AG_Write(ds, d->myData, MYDATASIZE);
}

AG_ObjectClass myDummyClass = {
	"MY_Dummy",
	sizeof(MY_Dummy),
	{ 1,0, 0,0 },
	Init,
	NULL,      /* reset */
	Destroy,
	Load,
	Save,
	NULL       /* edit */
};

The following code maps the "MY_" prefix to a new namespace "MyPackage" and uses it in the class description string classSpec passed to the AG_LookupClass() function:

AG_ObjectClass *C;

AG_RegisterNamespace("MyPackage", "MY_",
    "https://example.com/");

AG_RegisterClass(&myImageViewerClass);

C = AG_LookupClass("Agar(Widget):"
                   "MyPackage(ImageViewer)");
if (C != NULL) {
	AG_Verbose("Found class %s\n", C->name);
	AG_Verbose("Structure size = %d\n", C->size);
}

The following code prints the inheritance hierarchy of an object:

void
PrintInheritHier(AG_Object *obj)
{
	AG_ObjectClass *hier;
	int nHier, i;

	if (AG_ObjectGetInheritHier(obj,
	    &hier, &nHier) != 0) {
		AG_FatalError(NULL);
	}
	AG_Verbose("AG_Object");
	for (i = 0; i < nHier; i++) {
		AG_Verbose(" -> %s",
		    hier[i]->name);
	}
	AG_Verbose("\n");
	AG_Free(hier);
}

The following code loads an object from a file, increments a variable counter and writes back the object to the file:

AG_Object obj;
int counter;

AG_ObjectInit(&obj, NULL, &agObjectClass);
AG_SetInt(&obj, "counter", 0);

if (AG_ObjectLoadFromFile(&obj,
    "test.obj") == -1)
	AG_FatalError(NULL);

counter = AG_GetInt(&obj, "counter");
AG_Debug(&obj, "Counter: %d -> %d\n",
    counter, counter+1);
AG_SetInt(&obj, "counter", counter+1);

AG_ObjectSaveToFile(obj, "test.obj");

The Agar GUI represents user interfaces using a tree of AG_Widget(3) objects attached to a parent AG_Window(3) which is itself attached to some parent AG_Driver(3).

The SG(3) scene-graph structure of Agar-SG is a VFS of SG_Node(3) objects. Non-visible nodes can be paged out to storage, saving memory.

Edacious (https://edacious.hypertriton.com/) represents circuits, components and simulation data using an in-memory VFS. Circuits are saved to a flat binary file which embeds the circuit's serialized data with that of its sub-components (which may include third-party components, in which case AG_Object will autoload any required DSOs).

AG_Event(3), AG_Intro(3), AG_Timer(3), AG_Variable(3)

The AG_Object interface appeared in Agar 1.0. AG_ObjectFreeDataset() was renamed AG_ObjectReset() in Agar 1.6.0. The functions AG_CreateClass(), AG_ClassSetInit(), AG_ClassSetReset(), AG_ClassSetDestroy(), AG_ClassSetLoad(), AG_ClassSetSave(), AG_ClassSetEdit(), AG_DestroyClass() and AG_ObjectGetClassName() appeared in Agar 1.6.0.

December 21, 2022 Agar 1.7

Search for    or go to Top of page |  Section 3 |  Main Index

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with ManDoc.