FreeBSD Manual Pages
AG_EVENT(3) BSD Library Functions Manual AG_EVENT(3) NAME AG_Event -- agar event system SYNOPSIS #include <agar/core.h> DESCRIPTION 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_EventLoop(3). EVENT PROCESSING 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. EVENT ARGUMENTS 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: void 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: void 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 STRUCTURE DATA). 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 raised. ARGUMENT MANIPULATION 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- guments. 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 va_arg(3). AG_EventPopArgument() removes the last argument from the list. 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_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. AG_PostEvent(). STRUCTURE DATA 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)). EVENT FLAGS 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. 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) manual, 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); /* 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- gument: 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: void 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); SayHello(&event); 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. BSD September 16, 2002 BSD
NAME | SYNOPSIS | DESCRIPTION | EVENT PROCESSING | EVENT ARGUMENTS | ARGUMENT MANIPULATION | EVENT QUEUES | STRUCTURE DATA | EVENT FLAGS | EXAMPLES | SEE ALSO | HISTORY
Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=AG_Event&sektion=3&manpath=FreeBSD+13.0-RELEASE+and+Ports>