summaryrefslogtreecommitdiff
path: root/comm/testbus.cc
blob: 757688bba7aad255ca7d95e85fc61f96e4dfbe01 (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
115
116
117
118
119
120
121
122
123
124
125

#include "Multiplexer.h"
#include "TimeOut.h"
#include "BusAccess.h"
#include "dnn/Reaction.h"
#include <stdlib.h>
#include <stdio.h>
#include <ostream.h>
class DnnEvent;


/*
Global variables. This is because we use DnnCallbacks and functions
instead of DnnReactions and objects. But this is only a test...
*/
UchBusAccess* A;
DnnCallback* 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 (DnnEvent& ev)
{
	UchBusEvent* be = dynamic_cast<UchBusEvent*> (&ev);
	if (!be)
		return;
	const char* m = be->Matches;
	cout << "Event '" << be->Matches << "' matches '" << be->Regexp << "'\n";
	cout << "\t(" << be->NbMatches << " matches:";
	CcuListIterOf<CcuString> 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 (DnnEvent& ev)
{
	UchAgentEvent* ae = dynamic_cast<UchAgentEvent*> (&ev);
	if (!ae)
		return;

	UchBusAgent* 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 (DnnEvent& ev)
{
	UchAgentEvent* ae = dynamic_cast<UchAgentEvent*> (&ev);
	if (!ae)
		return;
	UchBusAgent* a = ae->GetAgent ();
	cout << "BYE " << a->GetName () << "!\n";

}



main ()
{
	fprintf (stderr, "00\n");
	const char* bus = getenv ("IVYBUS");
	int bus_number = bus ? atoi (bus) : 2010;

	fprintf (stderr, "0\n");
	UchOpen ();
	fprintf (stderr, "1\n");
	UchBusAccess a ("Uch test", bus_number); A = &a;

	fprintf (stderr, "2\n");
	/* periodically send messages on the bus (see foo for timeout handling) */
	UchTimeOut t (1000, foo);

	fprintf (stderr, "3\n");
	/* subscribe to a few types of events (see print_event for event handling) */
	/* Note that you can use every subclass of DnnBaseReaction instead
	    of DnnCallback */
	DnnCallback c1 (print_event);
	a.Subscribe (c1, "^(glidepoint) (.*)");
	a.Subscribe (c1, "TRAFFIC START");
	a.Subscribe (c1, "(.*TRAFFIC FILE NAME.*)");
	a.Subscribe (c1, "^AVION:(.*) RADAR (.*)");

	/* react to new agents calling (see agentready for event handling) */
	DnnCallback c3 (agentready);
	c3.SubscribeTo (a.NewAgents);
	fprintf (stderr, "4\n");

	/* reaction to agents leaving (see agentready for subscription,
	   and agentbye for event handling) */
	DnnCallback c4 (agentbye); C = &c4;

	UchLoop ();
}