00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __INITSEQUENCER_H__
00018 #define __INITSEQUENCER_H__
00019
00020 #include <vector>
00021 #include <map>
00022 #include <string>
00023
00024 #include "../util/Singleton.h"
00025 #include "../debug/Logger.h"
00026
00027 namespace oasys {
00028
00029
00030 class InitStep;
00031 class InitExtraDependency;
00032
00077 class InitSequencer : public Logger {
00078 friend class InitExtraDependency;
00079
00080 public:
00081 typedef std::map<std::string, InitStep*> StepMap;
00082 typedef std::vector<std::string> Plan;
00083
00084 InitSequencer();
00085
00093 int start(std::string step, Plan* plan = 0);
00094
00098 void add_step(InitStep* step);
00099
00103 InitStep* get_step(const std::string& name);
00104
00110 void reset();
00111
00115 void print_dot();
00116
00117 private:
00118 typedef std::vector<std::string> ReverseDepList;
00119 typedef std::map<std::string, ReverseDepList> ReverseDepEdges;
00120
00121 StepMap steps_;
00122 int dfs_time_;
00123
00124 std::vector<InitExtraDependency*> extra_dependencies_;
00125
00127 int run_steps();
00128
00130 int topo_sort();
00131
00132
00133 void dfs(InitStep* step, ReverseDepEdges& edges);
00134
00136 void mark_dep(const std::string& target);
00137
00139 void add_extra_dep(InitExtraDependency* extra_dep);
00140
00142 void add_extra_deps();
00143 };
00144
00148 class InitStep {
00149 friend class InitSequencer;
00150
00151 public:
00152 typedef std::vector<std::string> DepList;
00153
00157 InitStep(const std::string& the_namespace, const std::string& name);
00158 InitStep(const std::string& the_namespace,
00159 const std::string& name, int depsize, ...);
00160 InitStep(const std::string& the_namespace,
00161 const std::string& name, const DepList& deps);
00162
00163 virtual ~InitStep() {}
00164
00168 virtual int run();
00169
00173 bool dep_are_satisfied();
00174
00175 const DepList& dependencies() { return dependencies_; }
00176 std::string name() { return name_; }
00177 bool done() { return done_; }
00178 int time() { return time_; }
00179
00180 protected:
00181 bool done_;
00182
00184 virtual int run_component() = 0;
00185
00186 private:
00187 std::string name_;
00188 DepList dependencies_;
00189
00190 bool mark_;
00191 int time_;
00192
00193 void add_dep(const std::string& dep) { dependencies_.push_back(dep); }
00194 };
00195
00201 class InitConfigStep : public InitStep {
00202 public:
00203 InitConfigStep(const std::string& the_namespace,
00204 const std::string& name)
00205 : InitStep(the_namespace, name) {}
00206
00207 int run() { return 0; }
00208 void configuration_done() { done_ = true; }
00209
00210 protected:
00211 int run_component() { NOTREACHED; }
00212 };
00213
00219 struct InitExtraDependency {
00220 InitExtraDependency(const std::string& new_dep,
00221 const std::string& depender)
00222 : new_dep_(new_dep), depender_(depender)
00223 {
00224 Singleton<InitSequencer>::instance()->add_extra_dep(this);
00225 }
00226
00227 std::string new_dep_;
00228 std::string depender_;
00229 };
00230
00231
00233
00237 #define OASYS_DECLARE_INIT_MODULE_0(_namespace, _name) \
00238 class InitModule##_namespace##_name : public ::oasys::InitStep { \
00239 public: \
00240 InitModule##_namespace##_name() : InitStep(#_namespace, #_name) {} \
00241 protected: \
00242 int run_component(); \
00243 }; \
00244 InitModule##_namespace##_name * \
00245 ::oasys::Singleton<InitModule##_namespace##_name>::instance_ = 0; \
00246 InitModule##_namespace##_name * init_module_##_name = \
00247 ::oasys::Singleton<InitModule##_namespace##_name>::instance(); \
00248 int InitModule##_namespace##_name::run_component()
00249
00250 #define OASYS_DECLARE_INIT_MODULE_1(_namespace, _name, _dep1) \
00251 OASYS_DECLARE_INIT_MODULE(_namespace, _name, 1, _dep1)
00252 #define OASYS_DECLARE_INIT_MODULE_2(_namespace, _name, _dep1, _dep2) \
00253 OASYS_DECLARE_INIT_MODULE(_namespace, _name, 2, _dep1, _dep2)
00254 #define OASYS_DECLARE_INIT_MODULE_3(_namespace, _name, _dep1, _dep2, _dep3) \
00255 OASYS_DECLARE_INIT_MODULE(_namespace, _name, 3, _dep1, _dep2, _dep3)
00256 #define OASYS_DECLARE_INIT_MODULE_4(_namespace, _name, _dep1, _dep2, _dep3, _dep4) \
00257 OASYS_DECLARE_INIT_MODULE(_namespace, _name, 4, _dep1, _dep2, _dep3, _dep4)
00259
00260
00264 #define OASYS_DECLARE_INIT_MODULE(_namespace, _name, _num_dep, _args...) \
00265 class InitModule##_namespace##_name : public ::oasys::InitStep { \
00266 public: \
00267 InitModule##_namespace##_name() \
00268 : InitStep(#_namespace, #_name, _num_dep, _args) {} \
00269 protected: \
00270 int run_component(); \
00271 }; \
00272 InitModule##_namespace##_name * \
00273 ::oasys::Singleton<InitModule##_namespace##_name>::instance_ = 0; \
00274 InitModule##_namespace##_name * init_module_##_name = \
00275 ::oasys::Singleton<InitModule##_namespace##_name>::instance(); \
00276 int InitModule##_namespace##_name::run_component()
00277
00281 #define OASYS_DECLARE_INIT_CONFIG(_namespace, _name) \
00282 class InitModule##_namespace##_name : public InitConfigStep { \
00283 public: \
00284 InitModule##_namespace##_name() \
00285 : InitConfigStep(#_namespace, #_name) {} \
00286 }; \
00287 InitModule##_namespace##_name * \
00288 ::oasys::Singleton<InitModule##_namespace##_name>::instance_ = 0; \
00289 InitModule##_namespace##_name * init_module_##_name = \
00290 ::oasys::Singleton<InitModule##_namespace##_name>::instance()
00291
00295 #define OASYS_INIT_CONFIG_DONE(_namespace, _name) \
00296 do { \
00297 ::oasys::Singleton<InitModule##_namespace##_name>::instance() \
00298 ->configuration_done(); \
00299 } while (0)
00300
00304 #define OASYS_INIT_ADD_DEP(_new_dep, _depender) \
00305 ::oasys::InitExtraDependency init_extra_dep_##__LINE__(_new_dep, _depender)
00306
00307 }
00308
00309 #endif