c1aecc05e6
This patch extensively modifies DSENT so that it can be accessed using Python. To access the Python interface, DSENT needs to compiled as a shared library. For this purpose a CMakeLists.txt file has been added. Some of the code that is not required is being removed.
719 lines
23 KiB
C++
719 lines
23 KiB
C++
/* Copyright (c) 2012 Massachusetts Institute of Technology
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
* THE SOFTWARE.
|
|
*/
|
|
|
|
#include "model/Model.h"
|
|
|
|
#include <vector>
|
|
|
|
#include "util/Result.h"
|
|
|
|
namespace DSENT
|
|
{
|
|
using std::vector;
|
|
using LibUtil::deletePtrMap;
|
|
using LibUtil::clonePtrMap;
|
|
|
|
Model::SubModel::SubModel(Model* model_, double num_models_)
|
|
: m_model_(model_), m_num_models_(num_models_)
|
|
{}
|
|
|
|
Model::SubModel::~SubModel()
|
|
{
|
|
delete m_model_;
|
|
}
|
|
|
|
Model* Model::SubModel::getModel()
|
|
{
|
|
return m_model_;
|
|
}
|
|
|
|
const Model* Model::SubModel::getModel() const
|
|
{
|
|
return m_model_;
|
|
}
|
|
|
|
double Model::SubModel::getNumModels() const
|
|
{
|
|
return m_num_models_;
|
|
}
|
|
|
|
Model::SubModel* Model::SubModel::clone() const
|
|
{
|
|
return new SubModel(*this);
|
|
}
|
|
|
|
Model::SubModel::SubModel(const SubModel& sub_model_)
|
|
{
|
|
m_model_ = sub_model_.m_model_->clone();
|
|
m_num_models_ = sub_model_.m_num_models_;
|
|
}
|
|
|
|
const char Model::TYPE_SEPARATOR[] = ">>";
|
|
const char Model::HIERARCHY_SEPARATOR[] = "->";
|
|
const char Model::SUBFIELD_SEPARATOR[] = ":";
|
|
const char Model::DETAIL_SEPARATOR[] = "@";
|
|
|
|
Model::Model(const String& instance_name_, const TechModel* tech_model_)
|
|
: m_instance_name_(instance_name_), m_tech_model_(tech_model_),
|
|
m_constructed_(false), m_updated_(false), m_evaluated_(false)
|
|
{
|
|
m_property_names_ = new vector<String>;
|
|
m_parameter_names_ = new vector<String>;
|
|
m_parameters_ = new ParameterMap();
|
|
m_properties_ = new PropertyMap();
|
|
m_generated_properties_ = new PropertyMap();
|
|
m_sub_instances_ = new Map<SubModel*>();
|
|
m_event_map_ = new Map<Result*>();
|
|
m_area_map_ = new Map<Result*>();
|
|
m_ndd_power_map_ = new Map<Result*>();
|
|
}
|
|
|
|
Model::~Model()
|
|
{
|
|
// Clear parameter names
|
|
delete m_parameter_names_;
|
|
// Clear property name
|
|
delete m_property_names_;
|
|
|
|
// Clear parameters
|
|
delete m_parameters_;
|
|
m_parameters_ = NULL;
|
|
// Clear input properties
|
|
delete m_properties_;
|
|
m_properties_ = NULL;
|
|
|
|
// Clear generated properties
|
|
delete m_generated_properties_;
|
|
m_generated_properties_ = NULL;
|
|
|
|
// Clear sub models
|
|
deletePtrMap<SubModel>(m_sub_instances_);
|
|
m_sub_instances_ = NULL;
|
|
|
|
// Clear all results
|
|
deletePtrMap<Result>(m_event_map_);
|
|
m_event_map_ = NULL;
|
|
deletePtrMap<Result>(m_area_map_);
|
|
m_area_map_ = NULL;
|
|
deletePtrMap<Result>(m_ndd_power_map_);
|
|
m_ndd_power_map_ = NULL;
|
|
}
|
|
|
|
void Model::setInstanceName(const String& instance_name_)
|
|
{
|
|
m_instance_name_ = instance_name_;
|
|
return;
|
|
}
|
|
|
|
const String& Model::getInstanceName() const
|
|
{
|
|
return m_instance_name_;
|
|
}
|
|
|
|
void Model::setIsTopModel(bool is_top_model_)
|
|
{
|
|
m_is_top_model_ = is_top_model_;
|
|
return;
|
|
}
|
|
|
|
bool Model::getIsTopModel() const
|
|
{
|
|
return m_is_top_model_;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
// Parameters and properties checks
|
|
//-------------------------------------------------------------------------
|
|
void Model::addParameterName(const String& parameter_name_)
|
|
{
|
|
ASSERT(!m_constructed_, "[Error] " + getInstanceName() +
|
|
" -> Cannot add additional parameters names after model is constructed!");
|
|
m_parameter_names_->push_back(parameter_name_);
|
|
|
|
return;
|
|
}
|
|
|
|
void Model::addParameterName(const String& parameter_name_, const String& parameter_default_)
|
|
{
|
|
ASSERT(!m_constructed_, "[Error] " + getInstanceName() +
|
|
" -> Cannot add additional parameters names after model is constructed!");
|
|
m_parameter_names_->push_back(parameter_name_);
|
|
setParameter(parameter_name_, parameter_default_);
|
|
return;
|
|
}
|
|
|
|
const vector<String>* Model::getParameterNames() const
|
|
{
|
|
return m_parameter_names_;
|
|
}
|
|
|
|
void Model::addPropertyName(const String& property_name_)
|
|
{
|
|
ASSERT(!m_constructed_, "[Error] " + getInstanceName() +
|
|
" -> Cannot add additional property names after model is constructed!");
|
|
m_property_names_->push_back(property_name_);
|
|
return;
|
|
}
|
|
|
|
void Model::addPropertyName(const String& property_name_, const String& property_default_)
|
|
{
|
|
ASSERT(!m_constructed_, "[Error] " + getInstanceName() +
|
|
" -> Cannot add additional property names after model is constructed!");
|
|
m_property_names_->push_back(property_name_);
|
|
setProperty(property_name_, property_default_);
|
|
return;
|
|
}
|
|
|
|
const vector<String>* Model::getPropertyNames() const
|
|
{
|
|
return m_property_names_;
|
|
}
|
|
|
|
void Model::checkParameters() const
|
|
{
|
|
String missing_parameters = "";
|
|
|
|
for(int i = 0; i < (int)m_parameter_names_->size(); ++i)
|
|
{
|
|
const String& parameter_name = m_parameter_names_->at(i);
|
|
if (!m_parameters_->keyExist(parameter_name))
|
|
missing_parameters += " " + parameter_name + "\n";
|
|
}
|
|
|
|
ASSERT(missing_parameters.size() == 0, "[Error] " + m_instance_name_ +
|
|
" -> Missing parameters:\n" + missing_parameters);
|
|
return;
|
|
}
|
|
|
|
void Model::checkProperties() const
|
|
{
|
|
String missing_properties = "";
|
|
|
|
for(int i = 0; i < (int)m_property_names_->size(); ++i)
|
|
{
|
|
const String& property_name = m_property_names_->at(i);
|
|
if (!m_properties_->keyExist(property_name))
|
|
missing_properties += " " + property_name + "\n";
|
|
}
|
|
|
|
ASSERT(missing_properties.size() == 0, "[Error] " + m_instance_name_ +
|
|
" -> Missing properties:\n" + missing_properties);
|
|
return;
|
|
}
|
|
//-------------------------------------------------------------------------
|
|
|
|
//-------------------------------------------------------------------------
|
|
// Parameters Manipulation
|
|
//-------------------------------------------------------------------------
|
|
const ParameterMap* Model::getParameters() const
|
|
{
|
|
return m_parameters_;
|
|
}
|
|
|
|
const String Model::getParameter(const String& parameter_name_) const
|
|
{
|
|
return m_parameters_->get(parameter_name_);
|
|
}
|
|
|
|
void Model::setParameter(const String& parameter_name_, const String& parameter_value_)
|
|
{
|
|
ASSERT(!m_constructed_, "[Error] " + getInstanceName() +
|
|
" -> Cannot set parameters after model is constructed!");
|
|
m_parameters_->set(parameter_name_, parameter_value_);
|
|
}
|
|
//-------------------------------------------------------------------------
|
|
|
|
//-------------------------------------------------------------------------
|
|
// Properties Manipulation
|
|
//-------------------------------------------------------------------------
|
|
const PropertyMap* Model::getProperties() const
|
|
{
|
|
return m_properties_;
|
|
}
|
|
|
|
const String Model::getProperty(const String& property_name_) const
|
|
{
|
|
return m_properties_->get(property_name_);
|
|
}
|
|
|
|
void Model::setProperty(const String& property_name_, const String& property_value_)
|
|
{
|
|
// If any properties changed, reset updated and evaluated flags
|
|
m_updated_ = false;
|
|
m_evaluated_ = false;
|
|
m_properties_->set(property_name_, property_value_);
|
|
}
|
|
//-------------------------------------------------------------------------
|
|
|
|
PropertyMap* Model::getGenProperties()
|
|
{
|
|
return m_generated_properties_;
|
|
}
|
|
|
|
const PropertyMap* Model::getGenProperties() const
|
|
{
|
|
return m_generated_properties_;
|
|
}
|
|
|
|
void Model::addSubInstances(Model* sub_instance_, double num_sub_instances_)
|
|
{
|
|
// Get instance name
|
|
const String& sub_instance_name = sub_instance_->getInstanceName();
|
|
|
|
// Check if the instance exists
|
|
if(m_sub_instances_->keyExist(sub_instance_name))
|
|
{
|
|
const String& error_msg = "[Error] " + m_instance_name_ +
|
|
" -> Instance exists (" + sub_instance_name + ")";
|
|
throw Exception(error_msg);
|
|
}
|
|
|
|
// Check if the num_sub_instances_ is a positive number
|
|
ASSERT((num_sub_instances_ >= 0), "[Error] " + m_instance_name_ +
|
|
" -> Invalid number of instance (" + String(num_sub_instances_) + ")");
|
|
|
|
// Add the instance
|
|
m_sub_instances_->set(sub_instance_name, new SubModel(sub_instance_, num_sub_instances_));
|
|
return;
|
|
}
|
|
|
|
Model* Model::getSubInstance(const String& sub_instance_name_)
|
|
{
|
|
// Throw an Exception if the instance already exists
|
|
if(!m_sub_instances_->keyExist(sub_instance_name_))
|
|
{
|
|
const String& error_msg = "[Error] " + m_instance_name_ +
|
|
" -> Instance not exists (" + sub_instance_name_ + ")";
|
|
throw Exception(error_msg);
|
|
}
|
|
|
|
return m_sub_instances_->get(sub_instance_name_)->getModel();
|
|
}
|
|
|
|
const Model* Model::getSubInstance(const String& sub_instance_name_) const
|
|
{
|
|
// Throw an Exception if the instance does not exist
|
|
if(!m_sub_instances_->keyExist(sub_instance_name_))
|
|
{
|
|
const String& error_msg = "[Error] " + m_instance_name_ +
|
|
" -> Instance not exists (" + sub_instance_name_ + ")";
|
|
throw Exception(error_msg);
|
|
}
|
|
|
|
return m_sub_instances_->get(sub_instance_name_)->getModel();
|
|
}
|
|
|
|
bool Model::hasSubInstance(const String& sub_instance_name_) const
|
|
{
|
|
return m_sub_instances_->keyExist(sub_instance_name_);
|
|
}
|
|
|
|
void Model::addAreaResult(Result* area_)
|
|
{
|
|
const String& area_name = area_->getName();
|
|
|
|
// Throw an Exception if the area already exists
|
|
if(m_area_map_->keyExist(area_name))
|
|
{
|
|
const String& error_msg = "Internal error: area (" + area_name +
|
|
") exists";
|
|
throw Exception(error_msg);
|
|
}
|
|
|
|
// Add the area
|
|
m_area_map_->set(area_name, area_);
|
|
return;
|
|
}
|
|
|
|
Result* Model::getAreaResult(const String& area_name_)
|
|
{
|
|
return m_area_map_->get(area_name_);
|
|
}
|
|
|
|
const Result* Model::getAreaResult(const String& area_name_) const
|
|
{
|
|
return m_area_map_->get(area_name_);
|
|
}
|
|
|
|
bool Model::hasAreaResult(const String& area_name_) const
|
|
{
|
|
return m_area_map_->keyExist(area_name_);
|
|
}
|
|
|
|
void Model::addNddPowerResult(Result* ndd_power_)
|
|
{
|
|
const String& ndd_power_name = ndd_power_->getName();
|
|
|
|
// Throw an Exception if the ndd_power already exists
|
|
if(m_ndd_power_map_->keyExist(ndd_power_name))
|
|
{
|
|
const String& error_msg = "Internal error: ndd_power (" + ndd_power_name +
|
|
") exists";
|
|
throw Exception(error_msg);
|
|
}
|
|
|
|
// Add the ndd_power
|
|
m_ndd_power_map_->set(ndd_power_name, ndd_power_);
|
|
return;
|
|
}
|
|
|
|
Result* Model::getNddPowerResult(const String& ndd_power_name_)
|
|
{
|
|
return m_ndd_power_map_->get(ndd_power_name_);
|
|
}
|
|
|
|
const Result* Model::getNddPowerResult(const String& ndd_power_name_) const
|
|
{
|
|
return m_ndd_power_map_->get(ndd_power_name_);
|
|
}
|
|
|
|
bool Model::hasNddPowerResult(const String& ndd_power_name_) const
|
|
{
|
|
return m_ndd_power_map_->keyExist(ndd_power_name_);
|
|
}
|
|
|
|
void Model::addEventResult(Result* event_)
|
|
{
|
|
const String& event_name = event_->getName();
|
|
|
|
// Throw an Exception if the event already exists
|
|
if(m_event_map_->keyExist(event_name))
|
|
{
|
|
const String& error_msg = "Internal error: event (" + event_name +
|
|
") exists";
|
|
throw Exception(error_msg);
|
|
}
|
|
|
|
// Add the event
|
|
m_event_map_->set(event_name, event_);
|
|
return;
|
|
}
|
|
|
|
Result* Model::getEventResult(const String& event_name_)
|
|
{
|
|
return m_event_map_->get(event_name_);
|
|
}
|
|
|
|
const Result* Model::getEventResult(const String& event_name_) const
|
|
{
|
|
return m_event_map_->get(event_name_);
|
|
}
|
|
|
|
bool Model::hasEventResult(const String& event_name_) const
|
|
{
|
|
return m_event_map_->keyExist(event_name_);
|
|
}
|
|
|
|
const TechModel* Model::getTechModel() const
|
|
{
|
|
return m_tech_model_;
|
|
}
|
|
|
|
const void* Model::parseQuery(const String& query_type_, const String& query_hier_, const String& query_sub_field_)
|
|
{
|
|
// Break query by hierarchy separator
|
|
vector<String> hier_split = query_hier_.splitByString(HIERARCHY_SEPARATOR);
|
|
|
|
// Check if the query_hier matches the instance name
|
|
ASSERT((hier_split[0] == m_instance_name_), "[Error] " +
|
|
m_instance_name_ + " -> Mismatch in instance name (" +
|
|
hier_split[0] + ")");
|
|
|
|
// If there is no more hierarchy separator, this process the query
|
|
if(hier_split.size() == 1)
|
|
{
|
|
// Query the model
|
|
return processQuery(query_type_, query_sub_field_);
|
|
}
|
|
else
|
|
{
|
|
// Reconstruct the query
|
|
String temp_query_hier = hier_split[1];
|
|
for(int i = 2; i < (int)hier_split.size(); ++i)
|
|
{
|
|
temp_query_hier += HIERARCHY_SEPARATOR + hier_split[i];
|
|
}
|
|
|
|
// Get sub instance's name
|
|
const String& temp_sub_instance_name = hier_split[1];
|
|
ASSERT(m_sub_instances_->keyExist(temp_sub_instance_name), "[Error] " +
|
|
m_instance_name_ + " -> No sub-instances queried (" +
|
|
temp_sub_instance_name + ")");
|
|
|
|
return m_sub_instances_->get(temp_sub_instance_name)->getModel()->parseQuery(query_type_, temp_query_hier, query_sub_field_);
|
|
}
|
|
}
|
|
|
|
const void* Model::processQuery(const String& query_type_, const String& query_sub_field_)
|
|
{
|
|
if(query_type_ == "Property")
|
|
{
|
|
return getProperties();
|
|
}
|
|
else if(query_type_ == "Parameter")
|
|
{
|
|
return getParameters();
|
|
}
|
|
else if(query_type_.contain("Hier"))
|
|
{
|
|
return this;
|
|
}
|
|
else if(query_type_ == "Area")
|
|
{
|
|
return queryArea(query_sub_field_);
|
|
}
|
|
else if(query_type_ == "NddPower")
|
|
{
|
|
return queryNddPower(query_sub_field_);
|
|
}
|
|
else if(query_type_ == "Energy")
|
|
{
|
|
return queryEventEnergyCost(query_sub_field_);
|
|
}
|
|
else
|
|
{
|
|
const String& error_msg = "[Error] " + m_instance_name_ + " -> Unknown query type (" + query_type_ + ")";
|
|
throw Exception(error_msg);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
const Result* Model::queryArea(const String& area_name_) const
|
|
{
|
|
ASSERT(m_area_map_->keyExist(area_name_), "[Error] " + m_instance_name_ +
|
|
" -> Unknown queried area name (" + area_name_ + ")");
|
|
return m_area_map_->get(area_name_);
|
|
}
|
|
|
|
const Result* Model::queryNddPower(const String& ndd_power_name_)
|
|
{
|
|
ASSERT(m_ndd_power_map_->keyExist(ndd_power_name_), "[Error] " + m_instance_name_ +
|
|
" -> Unknown queried ndd power name (" + ndd_power_name_ + ")");
|
|
|
|
use("Idle");
|
|
return m_ndd_power_map_->get(ndd_power_name_);
|
|
}
|
|
|
|
const Result* Model::queryEventEnergyCost(const String& event_name_)
|
|
{
|
|
ASSERT(m_event_map_->keyExist(event_name_), "[Error] " + m_instance_name_ +
|
|
" -> Unknown queried event name (" + event_name_ + ")");
|
|
|
|
use(event_name_);
|
|
return m_event_map_->get(event_name_);
|
|
}
|
|
|
|
// Update checks whether the model needs updating, whether all properties have been specified,
|
|
// and calls updateModel if update is necessary
|
|
void Model::construct()
|
|
{
|
|
// Model should not be constructed yet
|
|
ASSERT(!m_constructed_, "[Error] " + getInstanceName() + " -> Cannot construct an already contructed model!");
|
|
// Check if whether all needed parameters are defined
|
|
checkParameters();
|
|
constructModel();
|
|
m_constructed_ = true;
|
|
m_updated_ = false;
|
|
m_evaluated_ = false;
|
|
return;
|
|
}
|
|
|
|
// Update checks whether the model needs updating, whether all properties have been specified,
|
|
// and calls updateModel if update is necessary
|
|
void Model::update()
|
|
{
|
|
// Model should be constructed
|
|
ASSERT(m_constructed_, "[Error] " + getInstanceName() + " -> Cannot update an unconstructed model!");
|
|
// If the model needs updating (due to property change)
|
|
// an update is necessary
|
|
if (!m_updated_)
|
|
{
|
|
// Check if all properties needed exist
|
|
checkProperties();
|
|
updateModel();
|
|
m_updated_ = true;
|
|
m_evaluated_ = false;
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Evaluate checks whether the model needs to be evaluated.
|
|
void Model::evaluate()
|
|
{
|
|
// Model should be constructed
|
|
ASSERT(m_constructed_, "[Error] " + getInstanceName() + " -> Cannot evaluate an unconstructed model!");
|
|
// Model should be updated
|
|
ASSERT(m_updated_, "[Error] " + getInstanceName() + " -> Cannot evaluate without first updating!");
|
|
// If the model needs evaluating
|
|
if (!m_evaluated_)
|
|
{
|
|
evaluateModel();
|
|
m_evaluated_ = true;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void Model::use(const String& event_name_)
|
|
{
|
|
useModel(event_name_);
|
|
return;
|
|
}
|
|
|
|
void Model::use()
|
|
{
|
|
useModel();
|
|
return;
|
|
}
|
|
|
|
// By default, update model will iterate through all sub-instances and do updateModel on them
|
|
void Model::updateModel()
|
|
{
|
|
Map<SubModel*>::Iterator iter = m_sub_instances_->begin();
|
|
Map<SubModel*>::Iterator end = m_sub_instances_->end();
|
|
while (iter != end)
|
|
{
|
|
iter->second->getModel()->update();
|
|
iter++;
|
|
}
|
|
return;
|
|
}
|
|
|
|
// By default, update model will iterate through all sub-instances and do updateModel on them
|
|
void Model::evaluateModel()
|
|
{
|
|
Map<SubModel*>::Iterator iter = m_sub_instances_->begin();
|
|
Map<SubModel*>::Iterator end = m_sub_instances_->end();
|
|
while (iter != end)
|
|
{
|
|
iter->second->getModel()->evaluate();
|
|
iter++;
|
|
}
|
|
return;
|
|
}
|
|
|
|
void Model::useModel(const String& /* event_name_ */)
|
|
{}
|
|
|
|
void Model::useModel()
|
|
{}
|
|
|
|
void Model::printHierarchy(const String& query_type_, const String& query_sub_field_, const String& prepend_str_, int detail_level_, ostream& ost_) const
|
|
{
|
|
if(query_type_ == "InstHier")
|
|
{
|
|
ost_ << prepend_str_ << getInstanceName() << endl;
|
|
printInstHierarchy(prepend_str_, detail_level_, ost_);
|
|
//if(detail_level_ > 0)
|
|
//{
|
|
//for(Map<SubModel*>::ConstIterator it = m_sub_instances_->begin(); it != m_sub_instances_->end(); ++it)
|
|
//{
|
|
//const Model* sub_model = (it->second)->getModel();
|
|
//String temp_prepend_str = prepend_str_ + " ";
|
|
//sub_model->printHierarchy(query_type_, query_sub_field_, temp_prepend_str, detail_level_ - 1, ost_);
|
|
//}
|
|
//}
|
|
}
|
|
else
|
|
{
|
|
const Map<Result*>* result_map;
|
|
|
|
if(query_type_ == "AreaHier")
|
|
{
|
|
result_map = m_area_map_;
|
|
}
|
|
else if(query_type_ == "NddPowerHier")
|
|
{
|
|
result_map = m_ndd_power_map_;
|
|
}
|
|
else if(query_type_ == "EventHier")
|
|
{
|
|
result_map = m_event_map_;
|
|
}
|
|
else
|
|
{
|
|
const String& error_msg = "[Error] " + m_instance_name_ + " -> Unknown query type (" + query_type_ + ")";
|
|
throw Exception(error_msg);
|
|
return;
|
|
}
|
|
|
|
if(query_sub_field_ == "")
|
|
{
|
|
for(Map<Result*>::ConstIterator it = result_map->begin(); it != result_map->end(); ++it)
|
|
{
|
|
const Result* result = it->second;
|
|
ost_ << prepend_str_ << getInstanceName() << "->" << result->getName() << endl;
|
|
result->printHierarchy(prepend_str_, detail_level_, ost_);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const Result* result = result_map->get(query_sub_field_);
|
|
ost_ << prepend_str_ << getInstanceName() << "->" << result->getName() << endl;
|
|
result->printHierarchy(prepend_str_, detail_level_, ost_);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
void Model::printInstHierarchy(const String& prepend_str_, int detail_level_, ostream& ost_) const
|
|
{
|
|
if(detail_level_ > 0)
|
|
{
|
|
for(Map<SubModel*>::ConstIterator it = m_sub_instances_->begin(); it != m_sub_instances_->end(); ++it)
|
|
{
|
|
const Model* sub_model = it->second->getModel();
|
|
String temp_prepend_str = prepend_str_ + " ";
|
|
|
|
ost_ << prepend_str_ << " |--" << sub_model->getInstanceName() << endl;
|
|
sub_model->printInstHierarchy(temp_prepend_str, detail_level_ - 1, ost_);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
Model* Model::clone() const
|
|
{
|
|
throw Exception(getInstanceName() + " -> Cannot be cloned!");
|
|
}
|
|
|
|
Model::Model(const Model& model_)
|
|
{
|
|
// Copy instance's name
|
|
m_instance_name_ = model_.m_instance_name_;
|
|
|
|
// Clone properties
|
|
m_properties_ = model_.m_properties_->clone();
|
|
|
|
// Clone instances
|
|
m_sub_instances_ = clonePtrMap(model_.m_sub_instances_);
|
|
|
|
// Clone events, area, ndd_power
|
|
m_event_map_ = clonePtrMap(model_.m_event_map_);
|
|
m_area_map_ = clonePtrMap(model_.m_area_map_);
|
|
m_ndd_power_map_ = clonePtrMap(model_.m_ndd_power_map_);
|
|
|
|
// Copy tech model pointer
|
|
m_tech_model_ = model_.m_tech_model_;
|
|
}
|
|
|
|
} // namespace DSENT
|
|
|