From f2a55c544c48c5197b42af2873d75df7a3e327da Mon Sep 17 00:00:00 2001 From: lempinen Date: Tue, 29 May 2012 09:18:27 +0000 Subject: [PATCH] Improved spreadsheet handling for 1.6: Model sheets can be used in module instances. (refs #3414) git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@25066 ac1ea38d-2e2b-0410-8846-a27921b304fc --- .../sysdyn/ui/utils/ExpressionUtils.java | 9 ++++ .../sysdyn/adapter/VariableRVIUtils.java | 13 +++-- .../sysdyn/modelica/ModelicaWriter.java | 50 ++++++++++++------- .../simantics/sysdyn/representation/Book.java | 7 +++ .../sysdyn/representation/Model.java | 14 ++++++ .../sysdyn/representation/Sheet.java | 2 +- .../sysdyn/representation/Variability.java | 22 +++++++- .../utils/SheetFormatUtils.java | 11 ++++ 8 files changed, 100 insertions(+), 28 deletions(-) diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ExpressionUtils.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ExpressionUtils.java index 6773376d..fa3d62ab 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ExpressionUtils.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ExpressionUtils.java @@ -43,6 +43,7 @@ import org.simantics.sysdyn.representation.Configuration; import org.simantics.sysdyn.representation.Enumeration; import org.simantics.sysdyn.representation.EnumerationIndex; import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.Model; import org.simantics.sysdyn.representation.Module; import org.simantics.sysdyn.representation.Sheet; import org.simantics.sysdyn.representation.Variable; @@ -184,6 +185,14 @@ public class ExpressionUtils { for(int i = 0; i < parts.length && current != null; i++) { current = getElement(current, parts[i]); } + + if(current == null) { + // Sheets are currently located in the model root. Try to find the sheet. + current = conf.getModuleType().getParent(); // Get module type parent (should be a model) + if(current instanceof Model) + current = getElement(((Model)current).getModelConfiguration(), parts[0]); // Try to get the sheet + } + if(current != null && current instanceof Sheet) { Sheet sheet = (Sheet) current; String e = ef.getExpression(); diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/VariableRVIUtils.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/VariableRVIUtils.java index 62118077..63143b0e 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/VariableRVIUtils.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/VariableRVIUtils.java @@ -59,7 +59,7 @@ public class VariableRVIUtils { * @throws DatabaseException */ private static void traverseIndexes(ReadGraph g, String rvi, HashMap rvis, List arrayIndexes) throws DatabaseException { - traverseIndexes(g, rvi, rvis, arrayIndexes, arrayIndexes.get(0), "", ""); + traverseIndexes(g, rvi, rvis, arrayIndexes, 0, "", ""); } /** @@ -76,10 +76,10 @@ public class VariableRVIUtils { * @param indexNamesSoFar String representation of the indexes so far in name format * @throws DatabaseException */ - private static void traverseIndexes(ReadGraph g, String rvi, HashMap rvis, List arrayIndexes, Resource currentEnumeration, String indexesSoFar, String indexNamesSoFar) throws DatabaseException { + private static void traverseIndexes(ReadGraph g, String rvi, HashMap rvis, List arrayIndexes, int currentIndex, String indexesSoFar, String indexNamesSoFar) throws DatabaseException { SysdynResource sr = SysdynResource.getInstance(g); // Enumeration indexes of the current enumeration (e.g. the first EnumIndexes in Var[EnumIndexes, EnumIndexes, EnumIndexes]) - Resource enumerationIndexes = g.getPossibleObject(currentEnumeration, sr.Enumeration_enumerationIndexes); + Resource enumerationIndexes = g.getPossibleObject(arrayIndexes.get(currentIndex), sr.Enumeration_enumerationIndexes); if(enumerationIndexes == null) return; List indexes = OrderedSetUtils.toList(g, enumerationIndexes); @@ -87,12 +87,11 @@ public class VariableRVIUtils { Boolean b = g.getPossibleRelatedValue(indexes.get(i), sr.EnumerationIndex_showEnumerationIndexInCharts, Bindings.BOOLEAN); // If this index is not wanted to be shown in charts, the recursion does not go any further and rvis.put() is not called for this enumeration if(Boolean.TRUE.equals(b)) { - int arrayIndex = arrayIndexes.indexOf(currentEnumeration); // Get the name of the index String name = g.getRelatedValue(indexes.get(i), Layer0.getInstance(g).HasName); - if(arrayIndex < arrayIndexes.size() - 1) + if(currentIndex < arrayIndexes.size() - 1) // If there are still more EnumIndexes, recursively call the function and add current index to indexesSoFar and indexNamesSoFar - traverseIndexes(g, rvi, rvis, arrayIndexes, arrayIndexes.get(arrayIndex + 1), + traverseIndexes(g, rvi, rvis, arrayIndexes, currentIndex + 1, indexesSoFar + (i + 1) +",", indexNamesSoFar + (name) +","); else { // The last enumeration. Add [rvi[1, 1, 1] = rvi[index1, index1, index1]}and so on to the rvis map @@ -129,7 +128,7 @@ public class VariableRVIUtils { // Find all redeclarations for(Resource redeclaration : graph.syncRequest(new ObjectsWithType(module, sr.Module_redeclaration, sr.Redeclaration))) { Resource replaced = graph.getSingleObject(redeclaration, sr.Redeclaration_replacedEnumeration); - if(enumerations.contains(replaced)) { + while(enumerations.contains(replaced)) { // Replace the redelcared enumeration in enumerations -list with the replacing enumeration enumerations.add(enumerations.indexOf(replaced), graph.getSingleObject(redeclaration, sr.Redeclaration_replacingEnumeration)); enumerations.remove(replaced); diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/modelica/ModelicaWriter.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/modelica/ModelicaWriter.java index ab41ec5f..090af57a 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/modelica/ModelicaWriter.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/modelica/ModelicaWriter.java @@ -50,12 +50,32 @@ public class ModelicaWriter { b.append(" parameter Integer size;\n"); b.append(" parameter Integer elements[:];\n"); b.append("end Enumeration_class;\n\n"); - + for(Configuration conf : configurations) - writeConfiguration(conf, b); + writeConfiguration(conf, "SpreadSheetBook", b); + + b.append(getGlobalSpreadSheets(configurations)); return b.toString(); } + + /** + * + */ + private static String getGlobalSpreadSheets(Collection configurations) { + StringBuilder sheets = new StringBuilder(); + for(Configuration conf : configurations) { + if(conf.getModel() != null) { + for(IElement e : conf.getElements()) { + if(e instanceof Book) { + return ((Book)e).getBook(); + } + } + } + } + + return sheets.toString(); + } /** * Write a single configuration to a given string builder @@ -63,7 +83,7 @@ public class ModelicaWriter { * @param configuration Model or module configuration * @param b String builder */ - private static void writeConfiguration(Configuration configuration, StringBuilder b) { + private static void writeConfiguration(Configuration configuration, String spreadSheetClass, StringBuilder b) { String app; boolean game = RepresentationUtils.isGameExperimentActive(); @@ -77,7 +97,6 @@ public class ModelicaWriter { ArrayList inputDependencies = new ArrayList(); ArrayList outputDependencies = new ArrayList(); HashMap> moduleInputs = new HashMap>(); - Book book = null; // Initialize lists for(IElement element : configuration.getElements()) { @@ -112,9 +131,6 @@ public class ModelicaWriter { // References from child modules inputDependencies.add(dependency); } - } else if (element instanceof Book) { - // Spreadsheet book - book = (Book)element; } } @@ -126,7 +142,14 @@ public class ModelicaWriter { // If the configuration is model configuration, use model name. Otherwise, use configuration name. ModuleType mt = configuration.getModuleType(); String className = mt != null ? (mt.getName().replace(" ", "")) : (configuration.getName().replace(" ", "")); - b.append("class ").append(className).append('\n'); + + b.append("class ").append(className); + + // Extend spreadsheetclass to get spreadsheet cell info + if(spreadSheetClass != null && !spreadSheetClass.isEmpty()) + b.append("\n extends " + spreadSheetClass + ";"); + + b.append("\n"); b.append("// Variable definitions\n"); for(IndependentVariable variable : variables) { @@ -164,11 +187,6 @@ public class ModelicaWriter { } } - if(book != null) { - b.append("// Spreadsheet definition\n"); - b.append(book.markBook()); - } - boolean initialEquations = false; for(Stock stock : stocks) { app = stock.getInitialEquation(); @@ -221,12 +239,6 @@ public class ModelicaWriter { b.append("end ").append(className).append(";\n\n"); - - // Update sheet definitions to contain the elements that were used. - if(book != null) { - int s = b.indexOf(book.markBook()); - b.replace(s, s + book.markBook().length(), book.getBook()); - } } /** diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Book.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Book.java index c4621a7e..031d4f43 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Book.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Book.java @@ -31,9 +31,16 @@ public class Book extends Variable { public String getBook() { StringBuilder book = new StringBuilder(); + + book.append("partial class SpreadSheetBook\n"); + for(Sheet sheet : sheets) book.append(sheet.getStringRepresentation()); + + book.append("end SpreadSheetBook;"); + return book.toString(); + } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Model.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Model.java index dbda4ea3..3cb5be55 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Model.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Model.java @@ -16,8 +16,10 @@ import java.util.HashMap; import org.simantics.layer0.Layer0; import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElement; import org.simantics.objmap.annotations.RelatedElements; import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.simulation.ontology.SimulationResource; import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.representation.annotations.BuiltinFunctions; @@ -46,6 +48,9 @@ public class Model { @RelatedValue(SysdynResource.URIs.SysdynModel_variableFilter) private String variableFilter; + + @RelatedElement(SimulationResource.URIs.HasConfiguration) + private Configuration configuration; @RelatedElements( value = Layer0.URIs.ConsistsOf, @@ -176,4 +181,13 @@ public class Model { public FunctionLibrary getBuiltins() { return builtins; } + + + /** + * + * @return Configuration of this model + */ + public Configuration getModelConfiguration() { + return configuration; + } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Sheet.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Sheet.java index 24106097..85331ac2 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Sheet.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Sheet.java @@ -163,7 +163,7 @@ public class Sheet extends org.simantics.sysdyn.representation.Variable { Variant cell = matrix.get(i, j); if(cell.getBinding().equals(Bindings.DOUBLE)) { array[i][j] = (Double)cell.getValue(); - } else if (cell.getBinding().equals(Bindings.MUTABLE_STRING)) { + } else if (cell.getBinding().equals(Bindings.MUTABLE_STRING) || (cell.getBinding().equals(Bindings.STRING))) { try { array[i][j] = Double.parseDouble(cell.getValue().toString()); } catch (NumberFormatException e) { diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variability.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variability.java index 7a5f165b..e12969f8 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variability.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variability.java @@ -71,7 +71,6 @@ public enum Variability { private static boolean isParameter(IndependentVariable variable, Configuration configuration, String reference, boolean allowVariables) { // Check if references are references to sheets or enumerations. // Sheet and Enumeration references are allowed, since sheets contain only constants / parameters - String r = reference.split("\\.")[0]; for(IElement element : configuration.getElements()) { if(element instanceof Module) { @@ -124,6 +123,27 @@ public enum Variability { } } } + + // Try to find sheet in another way: this might be a module type configuration. Find the model configuration and its sheet + if(configuration.getModuleType() != null) { + Object parent = configuration.getModuleType().getParent(); + if(parent != null && parent instanceof Model) { + configuration = ((Model)parent).getModelConfiguration(); + for(IElement element : configuration.getElements()) { + if(element instanceof Book) { + for(Sheet sheet : ((Book)element).getSheets()) { + if(r.equals(sheet.getName())) { + return true; + } + } + break; + } + } + } + } + + + // If there was no sheet for this reference name, or there was some other problem, return false return false; } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/SheetFormatUtils.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/SheetFormatUtils.java index 918eccbb..0eb9f750 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/SheetFormatUtils.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/SheetFormatUtils.java @@ -22,6 +22,8 @@ import org.simantics.sysdyn.expressionParser.ParseException; import org.simantics.sysdyn.expressionParser.Token; import org.simantics.sysdyn.representation.Configuration; import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.Model; +import org.simantics.sysdyn.representation.ModuleType; import org.simantics.sysdyn.representation.Sheet; import org.simantics.sysdyn.representation.Variable; @@ -38,6 +40,15 @@ public class SheetFormatUtils { for(String key : functionCalls.keySet()) { String[] parts = key.split("\\."); Object current = v.getParentConfiguration(); + + // Hack. Sheets can currently exist only in models, not in module types. + ModuleType moduleType= ((Configuration)current).getModuleType(); + if(moduleType != null) { + if(moduleType.getParent() != null && moduleType.getParent() instanceof Model) + current = ((Model)moduleType.getParent()).getModelConfiguration(); + } + // end Hack. + Object found = null; for(int i = 0; i < parts.length && current != null; i++) { found = null; -- 2.47.1