<-- Back to AG_Intro.3


#include <agar/core.h>


In the Agar object system, each AG_Object(3) instance has a set of typed variables. Variables can be named (accessed by a string key), or anonymous (by pointer). Basic types are supported:
  • Integers (e.g., int, Uint, long, Sint16, Uint64)
  • Floating-point numbers (e.g., float, double, long double)
  • Unbounded C strings (auto-allocated)
  • Generic pointers

"Pointer" variables can also reference typed data. Optionally, pointer variables can be configured to acquire a AG_Mutex(3) locking device prior to accessing the data. Supported reference types include:
  • Integers (e.g., int*, long*, Uint*, Sint16*, Uint64*)
  • Floating-point numbers (e.g., float*, double*, long double*)
  • Bits in a fixed-size word (per given bitmask)
  • Bounded C strings (in fixed-size buffer)
  • Agar objects (pointer to AG_Object(3))
  • Proxy for a named AG_Variable in an external AG_Object(3)

There are other uses for AG_Variable besides representing AG_Object(3) variables. For instance, AG_Variable is used to represent arguments passed to AG_Event(3) callback functions. In Agar-GUI, widgets use Agar variables to reference data in memory (also known as "bindings"). For example, the "value" of an AG_Numerical(3) spinbutton can be tied to an int, a float a mutex-protected Uint32, etc. See the "BINDINGS" section of a widget's manual page for the list of bindings and types supported.


int AG_Defined (AG_Object *obj, const char *name)

AG_Variable * AG_GetVariable (AG_Object *obj, const char *name, void **data)

AG_Variable * AG_AccessVariable (AG_Object *obj, const char *name)

AG_Variable * AG_FetchVariable (AG_Object *obj, const char *name, enum ag_variable_type type)

AG_Variable * AG_FetchVariableOfType (AG_Object *obj, const char *name, enum ag_variable_type type)

void AG_LockVariable (AG_Variable *var)

void AG_UnlockVariable (AG_Variable *var)

AG_Variable * AG_GetVariableVFS (AG_Object *obj, const char *path)

int AG_EvalVariable (AG_Object *obj, AG_Variable *var)

void AG_PrintVariable (char *dst, AG_Size len, AG_Variable *var)

void AG_CopyVariable (AG_Variable *Vdst, const AG_Variable *Vsrc)

void AG_DerefVariable (AG_Variable *Vdst, const AG_Variable *Vsrc)

int AG_CompareVariables (const AG_Variable *a, const AG_Variable *b)

AG_Variable * AG_Set (AG_Object *obj, const char *name, const char *fmt, ...)

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

void AG_VariableSubst (AG_Object *obj, const char *s, char *dst, AG_Size dst_len)

AG_Defined() returns 1 if the variable name is defined under the object obj, otherwise it returns 0. The object obj must be locked.

The AG_GetVariable() function searches for a variable name under obj, and returns the matching AG_Variable in a locked condition (or NULL if undefined). If the variable is virtual function then it is evaluated implicitely. The caller must use AG_UnlockVariable() when finished accessing the variable data. A pointer to the data is also returned in the data argument if it is not NULL. If the variable is undefined, a fatal exception is raised.

The AG_AccessVariable() function searches for a variable by name and returns the matching AG_Variable in a locked condition. The caller must use AG_UnlockVariable() when done accessing the data. Unlike AG_GetVariable(), AG_AccessVariable() does not evaluate virtual functions, and returns NULL if the variable is undefined.

The AG_FetchVariable() function searches for a variable by name and type. If found, return the corresponding AG_Variable. If the variable is undefined then a new one of the specified type is automatically created and returned. Raises an exception if insufficient memory is available.

The AG_FetchVariableOfType() variant works like AG_FetchVariable(), except that if the variable exists and is of a different type, then it is implicitely mutated into type and returned.

Note: Unlike AG_GetVariable() and AG_AccessVariable(), AG_FetchVariable() and AG_FetchVariableOfType() do not return the AG_Variable locked.

AG_LockVariable() and AG_UnlockVariable() acquire and release any locking device associated with the specified variable.

