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 String UNSATISFIED_LINK = "Method not found. DLL might not be loaded properly.";
43 public static final String TEMP_FMU_DIRECTORY_NAME = "fmil";
44 public static String TEMP_FMU_COMMON_DIRECTORY;
45 public static String LOCK_FILE_NAME = "fmil.lock";
47 public static Object syncObject = new Object();
50 * Static: load native libraries required for the FMU simulation to work.
54 File[] libraries = new File[2];
56 ExecEnvironment env = ExecEnvironment.calculate();
59 URL sharedFMILIBUrl = null;
60 URL simulatorFMIUrl = null;
61 Bundle b = Platform.getBundle("org.simantics.fmil.core");
63 if (env.os == OSType.WINDOWS) {
64 sharedFMILIBUrl = FileLocator.find(b, new Path("libraries/fmilib_shared.dll"), null);
65 simulatorFMIUrl = FileLocator.find(b, new Path("libraries/FMUSimulator.dll"), null);
66 } else if(env.os == OSType.LINUX) {
67 sharedFMILIBUrl = FileLocator.find(b, new Path("libraries/libfmilib_shared.so"), null);
68 simulatorFMIUrl = FileLocator.find(b, new Path("libraries/libFMUSimulator.so"), null);
71 libraries[0] = new File(FileLocator.toFileURL(sharedFMILIBUrl).getPath());
72 libraries[1] = new File(FileLocator.toFileURL(simulatorFMIUrl).getPath());
73 } catch (Exception e) {
74 LOGGER.error("Failed to resolve native FMU simulation library for execution environment {}.{}", env.os, env.arch, e);
77 for(File library : libraries) {
79 System.err.println("FMU library not loaded. FMU simulation not working.");
81 } else if(!library.isFile()) {
82 System.err.println(library.getAbsolutePath() + " not found");
85 System.load(library.getAbsolutePath());
86 } catch (Throwable t) {
87 System.err.println(t.getMessage());
94 * Static: initialize fmu temp folder from current working directory
97 TEMP_FMU_COMMON_DIRECTORY = Paths.get(".").toAbsolutePath().normalize().toString();
100 public static void setTempFMUCommonDir(File dir) {
101 TEMP_FMU_COMMON_DIRECTORY = dir.getAbsolutePath();
104 private String fmuDir;
107 public String TEMP_FOLDER_1;
108 public String TEMP_FOLDER_2;
109 public String TEMP_FMU_DIRECTORY;
110 private String dirName;
112 private String[] variableNames;
113 private String[] variableDescriptions;
114 private String[] variableDeclaredTypes;
115 private int[] variableReferences;
116 private int[] variableTypes;
117 private int[] variableCausalities;
118 private int[] variableVariabilities;
120 private String[] declaredTypes;
121 private String[] declaredTypeDescriptions;
122 private String[] declaredTypeQuantities;
123 private String[] declaredTypeUnits;
125 private TObjectIntHashMap<String> variableMap = new TObjectIntHashMap<String>();
127 private Set<String> subscriptionSet = new HashSet<String>();
128 private TIntArrayList subscription = new TIntArrayList();
129 private ArrayList<String> subscribedNames = new ArrayList<String>();
131 public List<String> getSubscribedNames() {
132 return subscribedNames;
135 public boolean subscribe(String name) throws FMILException {
136 synchronized(syncObject) {
138 int vr = variableMap.get(name);
139 if(vr == 0) return false;
140 if(!subscriptionSet.add(name)) return false;
141 subscribedNames.add(name);
142 subscription.add(vr);
143 subscribe(new int[] { vr });
149 // Create a directory for this control
150 File tempDir = new File(TEMP_FMU_COMMON_DIRECTORY, UUID.randomUUID().toString());
152 TEMP_FMU_DIRECTORY = tempDir.getAbsolutePath();
154 // Create two directories inside the temp directory for this control
155 dirName = UUID.randomUUID().toString();
156 File fmuDir = new File(TEMP_FMU_DIRECTORY, dirName);
159 TEMP_FOLDER_1 = fmuDir.toString();
160 TEMP_FOLDER_2 = fmuDir.toString() + "_2";
162 // Lock fmu directory in temp directory
166 public int getModelIDNew() {
170 public String getModelID() {
174 public String getFmuDir() {
179 * Load fmu from a given file path. Releases the (possible) previously
182 * @param path absolute file path for fmu file
183 * @throws FMILException
185 private int fmuN = 0;
186 private boolean fmuLoaded = false;
187 public void loadFMUFile(String path) throws FMILException {
189 if (!Files.exists(Paths.get(path)))
190 throw new FMILException("File " + path + " does not exist");
191 if (!Files.isRegularFile(Paths.get(path)))
192 throw new FMILException("Path " + path + " is not a file");
194 synchronized(syncObject) {
197 fmuDir = TEMP_FOLDER_1;
200 fmuDir = TEMP_FOLDER_2;
204 java.nio.file.Path tempDir = Paths.get(fmuDir);
205 if(Files.exists(tempDir) && Files.isDirectory(tempDir)) {
207 FileUtils.emptyDirectory(tempDir);
208 } catch (IOException e) {
209 throw new FMILException("Could not delete existing files from temp folder for fmu " + path, e);
213 Files.createDirectory(tempDir);
214 } catch (IOException e) {
215 throw new FMILException("Could not create temp folder for fmu " + path, e);
220 String tmpPath = tempDir.toString();
221 if(!tmpPath.endsWith("\\") && !tmpPath.endsWith("/"))
222 tmpPath = tmpPath + "/";
223 id = loadFMUFile_(path, tmpPath);
226 getAllVariableReferences();
228 for(int i=0;i<variableNames.length;i++) {
229 variableMap.put(variableNames[i], variableReferences[i]);
233 } catch (UnsatisfiedLinkError err) {
234 throw new FMILException(UNSATISFIED_LINK, err);
235 } catch (Exception e) {
236 LOGGER.error(e.getMessage());
237 throw new FMILException(e.getMessage());
242 private native int loadFMUFile_(String path, String toDir) throws FMILException;
245 * Set a step length for simulation
247 * @param step Step length for simulation
248 * @throws FMILException
250 public void setStepLength(double step) throws FMILException {
251 synchronized(syncObject) {
254 int ret = setStepLength_(getModelIDNew(), step);
256 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
258 } catch (UnsatisfiedLinkError err) {
259 throw new FMILException(UNSATISFIED_LINK);
260 } catch (Exception e) {
261 throw new FMILException(e.getMessage());
266 private native int setStepLength_(int id, double step);
269 * Instantiates a simulation.
271 * Make sure that an FMU is loaded first.
272 * @throws FMILException
274 public void instantiateSimulation() throws FMILException {
275 synchronized(syncObject) {
279 int ret = instantiateSimulation_(getModelIDNew());
281 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
283 } catch (FMILException e) {
285 } catch (UnsatisfiedLinkError err) {
286 throw new FMILException(UNSATISFIED_LINK);
287 } catch (Exception e) {
288 throw new FMILException(e.getMessage());
293 private native int instantiateSimulation_(int id) throws FMILException;
297 * Initializes a simulation.
299 * Make sure that simulation is instantiated first!
300 * @throws FMILException
302 public void initializeSimulation() throws FMILException {
303 synchronized(syncObject) {
307 int ret = initializeSimulation_(getModelIDNew());
309 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
311 } catch (FMILException e) {
313 } catch (UnsatisfiedLinkError err) {
314 throw new FMILException(UNSATISFIED_LINK);
315 } catch (Exception e) {
316 throw new FMILException(e.getMessage());
321 private native int initializeSimulation_(int id) throws FMILException;
324 * Subscribe a set of variables from a loaded simulation.
326 * Make sure that an FMU is loaded first.
327 * @param variables Array of variables
328 * @throws FMILException
330 public void subscribe(int[] variables) throws FMILException {
331 synchronized(syncObject) {
335 int ret = subscribe_(getModelIDNew(), variables);
337 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
339 } catch (UnsatisfiedLinkError err) {
340 throw new FMILException(UNSATISFIED_LINK);
341 } catch (Exception e) {
342 throw new FMILException(e.getMessage());
347 private native int subscribe_(int id, int[] variables);
350 * Set value of a real variable. If the variable is a
351 * parameter, the change is effective immediately.
353 * @param name Variable name
354 * @param value New value
355 * @throws FMILException
357 public void setRealValue(String name, double value) throws FMILException {
358 setRealValue(variableMap.get(name), value);
362 * Set value of a real variable. If the variable is a
363 * parameter, the change is effective immediately.
365 * @param name Variable id
366 * @param value New value
367 * @throws FMILException
369 public void setRealValue(int variableReference, double value) throws FMILException {
370 synchronized(syncObject) {
372 int ret = setRealValue_(getModelIDNew(), variableReference, value);
374 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
375 } catch (FMILException e) {
377 } catch (UnsatisfiedLinkError err) {
378 throw new FMILException(UNSATISFIED_LINK);
379 } catch (Exception e) {
380 throw new FMILException(e.getMessage());
385 private native int setRealValue_(int id, int variableReference, double value) throws FMILException;
389 * Set value of an integer variable. If the variable is a
390 * parameter, the change is effective immediately.
392 * @param name Variable name
393 * @param value New value
394 * @throws FMILException
396 public void setIntegerValue(String name, int value) throws FMILException {
397 setIntegerValue(variableMap.get(name), value);
401 * Set value of an integer variable. If the variable is a
402 * parameter, the change is effective immediately.
404 * @param name Variable id
405 * @param value New value
406 * @throws FMILException
408 public void setIntegerValue(int variableReference, int value) throws FMILException {
409 synchronized(syncObject) {
411 int ret = setIntegerValue_(getModelIDNew(), variableReference, value);
413 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
414 } catch (FMILException e) {
416 } catch (UnsatisfiedLinkError err) {
417 throw new FMILException(UNSATISFIED_LINK);
418 } catch (Exception e) {
419 throw new FMILException(e.getMessage());
424 private native int setIntegerValue_(int id, int variableReference, int value) throws FMILException;
428 * Set value of a boolean variable. If the variable is a
429 * parameter, the change is effective immediately.
431 * @param name Variable name
432 * @param value New value
433 * @throws FMILException
435 public void setBooleanValue(String name, boolean value) throws FMILException {
436 setBooleanValue(variableMap.get(name), value);
440 * Set value of a boolean variable. If the variable is a
441 * parameter, the change is effective immediately.
443 * @param name Variable id
444 * @param value New value
445 * @throws FMILException
447 public void setBooleanValue(int variableReference, boolean value) throws FMILException {
448 synchronized(syncObject) {
450 int ret = setBooleanValue_(getModelIDNew(), variableReference, value);
452 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
453 } catch (FMILException e) {
455 } catch (UnsatisfiedLinkError err) {
456 throw new FMILException(UNSATISFIED_LINK);
457 } catch (Exception e) {
458 throw new FMILException(e.getMessage());
463 private native int setBooleanValue_(int id, int variableReference, boolean value) throws FMILException;
467 * Set value of a string variable. If the variable is a
468 * parameter, the change is effective immediately.
470 * @param name Variable name
471 * @param value New value
472 * @throws FMILException
474 public void setStringValue(String name, String value) throws FMILException {
475 setStringValue(variableMap.get(name), value);
479 * Set value of a string variable. If the variable is a
480 * parameter, the change is effective immediately.
482 * @param name Variable id
483 * @param value New value
484 * @throws FMILException
486 public void setStringValue(int variableReference, String value) throws FMILException {
487 synchronized(syncObject) {
489 int ret = setStringValue_(getModelIDNew(), variableReference, value);
491 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
492 } catch (FMILException e) {
494 } catch (UnsatisfiedLinkError err) {
495 throw new FMILException(UNSATISFIED_LINK);
496 } catch (Exception e) {
497 throw new FMILException(e.getMessage());
502 private native int setStringValue_(int id, int variableReference, String value) throws FMILException;
506 * Simulate one step forward. The step length can be set with
509 * @throws FMILException
511 public void simulateStep() throws FMILException {
512 synchronized(syncObject) {
516 int ret = simulateStep_(getModelIDNew());
518 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
520 } catch (FMILException e) {
522 } catch (UnsatisfiedLinkError err) {
523 throw new FMILException(UNSATISFIED_LINK);
524 } catch (Exception e) {
525 throw new FMILException(e.getMessage());
529 private native int simulateStep_(int id) throws FMILException;
532 * Get an array containing the current values for subscribed variables. The
533 * values are in the same order as in the subscription.
535 * @param results An array the size of subscribed results
538 public double[] getSubscribedResults() throws FMILException {
539 synchronized(syncObject) {
543 double[] results = new double[subscription.size()];
544 Arrays.fill(results, Double.NaN);
546 return getSubscribedResults_(getModelIDNew(), results);
547 } catch (UnsatisfiedLinkError err) {
548 throw new FMILException(UNSATISFIED_LINK);
549 } catch (Exception e) {
550 throw new FMILException(e.getMessage());
555 private native double[] getSubscribedResults_(int id, double[] results);
559 * Unload FMU and the dll:s that it requires.
561 * To be called after all FMU simulations are ended.
562 * If the fmu is loaded again / changed, call to loadFMUFile is sufficient. loadFMUFile
563 * releases the previous fmu.dll
565 * @throws FMILException
567 public void unloadFMU() throws FMILException {
568 synchronized(syncObject) {
572 unlockFMUDirectory();
574 int ret = unloadFMU_(getModelIDNew());
576 LOGGER.warn("Function return value != OK, an exception should have been thrown from native code!");
579 removeFMUDirectoryContents();
581 } catch (FMILException e) {
583 } catch (UnsatisfiedLinkError err) {
584 throw new FMILException(UNSATISFIED_LINK);
585 } catch (Exception e) {
586 throw new FMILException(e.getMessage());
590 private native int unloadFMU_(int id) throws FMILException;
593 // * Checks if fmu has been initialized
594 // * @return current simulation time
596 // public boolean isInitialized() throws FMILException {
597 // synchronized(syncObject) {
599 // return isInitialized_(getModelID());
600 // } catch (UnsatisfiedLinkError err) {
601 // throw new FMILException(UNSATISFIED_LINK);
602 // } catch (Exception e) {
603 // throw new FMILException(e.getMessage());
608 // private native boolean isInitialized_(String id);
611 * Get the current simulation time
612 * @return current simulation time
614 public double getTime() throws FMILException {
615 synchronized(syncObject) {
619 return getTime_(getModelIDNew());
621 } catch (UnsatisfiedLinkError err) {
622 throw new FMILException(UNSATISFIED_LINK);
623 } catch (Exception e) {
624 throw new FMILException(e.getMessage());
629 private native double getTime_(int id);
632 * Get all variables in a loaded model
633 * @return all variables in a loaded model
635 public String[] getAllVariables() throws FMILException {
636 synchronized(syncObject) {
640 if(variableNames == null) {
641 variableNames = getAllVariables_(getModelIDNew());
643 return variableNames;
645 } catch (UnsatisfiedLinkError err) {
646 throw new FMILException(UNSATISFIED_LINK);
647 } catch (Exception e) {
648 throw new FMILException(e.getMessage());
653 private native String[] getAllVariables_(int id);
655 public String[] getAllVariableDescriptions() throws FMILException {
656 synchronized(syncObject) {
660 if(variableDescriptions == null) {
661 variableDescriptions = getAllVariableDescriptions_(getModelIDNew());
663 return variableDescriptions;
665 } catch (UnsatisfiedLinkError err) {
666 throw new FMILException(UNSATISFIED_LINK);
667 } catch (Exception e) {
668 throw new FMILException(e.getMessage());
673 private native String[] getAllVariableDescriptions_(int id);
675 public String[] getAllVariableDeclaredTypes() throws FMILException {
676 synchronized(syncObject) {
680 if(variableDeclaredTypes == null) {
681 variableDeclaredTypes = getAllVariableDeclaredTypes_(getModelIDNew());
683 return variableDeclaredTypes;
685 } catch (UnsatisfiedLinkError err) {
686 throw new FMILException(UNSATISFIED_LINK);
687 } catch (Exception e) {
688 throw new FMILException(e.getMessage());
693 private native String[] getAllVariableDeclaredTypes_(int id);
695 public int[] getAllVariableReferences() throws FMILException {
696 synchronized(syncObject) {
700 if(variableReferences == null) {
701 variableReferences = getAllVariableReferences_(getModelIDNew(), new int[variableNames.length]);
703 return variableReferences;
705 } catch (UnsatisfiedLinkError err) {
706 throw new FMILException(UNSATISFIED_LINK);
707 } catch (Exception e) {
708 throw new FMILException(e.getMessage());
713 private native int[] getAllVariableReferences_(int id, int[] array);
715 public int[] getAllVariableTypes() throws FMILException {
716 synchronized(syncObject) {
720 if(variableTypes == null) {
721 variableTypes = getAllVariableTypes_(getModelIDNew(), new int[variableNames.length]);
723 return variableTypes;
725 } catch (UnsatisfiedLinkError err) {
726 throw new FMILException(UNSATISFIED_LINK);
727 } catch (Exception e) {
728 throw new FMILException(e.getMessage());
733 private native int[] getAllVariableTypes_(int id, int[] array);
735 public int[] getAllVariableCausalities() throws FMILException {
736 synchronized(syncObject) {
740 if(variableCausalities == null) {
741 variableCausalities = getAllVariableCausalities_(getModelIDNew(), new int[variableNames.length]);
743 return variableCausalities;
745 } catch (UnsatisfiedLinkError err) {
746 throw new FMILException(UNSATISFIED_LINK);
747 } catch (Exception e) {
748 throw new FMILException(e.getMessage());
753 private native int[] getAllVariableCausalities_(int id, int[] array);
755 public int[] getAllVariableVariabilities() throws FMILException {
756 synchronized(syncObject) {
760 if(variableVariabilities == null) {
761 variableVariabilities = getAllVariableVariabilities_(getModelIDNew(), new int[variableNames.length]);
763 return variableVariabilities;
765 } catch (UnsatisfiedLinkError err) {
766 throw new FMILException(UNSATISFIED_LINK);
767 } catch (Exception e) {
768 throw new FMILException(e.getMessage());
773 private native int[] getAllVariableVariabilities_(int id, int[] array);
776 * Get all variables in a loaded model
777 * @return all variables in a loaded model
779 public String[] getAllDeclaredTypes() throws FMILException {
780 synchronized(syncObject) {
784 if(declaredTypes == null) {
785 declaredTypes = getAllDeclaredTypes_(getModelIDNew());
787 return declaredTypes;
789 } catch (UnsatisfiedLinkError err) {
790 throw new FMILException(UNSATISFIED_LINK);
791 } catch (Exception e) {
792 throw new FMILException(e.getMessage());
797 private native String[] getAllDeclaredTypes_(int id);
799 public String[] getAllDeclaredTypeDescriptions() throws FMILException {
800 synchronized(syncObject) {
804 if(declaredTypeDescriptions == null) {
805 declaredTypeDescriptions = getAllDeclaredTypeDescriptions_(getModelIDNew());
807 return declaredTypeDescriptions;
809 } catch (UnsatisfiedLinkError err) {
810 throw new FMILException(UNSATISFIED_LINK);
811 } catch (Exception e) {
812 throw new FMILException(e.getMessage());
817 private native String[] getAllDeclaredTypeDescriptions_(int id);
819 public String[] getAllDeclaredTypeQuantities() throws FMILException {
820 synchronized(syncObject) {
824 if(declaredTypeQuantities == null) {
825 declaredTypeQuantities = getAllDeclaredTypeQuantities_(getModelIDNew());
827 return declaredTypeQuantities;
829 } catch (UnsatisfiedLinkError err) {
830 throw new FMILException(UNSATISFIED_LINK);
831 } catch (Exception e) {
832 throw new FMILException(e.getMessage());
837 private native String[] getAllDeclaredTypeQuantities_(int id);
839 public String[] getAllDeclaredTypeUnits() throws FMILException {
840 synchronized(syncObject) {
844 if(declaredTypeUnits == null) {
845 declaredTypeUnits = getAllDeclaredTypeUnits_(getModelIDNew());
847 return declaredTypeUnits;
849 } catch (UnsatisfiedLinkError err) {
850 throw new FMILException(UNSATISFIED_LINK);
851 } catch (Exception e) {
852 throw new FMILException(e.getMessage());
857 private native String[] getAllDeclaredTypeUnits_(int id);
862 // * Get all variables from model that match the filter (and time variable)
864 // * @param regexp Regular expression filter
865 // * @return An array of variable names that match regexp filter (and time-variable)
866 // * @throws FMILException
868 // public String[] filterVariables(String regexp) throws FMILException {
869 // synchronized(syncObject) {
872 // return filterVariables_(getModelID(), regexp + "|time");
874 // } catch (UnsatisfiedLinkError err) {
875 // throw new FMILException(UNSATISFIED_LINK);
876 // } catch (Exception e) {
877 // throw new FMILException(e.getMessage());
882 // private native String[] filterVariables_(String id, String regexp);
885 // * Get the last error message
886 // * @return Last error message
888 // public String getLastErrorMessage() throws FMILException {
889 // synchronized(syncObject) {
894 // //return getLastErrorMessage_(getModelID());
896 // } catch (UnsatisfiedLinkError err) {
897 // throw new FMILException(UNSATISFIED_LINK);
898 // } catch (Exception e) {
899 // throw new FMILException(e.getMessage());
904 // private native String getLastErrorMessage_(String id);
907 * Get a value (double) for real variable
908 * @param name Name of the variable
910 * @throws FMILException
912 public double getRealValue(String name) throws FMILException {
913 double result = getRealValue(variableMap.get(name));
914 if (DEBUG) System.err.println("getRealValue " + name + " = " + result);
919 * Get a value (double) for real variable
920 * @param variableReference Numeric id of the variable
922 * @throws FMILException
924 public double getRealValue(int variableReference) throws FMILException {
925 synchronized(syncObject) {
927 return getRealValue_(getModelIDNew(), variableReference);
928 } catch (UnsatisfiedLinkError err) {
929 throw new FMILException(UNSATISFIED_LINK);
930 } catch (Exception e) {
931 throw new FMILException(e.getMessage());
936 private native double getRealValue_(int id, int variableReference) throws FMILException;
940 * Get value of integer variable
941 * @param name Name of the variable
943 * @throws FMILException
945 public int getIntegerValue(String name) throws FMILException {
946 int result = getIntegerValue(variableMap.get(name));
947 if (DEBUG) System.err.println("getIntegerValue " + name + " = " + result);
952 * Get a real (double) value for variable
953 * @param variableReference Numeric id of the variable
955 * @throws FMILException
957 public int getIntegerValue(int variableReference) throws FMILException {
958 synchronized(syncObject) {
960 return getIntegerValue_(getModelIDNew(), variableReference);
961 } catch (UnsatisfiedLinkError err) {
962 throw new FMILException(UNSATISFIED_LINK);
963 } catch (Exception e) {
964 throw new FMILException(e.getMessage());
969 private native int getIntegerValue_(int id, int variableReference) throws FMILException;
973 * Get value of boolean variable
974 * @param name Name of the variable
976 * @throws FMILException
978 public boolean getBooleanValue(String name) throws FMILException {
979 boolean result = getBooleanValue(variableMap.get(name));
980 if (DEBUG) System.err.println("getBooleanValue " + name + " = " + result);
985 * Get value of boolean variable
986 * @param variableReference Numeric id of the variable
988 * @throws FMILException
990 public boolean getBooleanValue(int variableReference) throws FMILException {
991 synchronized(syncObject) {
993 return getBooleanValue_(getModelIDNew(), variableReference);
994 } catch (UnsatisfiedLinkError err) {
995 throw new FMILException(UNSATISFIED_LINK);
996 } catch (Exception e) {
997 throw new FMILException(e.getMessage());
1002 private native boolean getBooleanValue_(int id, int variableReference) throws FMILException;
1006 * Get value of string variable
1007 * @param name Name of the variable
1009 * @throws FMILException
1011 public String getStringValue(String name) throws FMILException {
1012 String result = getStringValue(variableMap.get(name));
1013 if (DEBUG) System.err.println("getIntegerValue " + name + " = " + result);
1018 * Get value of string variable
1019 * @param variableReference Numeric id of the variable
1021 * @throws FMILException
1023 public String getStringValue(int variableReference) throws FMILException {
1024 synchronized(syncObject) {
1026 return getStringValue_(getModelIDNew(), variableReference);
1027 } catch (UnsatisfiedLinkError err) {
1028 throw new FMILException(UNSATISFIED_LINK);
1029 } catch (Exception e) {
1030 throw new FMILException(e.getMessage());
1035 private native String getStringValue_(int id, int variableReference) throws FMILException;
1038 private FileChannel channel;
1039 private FileLock lock;
1041 @SuppressWarnings("resource")
1042 private boolean lockFMUDirectory() {
1045 // Get a file channel for the lock file
1046 File lockFile = new File(TEMP_FMU_DIRECTORY, LOCK_FILE_NAME);
1047 if(!lockFile.isFile())
1048 lockFile.createNewFile();
1050 channel = new RandomAccessFile(lockFile, "rw").getChannel();
1052 // Use the file channel to create a lock on the file.
1053 // This method blocks until it can retrieve the lock.
1054 lock = channel.lock();
1056 // // Try acquiring the lock without blocking. This method returns
1057 // // null or throws an exception if the file is already locked.
1059 // lock = channel.tryLock();
1060 // } catch (OverlappingFileLockException e) {
1061 // // File is already locked in this thread or virtual machine
1063 } catch (IOException e) {
1070 private boolean unlockFMUDirectory() {
1079 } catch (IOException e) {
1085 private boolean removeFMUDirectoryContents() {
1088 File tempDir = new File(TEMP_FMU_DIRECTORY);
1089 FileUtils.deleteAll(tempDir);
1091 } catch (IOException e) {
1098 protected void finalize() throws Throwable {
1101 } catch (Throwable t) {
1102 LOGGER.error("Could not unload native FMU!", t);