bool Registry::AddVariableToCurrentImportList(Variable* import_var) { Module* submod = CurrentModule()->GetVariable(m_currentImportedModule)->GetModule(); Variable* var = submod->GetNextExportVariable(); if (var == NULL) { string error = "Unable to add variable '" + import_var->GetNameDelimitedBy(GetCC()) + "' when creating an instance of the module '" + submod->GetModuleName() + "' because this module is defined to have only " + SizeTToString(submod->GetNumExportVariables()) + " variable(s) definable by default in its construction."; SetError(error); return true; } var->Synchronize(import_var); return false; }
bool Registry::SynchronizeCellMLConnection(nsCOMPtr<cellml_apiIConnection> connection) { nsString cellmltext; string cellmlname; nsresult rv; nsCOMPtr<cellml_apiIModel> topmodel; //used when the encapsulation parent is null (in GetNameAccordingToEncapsulationParent) rv = connection->GetModelElement(getter_AddRefs(topmodel)); nsCOMPtr<cellml_apiICellMLElement> parentel; rv = topmodel->GetParentElement(getter_AddRefs(parentel)); while (parentel != NULL) { rv = parentel->GetModelElement(getter_AddRefs(topmodel)); rv = topmodel->GetParentElement(getter_AddRefs(parentel)); } //rv = topmodel->GetName(cellmltext); //cout << "Top model: " << ToThinString(cellmltext.get()) << endl; //First we get the list of the component and any/all encapsulation parents vector<string> comp1moduleparents, comp2moduleparents; vector<string> comp1modulenames, comp2modulenames; nsCOMPtr<cellml_apiIMapComponents> compmap; rv = connection->GetComponentMapping(getter_AddRefs(compmap)); nsCOMPtr<cellml_apiICellMLComponent> component; //First rv = compmap->GetFirstComponent(getter_AddRefs(component)); while (component != NULL) { string modname = GetModuleNameFrom(component); comp1moduleparents.insert(comp1moduleparents.begin(), modname); modname = GetNameAccordingToEncapsulationParent(component, topmodel); FixName(modname); comp1modulenames.insert(comp1modulenames.begin(), modname); rv = component->GetEncapsulationParent(getter_AddRefs(component)); } comp1moduleparents.insert(comp1moduleparents.begin(), CurrentModule()->GetModuleName()); //Second rv = compmap->GetSecondComponent(getter_AddRefs(component)); while (component != NULL) { string modname = GetModuleNameFrom(component); comp2moduleparents.insert(comp2moduleparents.begin(), modname); modname = GetNameAccordingToEncapsulationParent(component, topmodel); FixName(modname); comp2modulenames.insert(comp2modulenames.begin(), modname); rv = component->GetEncapsulationParent(getter_AddRefs(component)); } comp2moduleparents.insert(comp2moduleparents.begin(), CurrentModule()->GetModuleName()); //cout << "First component's parents: " << ToStringFromVecDelimitedBy(comp1moduleparents, '.') << endl << "Second component's parents: " << ToStringFromVecDelimitedBy(comp2moduleparents, '.') << endl; //cout << "First component's names: " << ToStringFromVecDelimitedBy(comp1modulenames, '.') << endl << "Second component's names: " << ToStringFromVecDelimitedBy(comp2modulenames, '.') << endl; //Now figure out the 'lowest' common parent in the encapsulation tree: string commonparent = ""; assert(comp1moduleparents.size() > 0 && comp2moduleparents.size() > 0 && comp1moduleparents[0] == comp2moduleparents[0]); size_t pnum = 0; while (comp1modulenames.size() > 0 && comp2modulenames.size() > 0 && comp1modulenames[0] == comp2modulenames[0]) { comp1modulenames.erase(comp1modulenames.begin()); comp2modulenames.erase(comp2modulenames.begin()); pnum++; } commonparent = comp1moduleparents[pnum]; //At this point, we have the name of the module where the encapsulation happens: Module* topmod = CurrentModule(); if (commonparent != "") { topmod = GetModule(commonparent); } assert(topmod != NULL); // cout << "Top module: " << commonparent << endl; // cout << "first compartment submodule name: " << ToStringFromVecDelimitedBy(comp1modulenames, '.') << endl; // cout << "second compartment submodule name: " << ToStringFromVecDelimitedBy(comp2modulenames, '.') << endl; //And we have the full names of the submodules whose variables need to be synchronized. But there might be multiple variables, so we go through them all: nsCOMPtr<cellml_apiIMapVariablesSet> mvs; rv = connection->GetVariableMappings(getter_AddRefs(mvs)); nsCOMPtr<cellml_apiIMapVariablesIterator> mvsi; rv = mvs->IterateMapVariables(getter_AddRefs(mvsi)); nsCOMPtr<cellml_apiIMapVariables> mapvars; rv = mvsi->NextMapVariable(getter_AddRefs(mapvars)); bool somefalse = false; while (mapvars != NULL) { rv = mapvars->GetFirstVariableName(cellmltext); cellmlname = ToThinString(cellmltext.get()); FixName(cellmlname); vector<string> fullvarname = comp1modulenames; fullvarname.push_back(cellmlname); Variable* firstvar = topmod->GetVariable(fullvarname); assert(firstvar != NULL); firstvar = firstvar->GetSameVariable(); rv = mapvars->GetSecondVariableName(cellmltext); cellmlname = ToThinString(cellmltext.get()); FixName(cellmlname); fullvarname = comp2modulenames; fullvarname.push_back(cellmlname); Variable* secondvar = topmod->GetVariable(fullvarname); assert(secondvar != NULL); secondvar = secondvar->GetSameVariable(); //Now we create a local name for the variables to be synchronized if one doesn't already exist. vector<string> firstvarname = firstvar->GetName(); vector<string> secondvarname = secondvar->GetName(); if (firstvarname.size() > 1 && secondvarname.size() > 1) { //Create a local variable vector<string> newvarname; newvarname.push_back(secondvarname[secondvarname.size()-1]); Variable* newvar = topmod->GetVariable(newvarname); if (newvar == NULL) { newvar = topmod->AddOrFindVariable(&newvarname[0]); } else { newvar = topmod->AddNewNumberedVariable(newvarname[0]); } if (firstvar->Synchronize(newvar)) { g_registry.AddWarning("In module '" + topmod->GetModuleName() + "', the variables " + firstvar->GetNameDelimitedBy('.') + " and " + newvar->GetNameDelimitedBy('.') + " were unable to be set as equivalent: " + g_registry.GetError()); somefalse = true; } if (secondvar->Synchronize(newvar)) { g_registry.AddWarning("In module '" + topmod->GetModuleName() + "', the variables " + secondvar->GetNameDelimitedBy('.') + " and " + newvar->GetNameDelimitedBy('.') + " were unable to be set as equivalent: " + g_registry.GetError()); somefalse = true; } } else { if (firstvar->Synchronize(secondvar)) { g_registry.AddWarning("In module '" + topmod->GetModuleName() + "', the variables " + firstvar->GetNameDelimitedBy('.') + " and " + secondvar->GetNameDelimitedBy('.') + " were unable to be set as equivalent: " + g_registry.GetError()); somefalse = true; } } rv = mvsi->NextMapVariable(getter_AddRefs(mapvars)); } return somefalse; }