00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef __INITSEQUENCER_H__
00039 #define __INITSEQUENCER_H__
00040
00041 #include <vector>
00042 #include <map>
00043 #include <string>
00044
00045 #include "../util/Singleton.h"
00046 #include "../debug/Logger.h"
00047
00048 namespace oasys {
00049
00050
00051 class InitStep;
00052 class InitExtraDependency;
00053
00098 class InitSequencer : public Logger {
00099 friend class InitExtraDependency;
00100
00101 public:
00102 typedef std::map<std::string, InitStep*> StepMap;
00103 typedef std::vector<std::string> Plan;
00104
00105 InitSequencer();
00106
00114 int start(std::string step, Plan* plan = 0);
00115
00119 void add_step(InitStep* step);
00120
00124 InitStep* get_step(const std::string& name);
00125
00131 void reset();
00132
00136 void print_dot();
00137
00138 private:
00139 typedef std::vector<std::string> ReverseDepList;
00140 typedef std::map<std::string, ReverseDepList> ReverseDepEdges;
00141
00142 StepMap steps_;
00143 int dfs_time_;
00144
00145 std::vector<InitExtraDependency*> extra_dependencies_;
00146
00148 int run_steps();
00149
00151 int topo_sort();
00152
00153
00154 void dfs(InitStep* step, ReverseDepEdges& edges);
00155
00157 void mark_dep(const std::string& target);
00158
00160 void add_extra_dep(InitExtraDependency* extra_dep);
00161
00163 void add_extra_deps();
00164 };
00165
00169 class InitStep {
00170 friend class InitSequencer;
00171
00172 public:
00173 typedef std::vector<std::string> DepList;
00174
00178 InitStep(const std::string& the_namespace, const std::string& name);
00179 InitStep(const std::string& the_namespace,
00180 const std::string& name, int depsize, ...);
00181 InitStep(const std::string& the_namespace,
00182 const std::string& name, const DepList& deps);
00183
00184 virtual ~InitStep() {}
00185
00189 virtual int run();
00190
00194 bool dep_are_satisfied();
00195
00196 const DepList& dependencies() { return dependencies_; }
00197 std::string name() { return name_; }
00198 bool done() { return done_; }
00199 int time() { return time_; }
00200
00201 protected:
00202 bool done_;
00203
00205 virtual int run_component() = 0;
00206
00207 private:
00208 std::string name_;
00209 DepList dependencies_;
00210
00211 bool mark_;
00212 int time_;
00213
00214 void add_dep(const std::string& dep) { dependencies_.push_back(dep); }
00215 };
00216
00222 class InitConfigStep : public InitStep {
00223 public:
00224 InitConfigStep(const std::string& the_namespace,
00225 const std::string& name)
00226 : InitStep(the_namespace, name) {}
00227
00228 int run() { return 0; }
00229 void configuration_done() { done_ = true; }
00230
00231 protected:
00232 int run_component() { NOTREACHED; }
00233 };
00234
00240 struct InitExtraDependency {
00241 InitExtraDependency(const std::string& new_dep,
00242 const std::string& depender)
00243 : new_dep_(new_dep), depender_(depender)
00244 {
00245 Singleton<InitSequencer>::instance()->add_extra_dep(this);
00246 }
00247
00248 std::string new_dep_;
00249 std::string depender_;
00250 };
00251
00252
00254
00258 #define OASYS_DECLARE_INIT_MODULE_0(_namespace, _name) \
00259 class InitModule##_namespace##_name : public ::oasys::InitStep { \
00260 public: \
00261 InitModule##_namespace##_name() : InitStep(#_namespace, #_name) {} \
00262 protected: \
00263 int run_component(); \
00264 }; \
00265 InitModule##_namespace##_name * \
00266 ::oasys::Singleton<InitModule##_namespace##_name>::instance_ = 0; \
00267 InitModule##_namespace##_name * init_module_##_name = \
00268 ::oasys::Singleton<InitModule##_namespace##_name>::instance(); \
00269 int InitModule##_namespace##_name::run_component()
00270
00271 #define OASYS_DECLARE_INIT_MODULE_1(_namespace, _name, _dep1) \
00272 OASYS_DECLARE_INIT_MODULE(_namespace, _name, 1, _dep1)
00273 #define OASYS_DECLARE_INIT_MODULE_2(_namespace, _name, _dep1, _dep2) \
00274 OASYS_DECLARE_INIT_MODULE(_namespace, _name, 2, _dep1, _dep2)
00275 #define OASYS_DECLARE_INIT_MODULE_3(_namespace, _name, _dep1, _dep2, _dep3) \
00276 OASYS_DECLARE_INIT_MODULE(_namespace, _name, 3, _dep1, _dep2, _dep3)
00277 #define OASYS_DECLARE_INIT_MODULE_4(_namespace, _name, _dep1, _dep2, _dep3, _dep4) \
00278 OASYS_DECLARE_INIT_MODULE(_namespace, _name, 4, _dep1, _dep2, _dep3, _dep4)
00280
00281
00285 #define OASYS_DECLARE_INIT_MODULE(_namespace, _name, _num_dep, _args...) \
00286 class InitModule##_namespace##_name : public ::oasys::InitStep { \
00287 public: \
00288 InitModule##_namespace##_name() \
00289 : InitStep(#_namespace, #_name, _num_dep, _args) {} \
00290 protected: \
00291 int run_component(); \
00292 }; \
00293 InitModule##_namespace##_name * \
00294 ::oasys::Singleton<InitModule##_namespace##_name>::instance_ = 0; \
00295 InitModule##_namespace##_name * init_module_##_name = \
00296 ::oasys::Singleton<InitModule##_namespace##_name>::instance(); \
00297 int InitModule##_namespace##_name::run_component()
00298
00302 #define OASYS_DECLARE_INIT_CONFIG(_namespace, _name) \
00303 class InitModule##_namespace##_name : public InitConfigStep { \
00304 public: \
00305 InitModule##_namespace##_name() \
00306 : InitConfigStep(#_namespace, #_name) {} \
00307 }; \
00308 InitModule##_namespace##_name * \
00309 ::oasys::Singleton<InitModule##_namespace##_name>::instance_ = 0; \
00310 InitModule##_namespace##_name * init_module_##_name = \
00311 ::oasys::Singleton<InitModule##_namespace##_name>::instance()
00312
00316 #define OASYS_INIT_CONFIG_DONE(_namespace, _name) \
00317 do { \
00318 ::oasys::Singleton<InitModule##_namespace##_name>::instance() \
00319 ->configuration_done(); \
00320 } while (0)
00321
00325 #define OASYS_INIT_ADD_DEP(_new_dep, _depender) \
00326 ::oasys::InitExtraDependency init_extra_dep_##__LINE__(_new_dep, _depender)
00327
00328 }
00329
00330 #endif