Skip to content

Commit e07f46c

Browse files
authored
implement oms_duplicateVariant() (#1178)
* implement oms_duplicateVariant() * assign unique signalFilter.xml names for variants * expected output * add test to filter signals in variants * create unique filename for local resources (.ssv,.ssm) when duplicating variants * fix variantNames for subsystems * fix handling variantNames
1 parent 5efd0b2 commit e07f46c

22 files changed

+1439
-27
lines changed

src/OMSimulatorLib/Component.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ namespace oms
6363
virtual ~Component();
6464

6565
virtual oms_status_enu_t addSignalsToResults(const char* regex) = 0;
66-
virtual oms_status_enu_t exportToSSD(pugi::xml_node& node, Snapshot& snapshot) const = 0;
66+
virtual oms_status_enu_t exportToSSD(pugi::xml_node& node, Snapshot& snapshot, std::string variantName) const = 0;
6767
virtual oms_status_enu_t exportToSSV(pugi::xml_node& ssvNode) { return logError_NotImplemented; }
6868
virtual void getFilteredUnitDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& unitDefinitions) { return ; }
6969

src/OMSimulatorLib/ComponentFMUCS.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ oms::Component* oms::ComponentFMUCS::NewComponent(const pugi::xml_node& node, om
366366
return component;
367367
}
368368

369-
oms_status_enu_t oms::ComponentFMUCS::exportToSSD(pugi::xml_node& node, Snapshot& snapshot) const
369+
oms_status_enu_t oms::ComponentFMUCS::exportToSSD(pugi::xml_node& node, Snapshot& snapshot, std::string variantName) const
370370
{
371371
#if !defined(NO_TLM)
372372
if (tlmbusconnectors[0])
@@ -394,7 +394,7 @@ oms_status_enu_t oms::ComponentFMUCS::exportToSSD(pugi::xml_node& node, Snapshot
394394
return oms_status_error;
395395

396396
// export ParameterBindings at component level
397-
values.exportParameterBindings(node, snapshot);
397+
values.exportParameterBindings(node, snapshot, variantName);
398398

399399
return oms_status_ok;
400400
}

src/OMSimulatorLib/ComponentFMUCS.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ namespace oms
6060
static Component* NewComponent(const pugi::xml_node& node, System* parentSystem, const std::string& sspVersion, const Snapshot& snapshot);
6161
const FMUInfo* getFMUInfo() const {return &(this->fmuInfo);}
6262

63-
oms_status_enu_t exportToSSD(pugi::xml_node& node, Snapshot& snapshot) const;
63+
oms_status_enu_t exportToSSD(pugi::xml_node& node, Snapshot& snapshot, std::string variantName) const;
6464
oms_status_enu_t exportToSSV(pugi::xml_node& ssvNode);
6565
void getFilteredUnitDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& unitDefinitions);
6666
oms_status_enu_t exportToSSVTemplate(pugi::xml_node& ssvNode, Snapshot& snapshot);

src/OMSimulatorLib/ComponentFMUME.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ oms::Component* oms::ComponentFMUME::NewComponent(const pugi::xml_node& node, om
367367
return component;
368368
}
369369

