AG_OBJECT(3)

NAME
AG_Object - agar object system

SYNOPSIS

    #include <agar/core.h>

DESCRIPTION
The Agar object system provides object-oriented programming functionality (e.g., inheritance, virtual functions) to applications written in different languages (currently C, C++, Objective C, Perl and Ada). Agar objects can be organized into a virtual filesystem (VFS), and the process of archiving (serialization) is tightly integrated in the object system.

INITIALIZATION
AG_Object * AG_ObjectNew(AG_Object *parent, const char *name, AG_ObjectClass *classInfo)

void AG_ObjectInit(AG_Object *obj, AG_ObjectClass *classInfo)

void AG_ObjectInitStatic(AG_Object *obj, AG_ObjectClass *classInfo)

void AG_ObjectInitNamed(AG_Object *obj, AG_ObjectClass *classInfo, const char *name)

void AG_ObjectAttach(AG_Object *new_parent, AG_Object *obj)

void AG_ObjectAttachToNamed(AG_Object *vfsRoot, const char *path, AG_Object *child)

void AG_ObjectDetach(AG_Object *obj)

void AG_ObjectMoveToHead(AG_Object *obj)

void AG_ObjectMoveToTail(AG_Object *obj)

void AG_ObjectMoveUp(AG_Object *obj)

void AG_ObjectMoveDown(AG_Object *obj)

void AG_ObjectDelete(AG_Object *obj)

AG_Object * AG_ObjectRoot(AG_Object *obj)

AG_Object * AG_ObjectParent(AG_Object *obj)

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

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

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

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

char * AG_ObjectGetName(AG_Object *obj)

int AG_ObjectCopyName(AG_Object *obj, char *pathbuf, size_t pathbuf_len)

void AG_ObjectLock(AG_Object *obj)

void AG_ObjectUnlock(AG_Object *obj)

void AG_LockVFS(AG_Object *obj)

void AG_UnlockVFS(AG_Object *obj)

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

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

void AG_ObjectGenName(AG_Object *obj, AG_ObjectClass *classInfo, char *name, size_t len)

void AG_ObjectGenNamePfx(AG_Object *obj, const char *prefix, char *name, size_t len)

void AG_ObjectSetAttachFn(AG_Object *obj, void (*fn)(struct ag_event *), const char *fmt, ...)

void AG_ObjectSetDetachFn(AG_Object *obj, void (*fn)(struct ag_event *), const char *fmt, ...)

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

The AG_ObjectNew() function allocates and initializes a new object instance of the given class. The object is attached to parent, unless the argument is NULL. If name is NULL, a unique name of the form “<class-name> #<number>” is automatically generated. If both parent and name are specified and the parent object already has a child of the given name, AG_ObjectNew() fails and returns NULL.

The AG_ObjectInit() function initializes an object of the specified class. This involves invoking the init() operation associated with every class in the inheritance hierarchy The name argument specifies a name for the object instance relative to its parent (maximum AG_OBJECT_NAME_MAX bytes and must not contain ‘/’ characters). classInfo should point to an initialized AG_ObjectClass structure (see CLASSES section). The flags argument specifies a default set of flags (see FLAGS section).

The AG_ObjectInitStatic() variant of AG_ObjectInit() implicitely sets the AG_OBJECT_STATIC flag (see FLAGS). The AG_ObjectInitNamed() variant either implicitely calls AG_ObjectSetNameS() if the name argument is non-NULL, or it sets the AG_OBJECT_NAME_ONATTACH flag if the name is NULL (see FLAGS section for details).

The function AG_ObjectAttach() attaches an object to a new parent and AG_ObjectDetach() detaches an object from its current parent. These operations raise ‘attached’ and ‘detached’ events. Prior to detaching the object, AG_ObjectDetach() cancels any scheduled AG_Timer(3) callback. If parent is NULL, AG_ObjectAttach() is a no-op.

