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

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