370-
oms_status_enu_t oms::ComponentFMUME::exportToSSD(pugi::xml_node& node, Snapshot& snapshot) const
370+
oms_status_enu_t oms::ComponentFMUME::exportToSSD(pugi::xml_node& node, Snapshot& snapshot, std::string variantName) const
371371
{
372372
#if !defined(NO_TLM)
373373
if (tlmbusconnectors[0])
@@ -395,7 +395,7 @@ oms_status_enu_t oms::ComponentFMUME::exportToSSD(pugi::xml_node& node, Snapshot
395395
return oms_status_error;
396396

397397
// export ParameterBindings at component level
398-
values.exportParameterBindings(node, snapshot);
398+
values.exportParameterBindings(node, snapshot, variantName);
399399

400400
return oms_status_ok;
401401
}

src/OMSimulatorLib/ComponentFMUME.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ namespace oms
5757
static Component* NewComponent(const pugi::xml_node& node, System* parentSystem, const std::string& sspVersion, const Snapshot& snapshot);
5858
const FMUInfo* getFMUInfo() const {return &(this->fmuInfo);}
5959

60-
oms_status_enu_t exportToSSD(pugi::xml_node& node, Snapshot& snapshot) const;
60+
oms_status_enu_t exportToSSD(pugi::xml_node& node, Snapshot& snapshot, std::string variantName) const;
6161
oms_status_enu_t exportToSSV(pugi::xml_node& ssvNode);
6262
void getFilteredUnitDefinitionsToSSD(std::map<std::string, std::map<std::string, std::string>>& unitDefinitions);
6363
oms_status_enu_t exportToSSVTemplate(pugi::xml_node& ssvNode, Snapshot& snapshot);

src/OMSimulatorLib/ComponentTable.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ oms::Component* oms::ComponentTable::NewComponent(const pugi::xml_node& node, om
161161
return component;
162162
}
163163

164-
oms_status_enu_t oms::ComponentTable::exportToSSD(pugi::xml_node& node, Snapshot& snapshot) const
164+
oms_status_enu_t oms::ComponentTable::exportToSSD(pugi::xml_node& node, Snapshot& snapshot, std::string variantName) const
165165
{
166166
node.append_attribute("name") = this->getCref().c_str();
167167
node.append_attribute("type") = "application/table";

src/OMSimulatorLib/ComponentTable.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ namespace oms
5555
static Component* NewComponent(const oms::ComRef& cref, System* parentSystem, const std::string& path);
5656
static Component* NewComponent(const pugi::xml_node& node, System* parentSystem, const std::string& sspVersion, const Snapshot& snapshot);
5757

58-
oms_status_enu_t exportToSSD(pugi::xml_node& node, Snapshot& snapshot) const;
58+
oms_status_enu_t exportToSSD(pugi::xml_node& node, Snapshot& snapshot, std::string variantName) const;
5959
oms_status_enu_t exportToSSVTemplate(pugi::xml_node& ssvNode) {return oms_status_ok;}
6060
oms_status_enu_t exportToSSMTemplate(pugi::xml_node& ssmNode) {return oms_status_ok;}
6161
oms_status_enu_t instantiate();

src/OMSimulatorLib/Model.cpp

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,23 @@ oms_status_enu_t oms::Model::loadSnapshot(const pugi::xml_node& node)
187187
return oms_status_ok;
188188
}
189189

190+
oms_status_enu_t oms::Model::duplicateVariant(const ComRef& crefA, const ComRef& crefB)
191+
{
192+
if (!crefA.isEmpty())
193+
return logError("only top level model is allowed");
194+
195+
// copy the current snapshot
196+
char* fullsnapshot = NULL;
197+
exportSnapshot("", &fullsnapshot);
198+
199+
listVariants.push_back(fullsnapshot);
200+
201+
// set the current variantName
202+
this->variantName = std::string(crefB) + ".ssd";
203+
this->signalFilterFilename = "resources/signalFilter_" + std::string(crefB) + ".xml";
204+
return oms_status_ok;
205+
}
206+
190207
oms_status_enu_t oms::Model::importSnapshot(const char* snapshot_, char** newCref)
191208
{
192209
if (!validState(oms_modelState_virgin))
@@ -343,7 +360,7 @@ oms_status_enu_t oms::Model::list(const oms::ComRef& cref, char** contents)
343360
pugi::xml_node ssdNode = snapshot.getTemplateResourceNodeSSD("SystemStructure.ssd", this->getCref());
344361
pugi::xml_node system_node = ssdNode.append_child(oms::ssp::Draft20180219::ssd::system);
345362

346-
subsystem->exportToSSD(system_node, snapshot);
363+
subsystem->exportToSSD(system_node, snapshot, this->variantName);
347364
doc.append_copy(snapshot.getResourceNode("SystemStructure.ssd").first_child());
348365
}
349366
else
@@ -356,7 +373,7 @@ oms_status_enu_t oms::Model::list(const oms::ComRef& cref, char** contents)
356373
pugi::xml_node ssdNode = snapshot.getTemplateResourceNodeSSD("SystemStructure.ssd", this->getCref());
357374
pugi::xml_node system_node = ssdNode.append_child(oms::ssp::Draft20180219::ssd::system);
358375

359-
component->exportToSSD(system_node, snapshot);
376+
component->exportToSSD(system_node, snapshot, this->variantName);
360377
doc.append_copy(snapshot.getResourceNode("SystemStructure.ssd").first_child());
361378
}
362379
}
@@ -703,12 +720,12 @@ oms_status_enu_t oms::Model::addSystem(const oms::ComRef& cref, oms_system_enu_t
703720

704721
oms_status_enu_t oms::Model::exportToSSD(Snapshot& snapshot) const
705722
{
706-
pugi::xml_node ssdNode = snapshot.getTemplateResourceNodeSSD("SystemStructure.ssd", this->getCref());
723+
pugi::xml_node ssdNode = snapshot.getTemplateResourceNodeSSD(this->variantName, this->getCref());
707724

708725
if (system)
709726
{
710727
pugi::xml_node system_node = ssdNode.append_child(oms::ssp::Draft20180219::ssd::system);
711-
if (oms_status_ok != system->exportToSSD(system_node, snapshot))
728+
if (oms_status_ok != system->exportToSSD(system_node, snapshot, this->variantName))
712729
return logError("export of system failed");
713730
}
714731

@@ -958,6 +975,27 @@ void oms::Model::writeAllResourcesToFilesystem(std::vector<std::string>& resourc
958975
logError("failed to export \"" + filename + " to directory " + tempDir);
959976
}
960977

978+
// get all the variants and its resources
979+
// TODO how to handle mutiple resouces with same file name (e.g) resources/signalFilter.xml and other ssv resouces
980+
for (auto const & variant : listVariants)
981+
{
982+
std::vector<std::string> variantResources;
983+
Snapshot snapshot_;
984+
snapshot_.import(variant);
985+
snapshot_.getResources(variantResources);
986+
//snapshot_.debugPrintAll();
987+
for (auto const &variantfilename : variantResources)
988+
{
989+
//std::cout << "\n variant resources : " << variantfilename;
990+
auto file = std::find(resources.begin(), resources.end(), variantfilename);
991+
if (file == resources.end())
992+
{
993+
resources.push_back(variantfilename);
994+
snapshot_.writeResourceNode(variantfilename, filesystem::path(tempDir));
995+
}
996+
}
997+
}
998+
961999
// export the unreferenced ssv and ssm files to ssp, this must be extended to export all unreferenced resources
9621000
for (auto & it : importedResources)
9631001
{

src/OMSimulatorLib/Model.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ namespace oms
7878
oms_status_enu_t addResources(const ComRef& cref, const std::string& path);
7979
oms_status_enu_t deleteReferencesInSSD(const ComRef& cref);
8080
oms_status_enu_t deleteResourcesInSSP(const std::string& filename);
81+
oms_status_enu_t duplicateVariant(const ComRef& crefA, const ComRef& crefB);
8182
oms_status_enu_t referenceResources(const ComRef& cref, const std::string& ssmFile);
8283
oms_status_enu_t reduceSSV(const std::string& ssvfile, const std::string& ssmfile, const std::string& filepath);
8384
oms_status_enu_t exportToSSD(Snapshot& snapshot) const;
@@ -135,6 +136,10 @@ namespace oms
135136

136137
std::vector<std::string> importedResources; ///< list of imported resources from ssp
137138

139+
std::vector<char*> listVariants; ///< list of all variants copied when user create a new variant using oms_duplicateVariant()
140+
141+
std::string getVariantName() {return variantName;}
142+
138143
private: // methods
139144
Model(const ComRef& cref, const std::string& tempDir);
140145

@@ -169,6 +174,8 @@ namespace oms
169174
std::string resultFilename; ///< default <name>_res.mat
170175
std::string signalFilterFilename = "resources/signalFilter.xml";
171176

177+
std::string variantName = "SystemStructure.ssd"; ///< default name
178+
172179
std::vector<std::string> externalResources; ///< list of external ssv or ssm resources from filesystem
173180

174181
bool isolatedFMU = false;

src/OMSimulatorLib/OMSimulator.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,19 @@ oms_status_enu_t oms_addSubModel(const char* cref, const char* fmuPath)
916916
return system->addSubModel(tail, fmuPath);
917917
}
918918

919+
oms_status_enu_t oms_duplicateVariant(const char* crefA, const char* crefB)
920+
{
921+
oms::ComRef tail(crefA);
922+
oms::ComRef front = tail.pop_front();
923+
924+
oms::Model* model = oms::Scope::GetInstance().getModel(front);
925+
if (!model)
926+
return logError_ModelNotInScope(front);
927+
928+
return model->duplicateVariant(tail, crefB);
929+
930+
}
931+
919932
oms_status_enu_t oms_replaceSubModel(const char* cref, const char* fmuPath, bool dryRun, int* warningCount)
920933
{
921934
oms::ComRef tail(cref);

0 commit comments

Comments
 (0)