The AG_ObjectMoveUp(), AG_ObjectMoveDown(), AG_ObjectMoveToHead() and AG_ObjectMoveToTail() functions move the object in the parent object's list of child objects. These functions are useful when the ordering is important - when the child objects represent a stack, for instance.

The AG_ObjectDelete() routine invokes AG_ObjectDetach() if the object is attached to a parent, followed by AG_ObjectDestroy().

AG_ObjectAttachToNamed() is a variant of AG_ObjectAttach() which looks up the parent inside the specified VFS using the pathname path.

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

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

AG_ObjectFindParent() returns the first ancestor of the object matching either the name or type string (whichever is non-NULL).

AG_ObjectFindChild() performs a name lookup on the immediate children of the specified object. The function returns the matching object if it was found, otherwise NULL.

AG_ObjectGetName() returns a newly-allocated string containing the full pathname of an object. The function returns NULL if insufficient memory is available. The AG_ObjectCopyName() function copies the object's pathname to a fixed-size buffer.

AG_ObjectLock() 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(). In most cases, it is best to use the AG_ObjectLock() mutex as a general-purpose locking device for subclasses of AG_Object, because it is guaranteed to be held during processing of events posted to the object, or object operations such as load() and save().

The AG_LockVFS() and AG_UnlockVFS() functions acquire or release the lock protecting the layout of the entire virtual system which the given object is part of.

Note that all lock/unlock functions are turned to no-ops if Agar is compiled without threads support.

AG_ObjectSetName() changes the name of the given object. If the object is attached to a VFS, it is assumed to be locked.

AG_ObjectGenName() generates an object name string unique to the specified parent object obj. The class name is used as prefix, followed by a number. The name is written to the fixed-size buffer name of the given size len. In a multithreaded context, the name is only guaranteed to remain unique as long as the parent object's VFS is locked. Similarly, AG_ObjectGenNamePfx() generates a name using the specified prefix instead of the class name.

AG_ObjectSetAttachFn() and AG_ObjectSetDetachFn() allow custom "attach" and "detach" hooks to be registered. These hooks are used where it is necessary to control the order of the child objects (for example, in the AG_Window(3) system of Agar-GUI, the ordering of window objects is important as it determines the order of rendering). The hook function is expected to insert the child object somewhere into the parent's children list.

The AGOBJECT_FOREACH_CHILD() macro iterates child over every child object of parent. The child pointer is cast to the given structure type, without type checking. Example:

    struct my_class *chld;
    AGOBJECT_FOREACH_CHILD(chld, parent, my_class) {
    	printf("Child object: %s\n", AGOBJECT(chld)->name);
    }

CLASSES
void AG_RegisterClass(AG_ObjectClass *classInfo)

void AG_UnregisterClass(AG_ObjectClass *classInfo)

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

void AG_UnregisterNamespace(const char *name)

AG_ObjectClass * AG_LookupClass(const char *classSpec)

AG_ObjectClass * AG_LoadClass(const char *classSpec)

void AG_RegisterModuleDirectory(const char *path)

void AG_UnregisterModuleDirectory(const char *path)

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

AG_ObjectClass * AG_ObjectSuperclass(AG_Object *obj)

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

void AG_ObjectGetInheritHierString(AG_Object *obj, char *buf, size_t buf_len)

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

The AG_RegisterClass() function registers a new object class. The classInfo argument should point to an AG_ObjectClass structure, with the following members initialized:

    typedef struct ag_object_class {
    	char hier[AG_OBJECT_HIER_MAX];	/* Full class name */
    	size_t size;             	/* Size of instance structure */
    	AG_Version ver;          	/* Version numbers */
    	void (*init)(void *obj);
    	void (*reinit)(void *obj);
    	void (*destroy)(void *obj);
    	int  (*load)(void *obj, AG_DataSource *buf, const AG_Version *ver);
    	int  (*save)(void *obj, AG_DataSource *buf);
    	void *(*edit)(void *obj);
    } AG_ObjectClass;

The AG_ObjectClass structure also contains read-only members which are initialized internally by the object system (see STRUCTURE DATA).

