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@121: #include "Support/ModuleFactory.h" tomwalters@121: #include "Support/Module.h" tomwalters@114: #include "Support/ModuleTree.h" tomwalters@114: tomwalters@84: namespace aimc { tomwalters@121: using std::endl; tomwalters@121: ModuleTree::ModuleTree() : root_module_(NULL), tomwalters@121: initialized_(false) { tomwalters@121: tomwalters@121: } tomwalters@121: tomwalters@120: bool ModuleTree::LoadConfigFile(const string &filename) { tomwalters@120: config_.Load(filename.c_str()); tomwalters@114: return ConstructTree(); tomwalters@114: } tomwalters@114: tomwalters@120: bool ModuleTree::LoadConfigText(const string &config) { tomwalters@120: config_.Parse(config.c_str()); tomwalters@114: return ConstructTree(); tomwalters@114: } tomwalters@114: tomwalters@120: bool ModuleTree::ConstructTree() { tomwalters@114: // Make two passes over the configuration file. tomwalters@114: // The first pass creates all the named modules with their parameters. tomwalters@114: bool done = false; tomwalters@114: bool error = false; tomwalters@114: int module_number = 1; tomwalters@121: LOG_INFO("Parsing tree..."); tomwalters@121: while (!done) { tomwalters@121: char module_name_var[Parameters::MaxParamNameLength]; tomwalters@121: char module_id_var[Parameters::MaxParamNameLength]; tomwalters@121: char module_parameters_var[Parameters::MaxParamNameLength]; tomwalters@120: sprintf(module_name_var, "module%d.name", module_number); tomwalters@120: sprintf(module_id_var, "module%d.id", module_number); tomwalters@120: sprintf(module_parameters_var, "module%d.parameters", module_number); tomwalters@121: if (config_.IsSet(module_name_var)) { tomwalters@121: string module_name(config_.GetString(module_name_var)); tomwalters@121: LOG_INFO("Module number %d, name %s", module_number, module_name.c_str()); tomwalters@120: if (config_.IsSet(module_id_var)) { tomwalters@121: const char* id = config_.GetString(module_id_var); tomwalters@121: const char* parameters = config_.DefaultString(module_parameters_var, ""); tomwalters@121: linked_ptr params(new Parameters); tomwalters@121: parameters_[module_name] = params; tomwalters@121: parameters_[module_name]->Parse(parameters); tomwalters@121: linked_ptr module(ModuleFactory::Create(id, parameters_[module_name].get())); tomwalters@121: if (module.get() != NULL) { tomwalters@121: module->set_instance_name(module_name); tomwalters@121: modules_[module_name] = module; tomwalters@121: } else { tomwalters@121: LOG_ERROR("Module name: %s of type %s not created", module_name.c_str(), id); tomwalters@121: done = true; tomwalters@121: error = true; tomwalters@121: } tomwalters@121: if (module_number == 1) { tomwalters@121: root_module_ = module.get(); tomwalters@121: } tomwalters@120: } else { tomwalters@121: LOG_ERROR("id field missing for module named %s", module_name.c_str()); tomwalters@120: error = true; tomwalters@120: done = true; tomwalters@120: } tomwalters@115: } else { tomwalters@115: done = true; tomwalters@115: } tomwalters@115: ++module_number; tomwalters@115: } tomwalters@115: // The second pass connects up all the modules into a tree. tomwalters@121: char module_child_var[Parameters::MaxParamNameLength]; tomwalters@121: char module_name_var[Parameters::MaxParamNameLength]; tomwalters@121: LOG_INFO("A total of %d modules", modules_.size()); tomwalters@121: for (unsigned int i = 1; i < modules_.size() + 1; ++i) { tomwalters@120: int child_number = 1; tomwalters@120: done = false; tomwalters@121: sprintf(module_name_var, "module%d.name", i); tomwalters@121: if (config_.IsSet(module_name_var)) { tomwalters@121: string module_name(config_.GetString(module_name_var)); tomwalters@120: while (!done) { tomwalters@120: sprintf(module_child_var, "module%d.child%d", i, child_number); tomwalters@121: LOG_INFO("Trying %s", module_child_var); tomwalters@121: if (config_.IsSet(module_child_var)) { tomwalters@121: string child(config_.GetString(module_child_var)); tomwalters@121: if ((modules_.find(module_name) != modules_.end()) tomwalters@121: && (modules_.find(child) != modules_.end())) { tomwalters@121: modules_[module_name]->AddTarget(modules_[child].get()); tomwalters@121: } else { tomwalters@121: LOG_ERROR("Module name not found"); tomwalters@121: } tomwalters@120: } else { tomwalters@120: done = true; tomwalters@120: } tomwalters@121: ++child_number; tomwalters@120: } tomwalters@114: } else { tomwalters@121: LOG_ERROR("field missing for entry %s", module_name_var); tomwalters@120: error = true; tomwalters@120: break; tomwalters@114: } tomwalters@114: } tomwalters@121: return !error; tomwalters@114: } tomwalters@120: tomwalters@120: bool ModuleTree::Initialize(Parameters *global_parameters) { tomwalters@121: if (root_module_ == NULL) { tomwalters@121: return false; tomwalters@121: } tomwalters@121: // Dummy signal bank for the root module. tomwalters@121: s_.Initialize(1, 1, 1); tomwalters@121: initialized_ = root_module_->Initialize(s_, global_parameters); tomwalters@121: return initialized_; tomwalters@121: } tomwalters@121: tomwalters@121: void ModuleTree::Reset() { tomwalters@121: if (root_module_ == NULL) { tomwalters@121: return; tomwalters@121: } tomwalters@121: root_module_->Reset(); tomwalters@121: } tomwalters@121: tomwalters@121: void ModuleTree::PrintConfiguration(ostream &out) { tomwalters@121: if (root_module_ == NULL) { tomwalters@121: return; tomwalters@121: } tomwalters@121: root_module_->PrintTargets(out); tomwalters@121: root_module_->PrintConfiguration(out); tomwalters@121: } tomwalters@121: tomwalters@121: void ModuleTree::Process() { tomwalters@121: if (root_module_ == NULL) { tomwalters@121: return; tomwalters@121: } tomwalters@121: if (!initialized_) { tomwalters@121: LOG_ERROR(_T("Module tree not initialized.")); tomwalters@121: return; tomwalters@121: } tomwalters@121: while (!root_module_->done()) { tomwalters@121: root_module_->Process(s_); tomwalters@121: } tomwalters@121: } tomwalters@121: tomwalters@121: void ModuleTree::MakeDotGraph(ostream &out) { tomwalters@121: if (root_module_ == NULL) { tomwalters@121: return; tomwalters@121: } tomwalters@121: out << "digraph G {" << endl; tomwalters@121: root_module_->PrintTargetsForDot(out); tomwalters@121: out << "}" << endl; tomwalters@120: } tomwalters@120: tomwalters@115: } // namespace aimc