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 fmuLoaded = 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]);
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!");
284 } catch (FMILException e) {
286 } catch (UnsatisfiedLinkError err) {
287 throw new FMILException(UNSATISFIED_LINK);
288 } catch (Exception e) {
289 throw new FMILException(e.getMessage());
294 private native int instantiateSimulation_(int id) throws FMILException;
298 * Initializes a simulation.
300 * Make sure that simulation is instantiated first!
301 * @throws FMILException
303 public void initializeSimulation() throws FMILException {
304 synchronized(syncObject) {
308 int ret = initializeSimulation_(getModelIDNew());
310 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
312 } catch (FMILException e) {
314 } catch (UnsatisfiedLinkError err) {
315 throw new FMILException(UNSATISFIED_LINK);
316 } catch (Exception e) {
317 throw new FMILException(e.getMessage());
322 private native int initializeSimulation_(int id) throws FMILException;
325 * Subscribe a set of variables from a loaded simulation.
327 * Make sure that an FMU is loaded first.
328 * @param variables Array of variables
329 * @throws FMILException
331 public void subscribe(int[] variables) throws FMILException {
332 synchronized(syncObject) {
336 int ret = subscribe_(getModelIDNew(), variables);
338 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
340 } catch (UnsatisfiedLinkError err) {
341 throw new FMILException(UNSATISFIED_LINK);
342 } catch (Exception e) {
343 throw new FMILException(e.getMessage());
348 private native int subscribe_(int id, int[] variables);
351 * Set value of a real variable. If the variable is a
352 * parameter, the change is effective immediately.
354 * @param name Variable name
355 * @param value New value
356 * @throws FMILException
358 public void setRealValue(String name, double value) throws FMILException {
359 setRealValue(variableMap.get(name), value);
363 * Set value of a real variable. If the variable is a
364 * parameter, the change is effective immediately.
366 * @param name Variable id
367 * @param value New value
368 * @throws FMILException
370 public void setRealValue(int variableReference, double value) throws FMILException {
371 synchronized(syncObject) {
373 int ret = setRealValue_(getModelIDNew(), variableReference, value);
375 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
376 } catch (FMILException e) {
378 } catch (UnsatisfiedLinkError err) {
379 throw new FMILException(UNSATISFIED_LINK);
380 } catch (Exception e) {
381 throw new FMILException(e.getMessage());
386 private native int setRealValue_(int id, int variableReference, double value) throws FMILException;
390 * Set value of an integer variable. If the variable is a
391 * parameter, the change is effective immediately.
393 * @param name Variable name
394 * @param value New value
395 * @throws FMILException
397 public void setIntegerValue(String name, int value) throws FMILException {
398 setIntegerValue(variableMap.get(name), value);
402 * Set value of an integer variable. If the variable is a
403 * parameter, the change is effective immediately.
405 * @param name Variable id
406 * @param value New value
407 * @throws FMILException
409 public void setIntegerValue(int variableReference, int value) throws FMILException {
410 synchronized(syncObject) {
412 int ret = setIntegerValue_(getModelIDNew(), variableReference, value);
414 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
415 } catch (FMILException e) {
417 } catch (UnsatisfiedLinkError err) {
418 throw new FMILException(UNSATISFIED_LINK);
419 } catch (Exception e) {
420 throw new FMILException(e.getMessage());
425 private native int setIntegerValue_(int id, int variableReference, int value) throws FMILException;
429 * Set value of a boolean variable. If the variable is a
430 * parameter, the change is effective immediately.
432 * @param name Variable name
433 * @param value New value
434 * @throws FMILException
436 public void setBooleanValue(String name, boolean value) throws FMILException {
437 setBooleanValue(variableMap.get(name), value);
441 * Set value of a boolean variable. If the variable is a
442 * parameter, the change is effective immediately.
444 * @param name Variable id
445 * @param value New value
446 * @throws FMILException
448 public void setBooleanValue(int variableReference, boolean value) throws FMILException {
449 synchronized(syncObject) {
451 int ret = setBooleanValue_(getModelIDNew(), variableReference, value);
453 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
454 } catch (FMILException e) {
456 } catch (UnsatisfiedLinkError err) {
457 throw new FMILException(UNSATISFIED_LINK);
458 } catch (Exception e) {
459 throw new FMILException(e.getMessage());
464 private native int setBooleanValue_(int id, int variableReference, boolean value) throws FMILException;
468 * Set value of a string variable. If the variable is a
469 * parameter, the change is effective immediately.
471 * @param name Variable name
472 * @param value New value
473 * @throws FMILException
475 public void setStringValue(String name, String value) throws FMILException {
476 setStringValue(variableMap.get(name), value);
480 * Set value of a string variable. If the variable is a
481 * parameter, the change is effective immediately.
483 * @param name Variable id
484 * @param value New value
485 * @throws FMILException
487 public void setStringValue(int variableReference, String value) throws FMILException {
488 synchronized(syncObject) {
490 int ret = setStringValue_(getModelIDNew(), variableReference, value);
492 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
493 } catch (FMILException e) {
495 } catch (UnsatisfiedLinkError err) {
496 throw new FMILException(UNSATISFIED_LINK);
497 } catch (Exception e) {
498 throw new FMILException(e.getMessage());
503 private native int setStringValue_(int id, int variableReference, String value) throws FMILException;
507 * Simulate one step forward. The step length can be set with
510 * @throws FMILException
512 public void simulateStep() throws FMILException {
513 synchronized(syncObject) {
517 int ret = simulateStep_(getModelIDNew()); //0 is ok, 1 is error, 2 is pending
519 LOGGER.warn("Pending status return from FMU. This is not implemented in our Simulator yet!");
521 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
522 } catch (FMILException e) {
524 } catch (UnsatisfiedLinkError err) {
525 throw new FMILException(UNSATISFIED_LINK);
526 } catch (Exception e) {
527 throw new FMILException(e.getMessage());
531 private native int simulateStep_(int id) throws FMILException;
534 * Get an array containing the current values for subscribed variables. The
535 * values are in the same order as in the subscription.
537 * @param results An array the size of subscribed results
540 public double[] getSubscribedResults() throws FMILException {
541 synchronized(syncObject) {
545 double[] results = new double[subscription.size()];
546 Arrays.fill(results, Double.NaN);
548 return getSubscribedResults_(getModelIDNew(), results);
549 } catch (UnsatisfiedLinkError err) {
550 throw new FMILException(UNSATISFIED_LINK);
551 } catch (Exception e) {
552 throw new FMILException(e.getMessage());
557 private native double[] getSubscribedResults_(int id, double[] results);
561 * Unload FMU and the dll:s that it requires.
563 * To be called after all FMU simulations are ended.
564 * If the fmu is loaded again / changed, call to loadFMUFile is sufficient. loadFMUFile
565 * releases the previous fmu.dll
567 * @throws FMILException
569 public void unloadFMU() throws FMILException {
570 synchronized(syncObject) {
574 unlockFMUDirectory();
576 int ret = unloadFMU_(getModelIDNew());
578 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
581 removeFMUDirectoryContents();
583 } catch (FMILException e) {
585 } catch (UnsatisfiedLinkError err) {
586 throw new FMILException(UNSATISFIED_LINK);
587 } catch (Exception e) {
588 throw new FMILException(e.getMessage());
592 private native int unloadFMU_(int id) throws FMILException;
595 // * Checks if fmu has been initialized
596 // * @return current simulation time
598 // public boolean isInitialized() throws FMILException {
599 // synchronized(syncObject) {
601 // return isInitialized_(getModelID());
602 // } catch (UnsatisfiedLinkError err) {
603 // throw new FMILException(UNSATISFIED_LINK);
604 // } catch (Exception e) {
605 // throw new FMILException(e.getMessage());
610 // private native boolean isInitialized_(String id);
613 * Get the current simulation time
614 * @return current simulation time
616 public double getTime() throws FMILException {
617 synchronized(syncObject) {
621 return getTime_(getModelIDNew());
623 } catch (UnsatisfiedLinkError err) {
624 throw new FMILException(UNSATISFIED_LINK);
625 } catch (Exception e) {
626 throw new FMILException(e.getMessage());
631 private native double getTime_(int id);
634 * Get all variables in a loaded model
635 * @return all variables in a loaded model
637 public String[] getAllVariables() throws FMILException {
638 synchronized(syncObject) {
642 if(variableNames == null) {
643 variableNames = getAllVariables_(getModelIDNew());
645 return variableNames;
647 } catch (UnsatisfiedLinkError err) {
648 throw new FMILException(UNSATISFIED_LINK);
649 } catch (Exception e) {
650 throw new FMILException(e.getMessage());
655 private native String[] getAllVariables_(int id);
657 public String[] getAllVariableDescriptions() throws FMILException {
658 synchronized(syncObject) {
662 if(variableDescriptions == null) {
663 variableDescriptions = getAllVariableDescriptions_(getModelIDNew());
665 return variableDescriptions;
667 } catch (UnsatisfiedLinkError err) {
668 throw new FMILException(UNSATISFIED_LINK);
669 } catch (Exception e) {
670 throw new FMILException(e.getMessage());
675 private native String[] getAllVariableDescriptions_(int id);
677 public String[] getAllVariableDeclaredTypes() throws FMILException {
678 synchronized(syncObject) {
682 if(variableDeclaredTypes == null) {
683 variableDeclaredTypes = getAllVariableDeclaredTypes_(getModelIDNew());
685 return variableDeclaredTypes;
687 } catch (UnsatisfiedLinkError err) {
688 throw new FMILException(UNSATISFIED_LINK);
689 } catch (Exception e) {
690 throw new FMILException(e.getMessage());
695 private native String[] getAllVariableDeclaredTypes_(int id);
697 public int[] getAllVariableReferences() throws FMILException {
698 synchronized(syncObject) {
702 if(variableReferences == null) {
703 variableReferences = getAllVariableReferences_(getModelIDNew(), new int[variableNames.length]);
705 return variableReferences;
707 } catch (UnsatisfiedLinkError err) {
708 throw new FMILException(UNSATISFIED_LINK);
709 } catch (Exception e) {
710 throw new FMILException(e.getMessage());
715 private native int[] getAllVariableReferences_(int id, int[] array);
717 public int[] getAllVariableTypes() throws FMILException {
718 synchronized(syncObject) {
722 if(variableTypes == null) {
723 variableTypes = getAllVariableTypes_(getModelIDNew(), new int[variableNames.length]);
725 return variableTypes;
727 } catch (UnsatisfiedLinkError err) {
728 throw new FMILException(UNSATISFIED_LINK);
729 } catch (Exception e) {
730 throw new FMILException(e.getMessage());
735 private native int[] getAllVariableTypes_(int id, int[] array);
737 public int[] getAllVariableCausalities() throws FMILException {
738 synchronized(syncObject) {
742 if(variableCausalities == null) {
743 variableCausalities = getAllVariableCausalities_(getModelIDNew(), new int[variableNames.length]);
745 return variableCausalities;
747 } catch (UnsatisfiedLinkError err) {
748 throw new FMILException(UNSATISFIED_LINK);
749 } catch (Exception e) {
750 throw new FMILException(e.getMessage());
755 private native int[] getAllVariableCausalities_(int id, int[] array);
757 public int[] getAllVariableVariabilities() throws FMILException {
758 synchronized(syncObject) {
762 if(variableVariabilities == null) {
763 variableVariabilities = getAllVariableVariabilities_(getModelIDNew(), new int[variableNames.length]);
765 return variableVariabilities;
767 } catch (UnsatisfiedLinkError err) {
768 throw new FMILException(UNSATISFIED_LINK);
769 } catch (Exception e) {
770 throw new FMILException(e.getMessage());
775 private native int[] getAllVariableVariabilities_(int id, int[] array);
778 * Get all variables in a loaded model
779 * @return all variables in a loaded model
781 public String[] getAllDeclaredTypes() throws FMILException {
782 synchronized(syncObject) {
786 if(declaredTypes == null) {
787 declaredTypes = getAllDeclaredTypes_(getModelIDNew());
789 return declaredTypes;
791 } catch (UnsatisfiedLinkError err) {
792 throw new FMILException(UNSATISFIED_LINK);
793 } catch (Exception e) {
794 throw new FMILException(e.getMessage());
799 private native String[] getAllDeclaredTypes_(int id);
801 public String[] getAllDeclaredTypeDescriptions() throws FMILException {
802 synchronized(syncObject) {
806 if(declaredTypeDescriptions == null) {
807 declaredTypeDescriptions = getAllDeclaredTypeDescriptions_(getModelIDNew());
809 return declaredTypeDescriptions;
811 } catch (UnsatisfiedLinkError err) {
812 throw new FMILException(UNSATISFIED_LINK);
813 } catch (Exception e) {
814 throw new FMILException(e.getMessage());
819 private native String[] getAllDeclaredTypeDescriptions_(int id);
821 public String[] getAllDeclaredTypeQuantities() throws FMILException {
822 synchronized(syncObject) {
826 if(declaredTypeQuantities == null) {
827 declaredTypeQuantities = getAllDeclaredTypeQuantities_(getModelIDNew());
829 return declaredTypeQuantities;
831 } catch (UnsatisfiedLinkError err) {
832 throw new FMILException(UNSATISFIED_LINK);
833 } catch (Exception e) {
834 throw new FMILException(e.getMessage());
839 private native String[] getAllDeclaredTypeQuantities_(int id);
841 public String[] getAllDeclaredTypeUnits() throws FMILException {
842 synchronized(syncObject) {
846 if(declaredTypeUnits == null) {
847 declaredTypeUnits = getAllDeclaredTypeUnits_(getModelIDNew());
849 return declaredTypeUnits;
851 } catch (UnsatisfiedLinkError err) {
852 throw new FMILException(UNSATISFIED_LINK);
853 } catch (Exception e) {
854 throw new FMILException(e.getMessage());
859 private native String[] getAllDeclaredTypeUnits_(int id);
864 // * Get all variables from model that match the filter (and time variable)
866 // * @param regexp Regular expression filter
867 // * @return An array of variable names that match regexp filter (and time-variable)
868 // * @throws FMILException
870 // public String[] filterVariables(String regexp) throws FMILException {
871 // synchronized(syncObject) {
874 // return filterVariables_(getModelID(), regexp + "|time");
876 // } catch (UnsatisfiedLinkError err) {
877 // throw new FMILException(UNSATISFIED_LINK);
878 // } catch (Exception e) {
879 // throw new FMILException(e.getMessage());
884 // private native String[] filterVariables_(String id, String regexp);
887 // * Get the last error message
888 // * @return Last error message
890 // public String getLastErrorMessage() throws FMILException {
891 // synchronized(syncObject) {
896 // //return getLastErrorMessage_(getModelID());
898 // } catch (UnsatisfiedLinkError err) {
899 // throw new FMILException(UNSATISFIED_LINK);
900 // } catch (Exception e) {
901 // throw new FMILException(e.getMessage());
906 // private native String getLastErrorMessage_(String id);
909 * Get a value (double) for real variable
910 * @param name Name of the variable
912 * @throws FMILException
914 public double getRealValue(String name) throws FMILException {
915 double result = getRealValue(variableMap.get(name));
916 if (DEBUG) System.err.println("getRealValue " + name + " = " + result);
921 * Get a value (double) for real variable
922 * @param variableReference Numeric id of the variable
924 * @throws FMILException
926 public double getRealValue(int variableReference) throws FMILException {
927 synchronized(syncObject) {
929 return getRealValue_(getModelIDNew(), variableReference);
930 } catch (UnsatisfiedLinkError err) {
931 throw new FMILException(UNSATISFIED_LINK);
932 } catch (Exception e) {
933 throw new FMILException(e.getMessage());
938 private native double getRealValue_(int id, int variableReference) throws FMILException;
942 * Get value of integer variable
943 * @param name Name of the variable
945 * @throws FMILException
947 public int getIntegerValue(String name) throws FMILException {
948 int result = getIntegerValue(variableMap.get(name));
949 if (DEBUG) System.err.println("getIntegerValue " + name + " = " + result);
954 * Get a real (double) value for variable
955 * @param variableReference Numeric id of the variable
957 * @throws FMILException
959 public int getIntegerValue(int variableReference) throws FMILException {
960 synchronized(syncObject) {
962 return getIntegerValue_(getModelIDNew(), variableReference);
963 } catch (UnsatisfiedLinkError err) {
964 throw new FMILException(UNSATISFIED_LINK);
965 } catch (Exception e) {
966 throw new FMILException(e.getMessage());
971 private native int getIntegerValue_(int id, int variableReference) throws FMILException;
975 * Get value of boolean variable
976 * @param name Name of the variable
978 * @throws FMILException
980 public boolean getBooleanValue(String name) throws FMILException {
981 boolean result = getBooleanValue(variableMap.get(name));
982 if (DEBUG) System.err.println("getBooleanValue " + name + " = " + result);
987 * Get value of boolean variable
988 * @param variableReference Numeric id of the variable
990 * @throws FMILException
992 public boolean getBooleanValue(int variableReference) throws FMILException {
993 synchronized(syncObject) {
995 return getBooleanValue_(getModelIDNew(), variableReference);
996 } catch (UnsatisfiedLinkError err) {
997 throw new FMILException(UNSATISFIED_LINK);
998 } catch (Exception e) {
999 throw new FMILException(e.getMessage());
1004 private native boolean getBooleanValue_(int id, int variableReference) throws FMILException;
1008 * Get value of string variable
1009 * @param name Name of the variable
1011 * @throws FMILException
1013 public String getStringValue(String name) throws FMILException {
1014 String result = getStringValue(variableMap.get(name));
1015 if (DEBUG) System.err.println("getIntegerValue " + name + " = " + result);
1020 * Get value of string variable
1021 * @param variableReference Numeric id of the variable
1023 * @throws FMILException
1025 public String getStringValue(int variableReference) throws FMILException {
1026 synchronized(syncObject) {
1028 return getStringValue_(getModelIDNew(), variableReference);
1029 } catch (UnsatisfiedLinkError err) {
1030 throw new FMILException(UNSATISFIED_LINK);
1031 } catch (Exception e) {
1032 throw new FMILException(e.getMessage());
1037 private native String getStringValue_(int id, int variableReference) throws FMILException;
1040 private FileChannel channel;
1041 private FileLock lock;
1043 @SuppressWarnings("resource")
1044 private boolean lockFMUDirectory() {
1047 // Get a file channel for the lock file
1048 File lockFile = new File(TEMP_FMU_DIRECTORY, LOCK_FILE_NAME);
1049 if(!lockFile.isFile())
1050 lockFile.createNewFile();
1052 channel = new RandomAccessFile(lockFile, "rw").getChannel();
1054 // Use the file channel to create a lock on the file.
1055 // This method blocks until it can retrieve the lock.
1056 lock = channel.lock();
1058 // // Try acquiring the lock without blocking. This method returns
1059 // // null or throws an exception if the file is already locked.
1061 // lock = channel.tryLock();
1062 // } catch (OverlappingFileLockException e) {
1063 // // File is already locked in this thread or virtual machine
1065 } catch (IOException e) {
1072 private boolean unlockFMUDirectory() {
1081 } catch (IOException e) {
1087 private boolean removeFMUDirectoryContents() {
1090 File tempDir = new File(TEMP_FMU_DIRECTORY);
1091 FileUtils.deleteAll(tempDir);
1093 } catch (IOException e) {
1100 protected void finalize() throws Throwable {
1103 } catch (Throwable t) {
1104 LOGGER.error("Could not unload native FMU!", t);