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

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