tomwalters@365: // Copyright 2010, Thomas Walters tomwalters@365: // tomwalters@365: // AIM-C: A C++ implementation of the Auditory Image Model tomwalters@365: // http://www.acousticscale.org/AIMC tomwalters@365: // tomwalters@365: // Licensed under the Apache License, Version 2.0 (the "License"); tomwalters@365: // you may not use this file except in compliance with the License. tomwalters@365: // You may obtain a copy of the License at tomwalters@365: // tomwalters@365: // http://www.apache.org/licenses/LICENSE-2.0 tomwalters@365: // tomwalters@365: // Unless required by applicable law or agreed to in writing, software tomwalters@365: // distributed under the License is distributed on an "AS IS" BASIS, tomwalters@365: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. tomwalters@365: // See the License for the specific language governing permissions and tomwalters@365: // limitations under the License. tomwalters@365: tomwalters@365: /*! \file tomwalters@365: * \brief Parse a configuration file to generate a tree of modules. tomwalters@365: */ tomwalters@365: tomwalters@365: /*! \author: Thomas Walters tomwalters@365: * \date 2010/08/08 tomwalters@365: * \version \$Id: $ tomwalters@365: */ tomwalters@365: tomwalters@402: #include "Support/ModuleFactory.h" tomwalters@402: #include "Support/Module.h" tomwalters@395: #include "Support/ModuleTree.h" tomwalters@395: tomwalters@365: namespace aimc { tomwalters@402: using std::endl; tomwalters@402: ModuleTree::ModuleTree() : root_module_(NULL), tomwalters@402: initialized_(false) { tomwalters@402: tomwalters@402: } tomwalters@402: tomwalters@401: bool ModuleTree::LoadConfigFile(const string &filename) { tomwalters@401: config_.Load(filename.c_str()); tomwalters@395: return ConstructTree(); tomwalters@395: } tomwalters@395: tomwalters@401: bool ModuleTree::LoadConfigText(const string &config) { tomwalters@401: config_.Parse(config.c_str()); tomwalters@395: return ConstructTree(); tomwalters@395: } tomwalters@395: tomwalters@401: bool ModuleTree::ConstructTree() { tomwalters@395: // Make two passes over the configuration file. tomwalters@395: // The first pass creates all the named modules with their parameters. tomwalters@395: bool done = false; tomwalters@395: bool error = false; tomwalters@395: int module_number = 1; tomwalters@402: LOG_INFO("Parsing tree..."); tomwalters@402: while (!done) { tomwalters@402: char module_name_var[Parameters::MaxParamNameLength]; tomwalters@402: char module_id_var[Parameters::MaxParamNameLength]; tomwalters@402: char module_parameters_var[Parameters::MaxParamNameLength]; tomwalters@401: sprintf(module_name_var, "module%d.name", module_number); tomwalters@401: sprintf(module_id_var, "module%d.id", module_number); tomwalters@401: sprintf(module_parameters_var, "module%d.parameters", module_number); tomwalters@402: if (config_.IsSet(module_name_var)) { tomwalters@402: string module_name(config_.GetString(module_name_var)); tomwalters@402: LOG_INFO("Module number %d, name %s", module_number, module_name.c_str()); tomwalters@401: if (config_.IsSet(module_id_var)) { tomwalters@402: const char* id = config_.GetString(module_id_var); tomwalters@402: const char* parameters = config_.DefaultString(module_parameters_var, ""); tomwalters@402: linked_ptr params(new Parameters); tomwalters@402: parameters_[module_name] = params; tomwalters@402: parameters_[module_name]->Parse(parameters); tomwalters@402: linked_ptr module(ModuleFactory::Create(id, parameters_[module_name].get())); tomwalters@402: if (module.get() != NULL) { tomwalters@402: module->set_instance_name(module_name); tomwalters@402: modules_[module_name] = module; tomwalters@402: } else { tomwalters@402: LOG_ERROR("Module name: %s of type %s not created", module_name.c_str(), id); tomwalters@402: done = true; tomwalters@402: error = true; tomwalters@402: } tomwalters@402: if (module_number == 1) { tomwalters@402: root_module_ = module.get(); tomwalters@402: } tomwalters@401: } else { tomwalters@402: LOG_ERROR("id field missing for module named %s", module_name.c_str()); tomwalters@401: error = true; tomwalters@401: done = true; tomwalters@401: } tomwalters@396: } else { tomwalters@396: done = true; tomwalters@396: } tomwalters@396: ++module_number; tomwalters@396: } tomwalters@396: // The second pass connects up all the modules into a tree. tomwalters@402: char module_child_var[Parameters::MaxParamNameLength]; tomwalters@402: char module_name_var[Parameters::MaxParamNameLength]; tomwalters@402: LOG_INFO("A total of %d modules", modules_.size()); tomwalters@402: for (unsigned int i = 1; i < modules_.size() + 1; ++i) { tomwalters@401: int child_number = 1; tomwalters@401: done = false; tomwalters@402: sprintf(module_name_var, "module%d.name", i); tomwalters@402: if (config_.IsSet(module_name_var)) { tomwalters@402: string module_name(config_.GetString(module_name_var)); tomwalters@401: while (!done) { tomwalters@401: sprintf(module_child_var, "module%d.child%d", i, child_number); tomwalters@402: LOG_INFO("Trying %s", module_child_var); tomwalters@402: if (config_.IsSet(module_child_var)) { tomwalters@402: string child(config_.GetString(module_child_var)); tomwalters@402: if ((modules_.find(module_name) != modules_.end()) tomwalters@402: && (modules_.find(child) != modules_.end())) { tomwalters@402: modules_[module_name]->AddTarget(modules_[child].get()); tomwalters@402: } else { tomwalters@402: LOG_ERROR("Module name not found"); tomwalters@402: } tomwalters@401: } else { tomwalters@401: done = true; tomwalters@401: } tomwalters@402: ++child_number; tomwalters@401: } tomwalters@395: } else { tomwalters@402: LOG_ERROR("field missing for entry %s", module_name_var); tomwalters@401: error = true; tomwalters@401: break; tomwalters@395: } tomwalters@395: } tomwalters@402: return !error; tomwalters@395: } tomwalters@401: tomwalters@401: bool ModuleTree::Initialize(Parameters *global_parameters) { tomwalters@402: if (root_module_ == NULL) { tomwalters@402: return false; tomwalters@402: } tomwalters@402: // Dummy signal bank for the root module. tomwalters@402: s_.Initialize(1, 1, 1); tomwalters@402: initialized_ = root_module_->Initialize(s_, global_parameters); tomwalters@402: return initialized_; tomwalters@402: } tomwalters@402: tomwalters@402: void ModuleTree::Reset() { tomwalters@402: if (root_module_ == NULL) { tomwalters@402: return; tomwalters@402: } tomwalters@402: root_module_->Reset(); tomwalters@402: } tomwalters@402: tomwalters@402: void ModuleTree::PrintConfiguration(ostream &out) { tomwalters@402: if (root_module_ == NULL) { tomwalters@402: return; tomwalters@402: } tomwalters@402: root_module_->PrintTargets(out); tomwalters@402: root_module_->PrintConfiguration(out); tomwalters@402: } tomwalters@402: tomwalters@402: void ModuleTree::Process() { tomwalters@402: if (root_module_ == NULL) { tomwalters@402: return; tomwalters@402: } tomwalters@402: if (!initialized_) { tomwalters@402: LOG_ERROR(_T("Module tree not initialized.")); tomwalters@402: return; tomwalters@402: } tomwalters@402: while (!root_module_->done()) { tomwalters@402: root_module_->Process(s_); tomwalters@402: } tomwalters@402: } tomwalters@402: tomwalters@402: void ModuleTree::MakeDotGraph(ostream &out) { tomwalters@402: if (root_module_ == NULL) { tomwalters@402: return; tomwalters@402: } tomwalters@402: out << "digraph G {" << endl; tomwalters@402: root_module_->PrintTargetsForDot(out); tomwalters@402: out << "}" << endl; tomwalters@401: } tomwalters@401: tomwalters@396: } // namespace aimc