00001 #ifndef Framework_EPStates_h
00002 #define Framework_EPStates_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "boost/statechart/event.hpp"
00016 #include "boost/statechart/state_machine.hpp"
00017 #include <boost/statechart/state.hpp>
00018 #include <boost/statechart/transition.hpp>
00019 #include <boost/mpl/list.hpp>
00020 #include <boost/statechart/custom_reaction.hpp>
00021 #include <vector>
00022 #include <set>
00023
00024 namespace sc = boost::statechart;
00025 namespace mpl = boost::mpl;
00026
00027 namespace edm {
00028 class IEventProcessor;
00029 }
00030
00031 namespace statemachine {
00032
00033 enum FileMode { NOMERGE, MERGE, FULLLUMIMERGE, FULLMERGE };
00034 int const INVALID_RUN = 0;
00035 int const INVALID_LUMI = 0;
00036
00037
00038
00039
00040 class Run : public sc::event<Run> {
00041 public:
00042 Run(int id);
00043 int id() const;
00044 private:
00045 int id_;
00046 };
00047
00048 class Lumi : public sc::event<Lumi> {
00049 public:
00050 Lumi(int id);
00051 int id() const;
00052 private:
00053 int id_;
00054 };
00055
00056
00057
00058 class Event : public sc::event<Event> { };
00059
00060 class File : public sc::event<File> {};
00061 class Stop : public sc::event<Stop> {};
00062 class Restart : public sc::event<Restart> {};
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 class Starting;
00073
00074 class Machine : public sc::state_machine<Machine, Starting>
00075 {
00076 public:
00077 Machine(edm::IEventProcessor* ep,
00078 FileMode fileMode,
00079 bool handleEmptyRuns,
00080 bool handleEmptyLumis);
00081
00082 edm::IEventProcessor& ep() const;
00083 FileMode fileMode() const;
00084 bool handleEmptyRuns() const;
00085 bool handleEmptyLumis() const;
00086
00087 void startingNewLoop(File const& file);
00088 void startingNewLoop(Stop const& stop);
00089 void rewindAndPrepareForNextLoop(Restart const& restart);
00090
00091 private:
00092
00093 edm::IEventProcessor* ep_;
00094 FileMode fileMode_;
00095 bool handleEmptyRuns_;
00096 bool handleEmptyLumis_;
00097 };
00098
00099 class Error;
00100 class HandleFiles;
00101 class EndingLoop;
00102
00103 class Starting : public sc::state<Starting, Machine>
00104 {
00105 public:
00106 Starting(my_context ctx);
00107 ~Starting();
00108
00109 typedef mpl::list<
00110 sc::transition<Event, Error>,
00111 sc::transition<Lumi, Error>,
00112 sc::transition<Run, Error>,
00113 sc::transition<File, HandleFiles, Machine, &Machine::startingNewLoop>,
00114 sc::transition<Stop, EndingLoop, Machine, &Machine::startingNewLoop>,
00115 sc::transition<Restart, Error> > reactions;
00116 };
00117
00118 class FirstFile;
00119
00120 class HandleFiles : public sc::state<HandleFiles, Machine, FirstFile>
00121 {
00122 public:
00123 HandleFiles(my_context ctx);
00124 void exit();
00125 ~HandleFiles();
00126
00127 typedef mpl::list<
00128 sc::transition<Event, Error>,
00129 sc::transition<Lumi, Error>,
00130 sc::transition<Run, Error>,
00131 sc::transition<File, Error>,
00132 sc::transition<Stop, EndingLoop>,
00133 sc::transition<Restart, Error> > reactions;
00134
00135 void closeFiles();
00136 void goToNewInputFile();
00137 bool shouldWeCloseOutput();
00138 private:
00139 edm::IEventProcessor & ep_;
00140 bool exitCalled_;
00141 };
00142
00143 class EndingLoop : public sc::state<EndingLoop, Machine>
00144 {
00145 public:
00146 EndingLoop(my_context ctx);
00147 ~EndingLoop();
00148 typedef mpl::list<
00149 sc::transition<Restart, Starting, Machine, &Machine::rewindAndPrepareForNextLoop>,
00150 sc::custom_reaction<Stop> > reactions;
00151
00152 sc::result react(Stop const&);
00153 private:
00154 edm::IEventProcessor & ep_;
00155 };
00156
00157 class Error : public sc::state<Error, Machine>
00158 {
00159 public:
00160 Error(my_context ctx);
00161 ~Error();
00162 typedef sc::transition<Stop, EndingLoop> reactions;
00163 private:
00164 edm::IEventProcessor & ep_;
00165 };
00166
00167 class HandleRuns;
00168
00169 class FirstFile : public sc::state<FirstFile, HandleFiles>
00170 {
00171 public:
00172 FirstFile(my_context ctx);
00173 ~FirstFile();
00174
00175 typedef mpl::list<
00176 sc::transition<Run, HandleRuns>,
00177 sc::custom_reaction<File> > reactions;
00178
00179 sc::result react(File const& file);
00180 void openFiles();
00181 private:
00182 edm::IEventProcessor & ep_;
00183 };
00184
00185 class HandleNewInputFile1 : public sc::state<HandleNewInputFile1, HandleFiles>
00186 {
00187 public:
00188 HandleNewInputFile1(my_context ctx);
00189 ~HandleNewInputFile1();
00190
00191 typedef mpl::list<
00192 sc::transition<Run, HandleRuns>,
00193 sc::custom_reaction<File> > reactions;
00194
00195 sc::result react(File const& file);
00196 };
00197
00198 class NewInputAndOutputFiles : public sc::state<NewInputAndOutputFiles, HandleFiles>
00199 {
00200 public:
00201 NewInputAndOutputFiles(my_context ctx);
00202 ~NewInputAndOutputFiles();
00203
00204 typedef mpl::list<
00205 sc::transition<Run, HandleRuns>,
00206 sc::custom_reaction<File> > reactions;
00207
00208 sc::result react(File const& file);
00209
00210 private:
00211
00212 void goToNewInputAndOutputFiles();
00213
00214 edm::IEventProcessor & ep_;
00215 };
00216
00217 class NewRun;
00218
00219 class HandleRuns : public sc::state<HandleRuns, HandleFiles, NewRun>
00220 {
00221 public:
00222 HandleRuns(my_context ctx);
00223 void exit();
00224 ~HandleRuns();
00225
00226 typedef sc::transition<File, NewInputAndOutputFiles> reactions;
00227
00228 bool beginRunCalled() const;
00229 int currentRun() const;
00230 bool runException() const;
00231 void setupCurrentRun();
00232 void beginRun(int run);
00233 void endRun(int run);
00234 void finalizeRun(Run const&);
00235 void finalizeRun();
00236 void beginRunIfNotDoneAlready();
00237 private:
00238 edm::IEventProcessor & ep_;
00239 bool exitCalled_;
00240 bool beginRunCalled_;
00241 int currentRun_;
00242 std::set<int> previousRuns_;
00243 bool runException_;
00244 };
00245
00246 class HandleLumis;
00247
00248 class NewRun : public sc::state<NewRun, HandleRuns>
00249 {
00250 public:
00251 NewRun(my_context ctx);
00252 ~NewRun();
00253
00254 typedef mpl::list<
00255 sc::transition<Lumi, HandleLumis>,
00256 sc::transition<Run, NewRun, HandleRuns, &HandleRuns::finalizeRun>,
00257 sc::custom_reaction<File> > reactions;
00258
00259 sc::result react(File const& file);
00260 };
00261
00262 class ContinueRun1;
00263
00264 class HandleNewInputFile2 : public sc::state<HandleNewInputFile2, HandleRuns>
00265 {
00266 public:
00267 HandleNewInputFile2(my_context ctx);
00268 ~HandleNewInputFile2();
00269 bool checkInvariant();
00270
00271 typedef mpl::list<
00272 sc::custom_reaction<Run>,
00273 sc::custom_reaction<File> > reactions;
00274
00275 sc::result react(Run const& run);
00276 sc::result react(File const& file);
00277 };
00278
00279 class ContinueRun1 : public sc::state<ContinueRun1, HandleRuns>
00280 {
00281 public:
00282 ContinueRun1(my_context ctx);
00283 ~ContinueRun1();
00284 bool checkInvariant();
00285
00286 typedef mpl::list<
00287 sc::transition<Run, NewRun, HandleRuns, &HandleRuns::finalizeRun>,
00288 sc::custom_reaction<File>,
00289 sc::transition<Lumi, HandleLumis> > reactions;
00290
00291 sc::result react(File const& file);
00292 private:
00293 edm::IEventProcessor & ep_;
00294 };
00295
00296 class FirstLumi;
00297
00298 class HandleLumis : public sc::state<HandleLumis, HandleRuns, FirstLumi>
00299 {
00300 public:
00301 typedef std::pair<int, int> LumiID;
00302 HandleLumis(my_context ctx);
00303 void exit();
00304 ~HandleLumis();
00305 bool checkInvariant();
00306
00307 LumiID currentLumi() const;
00308 bool currentLumiEmpty() const;
00309 std::vector<LumiID> const& unhandledLumis() const;
00310 void setupCurrentLumi();
00311 void finalizeAllLumis();
00312 void finalizeLumi();
00313 void finalizeOutstandingLumis();
00314 void markLumiNonEmpty();
00315
00316 typedef sc::transition<Run, NewRun, HandleRuns, &HandleRuns::finalizeRun> reactions;
00317
00318 private:
00319 edm::IEventProcessor & ep_;
00320 bool exitCalled_;
00321 bool currentLumiEmpty_;
00322 LumiID currentLumi_;
00323 std::set<LumiID> previousLumis_;
00324 std::vector<LumiID> unhandledLumis_;
00325 bool lumiException_;
00326 };
00327
00328 class HandleEvent;
00329 class AnotherLumi;
00330
00331 class FirstLumi : public sc::state<FirstLumi, HandleLumis>
00332 {
00333 public:
00334 FirstLumi(my_context ctx);
00335 ~FirstLumi();
00336 bool checkInvariant();
00337
00338 typedef mpl::list<
00339 sc::transition<Event, HandleEvent>,
00340 sc::transition<Lumi, AnotherLumi>,
00341 sc::custom_reaction<File> > reactions;
00342
00343 sc::result react(File const& file);
00344 };
00345
00346 class AnotherLumi : public sc::state<AnotherLumi, HandleLumis>
00347 {
00348 public:
00349 AnotherLumi(my_context ctx);
00350 ~AnotherLumi();
00351 bool checkInvariant();
00352
00353 typedef mpl::list<
00354 sc::transition<Event, HandleEvent>,
00355 sc::transition<Lumi, AnotherLumi>,
00356 sc::custom_reaction<File> > reactions;
00357
00358 sc::result react(File const& file);
00359 };
00360
00361 class HandleEvent : public sc::state<HandleEvent, HandleLumis>
00362 {
00363 public:
00364 HandleEvent(my_context ctx);
00365 ~HandleEvent();
00366 bool checkInvariant();
00367
00368 typedef mpl::list<
00369 sc::transition<Event, HandleEvent>,
00370 sc::transition<Lumi, AnotherLumi>,
00371 sc::custom_reaction<File> > reactions;
00372
00373 sc::result react(File const& file);
00374 void readAndProcessEvent();
00375 void markNonEmpty();
00376 private:
00377 edm::IEventProcessor & ep_;
00378 };
00379
00380 class HandleNewInputFile3 : public sc::state<HandleNewInputFile3, HandleLumis>
00381 {
00382 public:
00383 HandleNewInputFile3(my_context ctx);
00384 ~HandleNewInputFile3();
00385 bool checkInvariant();
00386
00387 typedef mpl::list<
00388 sc::custom_reaction<Run>,
00389 sc::custom_reaction<File> > reactions;
00390
00391 sc::result react(Run const& run);
00392 sc::result react(File const& file);
00393 };
00394
00395 class ContinueRun2 : public sc::state<ContinueRun2, HandleLumis>
00396 {
00397 public:
00398 ContinueRun2(my_context ctx);
00399 ~ContinueRun2();
00400 bool checkInvariant();
00401
00402 typedef mpl::list<
00403 sc::custom_reaction<Lumi>,
00404 sc::custom_reaction<File> > reactions;
00405
00406 sc::result react(Lumi const& lumi);
00407 sc::result react(File const& file);
00408 private:
00409 edm::IEventProcessor & ep_;
00410 };
00411
00412 class ContinueLumi : public sc::state<ContinueLumi, HandleLumis>
00413 {
00414 public:
00415 ContinueLumi(my_context ctx);
00416 ~ContinueLumi();
00417 bool checkInvariant();
00418
00419 typedef mpl::list<
00420 sc::transition<Event, HandleEvent>,
00421 sc::transition<Lumi, AnotherLumi>,
00422 sc::custom_reaction<File> > reactions;
00423
00424 sc::result react(File const& file);
00425 private:
00426 edm::IEventProcessor & ep_;
00427 };
00428 }
00429
00430 #endif