Traditionally, in C, the source file for an Agar object will contain a static initializer for AG_ObjectClass at the end of the file, like so:

    AG_ObjectClass MySomethingClass = {
    	"MySomething",
    	sizeof(MySomething),
    	{ 0,0 },
    	Init,
    	NULL,	/* reinit */
    	NULL,	/* destroy */
    	Load,
    	Save,
    	NULL	/* edit */
    };

Note that it is customary to "overload" AG_ObjectClass structure. For example, the AG_WidgetClass structure of the Agar-GUI library augments AG_ObjectClass with widget-specific operations, and the AG_ObjectClass initializer for a typical Agar widget will look like:

    AG_WidgetClass agButtonClass = {
    	{
    		"Agar(Widget:Button)",
    		sizeof(AG_Button),
    		{ 0,0 },
    		Init,
    		NULL,	/* free */
    		NULL,	/* destroy */
    		NULL,	/* load */
    		NULL,	/* save */
    		NULL	/* edit */
    	},
    	Draw,
    	SizeRequest,
    	SizeAllocate
    };

The hier member of AG_ObjectClass specifies the full class name, in the form “AG_Superclass:AG_Subclass”, or alternatively, “Namespace(Superclass:Subclass)” or “Namespace(Superclass:Subclass)@modules”. If the optional ‘@modules’ string exists, it specifies a comma-separated list of dynamically-linked library (modules) accessible from AG_DSO(3).

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

The init() operation is responsible for initializing a new AG_Object instance.

The optional reinit() function is expected to free any data that was dynamically allocated by the load() routine. The reinit() operation is automatically invoked prior to load(), and before destroy().

The destroy() operation is called from AG_ObjectDestroy() to release any resources which are not handled by reinit() (typically, resources that were allocated in init()). Note that destroy() must not free the AG_Object structure itself as this is already done in AG_ObjectDestroy().

The load() and save() operations are responsible for archiving the dataset (see the ARCHIVING section for more information).

When defined, the edit() operation generates user interface elements allowing the user to edit the object's dataset. It is a generic operation, not dependent on any particular GUI library. If using the Agar-GUI for example, edit() is expected to create a AG_Window(3) or a container widget such as AG_Box(3).

Note that whenever the init(), reinit(), load(), save() and destroy() operations are used, they are invoked for every class in the inheritance hierarchy of the given object.

AG_UnregisterClass() removes the specified object class.

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

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

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

    Agar(Widget:Button):MyLib(MyButton)

or the equivalent expanded format:

    AG_Widget:AG_Button:MY_Button

The AG_UnregisterNamespace() function removes all information about the specified namespace.

The AG_LookupClass() function looks up the AG_ObjectClass structure describing the specified class (in namespace or expanded format). If there is no currently registered class matching the specification, AG_LookupClass() returns NULL.

AG_LoadClass() ensures that the object class specified in classSpec (see AG_RegisterClass() for details on the format) is registered, possibly loading one or more dynamic library files if they are specified in the string. Dynamic library dependencies are given in the form of a terminating ‘@lib1,lib2,...’ string. AG_LoadClass() scans the registered module directories (see AG_RegisterModuleDirectory()) for the libraries specified in the string. Bare library names are given (the actual filenames are platform-dependent). Libraries that are found (and not already in memory) 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’), for an AG_ObjectClass structure describing the class (i.e., the same structure that is passed to AG_RegisterClass()).

AG_UnloadClass() 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 AG_RegisterModuleDirectory() function adds the specified directory to the module search path. AG_UnregisterModuleDirectory() removes the specified directory from the search path.

The AG_OfClass() function evaluates whether the given object is an instance of the specified class. The pattern string may contain wildcards such as “MyClass:*” or “MyClass:*:MySubclass:*”. AG_OfClass() returns 1 if the object's class matches the given pattern.

The AG_ObjectSuperclass() function returns a pointer to the AG_ObjectClass structure for the superclass of an object. Exceptionally, if the object is an instance of the base class (AG_Object), a pointer to the AG_Object class is returned.

