Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
AG_EVENT(3)		 BSD Library Functions Manual		   AG_EVENT(3)

     AG_Event -- agar event system

     #include <agar/core.h>

     The AG_Event interface implements a system	of virtual functions for pur-
     poses of servicing	events.	 An AG_Object(3) may act as an event sender,
     or	an event receiver.  Event handler functions are	passed a list of zero
     or	more arguments.	 Execution of event handlers can be delayed for	a set
     amount of time, or	marked for execution in	a separate thread (where
     thread support is available).

     Event processing is triggered by the AG_PostEvent() function, which
     causes the	execution the event handler routine(s) previously registered
     by	AG_SetEvent() or AG_AddEvent().	 Event handlers	are declared as:

     void MyEventHandler(AG_Event *event)

     The event structure contains the event arguments, which are most conve-
     nient retrieved using macros; see EVENT ARGUMENTS below for details.

     NOTE: This	manual page documents Agar's high-level	event processing in-
     terface.  For more	information on low-level event processing, see

     AG_Event *	AG_SetEvent(AG_Object *obj, const char *event_name, void
     (*fn)(AG_Event *event), const char	*fnArgs, ...)

     AG_Event *	AG_AddEvent(AG_Object *obj, const char *event_name, void
     (*fn)(AG_Event *event), const char	*fnArgs, ...)

     AG_Function * AG_SetVoidFn(AG_Object *obj,	void (*fn)(AG_Event *event),
     const char	*fnArgs, ...)

     AG_Function * AG_SetIntFn(AG_Object *obj, int (*fn)(AG_Event *event),
     const char	*fnArgs, ...)

     AG_Function * AG_SetUint8Fn(AG_Object *obj, Uint8 (*fn)(AG_Event *event),
     const char	*fnArgs, ...)

     AG_Function * AG_SetSint8Fn(AG_Object *obj, Sint8 (*fn)(AG_Event *event),
     const char	*fnArgs, ...)

     AG_Function * AG_SetUint16Fn(AG_Object *obj, Uint16 (*fn)(AG_Event
     *event), const char *fnArgs, ...)

     AG_Function * AG_SetSint16Fn(AG_Object *obj, Sint16 (*fn)(AG_Event
     *event), const char *fnArgs, ...)

     AG_Function * AG_SetUint32Fn(AG_Object *obj, Uint32 (*fn)(AG_Event
     *event), const char *fnArgs, ...)

     AG_Function * AG_SetSint32Fn(AG_Object *obj, Sint32 (*fn)(AG_Event
     *event), const char *fnArgs, ...)

     AG_Function * AG_SetUint64Fn(AG_Object *obj, Uint64 (*fn)(AG_Event
     *event), const char *fnArgs, ...)

     AG_Function * AG_SetSint64Fn(AG_Object *obj, Sint64 (*fn)(AG_Event
     *event), const char *fnArgs, ...)

     AG_Function * AG_SetFloatFn(AG_Object *obj, float (*fn)(AG_Event *event),
     const char	*fnArgs, ...)

     AG_Function * AG_SetDoubleFn(AG_Object *obj, double (*fn)(AG_Event
     *event), const char *fnArgs, ...)

     AG_Function * AG_SetLongDoubleFn(AG_Object	*obj, long double
     (*fn)(AG_Event *event), const char	*fnArgs, ...)

     AG_Function * AG_SetStringFn(AG_Object *obj, size_t (*fn)(AG_Event
     *event, char *buf,	size_f buf_size), const	char *fnArgs, ...)

     AG_Function * AG_SetPointerFn(AG_Object *obj, void	*(*fn)(AG_Event
     *event), const char *fnArgs, ...)

     AG_Function * AG_SetConstPointerFn(AG_Object *obj,	const void
     *(*fn)(AG_Event *event), const char *fnArgs, ...)

     AG_Function * AG_SetTextFn(AG_Object *obj,	AG_Text	*(*fn)(AG_Event
     *event), const char *fnArgs, ...)

     AG_Event *	AG_FindEventHandler(AG_Object *obj, const char *name)

     void AG_UnsetEvent(AG_Object *obj,	const char *event_name)

     int AG_PostEvent(AG_Object	*sndr, AG_Object *rcvr,	const char
     *event_name, const	char *fmt, ...)

     int AG_PostEventByPtr(AG_Object *sndr, AG_Object *rcvr, AG_Event *event,
     const char	*fmt, ...)

     int AG_SchedEvent(AG_Object *sndr,	AG_Object *rcvr, Uint32	ticks, const
     char *event_name, const char *fmt,	...)

     void AG_ForwardEvent(AG_Object *sndr, AG_Object *rcvr, AG_Event *event)

     The AG_SetEvent() function	registers a new	event handler to service
     events of type name.  If an event handler is already registered for the
     given event type, it is replaced.	The AG_AddEvent() variant preserves
     any existing event	handler, such that multiple handlers can be invoked
     when the event is raised.	The fn argument	is a pointer to	the event han-
     dler function, and	fnArgs is a special kind of format string specifying a
     list of arguments that should be passed on	to the event handler function.
     See EVENT ARGUMENTS below for details.

     The AG_Set<TYPE>Fn() family of functions create a virtual function	with a
     return value of the specified TYPE.  By default, virtual functions	are
     unnamed (and referenced by	the returned AG_Function() handle).  Names can
     still be assigned to virtual functions by setting the name	field.	Since
     event handlers and	virtual	functions are implemented identically, the
     AG_Function() type	is just	an alias for AG_Event().

     The AG_FindEventHandler() function	searches for an	event handler by name,
     returning a pointer to the	AG_Event element on success or NULL if there
     is	no match.

     The AG_UnsetEvent() function deletes the named event handler.

     The AG_PostEvent()	function immediately executes the event	handler	func-
     tion associated with the given event type,	if there is any.  The fn and
     fnArgs arguments to AG_PostEvent()	are interpreted	in the same way	as
     AG_SetEvent() and AG_AddEvent(), but the arguments	are appended at	the
     end of the	argument list.	When the event handler function	retrieves ar-
     guments by	index (as opposed to using argument names), it is important to
     remember that the arguments to AG_PostEvent() follow the arguments	given
     to	AG_SetEvent() or AG_AddEvent().

     The AG_PostEvent()	function returns 1 if an event handler was invoked, or
     0 if there	is no registered event handler for the specified event.

     The AG_PostEventByPtr() variant accepts a pointer to an AG_Event element,
     as	opposed	to looking up the event	handler	by name.

     The AG_SchedEvent() function provides an interface	similar	to
     AG_PostEvent(), except that the event is scheduled	to occur in the	given
     number of ticks AG_SchedEvent() returns 0 on success or -1	if the timer
     could not be created.  If the object is detached or destroyed, all	events
     scheduled for execution are automatically cancelled.  A more flexible in-
     terface for implementing timers is	described in AG_Timer(3) (which
     AG_SchedEvent() uses internally).

     The AG_ForwardEvent() function relays the given event to object rcvr,
     passing sndr as the sender	pointer.

     The AG_SetEvent(),	AG_AddEvent() and AG_PostEvent() routines accept a
     special fnArgs format string specifying a list of arguments to be passed
     to	the event handler function.  For example, the `%s,%p,%i' string	speci-
     fies that the following arguments are a string, a pointer and an int.
     The arguments would retrieved by the event	handler	function like so:

	   MyEventHandler(AG_Event *event)
		   char	*s = AG_STRING(1);
		   void	*p = AG_PTR(2);
		   int i = AG_INT(3);

     Named arguments are also supported.  For example, the format string
     `%s(foo),%p(bar),%i(baz)' specifies string, pointer and integer argu-
     ments, which can be retrieved using:

	   MyEventHandler(AG_Event *event)
		   char	*s = AG_STRING_NAMED("foo");
		   void	*p = AG_PTR_NAMED("bar");
		   int i = AG_INT_NAMED("baz");

     The following argument specifiers are accepted:
     %p	   An arbitrary	pointer	(void *).
     %Cp   An arbitrary	pointer	(const void *).
     %i	   A signed integer argument (int).
     %u	   An unsigned integer argument	(Uint).
     %li   A signed long integer argument (long).
     %lu   An unsigned long integer argument (Ulong).
     %f	   A real argument (float).
     %d	   A real argument (double).
     %s	   A string argument (char *).
     %Cs   A string argument (const char *).

     The following macros allow	event handler routines to retrieve the argu-
     ments passed to them.  Variable arguments are supported - in that case,
     arguments can be retrieved	directly from the event	structure (see

     AG_Object * AG_SELF(void)

     AG_Object * AG_SENDER(void)

     void * AG_PTR(int index)

     AG_Object * AG_OBJECT(int index, const char *classSpec)

     char * AG_STRING(int index)

     int AG_INT(int index)

     Uint AG_UINT(int index)

     long AG_LONG(int index)

     Ulong AG_ULONG(int	index)

     float AG_FLOAT(int	index)

     double AG_DOUBLE(int index)

     void * AG_PTR_NAMED(const char *key)

     AG_Object * AG_OBJECT_NAMED(const char *key, const	char *classSpec)

     char * AG_STRING_NAMED(const char *key)

     int AG_INT_NAMED(const char *key)

     Uint AG_UINT_NAMED(const char *key)

     long AG_LONG_NAMED(const char *key)

     Ulong AG_ULONG_NAMED(const	char *key)

     float AG_FLOAT_NAMED(const	char *key)

     double AG_DOUBLE_NAMED(const char *key)

     The AG_SELF() macro (equivalent to	AG_PTR(0)) returns a pointer to	the
     AG_Object(3) receiving the	event (the rcvr	argument to AG_PostEvent()).
     AG_SENDER() returns a pointer to the object sending the event (the	sndr
     argument to AG_PostEvent()), if there is one.

     The following macros return a specific item in the	list of	arguments.
     When retrieving arguments by index, keep in mind that the list of argu-
     ments passed by AG_PostEvent() follow the list of arguments provided by
     AG_SetEvent().  If	debugging was enabled at compile time, these macros
     also ensure type safety.

     AG_PTR() returns a	pointer, previously passed as a	`%p' argument.

     AG_OBJECT() returns a pointer to an AG_Object(3) (previously passed as a
     `%p' argument).  It differs from AG_PTR() in that the object pointer is
     verified against the specified object class and a fatal error is raised
     if	runtime	type checking is in effect.

     AG_STRING() returns a pointer to a	string,	previously passed as a `%s'
     argument.	The event handler is not allowed to modify the string.

     AG_INT(), AG_UINT(), AG_LONG() and	AG_ULONG() return the specified	native
     integral number, previously passed	as a `%i', `%u', `%li' or `%lu'	argu-
     ment respectively.

     AG_FLOAT()	and AG_DOUBLE()	return the specified native floating-point
     number, previously	passed as `%f' or `%F' argument	respectively.

     The AG_*_NAMED() macros retrieve the given	argument by name instead of by
     index.  If	there is no argument matching the name,	a fatal	error is

     In	some cases it is desirable for functions to accept a list of event
     handler arguments like AG_SetEvent(), and possibly	manipulate its entries
     directly.	For example, the AG_MenuAction(3) function of the GUI widget
     AG_Menu(3)	accepts	a pointer to an	event handler function,	followed by an
     AG_SetEvent() style format	string and a variable list of arguments.  The
     following functions allow such manipulations.

     void AG_EventInit(AG_Event	*ev)

     void AG_EventArgs(AG_Event	*ev, const char	*fmt, ...)

     void AG_EventPushPointer(AG_Event *ev, const char *key, void *val)

     void AG_EventPushString(AG_Event *ev, const char *key, char *val)

     void AG_EventPushInt(AG_Event *ev,	const char *key, int val)

     void AG_EventPushUint(AG_Event *ev, const char *key, Uint val)

     void AG_EventPushLong(AG_Event *ev, const char *key, long val)

     void AG_EventPushULong(AG_Event *ev, const	char *key, Ulong val)

     void AG_EventPushFloat(AG_Event *ev, const	char *key, float val)

     void AG_EventPushDouble(AG_Event *ev, const char *key, douvle val)

     void AG_EVENT_PUSH_ARG(va_list ap,	char formatChar, AG_Event *ev)

     void AG_EventPopArgument(AG_Event *ev)

     The AG_EventInit()	routine	initializes an AG_Event	structure with no ar-

     AG_EventArgs() initializes	ev and also specifies a	list of	arguments (in
     the same format as	AG_SetEvent()).

     The AG_EventPush*() functions append an argument to the end of the	argu-
     ment list for the specified AG_Event structure.

     The AG_EVENT_PUSH_ARG() macro also	insert an argument, except that	the
     type is obtained from formatChar, assumed to be a character from an
     AG_SetEvent() style format	string,	and the	argument is retrieved using

     AG_EventPopArgument() removes the last argument from the list.

     Under some	circumstances, it is useful to gather AG_Event objects into a
     simple queue.  For	example, a custom event	loop routine (see
     AG_EventLoop(3)) or a low-level Agar driver (see AG_Driver(3)) may	gather
     events from input devices and later process them.	The AG_EventQ struc-
     ture describes a queue of events:

     typedef struct ag_event_queue {
	     Uint     nEvents;
	     AG_Event *events;
     } AG_EventQ;

     The following routines operate on the AG_EventQ structure:

     void AG_InitEventQ(AG_EventQ *eq)

     void AG_FreeEventQ(AG_EventQ *eq)

     void AG_QueueEvent(AG_EventQ *eq, const char *event_name, const char
     *fmt, ...)

     The AG_InitEventQ() function initializes an AG_EventQ structure.
     AG_FreeEventQ() releases all resources allocated under an event queue.

     AG_QueueEvent() inserts an	event in an event queue	structure.  The	mean-
     ing of event_name as well as the syntax of	fmt are	identical to.

     For the AG_Event structure:

     char * name	 String	identifier for the event.
     Uint flags		 See EVENT FLAGS section below.
     int argc		 Argument count.
     AG_Variable *argv	 Argument data (see AG_Variable(3)).

     Acceptable	flags for the AG_Event structure include:

     AG_EVENT_ASYNC	  Arrange for the event	handler	to execute inside a
			  separate thread that will be automatically created
			  (and managed by the receiver object).	 This flag is
			  only available if Agar was compiled with the
			  AG_THREADS option.

     AG_EVENT_PROPAGATE	  Automatically	forward	events of this type to all at-
			  tached child objects.	 If AG_EVENT_ASYNC is also
			  set, the event handlers of the child objects are ex-
			  ecuted concurrently.

     The following code	fragment demonstrates a	typical	AG_Event usage in the
     Agar-GUI library.	We bind	an action to the button	press event, which is
     called `button-pushed'.  This event is documented in the AG_Button(3)
     manual, and so are	the arguments it appends to the	list of	arguments
     passed to the event handler (in this case,	a single int).

	   SayHello(AG_Event *event)
		   char	*s = AG_STRING(1);    /* Given in AG_SetEvent()	*/
		   int new_state = AG_INT(2); /* Passed	by 'button-pushed',
						 see AG_Button(3) */

		   AG_TextMsg(AG_MSG_INFO, "Hello, %s! (state =	%d)",
		       s, new_state);

	   AG_Button *btn = AG_ButtonNew(NULL, 0, "Say hello");
	   AG_SetEvent(btn, "button-pushed", SayHello, "%s", "World");

     The AG_Button API provides	a shorthand constructor	routine,
     AG_ButtonNewFn(), which accepts the `button-pushed' event handler as ar-

	   AG_ButtonNewFn(NULL,	0, "Say	hello",	SayHello, "%s",	"World");

     The following code	fragment is equivalent:

	   AG_Button *btn = AG_ButtonNew(NULL, 0, "Say hello");
	   AG_Event *event = AG_SetEvent(btn, "button-pushed", SayHello, NULL);
	   AG_EventPushString(event, NULL, "World");

     The following code	fragment invokes a handler routine artificially:

	   SayHello(AG_Event *event)
		   char	*foostring = AG_STRING(1);
		   int fooint =	AG_INT(2);

	   AG_Event event;
	   AG_EventArgs(&event,	"%s,%d", "Foo string", 1234);

     AG_EventLoop(3), AG_Intro(3), AG_Object(3), AG_Timer(3), AG_Variable(3)

     The AG_Event mechanism first appeared in Agar 1.0.	 The AG_Variable(3)
     structure was first used to represent event handler arguments in Agar

BSD			      September	16, 2002			   BSD


Want to link to this manual page? Use this URL:

home | help