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

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