The AG_ObjectGetInheritHier() 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 AG_ObjectGetInheritHierString() function returns into buf a string (of the form "MyClass:MySubclass:...") representing the inheritance hierarchy of an object. It is equivalent to copying the hier string of the AG_ObjectClass structure.

The AGOBJECT_FOREACH_CLASS() macro iterates child over every child object of parent which is an instance of the class specified by pattern. child is cast to the given structure type. Example:

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

DEPENDENCIES
int AG_ObjectInUse(AG_Object *obj)

AG_ObjectDep * AG_ObjectAddDep(AG_Object *obj, AG_Object *depobj, int persistent)

void AG_ObjectDelDep(AG_Object *obj, AG_Object *depobj)

Uint32 AG_ObjectEncodeName(AG_Object *obj, AG_Object *depobj)

int AG_ObjectFindDep(AG_Object *obj, Uint32 ind, AG_Object **objp)

AG_ObjectInUse() returns 1 if the given object is being referenced by another object instance or 0 if it isn't.

AG_ObjectAddDep() either creates a new dependency upon depobj or increments the reference count if one exists. If the persistent flag is set, the reference is preserved in object archives. AG_ObjectDelDep() decrements the reference count upon depobj and removes the dependency if the count reaches zero (unless the object has the AG_OBJECT_PRESERVE_DEPS flag set).

AG_ObjectEncodeName() returns a 32-bit integer identifier for the dependency, suitable for writing into data files. It may return the special values 0 (NULL reference) and 1 (self-reference), the meaning of which is object-specific.

AG_ObjectFindDep() tries to resolve the given 32-bit dependency identifier, return 0 on success and -1 on failure.

RELEASING RESOURCES
void AG_ObjectDestroy(AG_Object *obj)

void AG_ObjectFreeDataset(AG_Object *obj)

void AG_ObjectFreeEvents(AG_Object *obj)

void AG_ObjectFreeVariables(AG_Object *obj)

void AG_ObjectFreeDeps(AG_Object *obj)

void AG_ObjectFreeDummyDeps(AG_Object *obj)

void AG_ObjectFreeChildren(AG_Object *obj)

void AG_ObjectRemain(AG_Object *obj, Uint policy)

The AG_ObjectFreeDataset() function frees any dynamically allocated resources by invoking the reinit() of every class in the inheritance hierachy. Contrary to the destroy() operation, reinit() must leave the data structures in a consistent state (e.g., for a subsequent load() operation).

The AG_ObjectDestroy() function frees all resources reserved by the given object (and any of its children that is not being referenced). AG_ObjectDestroy() invokes the reinit() and destroy() operations of every class in the inheritance hierarchy. Note that AG_ObjectDestroy() also cancels any AG_Timeout(3) event scheduled for future execution. Unless the AG_OBJECT_STATIC flag is set, AG_ObjectDestroy() invokes free(3) on the structure.

Internally, AG_ObjectDestroy() invokes AG_ObjectFreeEvents(), AG_ObjectFreeVariables(), AG_ObjectFreeDeps() and AG_ObjectFreeChildren(), but these functions may be called directly in order to destroy and reinitialize the event handler list, the AG_Variable(3) table and destroy the child objects, respectively.

In addition to reinitializing the event handler table, AG_ObjectFreeEvents() also cancels scheduled events.

AG_ObjectFreeChildren() releases all resources allocated by child objects, under the specified parent object. The function assumes that none of the child objects are currently in use.

AG_ObjectFreeDummyDeps() removes entries in the dependency table where the reference count is zero (which occur in objects that have the AG_OBJECT_PRESERVE_DEPS flag set).

The AG_ObjectRemain() function specifies the behavior of AG_ObjectPageOut() once a dataset is no longer in use. The default behavior is to free the dataset. If an argument of AG_OBJECT_REMAIN_DATA is passed, the dataset will be kept in memory.

ARCHIVING
int AG_ObjectLoad(AG_Object *obj)

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

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

