Changeset 13671 for trunk/FACT++
- Timestamp:
- 05/12/12 12:41:13 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/dimctrl.cc
r13006 r13671 1 #ifndef FACT_DimCtrl 2 #define FACT_DimCtrl 3 4 #include "Main.h" 5 #include "tools.h" 6 #include "MessageDim.h" 1 7 #include "RemoteControl.h" 2 #include "Main.h"3 8 4 9 using namespace std; … … 33 38 34 39 // A simple dummy state machine 35 class DimCtrl : public MainImp, public MessageImp 36 { 37 bool fStop; 40 class DimCtrl : public MainImp, public DimCommandHandler, public MessageDimTX 41 { 42 int fLabel; 43 int fStop; 44 int fVerbosity; 45 bool fDebug; 46 bool fIsServer; 47 48 DimDescribedService fSrvState; 49 DimCommand fDimStart; 50 DimCommand fDimStop; 51 52 map<string,string> fData; 53 string fScript; 54 55 void ProcessStart() 56 { 57 if (!fScript.empty() || fLabel>=0) 58 { 59 Error("Script execution still in progress."); 60 return; 61 } 62 63 string opt(fDimStart.getString()); 64 65 fData = Tools::Split(opt); 66 67 if (opt.size()==0) 68 { 69 if (fData.size()==0) 70 Error("File name missing in DIM_CONTROL/START"); 71 else 72 Error("Equal sign missing in argument '"+fData.begin()->first+"'"); 73 74 return; 75 } 76 77 Debug("Start '"+opt+"' received."); 78 if (fDebug) 79 { 80 string d(fDimStart.getString()); 81 if (d.length()>opt.length()) 82 Debug("Received data: "+string(fDimStart.getString()).substr(opt.length()+1)); 83 } 84 85 if (fDebug) 86 { 87 for (auto it=fData.begin(); it!=fData.end(); it++) 88 Debug(" Arg: "+it->first+" = "+it->second); 89 } 90 91 fScript = opt; 92 } 93 94 void commandHandler() 95 { 96 if (getCommand()==&fDimStop) 97 { 98 Debug("Stop received"); 99 Readline::SetLabel(0); 100 } 101 102 if (getCommand()==&fDimStart) 103 ProcessStart(); 104 } 38 105 39 106 public: 40 DimCtrl(ostream &out=cout) : MessageImp(out), fStop(false) 41 { 42 } 43 44 int EvalOptions(Configuration &) { return -1; } 45 void Stop() { fStop = true; } 46 int Run(bool) { while (!fStop) usleep(1000); return 0; } 107 DimCtrl(ostream &out=cout) : MessageDimTX("DIM_CONTROL", out), 108 fLabel(-3), fStop(false), fVerbosity(0), fDebug(false), fIsServer(false), 109 fSrvState("DIM_CONTROL/STATE", "C", 110 "Provides the state of the state machine as quality of service." 111 "|Text[string]:A human readable string sent by the last state change."), 112 fDimStart("DIM_CONTROL/START", "C", this), 113 fDimStop("DIM_CONTROL/STOP", "", this) 114 { 115 } 116 ~DimCtrl() 117 { 118 DimServer::stop(); 119 } 120 121 bool check(string &str) 122 { 123 for (auto c=str.begin(); c<str.end(); c++) 124 { 125 if ((*c>='A' && *c<='Z') || *c=='_') 126 continue; 127 128 if (*c++!=':') 129 return false; 130 131 if (c==str.end()) 132 return false; 133 134 if (*c!=' ') 135 return false; 136 137 str = string(c+1, str.end()); 138 return true; 139 } 140 141 return false; 142 } 143 144 int Write(const Time &time, const std::string &txt, int qos=kMessage) 145 { 146 if (txt=="") 147 { 148 fLabel = qos; 149 150 if (fDebug) 151 { 152 ostringstream out; 153 if (fLabel<0) 154 { 155 if (fLabel==-1) 156 out << "========================== Begin ========================"; 157 else 158 out << "=========================== End ========================="; 159 } 160 else 161 out << "------------------------ Label " << setfill('0') << setw(3) << fLabel << " ----------------------"; 162 163 MessageDimTX::Write(time, out.str(), 90); 164 } 165 166 fSrvState.setQuality(fLabel); 167 switch (fLabel) 168 { 169 case -2: return fSrvState.Update("End of script execution"); 170 case -1: return fSrvState.Update("Start of script execution"); 171 default: return fSrvState.Update("New label"); 172 } 173 } 174 175 if (qos<fVerbosity) 176 return 0; 177 178 // Avoid recursions 179 if (fIsServer && txt.substr(0, 13)=="DIM_CONTROL: ") 180 return 0; 181 182 // Don't send received messages via dim 183 string cpy(txt); 184 if (fIsServer && check(cpy)) 185 return MessageImp::Write(time, cpy, qos); 186 187 // Send all of our own messages via dim 188 return MessageDimTX::Write(time, txt, qos); 189 } 190 191 int EvalOptions(Configuration &conf) 192 { 193 fVerbosity = 90; 194 195 if (conf.Get<bool>("stop")) 196 return Dim::SendCommand("DIM_CONTROL/STOP") + 1; 197 198 if (conf.Has("start")) 199 return Dim::SendCommand("DIM_CONTROL/START", conf.Get<string>("start")) + 1; 200 201 fVerbosity = 40; 202 203 fIsServer = conf.Get<bool>("server"); 204 if (fIsServer) 205 { 206 // Sleep needed to ensure that the server can send 207 // an EXIT if another instance is already running 208 DimServer::start("DIM_CONTROL"); 209 sleep(1); 210 } 211 212 if (conf.Has("verbosity")) 213 fVerbosity = conf.Get<uint32_t>("verbosity"); 214 215 if (conf.Get<bool>("quiet")) 216 fVerbosity = 90; 217 218 fDebug = conf.Get<bool>("debug"); 219 220 return -1; 221 } 222 223 void Stop(int stop=1) { fStop = stop; Readline::SetLabel(0); } 224 int Run(bool) 225 { 226 while (!fStop) 227 { 228 const string s = fScript; 229 if (!s.empty()) 230 { 231 Readline::Instance()->Execute(s, fData); 232 fScript = ""; 233 } 234 235 usleep(1000); 236 } 237 return fStop-1; } 47 238 }; 239 240 void SetupConfiguration(Configuration &conf) 241 { 242 po::options_description control("Dim Control"); 243 control.add_options() 244 ("server", po_bool(false), "Start dimctrl as a dim server") 245 ("verbosity,v", var<uint32_t>()->implicit_value(0), "Set a new verbosity level (see MessageImp)") 246 ("quiet,q", po_bool(false), "Suppress all output except comments (log-level>=90)") 247 ("debug", po_bool(false), "Print the labels for debugging purpose") 248 ("start", var<string>(), "") 249 ("stop", po_switch(), "") 250 ; 251 252 conf.AddOptions(control); 253 } 48 254 49 255 int main(int argc, const char *argv[]) … … 52 258 conf.SetPrintUsage(PrintUsage); 53 259 Main::SetupConfiguration(conf); 260 SetupConfiguration(conf); 54 261 55 262 if (!conf.DoParse(argc, argv, PrintHelp)) 56 263 return -1; 57 264 58 if (!conf.Has("console") || conf.Get<int>("console")==0) 265 if (!conf.Has("console")) 266 return Main::execute<RemoteStream, DimCtrl>(conf); 267 268 if (conf.Get<int>("console")==0) 59 269 return Main::execute<RemoteShell, DimCtrl>(conf); 60 270 else … … 63 273 return 0; 64 274 } 275 #endif
Note:
See TracChangeset
for help on using the changeset viewer.