/* * Copyright (c) 2003-2005 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer; * redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution; * neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "base/inifile.hh" #include "base/misc.hh" #include "sim/builder.hh" #include "sim/configfile.hh" #include "sim/config_node.hh" #include "sim/host.hh" #include "sim/sim_object.hh" #include "sim/root.hh" using namespace std; SimObjectBuilder::SimObjectBuilder(ConfigNode *_configNode) : ParamContext(_configNode->getPath(), NoAutoInit), configNode(_configNode) { } SimObjectBuilder::~SimObjectBuilder() { } /////////////////////////////////////////// // // SimObjectBuilder member definitions // /////////////////////////////////////////// // override ParamContext::parseParams() to check params based on // instance name first. If not found, then check based on iniSection // (as in default ParamContext implementation). void SimObjectBuilder::parseParams(IniFile &iniFile) { iniFilePtr = &iniFile; // set object member ParamList::iterator i; for (i = paramList->begin(); i != paramList->end(); ++i) { string string_value; if (iniFile.find(iniSection, (*i)->name, string_value)) (*i)->parse(string_value); } } void SimObjectBuilder::printErrorProlog(ostream &os) { ccprintf(os, "Error creating object '%s' of type '%s':\n", iniSection, configNode->getType()); } //////////////////////////////////////////////////////////////////////// // // SimObjectClass member definitions // //////////////////////////////////////////////////////////////////////// // Map of class names to SimObjectBuilder creation functions. Need to // make this a pointer so we can force initialization on the first // reference; otherwise, some SimObjectClass constructors may be invoked // before the classMap constructor. map *SimObjectClass::classMap = NULL; // SimObjectClass constructor: add mapping to classMap SimObjectClass::SimObjectClass(const string &className, CreateFunc createFunc) { if (classMap == NULL) classMap = new map(); if ((*classMap)[className]) panic("Error: simulation object class '%s' redefined\n", className); // add className --> createFunc to class map (*classMap)[className] = createFunc; } // // SimObject * SimObjectClass::createObject(IniFile &configDB, ConfigNode *configNode) { const string &type = configNode->getType(); // look up className to get appropriate createFunc if (classMap->find(type) == classMap->end()) panic("Simulator object type '%s' not found.\n", type); CreateFunc createFunc = (*classMap)[type]; // call createFunc with config hierarchy node to get object // builder instance (context with parameters for object creation) SimObjectBuilder *objectBuilder = (*createFunc)(configNode); assert(objectBuilder != NULL); // parse all parameters in context to generate parameter values objectBuilder->parseParams(configDB); // now create the actual simulation object SimObject *object = objectBuilder->create(); assert(object != NULL); // echo object parameters to stats file (for documenting the // config used to generate the associated stats) ccprintf(*configStream, "[%s]\n", object->name()); ccprintf(*configStream, "type=%s\n", type); objectBuilder->showParams(*configStream); ccprintf(*configStream, "\n"); // done with the SimObjectBuilder now delete objectBuilder; return object; } // // static method: // void SimObjectClass::describeAllClasses(ostream &os) { map::iterator iter; for (iter = classMap->begin(); iter != classMap->end(); ++iter) { const string &className = iter->first; CreateFunc createFunc = iter->second; os << "[" << className << "]\n"; // create dummy object builder just to instantiate parameters SimObjectBuilder *objectBuilder = (*createFunc)(NULL); // now get the object builder to describe ite params objectBuilder->describeParams(os); os << endl; // done with the object builder now delete objectBuilder; } }