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

Last change on this file since 14547 was 14541, checked in by tbretz, 12 years ago
Added time to State so that the time of state reception is propagated.
File size: 10.3 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 State(it->index, it->name, it->comment, time());
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<std::vector<Description>> descriptions;
187
188 virtual void Subscribe(StateMachineImp &imp)
189 {
190 imp.Subscribe(server+"/SERVICE_DESC")
191 (imp.Wrap(std::bind(&DimDescriptions::HandleServiceDesc, this, std::placeholders::_1)));
192
193 DimDescribedState::Subscribe(imp);
194 }
195
196 void SetCallbackDescriptions(const callback_desc &cb)
197 {
198 fCallbackDescriptions = cb;
199 }
200
201
202 int HandleServiceDesc(const EventImp &evt)
203 {
204 descriptions.clear();
205 if (evt.GetSize()>0)
206 {
207 std::string buf;
208 std::stringstream stream(evt.GetString());
209 while (getline(stream, buf, '\n'))
210 descriptions.push_back(Description::SplitDescription(buf));
211 }
212
213 CallbackDescriptions();
214
215 return StateMachineImp::kSM_KeepState;
216 }
217};
218
219class DimVersion : public DimState
220{
221 int Handler(const EventImp &evt)
222 {
223 HandlerImp(evt);
224
225 cur.second = evt.GetSize()==4 ? evt.GetInt() : kOffline;
226 if (cur.second==0)
227 cur.second=kOffline;
228
229 return Callback(evt);
230 }
231
232public:
233 DimVersion() : DimState("DIS_DNS", "VERSION_NUMBER") { }
234
235 std::string version() const
236 {
237 if (!online())
238 return "Offline";
239
240 std::ostringstream out;
241 out << "V" << state()/100 << 'r' << state()%100;
242 return out.str();
243 }
244
245 State description() const
246 {
247 return State(state(), version(), "", time());
248 }
249};
250
251class DimControl : public DimState
252{
253 std::map<std::string, callback> fCallbacks;
254
255 int Handler(const EventImp &evt)
256 {
257 HandlerImp(evt);
258
259 shortmsg = msg;
260 file = "";
261 scriptdepth = -1;
262
263 // Find begining of descriptor
264 const size_t p0 = msg.find_first_of(' ');
265 if (p0==std::string::npos)
266 return StateMachineImp::kSM_KeepState;
267
268 // Find begining of filename
269 const size_t p1 = msg.find_first_of(':');
270 if (p1==std::string::npos)
271 return StateMachineImp::kSM_KeepState;
272
273 // Find end of filename
274 const size_t p2 = msg.find_last_of('[');
275 if (p2==std::string::npos)
276 return StateMachineImp::kSM_KeepState;
277
278 scriptdepth = atoi(msg.c_str()+p0+1);
279 file = msg.substr(p1+1, p2-p1-1);
280
281 shortmsg.insert(0, msg.substr(p0+1, p1-p0));
282 shortmsg.erase(p1+1,p2-p0-1);
283
284 const int rc = Callback(evt);
285
286 const auto func = fCallbacks.find(file);
287 if (func==fCallbacks.end())
288 return rc;
289
290 // Call callback
291 return func->second(evt);
292 }
293
294
295public:
296 DimControl() : DimState("DIM_CONTROL") { }
297
298 std::string file;
299 std::string shortmsg;
300 int scriptdepth;
301
302 void AddCallback(const std::string &script, const callback &cb)
303 {
304 fCallbacks[script] = cb;
305 }
306
307 State description() const
308 {
309 return State(state(), "Current label", "", time());
310 }
311};
312
313class DimDnsServerList
314{
315protected:
316 typedef std::function<void(const std::string &)> callback_srv;
317 typedef std::function<void(const EventImp &)> callback_evt;
318
319 callback_srv fCallbackServerAdd;
320 callback_srv fCallbackServerRemove;
321 callback_evt fCallbackServerEvent;
322
323 std::set<std::string> fServerList;
324
325 void HandlerServerImp(const EventImp &evt);
326
327 virtual void CallbackServerAdd(const std::string &str)
328 {
329 if (fCallbackServerAdd)
330 fCallbackServerAdd(str);
331 }
332 virtual void CallbackServerRemove(const std::string &str)
333 {
334 if (fCallbackServerRemove)
335 fCallbackServerRemove(str);
336 }
337 virtual void CallbackServerEvent(const EventImp &evt)
338 {
339 if (fCallbackServerEvent)
340 fCallbackServerEvent(evt);
341 }
342 virtual int HandlerServer(const EventImp &evt)
343 {
344 HandlerServerImp(evt);
345 CallbackServerEvent(evt);
346
347 return StateMachineImp::kSM_KeepState;
348 }
349
350public:
351 DimDnsServerList()
352 {
353 }
354 virtual ~DimDnsServerList()
355 {
356 }
357
358 Time time;
359 std::string msg;
360
361 virtual void Subscribe(StateMachineImp &imp)
362 {
363 imp.Subscribe("DIS_DNS/SERVER_LIST")
364 (imp.Wrap(std::bind(&DimDnsServerList::HandlerServer, this, std::placeholders::_1)));
365 }
366
367 void SetCallbackServerAdd(const callback_srv &cb)
368 {
369 fCallbackServerAdd = cb;
370 }
371
372 void SetCallbackServerRemove(const callback_srv &cb)
373 {
374 fCallbackServerRemove = cb;
375 }
376
377 void SetCallbackServerEvent(const callback_evt &cb)
378 {
379 fCallbackServerEvent = cb;
380 }
381
382 //const Time &time() const { return time; }
383 //const std::string &msg() const { return msg; }
384};
385
386struct Service
387{
388 std::string name;
389 std::string server;
390 std::string service;
391 std::string format;
392 bool iscmd;
393};
394
395inline bool operator<(const Service& left, const Service& right)
396{
397 return left.name < right.name;
398}
399
400class DimDnsServiceList : public DimDnsServerList
401{
402 StateMachineImp *fStateMachine;
403
404 typedef std::function<void(const Service &)> callback_svc;
405
406 callback_svc fCallbackServiceAdd;
407 //callback_evt fCallbackServiceEvt;
408
409 std::vector<std::string> fServiceList;
410
411 void CallbackServerAdd(const std::string &server)
412 {
413 fStateMachine->Subscribe(server+"/SERVICE_LIST")
414 (fStateMachine->Wrap(std::bind(&DimDnsServiceList::HandlerServiceList, this, std::placeholders::_1)));
415
416 DimDnsServerList::CallbackServerAdd(server);
417 }
418
419 void HandlerServiceListImp(const EventImp &evt);
420
421/*
422 virtual void CallbackServiceEvt(const EventImp &evt)
423 {
424 if (fCallbackServiceEvt)
425 fCallbackServiceEvt(evt);
426 }
427*/
428 virtual int HandlerServiceList(const EventImp &evt)
429 {
430 HandlerServiceListImp(evt);
431 //CallbackServiceEvent(evt);
432
433 return StateMachineImp::kSM_KeepState;
434 }
435
436
437 virtual void CallbackServiceAdd(const Service &service)
438 {
439 if (fCallbackServiceAdd)
440 fCallbackServiceAdd(service);
441 }
442
443public:
444 DimDnsServiceList() : fStateMachine(0)
445 {
446 }
447
448 void Subscribe(StateMachineImp &imp)
449 {
450 fStateMachine = &imp;
451 DimDnsServerList::Subscribe(imp);
452 }
453
454 void SetCallbackServiceAdd(const callback_svc &cb)
455 {
456 fCallbackServiceAdd = cb;
457 }
458/*
459 void SetCallbackServiceEvt(const callback_svc &cb)
460 {
461 fCallbackServiceEvt = cb;
462 }
463*/
464};
465
466#endif
Note: See TracBrowser for help on using the repository browser.