| /* |
| * 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 <assert.h> |
| |
| #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<string,SimObjectClass::CreateFunc> *SimObjectClass::classMap = NULL; |
| |
| // SimObjectClass constructor: add mapping to classMap |
| SimObjectClass::SimObjectClass(const string &className, CreateFunc createFunc) |
| { |
| if (classMap == NULL) |
| classMap = new map<string,SimObjectClass::CreateFunc>(); |
| |
| 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<string,CreateFunc>::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; |
| } |
| } |