int AG_ObjectLoadData(AG_Object *obj)

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

int AG_ObjectLoadGeneric(AG_Object *obj)

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

int AG_ObjectSave(AG_Object *obj)

int AG_ObjectSaveAll(AG_Object *obj)

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

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

int AG_ObjectSerialize(AG_Object *obj, AG_DataSource *ds)

int AG_ObjectUnserialize(AG_Object *obj, AG_DataSource *ds)

int AG_ObjectReadHeader(AG_Object *obj, AG_ObjectHeader *header)

int AG_ObjectPageIn(AG_Object *obj)

int AG_ObjectPageOut(AG_Object *obj)

void AG_ObjectSetArchivePath(AG_Object *obj, const char *path)

void AG_ObjectGetArchivePath(AG_Object *obj, char *buf, size_t buf_len)

These functions implement archiving (or "serialization") of the state of an AG_Object instance to machine-independent binary format.

The AG_ObjectLoad*() family of functions load the state of an Agar object from some binary data source. The generic AG_Object state is loaded first, followed by the object's dataset (which is read by invoking the load() operation for every class in the object's inheritance hierarchy). The AG_ObjectLoad(), AG_ObjectLoadGeneric() and AG_ObjectLoadData() functions look for an archive file in the default search path (using the ‘load-path’ setting of AG_Config(3)). The AG_ObjectLoadFromFile(), 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 AG_ObjectSave*() 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 dataset (which is written by invoking the save() operation for every class in the object's inheritance hierarchy). The AG_ObjectSave() function creates an archive of the given object in the default location (i.e., the ‘save-path’ setting 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 AG_ObjectSerialize() 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 AG_ObjectReadHeader() routine decodes a standard Agar object archive header. On success, it returns 0 and writes the information to 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 specification */
    	Uint32 dataOffs;                    /* Dataset offset */
    	AG_Version ver;                     /* AG_Object version */
    	Uint flags;                         /* Object flags */
    } AG_ObjectHeader;

The AG_ObjectPageIn() function loads an object's dataset into memory and sets the AG_OBJECT_RESIDENT flag. AG_ObjectPageOut() checks whether an object is referenced by another object and if that is not the case, the dataset is archived to storage, freed from memory and the AG_OBJECT_RESIDENT flag is cleared. Both functions return 0 on success or -1 if an error occured.

The AG_ObjectSetArchivePath() and AG_ObjectGetArchivePath() functions respectively set or retrieve the object's application-specific archive path. In an editor application, for example, the archive path would be useful in remembering the last successful save location for a "Save" function.

FLAGS
The following public AG_Object flags are defined:

AG_OBJECT_FLOATING_VARS
    Remove all entries of the AG_Variable(3) table in AG_ObjectLoad(). By default, the existing table is preserved and entries are created or replaced by items found in the archive.

AG_OBJECT_NON_PERSISTENT
    Disables archiving of the object and its children. If set, AG_ObjectSave() becomes a no-op and AG_ObjectLoad() calls will fail.

AG_OBJECT_INDESTRUCTIBLE
    This is an advisory, application-specific flag indicating that the object should be protected from deletion.

AG_OBJECT_RESIDENT
    Set by AG_ObjectPageIn() and AG_ObjectPageOut() to keep track of whether an object's data is resident in memory.

AG_OBJECT_PRESERVE_DEPS
    Disable automatic removal of object dependencies when reference counts reach 0.

AG_OBJECT_STATIC
    Indicates that this object is either statically-allocated (or allocated through another facility than malloc(3)). The AG_ObjectDestroy() operation will not call free(3) on the structure.

AG_OBJECT_READONLY
    This is an advisory and application-specific flag indicating that the object is in "read-only" mode.

AG_OBJECT_REOPEN_ONLOAD
    If the object has a ‘edit’ operation, arrange for all graphical interface elements (as returned by ‘edit’) to be automatically destroyed and recreated after any AG_ObjectLoad() call. This flag is useful for complex objects where the graphical interface references elements of the dataset.

