tomwalters@365
|
1 // Copyright 2010, Thomas Walters
|
tomwalters@365
|
2 //
|
tomwalters@365
|
3 // AIM-C: A C++ implementation of the Auditory Image Model
|
tomwalters@365
|
4 // http://www.acousticscale.org/AIMC
|
tomwalters@365
|
5 //
|
tomwalters@365
|
6 // Licensed under the Apache License, Version 2.0 (the "License");
|
tomwalters@365
|
7 // you may not use this file except in compliance with the License.
|
tomwalters@365
|
8 // You may obtain a copy of the License at
|
tomwalters@365
|
9 //
|
tomwalters@365
|
10 // http://www.apache.org/licenses/LICENSE-2.0
|
tomwalters@365
|
11 //
|
tomwalters@365
|
12 // Unless required by applicable law or agreed to in writing, software
|
tomwalters@365
|
13 // distributed under the License is distributed on an "AS IS" BASIS,
|
tomwalters@365
|
14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
tomwalters@365
|
15 // See the License for the specific language governing permissions and
|
tomwalters@365
|
16 // limitations under the License.
|
tomwalters@365
|
17
|
tomwalters@365
|
18 /*! \file
|
tomwalters@365
|
19 * \brief Parse a configuration file to generate a tree of modules.
|
tomwalters@365
|
20 */
|
tomwalters@365
|
21
|
tomwalters@365
|
22 /*! \author: Thomas Walters <tom@acousticscale.org>
|
tomwalters@365
|
23 * \date 2010/08/08
|
tomwalters@365
|
24 * \version \$Id: $
|
tomwalters@365
|
25 */
|
tomwalters@365
|
26
|
tomwalters@402
|
27 #include "Support/ModuleFactory.h"
|
tomwalters@402
|
28 #include "Support/Module.h"
|
tomwalters@395
|
29 #include "Support/ModuleTree.h"
|
tomwalters@395
|
30
|
tomwalters@365
|
31 namespace aimc {
|
tomwalters@402
|
32 using std::endl;
|
tomwalters@402
|
33 ModuleTree::ModuleTree() : root_module_(NULL),
|
tomwalters@402
|
34 initialized_(false) {
|
tomwalters@402
|
35
|
tomwalters@402
|
36 }
|
tomwalters@402
|
37
|
tomwalters@401
|
38 bool ModuleTree::LoadConfigFile(const string &filename) {
|
tomwalters@401
|
39 config_.Load(filename.c_str());
|
tomwalters@395
|
40 return ConstructTree();
|
tomwalters@395
|
41 }
|
tomwalters@395
|
42
|
tomwalters@401
|
43 bool ModuleTree::LoadConfigText(const string &config) {
|
tomwalters@401
|
44 config_.Parse(config.c_str());
|
tomwalters@395
|
45 return ConstructTree();
|
tomwalters@395
|
46 }
|
tomwalters@395
|
47
|
tomwalters@401
|
48 bool ModuleTree::ConstructTree() {
|
tomwalters@395
|
49 // Make two passes over the configuration file.
|
tomwalters@395
|
50 // The first pass creates all the named modules with their parameters.
|
tomwalters@395
|
51 bool done = false;
|
tomwalters@395
|
52 bool error = false;
|
tomwalters@395
|
53 int module_number = 1;
|
tomwalters@402
|
54 LOG_INFO("Parsing tree...");
|
tomwalters@402
|
55 while (!done) {
|
tomwalters@402
|
56 char module_name_var[Parameters::MaxParamNameLength];
|
tomwalters@402
|
57 char module_id_var[Parameters::MaxParamNameLength];
|
tomwalters@402
|
58 char module_parameters_var[Parameters::MaxParamNameLength];
|
tomwalters@401
|
59 sprintf(module_name_var, "module%d.name", module_number);
|
tomwalters@401
|
60 sprintf(module_id_var, "module%d.id", module_number);
|
tomwalters@401
|
61 sprintf(module_parameters_var, "module%d.parameters", module_number);
|
tomwalters@402
|
62 if (config_.IsSet(module_name_var)) {
|
tomwalters@402
|
63 string module_name(config_.GetString(module_name_var));
|
tomwalters@402
|
64 LOG_INFO("Module number %d, name %s", module_number, module_name.c_str());
|
tomwalters@401
|
65 if (config_.IsSet(module_id_var)) {
|
tomwalters@402
|
66 const char* id = config_.GetString(module_id_var);
|
tomwalters@402
|
67 const char* parameters = config_.DefaultString(module_parameters_var, "");
|
tomwalters@402
|
68 linked_ptr<Parameters> params(new Parameters);
|
tomwalters@402
|
69 parameters_[module_name] = params;
|
tomwalters@402
|
70 parameters_[module_name]->Parse(parameters);
|
tomwalters@402
|
71 linked_ptr<Module> module(ModuleFactory::Create(id, parameters_[module_name].get()));
|
tomwalters@402
|
72 if (module.get() != NULL) {
|
tomwalters@402
|
73 module->set_instance_name(module_name);
|
tomwalters@402
|
74 modules_[module_name] = module;
|
tomwalters@402
|
75 } else {
|
tomwalters@402
|
76 LOG_ERROR("Module name: %s of type %s not created", module_name.c_str(), id);
|
tomwalters@402
|
77 done = true;
|
tomwalters@402
|
78 error = true;
|
tomwalters@402
|
79 }
|
tomwalters@402
|
80 if (module_number == 1) {
|
tomwalters@402
|
81 root_module_ = module.get();
|
tomwalters@402
|
82 }
|
tomwalters@401
|
83 } else {
|
tomwalters@402
|
84 LOG_ERROR("id field missing for module named %s", module_name.c_str());
|
tomwalters@401
|
85 error = true;
|
tomwalters@401
|
86 done = true;
|
tomwalters@401
|
87 }
|
tomwalters@396
|
88 } else {
|
tomwalters@396
|
89 done = true;
|
tomwalters@396
|
90 }
|
tomwalters@396
|
91 ++module_number;
|
tomwalters@396
|
92 }
|
tomwalters@396
|
93 // The second pass connects up all the modules into a tree.
|
tomwalters@402
|
94 char module_child_var[Parameters::MaxParamNameLength];
|
tomwalters@402
|
95 char module_name_var[Parameters::MaxParamNameLength];
|
tomwalters@402
|
96 LOG_INFO("A total of %d modules", modules_.size());
|
tomwalters@402
|
97 for (unsigned int i = 1; i < modules_.size() + 1; ++i) {
|
tomwalters@401
|
98 int child_number = 1;
|
tomwalters@401
|
99 done = false;
|
tomwalters@402
|
100 sprintf(module_name_var, "module%d.name", i);
|
tomwalters@402
|
101 if (config_.IsSet(module_name_var)) {
|
tomwalters@402
|
102 string module_name(config_.GetString(module_name_var));
|
tomwalters@401
|
103 while (!done) {
|
tomwalters@401
|
104 sprintf(module_child_var, "module%d.child%d", i, child_number);
|
tomwalters@402
|
105 LOG_INFO("Trying %s", module_child_var);
|
tomwalters@402
|
106 if (config_.IsSet(module_child_var)) {
|
tomwalters@402
|
107 string child(config_.GetString(module_child_var));
|
tomwalters@402
|
108 if ((modules_.find(module_name) != modules_.end())
|
tomwalters@402
|
109 && (modules_.find(child) != modules_.end())) {
|
tomwalters@402
|
110 modules_[module_name]->AddTarget(modules_[child].get());
|
tomwalters@402
|
111 } else {
|
tomwalters@402
|
112 LOG_ERROR("Module name not found");
|
tomwalters@402
|
113 }
|
tomwalters@401
|
114 } else {
|
tomwalters@401
|
115 done = true;
|
tomwalters@401
|
116 }
|
tomwalters@402
|
117 ++child_number;
|
tomwalters@401
|
118 }
|
tomwalters@395
|
119 } else {
|
tomwalters@402
|
120 LOG_ERROR("field missing for entry %s", module_name_var);
|
tomwalters@401
|
121 error = true;
|
tomwalters@401
|
122 break;
|
tomwalters@395
|
123 }
|
tomwalters@395
|
124 }
|
tomwalters@402
|
125 return !error;
|
tomwalters@395
|
126 }
|
tomwalters@401
|
127
|
tomwalters@401
|
128 bool ModuleTree::Initialize(Parameters *global_parameters) {
|
tomwalters@402
|
129 if (root_module_ == NULL) {
|
tomwalters@402
|
130 return false;
|
tomwalters@402
|
131 }
|
tomwalters@402
|
132 // Dummy signal bank for the root module.
|
tomwalters@402
|
133 s_.Initialize(1, 1, 1);
|
tomwalters@402
|
134 initialized_ = root_module_->Initialize(s_, global_parameters);
|
tomwalters@402
|
135 return initialized_;
|
tomwalters@402
|
136 }
|
tomwalters@402
|
137
|
tomwalters@402
|
138 void ModuleTree::Reset() {
|
tomwalters@402
|
139 if (root_module_ == NULL) {
|
tomwalters@402
|
140 return;
|
tomwalters@402
|
141 }
|
tomwalters@402
|
142 root_module_->Reset();
|
tomwalters@402
|
143 }
|
tomwalters@402
|
144
|
tomwalters@402
|
145 void ModuleTree::PrintConfiguration(ostream &out) {
|
tomwalters@402
|
146 if (root_module_ == NULL) {
|
tomwalters@402
|
147 return;
|
tomwalters@402
|
148 }
|
tomwalters@402
|
149 root_module_->PrintTargets(out);
|
tomwalters@402
|
150 root_module_->PrintConfiguration(out);
|
tomwalters@402
|
151 }
|
tomwalters@402
|
152
|
tomwalters@402
|
153 void ModuleTree::Process() {
|
tomwalters@402
|
154 if (root_module_ == NULL) {
|
tomwalters@402
|
155 return;
|
tomwalters@402
|
156 }
|
tomwalters@402
|
157 if (!initialized_) {
|
tomwalters@402
|
158 LOG_ERROR(_T("Module tree not initialized."));
|
tomwalters@402
|
159 return;
|
tomwalters@402
|
160 }
|
tomwalters@402
|
161 while (!root_module_->done()) {
|
tomwalters@402
|
162 root_module_->Process(s_);
|
tomwalters@402
|
163 }
|
tomwalters@402
|
164 }
|
tomwalters@402
|
165
|
tomwalters@402
|
166 void ModuleTree::MakeDotGraph(ostream &out) {
|
tomwalters@402
|
167 if (root_module_ == NULL) {
|
tomwalters@402
|
168 return;
|
tomwalters@402
|
169 }
|
tomwalters@402
|
170 out << "digraph G {" << endl;
|
tomwalters@402
|
171 root_module_->PrintTargetsForDot(out);
|
tomwalters@402
|
172 out << "}" << endl;
|
tomwalters@401
|
173 }
|
tomwalters@401
|
174
|
tomwalters@396
|
175 } // namespace aimc
|