AG_GetVariableVFS() searches through the VFS of AG_Object(3) (which has obj as its root) for a variable by name. The path argument is a string of the form "<object-path>:<variable-name>". If found, then the AG_Variable is returned in a locked condition. The caller must use AG_UnlockVariable() when done accessing the variable's data.

AG_EvalVariable() evaluates a virtual function and copies the return value into the data field. Return 0 on success or -1 if the virtual function is undefined. Note: AG_GetVariable() calls this implicitely.

AG_PrintVariable() returns a string representation of the value of variable var into a fixed-size buffer dst, of len bytes.

AG_CopyVariable() copies the contents of a variable from Vsrc to Vdst. Pointer references are preserved. Discrete strings are duplicated.

AG_DerefVariable() copies the contents of Vsrc to Vdst, converting pointer references to immediate values. Discrete strings are duplicated, and pointers to strings are turned into discrete strings.

The AG_CompareVariables() compares the value of two variables, returning zero if they are identical. If they differ, the difference between the two first differing bytes is returned. If AG_CompareVariables() encounters pointer types, they are not dereferenced (rather the value of the pointer itself is compared).

The AG_Set() sets an object-bound variable value using a format-string interface (see AG_PARSE_VARIABLE_ARGS()).

AG_Unset() deletes the named object-bound variable.

AG_VariableSubst() parses the string s for references of the form "$(foo)", and substitutes those references for the value of variable foo (under object obj). The substituted string is returned into fixed-size buffer dst, of size dst_size.


The following functions get and set variables of specific types.

AG_Get<Type>() returns the value of variable name under object obj with implicit dereferencing. If the variable is a pointer type then the value referenced by it is returned. If the variable is a virtual function, it is evaluated first.

The AG_Init<Type>() functions initialize an AG_Variable structure var with the specified value val.

The AG_Set<Type>() functions set the value of variable name to the specified value val. Implicit dereferencing is done. If the variable does not exist, it is created.

The AG_Bind<Type>() functions create or modify a typed pointer variable. The argument pVal is a pointer to the actual value.

The AG_Bind<Type>Mp() variant accepts an extra lock argument, which is a mutex device (i.e., an AG_Mutex or pthread_mutex_t) to be acquired whenever the data referenced by pVal will be accessed.

AG_Bind<Type>Fn() creates or modifies a variable, tying the variable to a virtual function fn, which will be evaluated whenever the variable is read. Following the F fnargument is a variable list of optional AG_Event(3) style arguments to pass to the virtual function.


Uint AG_GetUint (AG_Object *obj, const char *name)

void AG_InitUint (AG_Variable *var, Uint val)

AG_Variable * AG_SetUint (AG_Object *obj, const char *name, Uint val)

AG_Variable * AG_BindUint (AG_Object *obj, const char *name, Uint *pVal)

AG_Variable * AG_BindUintMp (AG_Object *obj, const char *name, Uint *pVal, AG_Mutex *lock)

AG_Variable * AG_BindUintFn (AG_Object *obj, const char *name, Uint (*fn)(AG_Event *), ...)

int AG_GetInt (AG_Object *obj, const char *name)

void AG_InitInt (AG_Variable *var, int val)

AG_Variable * AG_SetInt (AG_Object *obj, const char *name, int val)

AG_Variable * AG_BindInt (AG_Object *obj, const char *name, int *pVal)

AG_Variable * AG_BindIntMp (AG_Object *obj, const char *name, int *pVal, AG_Mutex *lock)

AG_Variable * AG_BindIntFn (AG_Object *obj, const char *name, int (*fn)(AG_Event *))

Uint8 AG_GetUint8 (AG_Object *obj, const char *name)

void AG_InitUint8 (AG_Variable *var, Uint8 val)

AG_Variable * AG_SetUint8 (AG_Object *obj, const char *name, Uint8 val)

AG_Variable * AG_BindUint8 (AG_Object *obj, const char *name, Uint8 *pVal)

AG_Variable * AG_BindUint8Mp (AG_Object *obj, const char *name, Uint8 *pVal, AG_Mutex *lock)

