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

FreeBSD Manual Pages

  
 
  

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

NAME
     AG_Event -- agar event handlers / virtual functions

SYNOPSIS
     #include <agar/core.h>

DESCRIPTION
     The  AG_Event  (or  AG_Function)  type represents an event handler (or more
     generally a virtual function) under an AG_Object(3).  It  provides  a  gen-
     eral-purpose,  thread-safe message passing system.  It is used to implement
     virtual functions in objects.  The AG_Event structure contains an	optional
     name  identifier  (a  string  of  up to AG_EVENT_NAME_MAX characters long).
     Event Handlers are declared as follows:

     void MyEventHandler(AG_Event *event)

     The final stack of arguments passed to MyEventHandler() contains  both  the
     arguments	from  the initial AG_SetEvent() call followed by any extra argu-
     ments  appended  by  subsequent  AG_PostEvent()  calls.   See  the   "EVENT
     ARGUMENTS" section for details and examples.

     An  AG_Event  may	store  up to AG_EVENT_ARGS_MAX arguments.  The arguments
     contained in an AG_Event can be accessed by the event handler either by in-
     dex or by name.

EVENT PROCESSING
     AG_Event	*   AG_SetEvent(AG_Object   *obj,   const   char   *name,   void
     (*fn)(AG_Event *event), const char *fmt, ...)

     AG_Event	*   AG_AddEvent(AG_Object   *obj,   const   char   *name,   void
     (*fn)(AG_Event *event), const char *fmt, ...)

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

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

     void AG_UnsetEventByPtr(AG_Object *obj, AG_Event *event)

     void AG_PostEvent(AG_Object *obj, const char *name, const char *fmt, ...)

     void AG_PostEventByPtr(AG_Object *obj, AG_Event *event,  const  char  *fmt,
     ...)

     int  AG_SchedEvent(AG_Object  *obj,  Uint32  ticks, const char *name, const
     char *fmt, ...)

     The AG_SetEvent() function sets an event handler to service events of  type
     name.   If a handler of the given name already exists, it is replaced.  The
     AG_AddEvent() variant preserves any pre-existing handler (such that  multi-
     ple  handlers  will be invoked by the event).  fn is a pointer to the event
     handler function.	fmt is an optional format string which specifies follow-
     ing arguments (see "EVENT ARGUMENTS").

     AG_FindEventHandler() searches for an event handler by name and  returns  a
     pointer to its AG_Event structure on success or NULL if not found.

     AG_UnsetEvent() and AG_UnsetEventByPtr() delete the given event handler.

     AG_PostEvent()  raises  the event identified by name under object obj.  fmt
     is an optional format string specifying following arguments  that	will  be
     passed to the event handler function.  The event handler will see the argu-
     ments added by AG_SetEvent() followed by those added by AG_PostEvent().

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

     AG_SchedEvent() provides an interface similar to AG_PostEvent() except that
     the  event  is scheduled to occur in the given number of ticks.  AG_SchedE-
     vent() returns 0 on success or -1 if the timer could not be created.   When
     an AG_Object(3) is detached or destroyed, any event scheduled for execution
     is  automatically	cancelled.   A more flexible interface for timers is de-
     scribed in AG_Timer(3) (which AG_SchedEvent() uses internally).

