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