From f6a815b6504e9c954b9d0af57a3de6ccb75b5321 Mon Sep 17 00:00:00 2001 From: jacomi Date: Mon, 12 Apr 1999 17:18:34 +0000 Subject: doc updated --- doc/ivy-c-1.html | 114 +++++++++++++++++++++++++++++++ doc/ivy-c-2.html | 38 +++++++++++ doc/ivy-c-3.html | 199 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ doc/ivy-c-4.html | 28 ++++++++ doc/ivy-c-5.html | 178 +++++++++++++++++++++++++++++++++++++++++++++++++ doc/ivy-c-6.html | 23 +++++++ doc/ivy-c.html | 68 +++++++++++++++++++ 7 files changed, 648 insertions(+) create mode 100644 doc/ivy-c-1.html create mode 100644 doc/ivy-c-2.html create mode 100644 doc/ivy-c-3.html create mode 100644 doc/ivy-c-4.html create mode 100644 doc/ivy-c-5.html create mode 100644 doc/ivy-c-6.html create mode 100644 doc/ivy-c.html diff --git a/doc/ivy-c-1.html b/doc/ivy-c-1.html new file mode 100644 index 0000000..69e9dee --- /dev/null +++ b/doc/ivy-c-1.html @@ -0,0 +1,114 @@ + + +
+ ++
Ivy is a software bus designed at CENA (France). A software bus is a system +that allows software applications to exchange information with the illusion of +broadcasting that information, selection being performed by the receiving +applications. Using a software bus is very similar to dealing with events in a +graphical toolkit: on one side, messages are emitted without caring about who +will handle them, and on the other side, one decide to handle the messages that +have a certain type or follow a certain pattern. Software buses are mainly aimed +at facilitating the rapid development of new agents, and at managing a dynamic +collection of agents on the bus: agents show up, emit messages and receive some, +then leave the bus without blocking the others. +
+
As opposed to other software buses, Ivy does not depend on a centralised +server. Actually, Ivy is mostly a communication convention between processes, +implemented through a collection of libraries in several languages. +
+
+
From the programmer's point of view, Ivy is an information broadcasting +channel. The main functions are: +
+
Ivy's +decentralised connection scheme probably incurs limitations in terms of how many +applications can be connected to an Ivy bus, but this simplifies management a +lot. Basically, an Ivy bus is just a set of applications that decide to +communicate together. The only conventions between these applications are: +
The messages are exchanged in text format, and bindings are based on regular
+expressions with captures. If an application subscribes to
+HELLO (.*)
an if another application emits the message HELLO WORLD
, a
+callback will be called in the first application with WORLD
as an argument.
+
+
+
You can use Ivy through applications that have been provided to you. This is the
+case for ivyprobe
, an Ivy agent that allows you to examine the messages
+exchanged on a given bus and to send messages on that bus. You can refer to the
+web site http:
for a list of available agents. However, what you will
+usually want to do is to develop your own applications. In order to do that you
+can use an Ivy connection kit, that is a library that implements Ivy.
+
+
+
Libraries that implement Ivy are available in the following environments: +
+
Connecting your application to an Ivy bus just consists in choosing the +appropriate library, add the appropriate message emission and reception calls to +your code, use the main loop provided in the library or make the necessary +integrations, and get your code running! +
+
The Ivy C library (aka Ivy-C or ivy-c) is a C library that allows you to connect +applications to an Ivy bus. You can use it to write applications in C or any +other language that supports C extensions. This guide documents how you can do +that. +
The Ivy C library is known to compile and work in WindowsNT and Linux +environments. It should be easy to use on most Posix environments. +
The Ivy C library was originally developed by François-Régis Colin at CENA. It +is maintained by the CENA-Toulouse team. +
+
You can get the latest versions of the Ivy C library from CENA (http://XXX) or +from one of the Fairway sites (for instance http://XXX). Depending whether you +use a supported distribution of Linux or not, you have the following options: +
+
+
+
+
+
+
+
Initializing an Ivy agent with the Ivy C library is a two step process. First of
+all, you should initialize the library by calling function IvyInit
. Once
+the library is initialized you can create timers and add subscriptions, but your
+agent is still not connected to any bus. In order to connect, you should call
+function IvyStart
. In theory, initialization is then over. However in
+practice, as for any asynchronous communication or interaction library, nothing
+happens until your application has reached the main loop.
+
The Ivy C library provides its own main loop: IvyMainLoop
. You should use
+it unless you already use a toolkit that provides its own main loop and you want
+to use that one. If it is the case, please refer to section XX. Otherwise, just
+call IvyMainLoop
. From within the main loop, you can call IvyStop
to
+exit the loop.
+
Here are more details on those functions: +
+
+
+void IvyInit (const char* agentname,
+ const char* hello_msg,
+ IvyApplicationCallback app_cb,
+ void *app_data,
+ IvyDieCallback die_cb,
+ void *die_data);
+
+
+
+initializes the library. blahblah
++
+
+void IvyStart (const char* bus);
+
+
+
+connects your application to the bus specified in bus
. The string provided
+should follow the convention described in section XX. Example: "127:2010"
.
++
+
+void IvyMainLoop (void (*hook) (void));
+
+
+
+makes your application enter the main loop in which it will handle asynchronous
+communications and signals.
++
+
+void IvyStop ();
+
+
+
+makes your application exit the main loop.
++
+
Emitting a message on an Ivy bus is much like printing a message on the standard
+output. However, do not forget that your message will not be emitted if Ivy has
+not been properly initialized and if you do not have a main loop of some sort
+running. To emit a message, use IvySendMsg
, which works like printf
:
+
+
+
+void IvySendMsg (const char* format, ...);
+
+
+
+sends a message on the bus. This function has exactly the same behaviour as
+printf
, sprintf
or fprintf
.
++
+
Subscribing to messages consists in binding a callback function to a message
+pattern. Patterns are described by regular expressions with captures. When a
+message matching the regular expression is detected on the bus, the callback
+function is called. The captures (ie the bits of the message that match the
+parts of regular expression delimited by brackets) are passed to the callback
+function much like options are passed to main
. Use function IvyBindMsg
+to bind a callback to a pattern, and function IvyUnbindMsg
to delete the
+binding.
+
+
+MsgRcvPtr IvyBindMsg (MsgCallback cb,
+ void* data,
+ const char* regex_format, ...);
+
+
+
+binds callback function cb
to the regular expression specified by
+regex_format
and the optional following arguments. regex_format
and
+the following arguments are handled as in printf
.
++
+
+void IvyUnbindMsg (MsgRcvPtr id);
+
+
+
+deletes the binding specified by id
++
In what precedes, MsgRcvPtr
is an opaque type used to identify bindings,
+data
is a user pointer passed to the callback whenever it is called, and
+Msgcallback
is defined as follows:
+
+
+typedef void (*MsgCallback)(IvyClientPtr app, void *data, int argc, char **argv);
+
+
++
+
The following application connects to an Ivy bus, translates messages "Hi
+[name]"
to "Bonjour [name]"
, and quits on message "Bye"
.
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <ivy.h>
+#include <ivyloop.h>
+
+/* callback associated to "Hi" messages */
+void HiCallback (IvyClientPtr app, void *data, int argc, char **argv)
+{
+ if (argc != 1)
+ fprintf (stderr, "wrong format!\n");
+ else
+ IvySendMsg ("Bonjour %s", argv[0]);
+}
+
+void ByeCallback (IvyClientPtr app, void *data, int argc, char **argv)
+{
+ IvyStop ();
+}
+
+main (int argc, char**argv)
+{
+ /* handling of -b option */
+ const char* bus = 0;
+ char c;
+ while (c = getopt (argc, argv, "b:") != EOF) {
+ switch (c) {
+ case 'b':
+ bus = optarg;
+ break;
+ }
+ }
+
+ /* handling of environment variable */
+ if (!bus)
+ bus = getenv ("IVYBUS");
+
+ /* initializations */
+ IvyInit ("MagicTranslater", "Hello le monde", 0, 0, 0, 0);
+ IvyStart (bus);
+
+ /* bindings */
+ IvyBindMsg (HiCallback, 0, "^Hi (.*)");
+ IvyBindMsg (ByeCallback, 0, "^Bye$");
+
+ /* main loop */
+ IvyMainLoop (0);
+}
+
+
++
+
+
+
+
In your applications, you may need to manage other input/output channels than an +Ivy bus: a serial driver, the channels defined by a graphical toolkit, or simply +stdin and stdout. The same applies for timers. You can either manage those +channels or timers from the Ivy main loop, or instead use the main loop provided by +another library. +
+
You can get a channel to be managed from the Ivy main loop by using functions
+IvyChannelSetUp
and IvyChannelClose
.
+
+
+Channel IvyChannelSetUp (HANDLE fd,
+ void* data,
+ ChannelHandleDelete handle_delete,
+ ChannelHandleRead handle_read);
+
+
+
+ensures that function handle_read
is called whenever data is read on file
+descriptor fd
, and function handle_delete
whenever fd
is
+closed, and
++
+
+void IvyChannelClose (Channel ch);
+
+
+
+terminates the management of channel ch
.
++
In what precedes, Channel
is an opaque type defined by the Ivy C library, data
is a pointer that will be passed to functions handle_read
+and handle_delete
. It can be defined at will by users.
+The types HANDLE, ChannelHandleDelete and
+ChannelHandleRead are as follows:
+
+Unix:
+
+typedef int HANDLE;
+
+
+Windows:
+
+typedef SOCKET HANDLE;
+
+
+
+typedef void (*ChannelHandleDelete)(void *data);
+typedef void (*ChannelHandleRead)(Channel ch, HANDLE fd, void* data);
+
+
++
+
You can get a function to be repeatedly called by using function
+TimerRepeatAfter
:
+
+
+
+TimerId TimerRepeatAfter (int nbticks, long delay, TimerCb handle_timer, void* data);
+
+
+
+ensures that function handle_timer
is called nbticks
times at
+intervals of delay
seconds, thus creating a timer.
++
+
+void TimerModify (TimerId id, long delay);
+
+
+
+changes the delay used for timer id
.
++
+
+void TimerRemove (TimerId id);
+
+
+
+deletes timer id
, thus stopping it.
+In what precedes, data
is passed to handle_timer
every time it is
+called. delay
is expressed in milliseconds.
+If nbticks
is set to TIMER_LOOP
, then handle_timer
will
+be called forever. TimerCb
is as follows:
+
+
+typedef void (*TimerCb)(TimerId id, void *data, unsigned long delta);
+
+
++
+
You can decide to use the main loop from another toolkit such as the X Toolkit +or the Tk toolkit. If you do that, you'll have to define three functions that +Ivy will use to get its own channels managed by the other toolkit. The three +following global variables should be defined: +
+
+ChannelInit channel_init;
+ChannelSetUp channel_setup;
+ChannelClose channel_close;
+
+
+They should point to functions that respectively: +
+
The types ChannelInit
, ChannelSetUp
and ChannelClose
are defined
+as follows:
+
+
+
+typedef void (*ChannelInit)(void);
+typedef Channel (*ChannelSetUp)(
+ HANDLE fd,
+ void *data,
+ ChannelHandleDelete handle_delete,
+ ChannelHandleRead handle_read);
+typedef void (*ChannelClose)( Channel channel );
+
+
++
+
In order to implement the three previous functions, you will need to define the
+hidden type struct _channel
(the type Channel
is defined as struct _channel*
). Use it to store the data provided by the other toolkit.
+
+
In order to override the default definition of the three previous variables, you +will need: +
ivyloop.o
with the file
+that contains your definitions+
+
+
+
+
+
... the environment variable IVYBUS
..., ... the option -b
...
+
+
chatty@cena.dgac.fr
+
+
+
+
+
+