EVENT ARGUMENTS
     The AG_SetEvent(), AG_AddEvent() and AG_PostEvent() routines accept a  spe-
     cial  fnArgs  format  string specifying a list of arguments to be passed to
     the event handler function.  For example,	"%s,%p,%i"  (or  "%s%p%i")  says
     that  the	following  arguments are a string, a pointer and an integer.  An
     event handler routine will typically use accessor macros to  extract  argu-
     ment values out of the event structure:

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

		   /* ... */
	   }

     It  is  customary	for  Agar  object  classes  to	define	accessor  macros
     AG_<T>_PTR() (for accessing arguments by index),  AG_<T>_NAMED()  (for  ac-
     cessing  arguments  by  name), and AG_<T>_SELF() (for accessing argument 0,
     equivalent to "AG_<T>_PTR(0)").  Arguments marked constant must be accessed
     with AG_c<T>_PTR() and AG_c<T>_SELF().

     Here is an example using Agar-GUI widget classes:

	   static void
	   PushedOK(AG_Event *event)
	   {
		   AG_Button *button = AG_BUTTON_SELF();
		   AG_Radio *radio   = AG_RADIO_PTR(1);
		   AG_Button *button = AG_BUTTON_PTR(2);
		   const AG_Checkbox *cb = AG_cCHECKBOX_PTR(3);

	   /*	   cb->invert = 1;		<- Incorrect (cb is const) */
	   /*	   AG_WidgetDisable(cb);	<- Incorrect (cb is const) */
		   AG_WidgetDisable(radio);  /* <- OK */
		   AG_WidgetDisable(button); /* <- OK */
	   }

	   AG_Window *win = AG_WindowNew(0);
	   AG_Checkbox *radio = AG_RadioNew(window, 0, NULL);
	   AG_Button *button = AG_ButtonNew(window, 0, "OK");
	   AG_Checkbox *checkbox = AG_CheckboxNew(window, 0, "Some option");

	   AG_SetEvent(button, "button-pushed",
	       PushedOK, "%p,%Cp", radio, checkbox);

     Arguments are optionally named (tagged with a string)  and  retrieved  with
     AG_<TYPE>_NAMED():

	   static void
	   CopySomeData(AG_Event *event)
	   {
		   const void *src = AG_cPTR_NAMED("src");
		   void *dst = AG_PTR_NAMED("dst");
		   long offs = AG_LONG_NAMED("offs");

		   /* ... */
	   }

	   void *src, *dst;
	   long offs = 0;

	   AG_SetEvent(obj, "some-event",
	       CopySomeData, "%Cp(src),%p(dst),%li(offs)",
	       src, dst, offs);

     The following argument specifiers are accepted:

     %p    A pointer to data: void *.
     %Cp   A pointer to const data: const void *.
     %i    Signed integer: int.
     %u    Unsigned integer: Uint.
     %li   Signed long integer: long.  Not in AG_SMALL.
     %lu   Unsigned long integer: Ulong.  Not in AG_SMALL.
     %f    Real number: float.	Requires AG_HAVE_FLOAT.
     %d    Real number: double.  Requires AG_HAVE_FLOAT.
     %s    C string (NUL-terminated): char *.

     The  following macros extract the arguments contained in an AG_Event struc-
     ture.  If Agar is compiled with  either  --enable-debug  or  --enable-type-
     safety, they also check for potential accesses to incorrect types.

     AG_Object * AG_SELF(void)

     const AG_Object * AG_cSELF(void)

     void * AG_PTR(int index)

     const void * AG_cPTR(int index)

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

     const AG_Object * AG_cOBJECT(int index, const char *hierarchy)

     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)

     const void * AG_cPTR_NAMED(const char *key)

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

     const AG_Object * AG_cOBJECT_NAMED(const char *key, const char *hierarchy)

     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() and AG_cSELF() macros expand to a pointer to the AG_Object(3)
     receiving	the event (the obj argument passed to AG_PostEvent()).	They are
     equivalent to AG_PTR(0) and AG_cPTR(0), respectively.

     The following macros return a specific item in the list of arguments.  When
     retrieving arguments by index, note that the  arguments  to  AG_PostEvent()
     follow the arguments to AG_SetEvent() (i.e., the arguments to AG_SetEvent()
     are  pushed  first  onto  the  argument stack, followed by the arguments to
     AG_PostEvent(), if any).  These macros ensure type safety if Agar	is  com-
     piled with --enable-debug or --enable-type-safety.

     AG_PTR()  returns	a  pointer (a `%p' argument).  AG_cPTR() returns a const
     pointer (a `%Cp' argument).

     AG_OBJECT() returns a pointer to an AG_Object(3) (a `%p' argument).  In de-
     bug mode, assert that the argument points to a valid AG_Object(3)	by  per-
     forming  a  validity  test,  and a class membership test.	The AG_cOBJECT()
     variant asserts that the pointer is a const pointer (a `%Cp' argument).

     AG_STRING() returns a pointer to a string (a `%s' argument).

     AG_INT(), AG_UINT(), AG_LONG() and AG_ULONG() return a natural or long  in-
     teger (a `%i', `%u', `%li' or `%lu' argument, respectively).

     AG_FLOAT()  and  AG_DOUBLE() return the given floating-point number (a `%f'
     for a float or `%d' for a double argument).

     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 raised.

ARGUMENT MANIPULATION
     In  some cases it is desirable for functions to accept a list of event han-
     dler arguments like AG_SetEvent(), and possibly manipulate its entries  di-
     rectly.   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_EventCopy(AG_Event *dst, const AG_Event *src)

     AG_Event * AG_EventDup(const AG_Event *src)

     void AG_EVENT_DUMP(const AG_Event *ev)

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

     void AG_EventPushConstPointer(AG_Event *ev, const	char  *key,  const  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, double val)

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

     void * AG_EventPopPointer(AG_Event *ev)

     const void * AG_EventPopConstPointer(AG_Event *ev)

     char * AG_EventPopString(AG_Event *ev)

     int AG_EventPopInt(AG_Event *ev)

     Uint AG_EventPopUint(AG_Event *ev)

     long AG_EventPopLong(AG_Event *ev)

     Ulong AG_EventPopUlong(AG_Event *ev)

     float AG_EventPopFloat(AG_Event *ev)

     double AG_EventPopDouble(AG_Event *ev)

     AG_EventInit() initializes an AG_Event structure with no arguments.

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

     AG_EventCopy() copies the function pointer and arguments from one	AG_Event
     to another.  AG_EventDup() returns a newly-allocated duplicate.

     The  AG_EVENT_DUMP() macro produces a listing of the arguments of ev on the
     console via AG_Debug(3).

     The AG_EventPush*() routines put a new argument  on  top  of  the	argument
     stack, incrementing the argument count.  AG_EventPop*() decrement the argu-
     ment count, returning a copy of the data of the last element.

     The AG_EVENT_PUSH_ARG() macro insert an argument on the argument stack, de-
     termining	the  type  from  formatChar  and  the  data  from  the following
     va_arg(3) arguments.  The supported formatChar characters are documented in
     the "EVENT ARGUMENTS" section.

EVENT QUEUES
     Under some circumstances, it is useful to gather AG_Event	objects  into  a
     simple  queue.   For  example,  a	custom event loop routine (see AG_Event-
     Loop(3)) or a low-level Agar driver (see AG_Driver(3))  may  gather  events
     from input devices and later process them.

STRUCTURE DATA
     For the AG_Event structure:

     char * name	 String identifier for the event.
     int argc		 Argument count.
     AG_Variable *argv	 Argument data (see AG_Variable(3)).

EXAMPLES
     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) man-
     ual, and so are the arguments it appends to the list of arguments passed to
     the event handler (in this case, a single int).

	   void
	   SayHello(AG_Event *event)
	   {
		   char *s   = AG_STRING(1);  /* From AG_SetEvent() */
		   int state = AG_INT(2);     /* From later AG_PostEvent() */

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

	   AG_Button *btn;

	   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_Button-
     NewFn(), which accepts the `button-pushed' event handler as argument:

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

     The following code fragment is equivalent:

	   AG_Button *btn;
	   AG_Event *ev;

	   btn = AG_ButtonNew(NULL, 0, "Say hello");
	   ev = AG_SetEvent(btn, "button-pushed", SayHello, NULL);
	   AG_EventPushString(ev, NULL, "World");

     The following code fragment invokes a handler routine artificially:

	   void
	   SayHello(AG_Event *event)
	   {
		   char *s = AG_STRING(1);
		   int	 i = AG_INT(2);
	   }

	   AG_Event ev;

	   AG_EventArgs(&ev, "%s,%d", "Foo string", 1234);
	   SayHello(&ev);

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

HISTORY
     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
     1.3.4.   Agar 1.6.0 added the const argument accessor macros and introduced
     validity and class membership tests for object pointers  in  event  handler
     arguments.  AG_EventCopy(), AG_EventDup() and AG_UnsetEventByPtr() appeared
     in Agar 1.6.0.

Agar 1.7			December 21, 2022		     AG_EVENT(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=AG_Event&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help