AG_OBJECT_REMAIN_DATA
    Prevent the object's dataset from being automatically freed (with AG_ObjectFreeDataset()) as a result of an AG_ObjectPageOut() call, when the reference count reaches zero. Also see AG_ObjectRemain().

AG_OBJECT_DEBUG
    Enable per-object debugging; application-specific.

AG_OBJECT_NAME_ONATTACH
    Request that AG_ObjectAttach() calls automatically generates a name for the child object being attached. The name will be unique in the parent.

AG_OBJECT_CHLD_AUTOSAVE
    Arrange for child objects to be automatically saved along with the object when AG_ObjectSave*() is invoked.

EVENTS
The AG_Object mechanism generates the following events:

attached(void)
    The object has been attached to another. This event originates from the parent object. The linkage lock is held during the execution of the event handler.

detached(void)
    The object has been detached from its parent. The linkage lock is held during the execution of the event handler. This event originates from the parent.

child-attached(void)
    Same as attached(), except that the event is sent from the child to the parent.

child-detached(void)
    Same as detached(), except that the event is sent from the child to the parent.

renamed(void)
    The object's name has changed.

object-post-load-data(const char *path)
    Invoked by AG_ObjectLoadData(), on success. If the object was loaded from file, path is the pathname of the file.

bound(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.

STRUCTURE DATA
For the AG_ObjectClass structure (see the CLASSES section):

char *hier
    Full class name / inheritance hierarchy.
size_t size
    Size of instance structure (in bytes).
AG_Version ver
    Versioning information (see AG_Version(3)).
void (*init)
    Initialization routine.
void (*reinit)
    Cleanup routine (for AG_ObjectFreeDataset()).
void (*destroy)
    Final cleanup routine.
int (*load)
    Dataset loading function (unserialization).
int (*save)
    Dataset archiving function (serialization).
void *(*edit)
    Interface-specific editor entry point.
char *name
    Short class name. Set internally to the last element in inheritance hierarchy.
char *libs
    Comma-separated list of modules (DSOs) which must be loaded before this class is used. Set internally when the class is registered.
TAILQ sub
    List of AG_ObjectClass structures representing direct subclasses of this class. This list is generated internally.
AG_ObjectClass *super
    Pointer to the superclass of this class. This field is set internally.

For the AG_Object structure:

char *name
    The name string is an arbitrary string identifier which is guaranteed to be unique relative to the object's parent. The name string is limited to AG_OBJECT_NAME_MAX bytes, and should not contain ‘/’ characters.

char *archivePath
    This is an optional, application-specific path name, which should be set with AG_ObjectSetArchivePath() and retrieved with AG_ObjectGetArchivePath(). In an editor application, for example, the archive path would be useful in remembering the last successful save location for a "Save" function.

char *save_pfx
    When the object is saved, this string will be prepended to the effective path name of the save file on disk (after the save directory path, and before the filename).

AG_ObjectClass *cls
    A pointer to the AG_ObjectClass class information structure for this object.

Uint flags
    Object flags (see FLAGS section).

TAILQ events
    List of AG_Event(3) items describing registered event handlers (as set by AG_SetEvent()), as well as virtual functions (as set by AG_Set<Type>Fn()).

TAILQ timeouts
    List of AG_Timeout(3) structure for the timers associated with the object.

TAILQ vars
    Named variables (see AG_Variable(3) for details).

TAILQ deps
    Registered dependencies (see DEPENDENCIES).

TAILQ children
    List of child objects. The AGOBJECT_FOREACH_CHILD(), AGOBJECT_FOREACH_CHILD_REVERSE(), AGOBJECT_NEXT_CHILD(), AGOBJECT_LAST_CHILD() and AGOBJECT_FOREACH_CLASS() macros may be used to iterate over this list.

EXAMPLES
See tests/objsystem.c in the Agar source distribution.

SEE ALSO
AG_Event(3), AG_Intro(3), AG_Timeout(3), AG_Variable(3)

HISTORY
The AG_Object interface appeared in Agar 1.0