AG_Variable * AG_BindUint8Fn (AG_Object *obj, const char *name, Uint8 (*fn)(AG_Event *))

Sint8 AG_GetSint8 (AG_Object *obj, const char *name)

void AG_InitSint8 (AG_Variable *var, Sint8 val)

AG_Variable * AG_SetSint8 (AG_Object *obj, const char *name, Sint8 val)

AG_Variable * AG_BindSint8 (AG_Object *obj, const char *name, Sint8 *pVal)

AG_Variable * AG_BindSint8Mp (AG_Object *obj, const char *name, Sint8 *pVal, AG_Mutex *lock)

AG_Variable * AG_BindSint8Fn (AG_Object *obj, const char *name, Sint8 (*fn)(AG_Event *))

Uint16 AG_GetUint16 (AG_Object *obj, const char *name)

void AG_InitUint16 (AG_Variable *var, Uint16 val)

AG_Variable * AG_SetUint16 (AG_Object *obj, const char *name, Uint16 val)

AG_Variable * AG_BindUint16 (AG_Object *obj, const char *name, Uint16 *pVal)

AG_Variable * AG_BindUint16Mp (AG_Object *obj, const char *name, Uint16 *pVal, AG_Mutex *lock)

AG_Variable * AG_BindUint16Fn (AG_Object *obj, const char *name, Uint16 (*fn)(AG_Event *))

Sint16 AG_GetSint16 (AG_Object *obj, const char *name)

void AG_InitSint16 (AG_Variable *var, Sint16 val)

AG_Variable * AG_SetSint16 (AG_Object *obj, const char *name, Sint16 val)

AG_Variable * AG_BindSint16 (AG_Object *obj, const char *name, Sint16 *pVal)

AG_Variable * AG_BindSint16Mp (AG_Object *obj, const char *name, Sint16 *pVal, AG_Mutex *lock)

AG_Variable * AG_BindSint16Fn (AG_Object *obj, const char *name, Sint16 (*fn)(AG_Event *))

Uint32 AG_GetUint32 (AG_Object *obj, const char *name)

void AG_InitUint32 (AG_Variable *var, Uint32 val)

AG_Variable * AG_SetUint32 (AG_Object *obj, const char *name, Uint32 val)

AG_Variable * AG_BindUint32 (AG_Object *obj, const char *name, Uint32 *pVal)

AG_Variable * AG_BindUint32Mp (AG_Object *obj, const char *name, Uint32 *pVal, AG_Mutex *lock)

AG_Variable * AG_BindUint32Fn (AG_Object *obj, const char *name, Uint32 (*fn)(AG_Event *))

Sint32 AG_GetSint32 (AG_Object *obj, const char *name)

void AG_InitSint32 (AG_Variable *var, Sint32 val)

AG_Variable * AG_SetSint32 (AG_Object *obj, const char *name, Sint32 val)

AG_Variable * AG_BindSint32 (AG_Object *obj, const char *name, Sint32 *pVal)

AG_Variable * AG_BindSint32Mp (AG_Object *obj, const char *name, Sint32 *pVal, AG_Mutex *lock)

AG_Variable * AG_BindSint32Fn (AG_Object *obj, const char *name, Sint32 (*fn)(AG_Event *))

Uint64 AG_GetUint64 (AG_Object *obj, const char *name)

void AG_InitUint64 (AG_Variable *var, Uint64 val)

AG_Variable * AG_SetUint64 (AG_Object *obj, const char *name, Uint64 val)

AG_Variable * AG_BindUint64 (AG_Object *obj, const char *name, Uint64 *pVal)

AG_Variable * AG_BindUint64Mp (AG_Object *obj, const char *name, Uint64 *pVal, AG_Mutex *lock)

AG_Variable * AG_BindUint64Fn (AG_Object *obj, const char *name, Uint64 (*fn)(AG_Event *))

Sint64 AG_GetSint64 (AG_Object *obj, const char *name)

void AG_InitSint64 (AG_Variable *var, Sint64 val)

AG_Variable * AG_SetSint64 (AG_Object *obj, const char *name, Sint64 val)

AG_Variable * AG_BindSint64 (AG_Object *obj, const char *name, Sint64 *pVal)

