adding GPL V3
[ixm-collector.git] / collector.cpp
blob408b534e749788855f8dbbed910c94fcc98e1745
1 #include "collector.h"
2 #include "SFBRandom.h" // For random(int)
3 #include "SFBPacket.h" // For packetSource
4 #include "SFBReactor.h" // For Body
5 #include "SFBPrint.h" // For facePrint
6 #include "SFBPrintf.h" // For pprintf, etc
7 #include "SFBAlarm.h" // For Alarms, etc
9 #define MAX_DIST 100
11 struct Collector {
12 bool initialized;
13 bool sent_prefix_p;
14 int count; // keep track of the last update
15 u32 out_face; // the immediate face through which to send data back
16 char path[MAX_DIST]; // the path back to the central scrutinizer
17 int x; int y; // (x,y) 2D coordinates
18 int ind; // counter used by report_prefix
19 // a variety of functions for reporting back to the central scrutinizer
20 void update_coords();
21 void report_prefix();
23 Collector collector;
25 char reverseStep(char step) {
26 switch(step) {
27 case 'f': return 'f';
28 case 'l': return 'r';
29 case 'r': return 'l';
30 default: pprintf("L hork on %c\n", step); return 'z';
34 void Collector::update_coords() {
35 int dir = 4;
36 int ind = 0;
37 y = 0;
38 x = 0;
39 while(path[ind] != '\0') {
40 // turn
41 switch (path[ind]) {
42 case 'f': break;
43 case 'l': dir = (dir - 1) % 4; break;
44 case 'r': dir = (dir + 1) % 4; break;
45 default: pprintf(" L hork on '%c' path to coord\n", path[ind]); return;
47 // step
48 switch (dir) {
49 case 0: ++y; break;
50 case 1: ++x; break;
51 case 2: --y; break;
52 case 3: --x; break;
53 case 4: ++y; break;
54 default: pprintf("L hork on '%d' path direction\n", dir); return;
56 ++ind;
60 void Collector::report_prefix() {
61 ind = 0;
62 while(path[ind] != '\0') ++ind; // rewind to the end of the string
63 while(ind > 0) { // then step back to front building an R packet
64 --ind; facePrintf(out_face, "R%c", reverseStep(path[ind]));
66 facePrintf(out_face, "(%d,%d) ", x, y);
69 void noticeCollector(u8 * packet) {
70 int count;
71 char dir;
72 int in;
73 int out;
74 if (packetScanf(packet, "c%d", &count) != 2) {
75 pprintf("L bad '%#p'\n",packet);
76 return;
78 if (count > collector.count) {
79 collector.initialized = true;
80 collector.count = count;
81 collector.out_face = packetSource(packet);
82 int path_ind = 0;
83 char ch;
84 while(packetScanf(packet, "%c", &ch)) { // extract the return path
85 if (ch != ' ') {
86 collector.path[path_ind] = ch;
87 ++path_ind;
90 collector.path[path_ind] = '\0';
91 collector.update_coords(); // update (x,y) coordinates
92 for (u32 f = NORTH; f <= WEST; ++f) { // send on to neighbors
93 if (collector.out_face != f) {
94 if (collector.out_face == 1) in = 2; // swap around south and east
95 else if (collector.out_face == 2) in = 1;
96 else in = collector.out_face;
97 if (f == 1) out = 2;
98 else if (f == 2) out = 1;
99 else out = f;
100 switch ((4 + out - in) % 4) { // find the dir l, r, or f
101 case 1: dir = 'l'; break;
102 case 2: dir = 'f'; break;
103 case 3: dir = 'r'; break;
104 default: pprintf(" L hork %d to %d is %d\n", in, out, ((4 + out - in) % 4)); return;
106 facePrintf(f, "c%d %s%c\n",
107 count, collector.path, dir); // append dir and send onward
113 // use collector through a virtual face printer
114 u8 virtual_face;
115 void collector_print(u8 face, u8 byte) {
116 if (collector.initialized) {
117 if (collector.sent_prefix_p != true) {
118 collector.report_prefix();
119 collector.sent_prefix_p = true;
121 facePrintf(collector.out_face, "%c", byte);
124 void collector_println(u8 face) {
125 if (collector.initialized) {
126 collector.sent_prefix_p = false;
127 facePrintf(collector.out_face, "\n");
130 const FacePrinter collector_printer = { collector_print, collector_println, 0, 0 };
132 int collector_x(){ return collector.x; }
133 int collector_y(){ return collector.y; }
135 // setup the collector, and return the number of our virtual face
136 int collector_init() {
137 Collector collector;
138 collector.initialized = false;
139 collector.sent_prefix_p = false;
140 Body.reflex('c', noticeCollector);
141 // setup virtual face printer
142 bool worked = faceFindFreeFace(virtual_face);
143 API_ASSERT_TRUE(worked);
144 faceSetPrinter(virtual_face, &collector_printer);
145 return(virtual_face);