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

Last change on this file since 14021 was 14015, checked in by tbretz, 12 years ago
Added support for 'the last state'
File size: 4.6 KB
Line 
1#ifndef FACT_DimState
2#define FACT_DimState
3
4#include "State.h"
5
6class DimState
7{
8protected:
9 typedef function<void(const EventImp &)> callback;
10
11 callback fCallback;
12
13 void HandlerImp(const EventImp &evt)
14 {
15 const bool disconnected = evt.GetSize()==0;
16
17 last = info;
18 info = make_pair(evt.GetTime(), disconnected ? -256 : evt.GetQoS());
19
20 msg = disconnected ? "" : evt.GetString();
21 }
22
23 void Callback(const EventImp &evt)
24 {
25 if (fCallback)
26 fCallback(evt);
27 }
28
29 virtual void Handler(const EventImp &evt)
30 {
31 HandlerImp(evt);
32 Callback(evt);
33 }
34
35public:
36 DimState(const string &n, const string s="STATE") : server(n),
37 service(n+"/"+s), info(make_pair(Time(), -256))
38 {
39 }
40 virtual ~DimState()
41 {
42 }
43
44 string server;
45 string service;
46
47 pair<Time, int> last;
48 pair<Time, int> info;
49 string msg;
50
51 virtual void Subscribe(StateMachineImp &imp)
52 {
53 imp.Subscribe(service.c_str())
54 (imp.Wrap(bind(&DimState::Handler, this, placeholders::_1)));
55 }
56
57 void SetCallback(const callback &cb)
58 {
59 fCallback = cb;
60 }
61
62 const Time &time() const { return info.first; }
63 const int &state() const { return info.second; }
64
65 bool online() const { return info.second>-256; }
66
67 virtual State description() const { return State(-257, ""); }
68};
69
70ostream &operator<<(ostream& out, const DimState &s)
71{
72 const State rc = s.description();
73
74 out << s.time().GetAsStr("%H:%M:%S.%f").substr(0, 12) << " - ";
75 out << kBold << s.server;
76
77 if (s.state()==-256)
78 return out << ": Offline";
79
80 if (rc.index==-257)
81 return out;
82
83 out << ": ";
84
85// if (rc.index==-2)
86// out << s.state();
87// else
88 out << rc.name << "[" << rc.index << "]";
89
90 if (!rc.comment.empty())
91 out << " - " << kBlue << rc.comment;
92
93 return out;
94}
95
96
97class DimDescribedState : public DimState
98{
99 vector<State> states;
100
101public:
102 DimDescribedState(const string &n) : DimState(n)
103 {
104 }
105
106 virtual void Subscribe(StateMachineImp &imp)
107 {
108 imp.Subscribe((server+"/STATE_LIST").c_str())
109 (imp.Wrap(bind(&DimDescribedState::HandleDesc, this, placeholders::_1)));
110
111 DimState::Subscribe(imp);
112 }
113
114 void HandleDesc(const EventImp &evt)
115 {
116 if (evt.GetSize()>0)
117 {
118 states = State::SplitStates(evt.GetString());
119 states.push_back(State(-256, "Offline"));
120 }
121 }
122
123 State description() const
124 {
125 for (auto it=states.begin(); it!=states.end(); it++)
126 if (it->index==state())
127 return *it;
128
129 return State(-257, "n/a");
130 }
131};
132
133class DimVersion : public DimState
134{
135 void Handler(const EventImp &evt)
136 {
137 HandlerImp(evt);
138
139 info.second = evt.GetSize()==4 ? evt.GetInt() : -256;
140 if (info.second==0)
141 info.second=-256;
142
143 Callback(evt);
144 }
145
146public:
147 DimVersion() : DimState("DIS_DNS", "VERSION_NUMBER") { }
148
149 string version() const
150 {
151 if (!online())
152 return "Offline";
153
154 ostringstream out;
155 out << "V" << info.second/100 << 'r' << info.second%100;
156 return out.str();
157 }
158
159 State description() const
160 {
161 return State(state(), version());
162 }
163};
164
165class DimControl : public DimState
166{
167 map<string, callback> fCallbacks;
168
169 void Handler(const EventImp &evt)
170 {
171 HandlerImp(evt);
172
173 shortmsg = msg;
174 file = "";
175 scriptdepth = -1;
176
177 // Evaluate msg
178 const size_t p0 = msg.find_first_of(':');
179 if (p0==string::npos)
180 return;
181
182 // Evaluate scriptdepth
183 const size_t ps = msg.find_first_of('-');
184 if (ps!=string::npos)
185 scriptdepth = atoi(msg.c_str()+ps+1);
186
187 // Find filename
188 const size_t p1 = msg.find_last_of('[');
189 if (p1==string::npos)
190 return;
191
192 const size_t p2 = msg.find_first_of(':', p0+1);
193
194 const size_t p3 = p2==string::npos || p2>p1 ? p1-1 : p2;
195
196 file = msg.substr(p0+2, p3-p0-2);
197
198 shortmsg.erase(p0, p3-p0);
199
200 Callback(evt);
201
202 const auto func = fCallbacks.find(file);
203 if (func==fCallbacks.end())
204 return;
205
206 // Call callback
207 func->second(evt);
208 }
209
210
211public:
212 DimControl() : DimState("DIM_CONTROL") { }
213
214 string file;
215 string shortmsg;
216 int scriptdepth;
217
218 void AddCallback(const string &script, const callback &cb)
219 {
220 fCallbacks[script] = cb;
221 }
222
223 State description() const
224 {
225 return State(state(), "Current label");
226 }
227};
228
229#endif
Note: See TracBrowser for help on using the repository browser.