source: branches/fscctrl_safety_limits/src/DimState.h@ 18801

Last change on this file since 18801 was 16282, checked in by tbretz, 12 years ago
Replaced push_back by emplac_back were reasonable.
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 "Service.h"
10#include "EventImp.h"
11#include "WindowLog.h"
12#include "Description.h"
13#include "StateMachineImp.h"
14
15class DimState
16{
17public:
18 enum
19 {
20 kOffline = -256,
21 kNotAvailable = -257,
22 };
23
24protected:
25 typedef std::function<int(const EventImp &)> callback;
26
27 callback fCallback;
28
29 void HandlerImp(const EventImp &evt)
30 {
31 const bool disconnected = evt.GetSize()==0;
32
33 last = cur;
34 cur = std::make_pair(evt.GetTime(), disconnected ? kOffline : evt.GetQoS());
35
36 msg = disconnected ? "" : evt.GetString();
37 }
38
39 int Callback(const EventImp &evt)
40 {
41 return fCallback ? fCallback(evt) : StateMachineImp::kSM_KeepState;
42 }
43
44 virtual int Handler(const EventImp &evt)
45 {
46 HandlerImp(evt);
47 return Callback(evt);
48 }
49
50public:
51 DimState() { }
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 int HandleDesc(const EventImp &evt)
148 {
149 if (evt.GetSize()>0)
150 {
151 states = State::SplitStates(evt.GetString());
152 states.emplace_back(kOffline, "Offline");
153
154 CallbackStates();
155 }
156
157 return StateMachineImp::kSM_KeepState;
158 }
159
160 State description() const
161 {
162 for (auto it=states.begin(); it!=states.end(); it++)
163 if (it->index==state())
164 return State(it->index, it->name, it->comment, time());
165
166 return State(kNotAvailable, "n/a");
167 }
168};
169
170class DimDescriptions : public DimDescribedState
171{
172 typedef std::function<void()> callback_desc;
173
174 callback_desc fCallbackDescriptions;
175
176 virtual void CallbackDescriptions()
177 {
178 if (fCallbackDescriptions)
179 fCallbackDescriptions();
180 }
181
182public:
183 DimDescriptions(const std::string &n) : DimDescribedState(n)
184 {
185 }
186
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(), "", time());
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", "", time());
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
387class DimDnsServiceList : public DimDnsServerList
388{
389 StateMachineImp *fStateMachine;
390
391 typedef std::function<void(const Service &)> callback_svc;
392
393 callback_svc fCallbackServiceAdd;
394 //callback_evt fCallbackServiceEvt;
395
396 std::vector<std::string> fServiceList;
397
398 std::set<std::string> fServers;
399
400 void CallbackServerAdd(const std::string &server)
401 {
402 DimDnsServerList::CallbackServerAdd(server);
403
404 if (fServers.find(server)!=fServers.end())
405 return;
406
407 fStateMachine->Subscribe(server+"/SERVICE_LIST")
408 (fStateMachine->Wrap(std::bind(&DimDnsServiceList::HandlerServiceList, this, std::placeholders::_1)));
409
410 fServers.insert(server);
411 }
412
413 void HandlerServiceListImp(const EventImp &evt);
414
415/*
416 virtual void CallbackServiceEvt(const EventImp &evt)
417 {
418 if (fCallbackServiceEvt)
419 fCallbackServiceEvt(evt);
420 }
421*/
422 virtual int HandlerServiceList(const EventImp &evt)
423 {
424 HandlerServiceListImp(evt);
425 //CallbackServiceEvent(evt);
426
427 return StateMachineImp::kSM_KeepState;
428 }
429
430
431 virtual void CallbackServiceAdd(const Service &service)
432 {
433 if (fCallbackServiceAdd)
434 fCallbackServiceAdd(service);
435 }
436
437public:
438 DimDnsServiceList() : fStateMachine(0)
439 {
440 }
441
442 void Subscribe(StateMachineImp &imp)
443 {
444 fStateMachine = &imp;
445 DimDnsServerList::Subscribe(imp);
446 }
447
448 void SetCallbackServiceAdd(const callback_svc &cb)
449 {
450 fCallbackServiceAdd = cb;
451 }
452/*
453 void SetCallbackServiceEvt(const callback_svc &cb)
454 {
455 fCallbackServiceEvt = cb;
456 }
457*/
458};
459
460#endif
Note: See TracBrowser for help on using the repository browser.