AG_Variable * AG_BindSint64Mp (AG_Object *obj, const char *name, Sint64 *pVal, AG_Mutex *lock)

AG_Variable * AG_BindSint64Fn (AG_Object *obj, const char *name, Sint64 (*fn)(AG_Event *))

These functions provide an interface to both natural and fixed-size integers. The Uint64 and Sint64 types are only available if AG_HAVE_64BIT is defined.


float AG_GetFloat (AG_Object *obj, const char *name)

void AG_InitFloat (AG_Variable *var, float val)

AG_Variable * AG_SetFloat (AG_Object *obj, const char *name, float val)

AG_Variable * AG_BindFloat (AG_Object *obj, const char *name, float *pVal)

AG_Variable * AG_BindFloatMp (AG_Object *obj, const char *name, float *pVal, AG_Mutex *lock)

AG_Variable * AG_BindFloatFn (AG_Object *obj, const char *name, float (*fn)(AG_Event *))

double AG_GetDouble (AG_Object *obj, const char *name)

void AG_InitDouble (AG_Variable *var, double val)

AG_Variable * AG_SetDouble (AG_Object *obj, const char *name, double val)

AG_Variable * AG_BindDouble (AG_Object *obj, const char *name, double *pVal)

AG_Variable * AG_BindDoubleMp (AG_Object *obj, const char *name, double *pVal, AG_Mutex *lock)

AG_Variable * AG_BindDoubleFn (AG_Object *obj, const char *name, double (*fn)(AG_Event *))

long double AG_GetLongDouble (AG_Object *obj, const char *name)

void AG_InitLongDouble (AG_Variable *var, long double val)

AG_Variable * AG_SetLongDouble (AG_Object *obj, const char *name, long double val)

AG_Variable * AG_BindLongDouble (AG_Object *obj, const char *name, long double *pVal)

AG_Variable * AG_BindLongDoubleMp (AG_Object *obj, const char *name, long double *pVal, AG_Mutex *lock)

AG_Variable * AG_BindLongDoubleFn (AG_Object *obj, const char *name, long double (*fn)(AG_Event *))

These functions provide an interface to floating-point numbers. The long double functions are only available if AG_HAVE_LONG_DOUBLE is defined.


AG_Size AG_GetString (AG_Object *obj, const char *name, char *dst, AG_Size dst_size)

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

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

void AG_InitString (AG_Variable *var, const char *s)

void AG_InitStringNODUP (AG_Variable *var, const char *s)

AG_Variable * AG_SetString (AG_Object *obj, const char *name, const char *s)

AG_Variable * AG_SetStringNODUP (AG_Object *obj, const char *name, const char *s)

AG_Variable * AG_PrtString (AG_Object *obj, const char *name, const char *fmt, ...)

AG_Variable * AG_BindString (AG_Object *obj, const char *name, char *s, AG_Size len)

AG_Variable * AG_BindStringMp (AG_Object *obj, const char *name, char *s, AG_Size len, AG_Mutex *lock)

AG_Variable * AG_BindStringFn (AG_Object *obj, const char *name, AG_Size (*fn)(AG_Event *, char *, AG_Size))

These functions provide an interface to C strings. A string variable may contain an unbounded string, or reference an external fixed-size buffer.

AG_GetString() returns the contents of a string variable. The string is safely copied to fixed-size buffer dst, of size dst_size. Return the number of bytes that would have been copied were dst_size unlimited.

AG_GetStringDup() returns a newly-allocated copy of the string variable. If the string cannot be allocated, NULL is returned.

