summaryrefslogtreecommitdiff
path: root/comm/testbus.cc
blob: 3de72b2e58551c1ae221d0151114b4162bcd3354 (plain)
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 ();
}