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

Last change on this file since 14348 was 14123, checked in by tbretz, 12 years ago
Fixed a problem when calling the base class in Subscribe
File size: 10.0 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<void(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 void Callback(const EventImp &evt)
39 {
40 if (fCallback)
41 fCallback(evt);
42 }
43
44 virtual void Handler(const EventImp &evt)
45 {
46 HandlerImp(evt);
47 Callback(evt);
48 }
49
50public:
51 DimState() { std::cout << "DefCon" << std::endl; }
52 DimState(const std::string &n, const std::string s="STATE") : server(n),
53 service(n+"/"+s),
54 last(std::make_pair(Time(), kOffline)), cur(std::make_pair(Time(), kOffline))
55 {
56 }
57 virtual ~DimState()
58 {
59 }
60
61 /*const*/ std::string server;
62 /*const*/ std::string service;
63
64 std::pair<Time, int32_t> last;
65 std::pair<Time, int32_t> cur;
66 std::string msg;
67
68 virtual void Subscribe(StateMachineImp &imp)
69 {
70 imp.Subscribe(service)
71 (imp.Wrap(std::bind(&DimState::Handler, this, std::placeholders::_1)));
72 }
73
74 void SetCallback(const callback &cb)
75 {
76 fCallback = cb;
77 }
78
79 const Time &time() const { return cur.first; }
80 const int32_t &state() const { return cur.second; }
81
82 bool online() const { return state()>kOffline; }
83
84 virtual State description() const { return State(kNotAvailable, ""); }
85};
86
87inline std::ostream &operator<<(std::ostream& out, const DimState &s)
88{
89 const State rc = s.description();
90
91 out << s.time().GetAsStr("%H:%M:%S.%f").substr(0, 12) << " - ";
92 out << kBold << s.server;
93
94 if (s.state()==DimState::kOffline)
95 return out << ": Offline";
96
97 if (rc.index==DimState::kNotAvailable)
98 return out;
99
100 out << ": ";
101
102// if (rc.index==-2)
103// out << s.state();
104// else
105 out << rc.name << "[" << rc.index << "]";
106
107 if (!rc.comment.empty())
108 out << " - " << kBlue << rc.comment;
109
110 return out;
111}
112
113
114class DimDescribedState : public DimState
115{
116 typedef std::function<void()> callback_desc;
117
118 callback_desc fCallbackStates;
119
120 virtual void CallbackStates()
121 {
122 if (fCallbackStates)
123 fCallbackStates();
124 }
125
126
127public:
128 DimDescribedState(const std::string &n) : DimState(n)
129 {
130 }
131
132 std::vector<State> states;
133
134 virtual void Subscribe(StateMachineImp &imp)
135 {
136 imp.Subscribe(server+"/STATE_LIST")
137 (imp.Wrap(std::bind(&DimDescribedState::HandleDesc, this, std::placeholders::_1)));
138
139 DimState::Subscribe(imp);
140 }
141
142 void SetCallbackStates(const callback_desc &cb)
143 {
144 fCallbackStates = cb;
145 }
146
147 void HandleDesc(const EventImp &evt)
148 {
149 if (evt.GetSize()>0)
150 {
151 states = State::SplitStates(evt.GetString());
152 states.push_back(State(kOffline, "Offline"));
153
154 CallbackStates();
155 }
156 }
157
158 State description() const
159 {
160 for (auto it=states.begin(); it!=states.end(); it++)
161 if (it->index==state())
162 return *it;
163
164 return State(kNotAvailable, "n/a");
165 }
166};
167
168class DimDescriptions : public DimDescribedState
169{
170 typedef std::function<void()> callback_desc;
171
172 callback_desc fCallbackDescriptions;
173
174 virtual void CallbackDescriptions()
175 {
176 if (fCallbackDescriptions)
177 fCallbackDescriptions();
178 }
179
180public:
181 DimDescriptions(const std::string &n) : DimDescribedState(n)
182 {
183 }
184
185 std::vector<State> states;
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 void 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};
216
217class DimVersion : public DimState
218{
219 void Handler(const EventImp &evt)
220 {
221 HandlerImp(evt);
222
223 cur.second = evt.GetSize()==4 ? evt.GetInt() : kOffline;
224 if (cur.second==0)
225 cur.second=kOffline;
226
227 Callback(evt);
228 }
229
230public:
231 DimVersion() : DimState("DIS_DNS", "VERSION_NUMBER") { }
232
233 std::string version() const
234 {
235 if (!online())
236 return "Offline";
237
238 std::ostringstream out;
239 out << "V" << state()/100 << 'r' << state()%100;
240 return out.str();
241 }
242
243 State description() const
244 {
245 return State(state(), version());
246 }
247};
248
249class DimControl : public DimState
250{
251 std::map<std::string, callback> fCallbacks;
252
253 void Handler(const EventImp &evt)
254 {
255 HandlerImp(evt);
256
257 shortmsg = msg;
258 file = "";
259 scriptdepth = -1;
260
261 // Evaluate msg
262 const size_t p0 = msg.find_first_of(':');
263 if (p0==std::string::npos)
264 return;
265
266 // Evaluate scriptdepth
267 const size_t ps = msg.find_first_of('-');
268 if (ps!=std::string::npos)
269 scriptdepth = atoi(msg.c_str()+ps+1);
270
271 // Find filename
272 const size_t p1 = msg.find_last_of('[');
273 if (p1==std::string::npos)
274 return;
275
276 const size_t p2 = msg.find_first_of(':', p0+1);
277
278 const size_t p3 = p2==std::string::npos || p2>p1 ? p1-1 : p2;
279
280 file = msg.substr(p0+2, p3-p0-2);
281
282 shortmsg.erase(p0, p3-p0);
283
284 Callback(evt);
285
286 const auto func = fCallbacks.find(file);
287 if (func==fCallbacks.end())
288 return;
289
290 // Call callback
291 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");
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 void HandlerServer(const EventImp &evt)
343 {
344 HandlerServerImp(evt);
345 CallbackServerEvent(evt);
346 }
347
348public:
349 DimDnsServerList()
350 {
351 }
352 virtual ~DimDnsServerList()
353 {
354 }
355
356 Time time;
357 std::string msg;
358
359 virtual void Subscribe(StateMachineImp &imp)
360 {
361 imp.Subscribe("DIS_DNS/SERVER_LIST")
362 (imp.Wrap(std::bind(&DimDnsServerList::HandlerServer, this, std::placeholders::_1)));
363 }
364
365 void SetCallbackServerAdd(const callback_srv &cb)
366 {
367 fCallbackServerAdd = cb;
368 }
369
370 void SetCallbackServerRemove(const callback_srv &cb)
371 {
372 fCallbackServerRemove = cb;
373 }
374
375 void SetCallbackServerEvent(const callback_evt &cb)
376 {
377 fCallbackServerEvent = cb;
378 }
379
380 //const Time &time() const { return time; }
381 //const std::string &msg() const { return msg; }
382};
383
384struct Service
385{
386 std::string name;
387 std::string server;
388 std::string service;
389 std::string format;
390 bool iscmd;
391};
392
393inline bool operator<(const Service& left, const Service& right)
394{
395 return left.name < right.name;
396}
397
398class DimDnsServiceList : public DimDnsServerList
399{
400 StateMachineImp *fStateMachine;
401
402 typedef std::function<void(const Service &)> callback_svc;
403
404 callback_svc fCallbackServiceAdd;
405 //callback_evt fCallbackServiceEvt;
406
407 std::vector<std::string> fServiceList;
408
409 void CallbackServerAdd(const std::string &server)
410 {
411 fStateMachine->Subscribe(server+"/SERVICE_LIST")
412 (fStateMachine->Wrap(std::bind(&DimDnsServiceList::HandlerServiceList, this, std::placeholders::_1)));
413
414 DimDnsServerList::CallbackServerAdd(server);
415 }
416
417 void HandlerServiceListImp(const EventImp &evt);
418
419/*
420 virtual void CallbackServiceEvt(const EventImp &evt)
421 {
422 if (fCallbackServiceEvt)
423 fCallbackServiceEvt(evt);
424 }
425*/
426 virtual void HandlerServiceList(const EventImp &evt)
427 {
428 HandlerServiceListImp(evt);
429 //CallbackServiceEvent(evt);
430 }
431
432
433 virtual void CallbackServiceAdd(const Service &service)
434 {
435 if (fCallbackServiceAdd)
436 fCallbackServiceAdd(service);
437 }
438
439public:
440 DimDnsServiceList() : fStateMachine(0)
441 {
442 }
443
444 void Subscribe(StateMachineImp &imp)
445 {
446 fStateMachine = &imp;
447 DimDnsServerList::Subscribe(imp);
448 }
449
450 void SetCallbackServiceAdd(const callback_svc &cb)
451 {
452 fCallbackServiceAdd = cb;
453 }
454/*
455 void SetCallbackServiceEvt(const callback_svc &cb)
456 {
457 fCallbackServiceEvt = cb;
458 }
459*/
460};
461
462#endif
Note: See TracBrowser for help on using the repository browser.