source: trunk/FACT++/src/DimState.h@ 14491

Last change on this file since 14491 was 14371, checked in by tbretz, 12 years ago
Adapted to new format of Dim Control messages.
File size: 10.2 KB
Line 
1#ifndef FACT_DimState
2#define FACT_DimState
3
4#include <set>
5#include <string>
6#include <functional>
7
8#include "State.h"
9#include "EventImp.h"
10#include "WindowLog.h"
11#include "Description.h"
12#include "StateMachineImp.h"
13
14class DimState
15{
16public:
17 enum
18 {
19 kOffline = -256,
20 kNotAvailable = -257,
21 };
22
23protected:
24 typedef std::function<int(const EventImp &)> callback;
25
26 callback fCallback;
27
28 void HandlerImp(const EventImp &evt)
29 {
30 const bool disconnected = evt.GetSize()==0;
31
32 last = cur;
33 cur = std::make_pair(evt.GetTime(), disconnected ? kOffline : evt.GetQoS());
34
35 msg = disconnected ? "" : evt.GetString();
36 }
37
38 int Callback(const EventImp &evt)
39 {
40 return fCallback ? fCallback(evt) : StateMachineImp::kSM_KeepState;
41 }
42
43 virtual int Handler(const EventImp &evt)
44 {
45 HandlerImp(evt);
46 return Callback(evt);
47 }
48
49public:
50 DimState() { }
51 DimState(const std::string &n, const std::string s="STATE") : server(n),
52 service(n+"/"+s),
53 last(std::make_pair(Time(), kOffline)), cur(std::make_pair(Time(), kOffline))
54 {
55 }
56 virtual ~DimState()
57 {
58 }
59
60 /*const*/ std::string server;
61 /*const*/ std::string service;
62
63 std::pair<Time, int32_t> last;
64 std::pair<Time, int32_t> cur;
65 std::string msg;
66
67 virtual void Subscribe(StateMachineImp &imp)
68 {
69 imp.Subscribe(service)
70 (imp.Wrap(std::bind(&DimState::Handler, this, std::placeholders::_1)));
71 }
72
73 void SetCallback(const callback &cb)
74 {
75 fCallback = cb;
76 }
77
78 const Time &time() const { return cur.first; }
79 const int32_t &state() const { return cur.second; }
80
81 bool online() const { return state()>kOffline; }
82
83 virtual State description() const { return State(kNotAvailable, ""); }
84};
85
86inline std::ostream &operator<<(std::ostream& out, const DimState &s)
87{
88 const State rc = s.description();
89
90 out << s.time().GetAsStr("%H:%M:%S.%f").substr(0, 12) << " - ";
91 out << kBold << s.server;
92
93 if (s.state()==DimState::kOffline)
94 return out << ": Offline";
95
96 if (rc.index==DimState::kNotAvailable)
97 return out;
98
99 out << ": ";
100
101// if (rc.index==-2)
102// out << s.state();
103// else
104 out << rc.name << "[" << rc.index << "]";
105
106 if (!rc.comment.empty())
107 out << " - " << kBlue << rc.comment;
108
109 return out;
110}
111
112
113class DimDescribedState : public DimState
114{
115 typedef std::function<void()> callback_desc;
116
117 callback_desc fCallbackStates;
118
119 virtual void CallbackStates()
120 {
121 if (fCallbackStates)
122 fCallbackStates();
123 }
124
125
126public:
127 DimDescribedState(const std::string &n) : DimState(n)
128 {
129 }
130
131 std::vector<State> states;
132
133 virtual void Subscribe(StateMachineImp &imp)
134 {
135 imp.Subscribe(server+"/STATE_LIST")
136 (imp.Wrap(std::bind(&DimDescribedState::HandleDesc, this, std::placeholders::_1)));
137
138 DimState::Subscribe(imp);
139 }
140
141 void SetCallbackStates(const callback_desc &cb)
142 {
143 fCallbackStates = cb;
144 }
145
146 int HandleDesc(const EventImp &evt)
147 {
148 if (evt.GetSize()>0)
149 {
150 states = State::SplitStates(evt.GetString());
151 states.push_back(State(kOffline, "Offline"));
152
153 CallbackStates();
154 }
155
156 return StateMachineImp::kSM_KeepState;
157 }
158
159 State description() const
160 {
161 for (auto it=states.begin(); it!=states.end(); it++)
162 if (it->index==state())
163 return *it;
164
165 return State(kNotAvailable, "n/a");
166 }
167};
168
169class DimDescriptions : public DimDescribedState
170{
171 typedef std::function<void()> callback_desc;
172
173 callback_desc fCallbackDescriptions;
174
175 virtual void CallbackDescriptions()
176 {
177 if (fCallbackDescriptions)
178 fCallbackDescriptions();
179 }
180
181public:
182 DimDescriptions(const std::string &n) : DimDescribedState(n)
183 {
184 }
185
186 std::vector<State> states;
187 std::vector<std::vector<Description>> descriptions;
188
189 virtual void Subscribe(StateMachineImp &imp)
190 {
191 imp.Subscribe(server+"/SERVICE_DESC")
192 (imp.Wrap(std::bind(&DimDescriptions::HandleServiceDesc, this, std::placeholders::_1)));
193
194 DimDescribedState::Subscribe(imp);
195 }
196
197 void SetCallbackDescriptions(const callback_desc &cb)
198 {
199 fCallbackDescriptions = cb;
200 }
201
202
203 int HandleServiceDesc(const EventImp &evt)
204 {
205 descriptions.clear();
206 if (evt.GetSize()>0)
207 {
208 std::string buf;
209 std::stringstream stream(evt.GetString());
210 while (getline(stream, buf, '\n'))
211 descriptions.push_back(Description::SplitDescription(buf));
212 }
213
214 CallbackDescriptions();
215
216 return StateMachineImp::kSM_KeepState;
217 }
218};
219
220class DimVersion : public DimState
221{
222 int Handler(const EventImp &evt)
223 {
224 HandlerImp(evt);
225
226 cur.second = evt.GetSize()==4 ? evt.GetInt() : kOffline;
227 if (cur.second==0)
228 cur.second=kOffline;
229
230 return Callback(evt);
231 }
232
233public:
234 DimVersion() : DimState("DIS_DNS", "VERSION_NUMBER") { }
235
236 std::string version() const
237 {
238 if (!online())
239 return "Offline";
240
241 std::ostringstream out;
242 out << "V" << state()/100 << 'r' << state()%100;
243 return out.str();
244 }
245
246 State description() const
247 {
248 return State(state(), version());
249 }
250};
251
252class DimControl : public DimState
253{
254 std::map<std::string, callback> fCallbacks;
255
256 int Handler(const EventImp &evt)
257 {
258 HandlerImp(evt);
259
260 shortmsg = msg;
261 file = "";
262 scriptdepth = -1;
263
264 // Find begining of descriptor
265 const size_t p0 = msg.find_first_of(' ');
266 if (p0==std::string::npos)
267 return StateMachineImp::kSM_KeepState;
268
269 // Find begining of filename
270 const size_t p1 = msg.find_first_of(':');
271 if (p1==std::string::npos)
272 return StateMachineImp::kSM_KeepState;
273
274 // Find end of filename
275 const size_t p2 = msg.find_last_of('[');
276 if (p2==std::string::npos)
277 return StateMachineImp::kSM_KeepState;
278
279 scriptdepth = atoi(msg.c_str()+p0+1);
280 file = msg.substr(p1+1, p2-p1-1);
281
282 shortmsg.insert(0, msg.substr(p0+1, p1-p0));
283 shortmsg.erase(p1+1,p2-p0-1);
284
285 const int rc = Callback(evt);
286
287 const auto func = fCallbacks.find(file);
288 if (func==fCallbacks.end())
289 return rc;
290
291 // Call callback
292 return func->second(evt);
293 }
294
295
296public:
297 DimControl() : DimState("DIM_CONTROL") { }
298
299 std::string file;
300 std::string shortmsg;
301 int scriptdepth;
302
303 void AddCallback(const std::string &script, const callback &cb)
304 {
305 fCallbacks[script] = cb;
306 }
307
308 State description() const
309 {
310 return State(state(), "Current label");
311 }
312};
313
314class DimDnsServerList
315{
316protected:
317 typedef std::function<void(const std::string &)> callback_srv;
318 typedef std::function<void(const EventImp &)> callback_evt;
319
320 callback_srv fCallbackServerAdd;
321 callback_srv fCallbackServerRemove;
322 callback_evt fCallbackServerEvent;
323
324 std::set<std::string> fServerList;
325
326 void HandlerServerImp(const EventImp &evt);
327
328 virtual void CallbackServerAdd(const std::string &str)
329 {
330 if (fCallbackServerAdd)
331 fCallbackServerAdd(str);
332 }
333 virtual void CallbackServerRemove(const std::string &str)
334 {
335 if (fCallbackServerRemove)
336 fCallbackServerRemove(str);
337 }
338 virtual void CallbackServerEvent(const EventImp &evt)
339 {
340 if (fCallbackServerEvent)
341 fCallbackServerEvent(evt);
342 }
343 virtual int HandlerServer(const EventImp &evt)
344 {
345 HandlerServerImp(evt);
346 CallbackServerEvent(evt);
347
348 return StateMachineImp::kSM_KeepState;
349 }
350
351public:
352 DimDnsServerList()
353 {
354 }
355 virtual ~DimDnsServerList()
356 {
357 }
358
359 Time time;
360 std::string msg;
361
362 virtual void Subscribe(StateMachineImp &imp)
363 {
364 imp.Subscribe("DIS_DNS/SERVER_LIST")
365 (imp.Wrap(std::bind(&DimDnsServerList::HandlerServer, this, std::placeholders::_1)));
366 }
367
368 void SetCallbackServerAdd(const callback_srv &cb)
369 {
370 fCallbackServerAdd = cb;
371 }
372
373 void SetCallbackServerRemove(const callback_srv &cb)
374 {
375 fCallbackServerRemove = cb;
376 }
377
378 void SetCallbackServerEvent(const callback_evt &cb)
379 {
380 fCallbackServerEvent = cb;
381 }
382
383 //const Time &time() const { return time; }
384 //const std::string &msg() const { return msg; }
385};
386
387struct Service
388{
389 std::string name;
390 std::string server;
391 std::string service;
392 std::string format;
393 bool iscmd;
394};
395
396inline bool operator<(const Service& left, const Service& right)
397{
398 return left.name < right.name;
399}
400
401class DimDnsServiceList : public DimDnsServerList
402{
403 StateMachineImp *fStateMachine;
404
405 typedef std::function<void(const Service &)> callback_svc;
406
407 callback_svc fCallbackServiceAdd;
408 //callback_evt fCallbackServiceEvt;
409
410 std::vector<std::string> fServiceList;
411
412 void CallbackServerAdd(const std::string &server)
413 {
414 fStateMachine->Subscribe(server+"/SERVICE_LIST")
415 (fStateMachine->Wrap(std::bind(&DimDnsServiceList::HandlerServiceList, this, std::placeholders::_1)));
416
417 DimDnsServerList::CallbackServerAdd(server);
418 }
419
420 void HandlerServiceListImp(const EventImp &evt);
421
422/*
423 virtual void CallbackServiceEvt(const EventImp &evt)
424 {
425 if (fCallbackServiceEvt)
426 fCallbackServiceEvt(evt);
427 }
428*/
429 virtual int HandlerServiceList(const EventImp &evt)
430 {
431 HandlerServiceListImp(evt);
432 //CallbackServiceEvent(evt);
433
434 return StateMachineImp::kSM_KeepState;
435 }
436
437
438 virtual void CallbackServiceAdd(const Service &service)
439 {
440 if (fCallbackServiceAdd)
441 fCallbackServiceAdd(service);
442 }
443
444public:
445 DimDnsServiceList() : fStateMachine(0)
446 {
447 }
448
449 void Subscribe(StateMachineImp &imp)
450 {
451 fStateMachine = &imp;
452 DimDnsServerList::Subscribe(imp);
453 }
454
455 void SetCallbackServiceAdd(const callback_svc &cb)
456 {
457 fCallbackServiceAdd = cb;
458 }
459/*
460 void SetCallbackServiceEvt(const callback_svc &cb)
461 {
462 fCallbackServiceEvt = cb;
463 }
464*/
465};
466
467#endif
Note: See TracBrowser for help on using the repository browser.