AG_GetStringP() returns a direct pointer to the buffer containing the string. If the variable is a virtual function, it is not evaluated. Warning: AG_GetStringP() is not free-threaded, so the object must be locked and calls should be protected by AG_LockVariable() (exceptionally, discrete strings set by AG_SetString() are safe to access without locking if the variable's parent object is locked).

AG_InitString() initializes a AG_Variable structure with the given string, which is copied from s. The AG_InitStringNODUP() variant sets the s pointer without copying the string.

The AG_SetString() function creates or modifies a string variable. The s argument is a C string which will be duplicated or copied. If the variable exists as a reference to a fixed-size buffer (i.e., it has been created by AG_BindString()), then the contents of s are copied to the buffer. If the buffer has insufficient space, the string is truncated. The s argument may be set to NULL (in which case further AG_GetString() calls will return NULL).

The AG_SetStringNODUP() variant accepts a pointer to a dynamically-allocated string buffer. This buffer will be freed automatically when the parent object is destroyed.

AG_PrtString() sets a string variable from a printf3 style format.

AG_BindString() creates or modifies a variable referencing a fixed-size string buffer s, of size len. The AG_BindStringFn() variant ties the variable to a function fn.


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

void AG_InitPointer (AG_Variable *var, void *val)

AG_Variable * AG_SetPointer (AG_Object *obj, const char *name, void *val)

AG_Variable * AG_BindPointer (AG_Object *obj, const char *name, void **pVal)

AG_Variable * AG_BindPointerMp (AG_Object *obj, const char *name, void **pVal, AG_Mutex *lock)

AG_Variable * AG_BindPointerFn (AG_Object *obj, const char *name, void *(*fn)(AG_Event *))

These functions provide an interface to generic pointer types.


AG_Variable * AG_BindFlag (AG_Object *obj, const char *name, Uint *pVal, Uint bitmask)

AG_Variable * AG_BindFlagMp (AG_Object *obj, const char *name, Uint *pVal, Uint bitmask, AG_Mutex *lock)

AG_Variable * AG_BindFlag8 (AG_Object *obj, const char *name, Uint8 *pVal, Uint8 bitmask)

AG_Variable * AG_BindFlag8Mp (AG_Object *obj, const char *name, Uint8 *pVal, Uint8 bitmask, AG_Mutex *lock)

AG_Variable * AG_BindFlag16 (AG_Object *obj, const char *name, Uint16 *pVal, Uint16 bitmask)

AG_Variable * AG_BindFlag16Mp (AG_Object *obj, const char *name, Uint16 *pVal, Uint16 bitmask, AG_Mutex *lock)

AG_Variable * AG_BindFlag32 (AG_Object *obj, const char *name, Uint32 *pVal, Uint32 bitmask)

AG_Variable * AG_BindFlag32Mp (AG_Object *obj, const char *name, Uint32 *pVal, Uint32 bitmask, AG_Mutex *lock)

These functions provide an interface for binding to specific bits in integers. They follow the standard form, with an extra bitmask argument.


AG_Variable * AG_BindObject (AG_Object *obj, const char *name, AG_Object *varObj)

AG_Variable * AG_BindVariable (AG_Object *obj, const char *name, AG_Object *varObj, const char *varKey)

The AG_BindObject() function creates an Object->Object reference and hard dependency to an external object varObj and return a P_OBJECT type Variable on success. A hard dependency implies that if both obj and varObj share the same VFS then Agar will not allow varObj to be released from memory (or detached from the VFS) for as long as the reference exists.

The AG_BindVariable() function creates an Object->Variable reference to the variable called varKey under an external object varObj, returning a P_VARIABLE type Variable on success. Whenever this Variable is accessed, the external object will be locked and a copy of its variable varKey will be returned implicitely. Note: Circular references must be avoided.

AG_BindVariable() implicitely creates an anonymous Object->Object reference to varObj (which is also removed implicitely by AG_Unset() or AG_ObjectFreeVariables(3) when no more Object->Variable references make use of the object).

AG_BindObject() and AG_BindVariable() may fail and return NULL.


For the AG_Variable structure:
char name[AG_VARIABLE_NAME_MAX] Variable name (or "" = anonymous).
AG_VariableType type Variable type (see <core/variable.h>).
AG_Mutex *mutex Mutex protecting referenced data.
union ag_variable_data data Stored data (see <core/variable.h>).


AG_Intro(3), AG_Event(3), AG_List(3), AG_Object(3), AG_Tbl(3)


The AG_Variable interface first appeared in Agar 1.3.4. It replaced the older AG_Prop(3) interface, and widget bindings which were previously stored in AG_Widget(3) itself.