1 package org.simantics.fmil.core;
4 import java.io.IOException;
5 import java.io.RandomAccessFile;
7 import java.nio.channels.FileChannel;
8 import java.nio.channels.FileLock;
9 import java.nio.file.Files;
10 import java.nio.file.Paths;
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.HashSet;
14 import java.util.List;
16 import java.util.UUID;
18 import org.eclipse.core.runtime.FileLocator;
19 import org.eclipse.core.runtime.Path;
20 import org.eclipse.core.runtime.Platform;
21 import org.osgi.framework.Bundle;
22 import org.simantics.fmil.core.ExecEnvironment.OSType;
23 import org.simantics.utils.FileUtils;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
27 import gnu.trove.list.array.TIntArrayList;
28 import gnu.trove.map.hash.TObjectIntHashMap;
33 private static final Logger LOGGER = LoggerFactory.getLogger(FMIL.class);
35 private static final boolean DEBUG = false;
40 private static int OK = 0;
41 private static int ERROR = 1;
42 private static int PENDING = 2;
43 private static String UNSATISFIED_LINK = "Method not found. DLL might not be loaded properly.";
44 public static final String TEMP_FMU_DIRECTORY_NAME = "fmil";
45 public static String TEMP_FMU_COMMON_DIRECTORY;
46 public static String LOCK_FILE_NAME = "fmil.lock";
48 public static Object syncObject = new Object();
51 * Static: load native libraries required for the FMU simulation to work.
55 File[] libraries = new File[2];
57 ExecEnvironment env = ExecEnvironment.calculate();
60 URL sharedFMILIBUrl = null;
61 URL simulatorFMIUrl = null;
62 Bundle b = Platform.getBundle("org.simantics.fmil.core");
64 if (env.os == OSType.WINDOWS) {
65 sharedFMILIBUrl = FileLocator.find(b, new Path("libraries/fmilib_shared.dll"), null);
66 simulatorFMIUrl = FileLocator.find(b, new Path("libraries/FMUSimulator.dll"), null);
67 } else if(env.os == OSType.LINUX) {
68 sharedFMILIBUrl = FileLocator.find(b, new Path("libraries/libfmilib_shared.so"), null);
69 simulatorFMIUrl = FileLocator.find(b, new Path("libraries/libFMUSimulator.so"), null);
72 libraries[0] = new File(FileLocator.toFileURL(sharedFMILIBUrl).getPath());
73 libraries[1] = new File(FileLocator.toFileURL(simulatorFMIUrl).getPath());
74 } catch (Exception e) {
75 LOGGER.error("Failed to resolve native FMU simulation library for execution environment {}.{}", env.os, env.arch, e);
78 for(File library : libraries) {
80 System.err.println("FMU library not loaded. FMU simulation not working.");
82 } else if(!library.isFile()) {
83 System.err.println(library.getAbsolutePath() + " not found");
86 System.load(library.getAbsolutePath());
87 } catch (Throwable t) {
88 System.err.println(t.getMessage());
95 * Static: initialize fmu temp folder from current working directory
98 TEMP_FMU_COMMON_DIRECTORY = Paths.get(".").toAbsolutePath().normalize().toString();
101 public static void setTempFMUCommonDir(File dir) {
102 TEMP_FMU_COMMON_DIRECTORY = dir.getAbsolutePath();
105 private String fmuDir;
108 public String TEMP_FOLDER_1;
109 public String TEMP_FOLDER_2;
110 public String TEMP_FMU_DIRECTORY;
111 private String dirName;
113 private String[] variableNames;
114 private String[] variableDescriptions;
115 private String[] variableDeclaredTypes;
116 private int[] variableReferences;
117 private int[] variableTypes;
118 private int[] variableCausalities;
119 private int[] variableVariabilities;
121 private String[] declaredTypes;
122 private String[] declaredTypeDescriptions;
123 private String[] declaredTypeQuantities;
124 private String[] declaredTypeUnits;
126 private TObjectIntHashMap<String> variableMap = new TObjectIntHashMap<String>();
128 private Set<String> subscriptionSet = new HashSet<String>();
129 private TIntArrayList subscription = new TIntArrayList();
130 private ArrayList<String> subscribedNames = new ArrayList<String>();
132 public List<String> getSubscribedNames() {
133 return subscribedNames;
136 public boolean subscribe(String name) throws FMILException {
137 synchronized(syncObject) {
139 int vr = variableMap.get(name);
140 if(vr == 0) return false;
141 if(!subscriptionSet.add(name)) return false;
142 subscribedNames.add(name);
143 subscription.add(vr);
144 subscribe(new int[] { vr });
150 // Create a directory for this control
151 File tempDir = new File(TEMP_FMU_COMMON_DIRECTORY, UUID.randomUUID().toString());
153 TEMP_FMU_DIRECTORY = tempDir.getAbsolutePath();
155 // Create two directories inside the temp directory for this control
156 dirName = UUID.randomUUID().toString();
157 File fmuDir = new File(TEMP_FMU_DIRECTORY, dirName);
160 TEMP_FOLDER_1 = fmuDir.toString();
161 TEMP_FOLDER_2 = fmuDir.toString() + "_2";
163 // Lock fmu directory in temp directory
167 public int getModelIDNew() {
171 public String getModelID() {
175 public String getFmuDir() {
180 * Load fmu from a given file path. Releases the (possible) previously
183 * @param path absolute file path for fmu file
184 * @throws FMILException
186 private int fmuN = 0;
187 private boolean instantiated = false;
188 public void loadFMUFile(String path) throws FMILException {
190 if (!Files.exists(Paths.get(path)))
191 throw new FMILException("File " + path + " does not exist");
192 if (!Files.isRegularFile(Paths.get(path)))
193 throw new FMILException("Path " + path + " is not a file");
195 synchronized(syncObject) {
198 fmuDir = TEMP_FOLDER_1;
201 fmuDir = TEMP_FOLDER_2;
205 java.nio.file.Path tempDir = Paths.get(fmuDir);
206 if(Files.exists(tempDir) && Files.isDirectory(tempDir)) {
208 FileUtils.emptyDirectory(tempDir);
209 } catch (IOException e) {
210 throw new FMILException("Could not delete existing files from temp folder for fmu " + path, e);
214 Files.createDirectory(tempDir);
215 } catch (IOException e) {
216 throw new FMILException("Could not create temp folder for fmu " + path, e);
221 String tmpPath = tempDir.toString();
222 if(!tmpPath.endsWith("\\") && !tmpPath.endsWith("/"))
223 tmpPath = tmpPath + "/";
224 id = loadFMUFile_(path, tmpPath);
227 getAllVariableReferences();
229 for(int i=0;i<variableNames.length;i++) {
230 variableMap.put(variableNames[i], variableReferences[i]);
233 instantiated = false;
234 } catch (UnsatisfiedLinkError err) {
235 throw new FMILException(UNSATISFIED_LINK, err);
236 } catch (Exception e) {
237 LOGGER.error(e.getMessage());
238 throw new FMILException(e.getMessage());
243 private native int loadFMUFile_(String path, String toDir) throws FMILException;
246 * Set a step length for simulation
248 * @param step Step length for simulation
249 * @throws FMILException
251 public void setStepLength(double step) throws FMILException {
252 synchronized(syncObject) {
255 int ret = setStepLength_(getModelIDNew(), step);
257 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
259 } catch (UnsatisfiedLinkError err) {
260 throw new FMILException(UNSATISFIED_LINK);
261 } catch (Exception e) {
262 throw new FMILException(e.getMessage());
267 private native int setStepLength_(int id, double step);
270 * Instantiates a simulation.
272 * Make sure that an FMU is loaded first.
273 * @throws FMILException
275 public void instantiateSimulation() throws FMILException {
276 synchronized(syncObject) {
280 int ret = instantiateSimulation_(getModelIDNew());
282 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
286 } catch (FMILException e) {
288 } catch (UnsatisfiedLinkError err) {
289 throw new FMILException(UNSATISFIED_LINK);
290 } catch (Exception e) {
291 throw new FMILException(e.getMessage());
296 private native int instantiateSimulation_(int id) throws FMILException;
300 * Initializes a simulation.
302 * Make sure that simulation is instantiated first!
303 * @throws FMILException
305 public void initializeSimulation() throws FMILException {
306 synchronized(syncObject) {
310 int ret = initializeSimulation_(getModelIDNew());
312 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
314 } catch (FMILException e) {
316 } catch (UnsatisfiedLinkError err) {
317 throw new FMILException(UNSATISFIED_LINK);
318 } catch (Exception e) {
319 throw new FMILException(e.getMessage());
324 private native int initializeSimulation_(int id) throws FMILException;
327 * Subscribe a set of variables from a loaded simulation.
329 * Make sure that an FMU is loaded first.
330 * @param variables Array of variables
331 * @throws FMILException
333 public void subscribe(int[] variables) throws FMILException {
334 synchronized(syncObject) {
338 int ret = subscribe_(getModelIDNew(), variables);
340 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
342 } catch (UnsatisfiedLinkError err) {
343 throw new FMILException(UNSATISFIED_LINK);
344 } catch (Exception e) {
345 throw new FMILException(e.getMessage());
350 private native int subscribe_(int id, int[] variables);
353 * Set value of a real variable. If the variable is a
354 * parameter, the change is effective immediately.
356 * @param name Variable name
357 * @param value New value
358 * @throws FMILException
360 public void setRealValue(String name, double value) throws FMILException {
361 setRealValue(variableMap.get(name), value);
365 * Set value of a real variable. If the variable is a
366 * parameter, the change is effective immediately.
368 * @param name Variable id
369 * @param value New value
370 * @throws FMILException
372 public void setRealValue(int variableReference, double value) throws FMILException {
373 synchronized(syncObject) {
375 int ret = setRealValue_(getModelIDNew(), variableReference, value);
377 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
378 } catch (FMILException e) {
380 } catch (UnsatisfiedLinkError err) {
381 throw new FMILException(UNSATISFIED_LINK);
382 } catch (Exception e) {
383 throw new FMILException(e.getMessage());
388 private native int setRealValue_(int id, int variableReference, double value) throws FMILException;
392 * Set value of an integer variable. If the variable is a
393 * parameter, the change is effective immediately.
395 * @param name Variable name
396 * @param value New value
397 * @throws FMILException
399 public void setIntegerValue(String name, int value) throws FMILException {
400 setIntegerValue(variableMap.get(name), value);
404 * Set value of an integer variable. If the variable is a
405 * parameter, the change is effective immediately.
407 * @param name Variable id
408 * @param value New value
409 * @throws FMILException
411 public void setIntegerValue(int variableReference, int value) throws FMILException {
412 synchronized(syncObject) {
414 int ret = setIntegerValue_(getModelIDNew(), variableReference, value);
416 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
417 } catch (FMILException e) {
419 } catch (UnsatisfiedLinkError err) {
420 throw new FMILException(UNSATISFIED_LINK);
421 } catch (Exception e) {
422 throw new FMILException(e.getMessage());
427 private native int setIntegerValue_(int id, int variableReference, int value) throws FMILException;
431 * Set value of a boolean variable. If the variable is a
432 * parameter, the change is effective immediately.
434 * @param name Variable name
435 * @param value New value
436 * @throws FMILException
438 public void setBooleanValue(String name, boolean value) throws FMILException {
439 setBooleanValue(variableMap.get(name), value);
443 * Set value of a boolean variable. If the variable is a
444 * parameter, the change is effective immediately.
446 * @param name Variable id
447 * @param value New value
448 * @throws FMILException
450 public void setBooleanValue(int variableReference, boolean value) throws FMILException {
451 synchronized(syncObject) {
453 int ret = setBooleanValue_(getModelIDNew(), variableReference, value);
455 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
456 } catch (FMILException e) {
458 } catch (UnsatisfiedLinkError err) {
459 throw new FMILException(UNSATISFIED_LINK);
460 } catch (Exception e) {
461 throw new FMILException(e.getMessage());
466 private native int setBooleanValue_(int id, int variableReference, boolean value) throws FMILException;
470 * Set value of a string variable. If the variable is a
471 * parameter, the change is effective immediately.
473 * @param name Variable name
474 * @param value New value
475 * @throws FMILException
477 public void setStringValue(String name, String value) throws FMILException {
478 setStringValue(variableMap.get(name), value);
482 * Set value of a string variable. If the variable is a
483 * parameter, the change is effective immediately.
485 * @param name Variable id
486 * @param value New value
487 * @throws FMILException
489 public void setStringValue(int variableReference, String value) throws FMILException {
490 synchronized(syncObject) {
492 int ret = setStringValue_(getModelIDNew(), variableReference, value);
494 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
495 } catch (FMILException e) {
497 } catch (UnsatisfiedLinkError err) {
498 throw new FMILException(UNSATISFIED_LINK);
499 } catch (Exception e) {
500 throw new FMILException(e.getMessage());
505 private native int setStringValue_(int id, int variableReference, String value) throws FMILException;
509 * Simulate one step forward. The step length can be set with
512 * @throws FMILException
514 public void simulateStep() throws FMILException {
515 synchronized(syncObject) {
519 int ret = simulateStep_(getModelIDNew()); //0 is ok, 1 is error, 2 is pending
521 LOGGER.warn("Pending status return from FMU. This is not implemented in our Simulator yet!");
523 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
524 } catch (FMILException e) {
526 } catch (UnsatisfiedLinkError err) {
527 throw new FMILException(UNSATISFIED_LINK);
528 } catch (Exception e) {
529 throw new FMILException(e.getMessage());
533 private native int simulateStep_(int id) throws FMILException;
536 * Get an array containing the current values for subscribed variables. The
537 * values are in the same order as in the subscription.
539 * @param results An array the size of subscribed results
542 public double[] getSubscribedResults() throws FMILException {
543 synchronized(syncObject) {
547 double[] results = new double[subscription.size()];
548 Arrays.fill(results, Double.NaN);
550 return getSubscribedResults_(getModelIDNew(), results);
551 } catch (UnsatisfiedLinkError err) {
552 throw new FMILException(UNSATISFIED_LINK);
553 } catch (Exception e) {
554 throw new FMILException(e.getMessage());
559 private native double[] getSubscribedResults_(int id, double[] results);
563 * Unload FMU and the dll:s that it requires.
565 * To be called after all FMU simulations are ended.
566 * If the fmu is loaded again / changed, call to loadFMUFile is sufficient. loadFMUFile
567 * releases the previous fmu.dll
569 * @throws FMILException
571 public void unloadFMU() throws FMILException {
572 synchronized(syncObject) {
576 unlockFMUDirectory();
578 // Many FMUs will not correctly clean-up during unload if the simulation isn't instantiated
579 // Essentially we'd likely be passing an invalid pointer to the FMU to cleanup, causing native c-level crashes.
582 int ret = unloadFMU_(getModelIDNew());
584 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
585 instantiated = false;
587 removeFMUDirectoryContents();
589 } catch (FMILException e) {
591 } catch (UnsatisfiedLinkError err) {
592 throw new FMILException(UNSATISFIED_LINK);
593 } catch (Exception e) {
594 throw new FMILException(e.getMessage());
598 private native int unloadFMU_(int id) throws FMILException;
601 // * Checks if fmu has been initialized
602 // * @return current simulation time
604 // public boolean isInitialized() throws FMILException {
605 // synchronized(syncObject) {
607 // return isInitialized_(getModelID());
608 // } catch (UnsatisfiedLinkError err) {
609 // throw new FMILException(UNSATISFIED_LINK);
610 // } catch (Exception e) {
611 // throw new FMILException(e.getMessage());
616 // private native boolean isInitialized_(String id);
619 * Get the current simulation time
620 * @return current simulation time
622 public double getTime() throws FMILException {
623 synchronized(syncObject) {
627 return getTime_(getModelIDNew());
629 } catch (UnsatisfiedLinkError err) {
630 throw new FMILException(UNSATISFIED_LINK);
631 } catch (Exception e) {
632 throw new FMILException(e.getMessage());
637 private native double getTime_(int id);
640 * Get all variables in a loaded model
641 * @return all variables in a loaded model
643 public String[] getAllVariables() throws FMILException {
644 synchronized(syncObject) {
648 if(variableNames == null) {
649 variableNames = getAllVariables_(getModelIDNew());
651 return variableNames;
653 } catch (UnsatisfiedLinkError err) {
654 throw new FMILException(UNSATISFIED_LINK);
655 } catch (Exception e) {
656 throw new FMILException(e.getMessage());
661 private native String[] getAllVariables_(int id);
663 public String[] getAllVariableDescriptions() throws FMILException {
664 synchronized(syncObject) {
668 if(variableDescriptions == null) {
669 variableDescriptions = getAllVariableDescriptions_(getModelIDNew());
671 return variableDescriptions;
673 } catch (UnsatisfiedLinkError err) {
674 throw new FMILException(UNSATISFIED_LINK);
675 } catch (Exception e) {
676 throw new FMILException(e.getMessage());
681 private native String[] getAllVariableDescriptions_(int id);
683 public String[] getAllVariableDeclaredTypes() throws FMILException {
684 synchronized(syncObject) {
688 if(variableDeclaredTypes == null) {
689 variableDeclaredTypes = getAllVariableDeclaredTypes_(getModelIDNew());
691 return variableDeclaredTypes;
693 } catch (UnsatisfiedLinkError err) {
694 throw new FMILException(UNSATISFIED_LINK);
695 } catch (Exception e) {
696 throw new FMILException(e.getMessage());
701 private native String[] getAllVariableDeclaredTypes_(int id);
703 public int[] getAllVariableReferences() throws FMILException {
704 synchronized(syncObject) {
708 if(variableReferences == null) {
709 variableReferences = getAllVariableReferences_(getModelIDNew(), new int[variableNames.length]);
711 return variableReferences;
713 } catch (UnsatisfiedLinkError err) {
714 throw new FMILException(UNSATISFIED_LINK);
715 } catch (Exception e) {
716 throw new FMILException(e.getMessage());
721 private native int[] getAllVariableReferences_(int id, int[] array);
723 public int[] getAllVariableTypes() throws FMILException {
724 synchronized(syncObject) {
728 if(variableTypes == null) {
729 variableTypes = getAllVariableTypes_(getModelIDNew(), new int[variableNames.length]);
731 return variableTypes;
733 } catch (UnsatisfiedLinkError err) {
734 throw new FMILException(UNSATISFIED_LINK);
735 } catch (Exception e) {
736 throw new FMILException(e.getMessage());
741 private native int[] getAllVariableTypes_(int id, int[] array);
743 public int[] getAllVariableCausalities() throws FMILException {
744 synchronized(syncObject) {
748 if(variableCausalities == null) {
749 variableCausalities = getAllVariableCausalities_(getModelIDNew(), new int[variableNames.length]);
751 return variableCausalities;
753 } catch (UnsatisfiedLinkError err) {
754 throw new FMILException(UNSATISFIED_LINK);
755 } catch (Exception e) {
756 throw new FMILException(e.getMessage());
761 private native int[] getAllVariableCausalities_(int id, int[] array);
763 public int[] getAllVariableVariabilities() throws FMILException {
764 synchronized(syncObject) {
768 if(variableVariabilities == null) {
769 variableVariabilities = getAllVariableVariabilities_(getModelIDNew(), new int[variableNames.length]);
771 return variableVariabilities;
773 } catch (UnsatisfiedLinkError err) {
774 throw new FMILException(UNSATISFIED_LINK);
775 } catch (Exception e) {
776 throw new FMILException(e.getMessage());
781 private native int[] getAllVariableVariabilities_(int id, int[] array);
784 * Get all variables in a loaded model
785 * @return all variables in a loaded model
787 public String[] getAllDeclaredTypes() throws FMILException {
788 synchronized(syncObject) {
792 if(declaredTypes == null) {
793 declaredTypes = getAllDeclaredTypes_(getModelIDNew());
795 return declaredTypes;
797 } catch (UnsatisfiedLinkError err) {
798 throw new FMILException(UNSATISFIED_LINK);
799 } catch (Exception e) {
800 throw new FMILException(e.getMessage());
805 private native String[] getAllDeclaredTypes_(int id);
807 public String[] getAllDeclaredTypeDescriptions() throws FMILException {
808 synchronized(syncObject) {
812 if(declaredTypeDescriptions == null) {
813 declaredTypeDescriptions = getAllDeclaredTypeDescriptions_(getModelIDNew());
815 return declaredTypeDescriptions;
817 } catch (UnsatisfiedLinkError err) {
818 throw new FMILException(UNSATISFIED_LINK);
819 } catch (Exception e) {
820 throw new FMILException(e.getMessage());
825 private native String[] getAllDeclaredTypeDescriptions_(int id);
827 public String[] getAllDeclaredTypeQuantities() throws FMILException {
828 synchronized(syncObject) {
832 if(declaredTypeQuantities == null) {
833 declaredTypeQuantities = getAllDeclaredTypeQuantities_(getModelIDNew());
835 return declaredTypeQuantities;
837 } catch (UnsatisfiedLinkError err) {
838 throw new FMILException(UNSATISFIED_LINK);
839 } catch (Exception e) {
840 throw new FMILException(e.getMessage());
845 private native String[] getAllDeclaredTypeQuantities_(int id);
847 public String[] getAllDeclaredTypeUnits() throws FMILException {
848 synchronized(syncObject) {
852 if(declaredTypeUnits == null) {
853 declaredTypeUnits = getAllDeclaredTypeUnits_(getModelIDNew());
855 return declaredTypeUnits;
857 } catch (UnsatisfiedLinkError err) {
858 throw new FMILException(UNSATISFIED_LINK);
859 } catch (Exception e) {
860 throw new FMILException(e.getMessage());
865 private native String[] getAllDeclaredTypeUnits_(int id);
870 // * Get all variables from model that match the filter (and time variable)
872 // * @param regexp Regular expression filter
873 // * @return An array of variable names that match regexp filter (and time-variable)
874 // * @throws FMILException
876 // public String[] filterVariables(String regexp) throws FMILException {
877 // synchronized(syncObject) {
880 // return filterVariables_(getModelID(), regexp + "|time");
882 // } catch (UnsatisfiedLinkError err) {
883 // throw new FMILException(UNSATISFIED_LINK);
884 // } catch (Exception e) {
885 // throw new FMILException(e.getMessage());
890 // private native String[] filterVariables_(String id, String regexp);
893 // * Get the last error message
894 // * @return Last error message
896 // public String getLastErrorMessage() throws FMILException {
897 // synchronized(syncObject) {
902 // //return getLastErrorMessage_(getModelID());
904 // } catch (UnsatisfiedLinkError err) {
905 // throw new FMILException(UNSATISFIED_LINK);
906 // } catch (Exception e) {
907 // throw new FMILException(e.getMessage());
912 // private native String getLastErrorMessage_(String id);
915 * Get a value (double) for real variable
916 * @param name Name of the variable
918 * @throws FMILException
920 public double getRealValue(String name) throws FMILException {
921 double result = getRealValue(variableMap.get(name));
922 if (DEBUG) System.err.println("getRealValue " + name + " = " + result);
927 * Get a value (double) for real variable
928 * @param variableReference Numeric id of the variable
930 * @throws FMILException
932 public double getRealValue(int variableReference) throws FMILException {
933 synchronized(syncObject) {
935 return getRealValue_(getModelIDNew(), variableReference);
936 } catch (UnsatisfiedLinkError err) {
937 throw new FMILException(UNSATISFIED_LINK);
938 } catch (Exception e) {
939 throw new FMILException(e.getMessage());
944 private native double getRealValue_(int id, int variableReference) throws FMILException;
948 * Get value of integer variable
949 * @param name Name of the variable
951 * @throws FMILException
953 public int getIntegerValue(String name) throws FMILException {
954 int result = getIntegerValue(variableMap.get(name));
955 if (DEBUG) System.err.println("getIntegerValue " + name + " = " + result);
960 * Get a real (double) value for variable
961 * @param variableReference Numeric id of the variable
963 * @throws FMILException
965 public int getIntegerValue(int variableReference) throws FMILException {
966 synchronized(syncObject) {
968 return getIntegerValue_(getModelIDNew(), variableReference);
969 } catch (UnsatisfiedLinkError err) {
970 throw new FMILException(UNSATISFIED_LINK);
971 } catch (Exception e) {
972 throw new FMILException(e.getMessage());
977 private native int getIntegerValue_(int id, int variableReference) throws FMILException;
981 * Get value of boolean variable
982 * @param name Name of the variable
984 * @throws FMILException
986 public boolean getBooleanValue(String name) throws FMILException {
987 boolean result = getBooleanValue(variableMap.get(name));
988 if (DEBUG) System.err.println("getBooleanValue " + name + " = " + result);
993 * Get value of boolean variable
994 * @param variableReference Numeric id of the variable
996 * @throws FMILException
998 public boolean getBooleanValue(int variableReference) throws FMILException {
999 synchronized(syncObject) {
1001 return getBooleanValue_(getModelIDNew(), variableReference);
1002 } catch (UnsatisfiedLinkError err) {
1003 throw new FMILException(UNSATISFIED_LINK);
1004 } catch (Exception e) {
1005 throw new FMILException(e.getMessage());
1010 private native boolean getBooleanValue_(int id, int variableReference) throws FMILException;
1014 * Get value of string variable
1015 * @param name Name of the variable
1017 * @throws FMILException
1019 public String getStringValue(String name) throws FMILException {
1020 String result = getStringValue(variableMap.get(name));
1021 if (DEBUG) System.err.println("getIntegerValue " + name + " = " + result);
1026 * Get value of string variable
1027 * @param variableReference Numeric id of the variable
1029 * @throws FMILException
1031 public String getStringValue(int variableReference) throws FMILException {
1032 synchronized(syncObject) {
1034 return getStringValue_(getModelIDNew(), variableReference);
1035 } catch (UnsatisfiedLinkError err) {
1036 throw new FMILException(UNSATISFIED_LINK);
1037 } catch (Exception e) {
1038 throw new FMILException(e.getMessage());
1043 private native String getStringValue_(int id, int variableReference) throws FMILException;
1046 private FileChannel channel;
1047 private FileLock lock;
1049 @SuppressWarnings("resource")
1050 private boolean lockFMUDirectory() {
1053 // Get a file channel for the lock file
1054 File lockFile = new File(TEMP_FMU_DIRECTORY, LOCK_FILE_NAME);
1055 if(!lockFile.isFile())
1056 lockFile.createNewFile();
1058 channel = new RandomAccessFile(lockFile, "rw").getChannel();
1060 // Use the file channel to create a lock on the file.
1061 // This method blocks until it can retrieve the lock.
1062 lock = channel.lock();
1064 // // Try acquiring the lock without blocking. This method returns
1065 // // null or throws an exception if the file is already locked.
1067 // lock = channel.tryLock();
1068 // } catch (OverlappingFileLockException e) {
1069 // // File is already locked in this thread or virtual machine
1071 } catch (IOException e) {
1078 private boolean unlockFMUDirectory() {
1087 } catch (IOException e) {
1093 private boolean removeFMUDirectoryContents() {
1096 File tempDir = new File(TEMP_FMU_DIRECTORY);
1097 FileUtils.deleteAll(tempDir);
1099 } catch (IOException e) {
1106 protected void finalize() throws Throwable {
1109 } catch (Throwable t) {
1110 LOGGER.error("Could not unload native FMU!", t);