1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
#include "Scheduler.h"
#include "TimeOut.h"
#include "BusAccess.h"
#include "ivl/Reaction.h"
#include <stdlib.h>
#include <stdio.h>
#include <ostream.h>
class IvlEvent;
/*
Global variables. This is because we use IvlCallbacks and functions
instead of IvlReactions and objects. But this is only a test...
*/
IvlBusAccess* A;
IvlCallback* C;
/*
This is an example of how to emit messages on the bus.
Here, this function is called periodically so as to demonstrate
the behaviour of the bus.
*/
void
foo (Millisecond t)
{
static int i;
static const char* cmds [] = {"free", "click", "lock"};
A->Emit ("tick %d", t);
if (i %10 == 0)
A->Emit ("knob %s", cmds[(i/10)%3]);
++i;
}
/*
This is an example of how to handle messages coming
from the bus. Here, this function is associated to a callback,
which in turn is associated to a regexp (see in main).
*/
void
print_event (IvlEvent& ev)
{
IvlBusEvent* be = dynamic_cast<IvlBusEvent*> (&ev);
if (!be)
return;
cout << "Event matches '" << be->Regexp << "'\n";
cout << "\t(" << be->NbMatches << " matches: ";
IvlListIterOf<IvlString> li = be->MatchList;
while (++li)
cout << "'" << **li << "' ";
cout << ")\n";
}
/*
This is an example of how to handle a new agent connecting to
the bus. Most applications are not interested in such events...
*/
void
agentready (IvlEvent& ev)
{
IvlBusAgentEvent* ae = dynamic_cast<IvlBusAgentEvent*> (&ev);
if (!ae)
return;
IvlBusAgent* a = ae->GetAgent ();
cout << "Hello " << a->GetName () << "!\n";
C->SubscribeTo (a->Bye);
}
/*
This is an example of how to handle an agent leaving
the bus. Most applications are not interested in such events...
*/
void
agentbye (IvlEvent& ev)
{
IvlBusAgentEvent* ae = dynamic_cast<IvlBusAgentEvent*> (&ev);
if (!ae)
return;
IvlBusAgent* a = ae->GetAgent ();
cout << "BYE " << a->GetName () << "!\n";
}
main ()
{
/* initialize communication library */
IvlOpen ();
/* create bus access */
IvlBusAccess a ("Ivl test"); A = &a;
/* periodically send messages on the bus (see foo for timeout handling) */
IvlTimeOut t (1000, foo);
/* subscribe to a few event types (see print_event for event handling) */
/* Note that you can use every subclass of IvlBaseReaction instead
of IvlCallback */
IvlCallback c1 (print_event);
a.Subscribe (c1, "^(CLOCK) (.*)");
a.Subscribe (c1, "TRAFFIC Start");
a.Subscribe (c1, "(.*Tick.*)");
a.Subscribe (c1, "^AIRCRAFT:(.*) Moved (.*)");
/* react to new agents calling (see agentready for event handling) */
IvlCallback c3 (agentready);
c3.SubscribeTo (a.NewAgents);
/* reaction to agents leaving (see agentready for subscription,
and agentbye for event handling) */
IvlCallback c4 (agentbye); C = &c4;
IvlLoop ();
}
|