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
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
25 char reverseStep(char step
) {
30 default: pprintf("L hork on %c\n", step
); return 'z';
34 void Collector::update_coords() {
39 while(path
[ind
] != '\0') {
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;
54 default: pprintf("L hork on '%d' path direction\n", dir
); return;
60 void Collector::report_prefix() {
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
) {
74 if (packetScanf(packet
, "c%d", &count
) != 2) {
75 pprintf("L bad '%#p'\n",packet
);
78 if (count
> collector
.count
) {
79 collector
.initialized
= true;
80 collector
.count
= count
;
81 collector
.out_face
= packetSource(packet
);
84 while(packetScanf(packet
, "%c", &ch
)) { // extract the return path
86 collector
.path
[path_ind
] = ch
;
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
;
98 else if (f
== 2) out
= 1;
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
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() {
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
);