]> gerrit.simantics Code Review - simantics/fmil.git/blobdiff - org.simantics.fmil.core/native/FMUSimulator/src/fmu_control.cpp
Switch to full JavaSE-11+ compatibility
[simantics/fmil.git] / org.simantics.fmil.core / native / FMUSimulator / src / fmu_control.cpp
index 285be84e42627582224722227a789c39fd9436a5..28e75f74c2b3a4c7dde14119cea95a1be1885902 100644 (file)
@@ -19,6 +19,7 @@
 #include <vector>
 #include <iostream>
 #include <regex>
+#include <atomic>
 
 #include <org_simantics_fmil_FMILJNI.h>
 
@@ -33,6 +34,12 @@ extern "C" {
 
 using namespace std;
 
+static std::atomic<int> instanceNameID;
+
+int create_id() {
+    return instanceNameID++;
+}
+
 struct FMI1 {
 
        void *fmu;
@@ -226,7 +233,7 @@ JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_loadFMUFile_1
        env->ReleaseStringUTFChars(path, fmuPath);
        env->ReleaseStringUTFChars(tempDir, fmuTempDir);
 
-       return fmus.size() - 1;
+       return (jint)fmus.size() - 1;
 
 }
 
@@ -289,109 +296,75 @@ string getTypeString(ScalarVariable* sv) {
 JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_setRealValue_1
   (JNIEnv *env, jobject obj, jint id, jint vr, jdouble value) {
 
-         const char *error = "";
-         FMI1 fmi = fmus[id];
-         if (fmi.version == 1) {
+       const char *error = "";
+       FMI1 &fmi = fmus[id];
+       if (fmi.version == 1) {
                FMI1_CS_SET_REAL(fmi.fmu, vr, value, &error);
-         } else if (fmi.version == 2) {
-                 FMI2_CS_SET_REAL(fmi.fmu, vr, value, &error);
-         }
-         if (!isEmpty(error)) {
-                 string message = "Could not set real value ";
-                 return throwFMILException(env, message += error);
-      }
-         return 0;
+       }
+       else if (fmi.version == 2) {
+               FMI2_CS_SET_REAL(fmi.fmu, vr, value, &error);
+       }
+       if (!isEmpty(error)) {
+               string message = "Could not set real value: ";
+               return throwFMILException(env, message += error);
+    }
+       return 0;
 }
 
 JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_setIntegerValue_1
-  (JNIEnv *env, jobject obj, jstring id, jstring parameter, jint value) {
-         /*
-       const char *fmuId = env->GetStringUTFChars(id, 0);
-       if(exists(fmuId)) {
-               FMUControlStruct& fmuStruct = fmus[fmuId];
-               const char *name = env->GetStringUTFChars(parameter, 0);
-               string nameString = name;
-               string modelId = fmuId;
-               if(!referenceExists(fmuStruct, name)) {
-                       string errorMessage = "setIntegerValue: Model (id " + modelId + ") does not contain variable: " + nameString;
-                       env->ReleaseStringUTFChars(parameter, name);
-                       env->ReleaseStringUTFChars(id, fmuId);
-                       return throwException(env, errorMessage);
-               } else {
-                       // Check variable type
-                       ScalarVariable* sv = fmuStruct.vars[fmuStruct.indexes[name]];
-                       switch (sv->typeSpec->type){
-                               case elm_Integer:
-                                       break; // ok
-                               default: {
-                                       string errorMessage = "setIntegerValue: " + nameString + " is not of type Integer. (type: + " + getTypeString(sv) + ")";
-                                       env->ReleaseStringUTFChars(parameter, name);
-                                       env->ReleaseStringUTFChars(id, fmuId);
-                                       return throwException(env, errorMessage);
-                               }
-                       }
-
-                       // Change value
-                       fmiValueReference vr = getReference(fmuStruct, name);
-                       const int intValue = (int) value;
-                       fmuStruct.fmu.setInteger(fmuStruct.c, &vr, 1, &intValue);
-                       env->ReleaseStringUTFChars(parameter, name);
-                       env->ReleaseStringUTFChars(id, fmuId);
-                       return 1;
-               }
-       }  else {
-               string message = fmuId;
-               env->ReleaseStringUTFChars(id, fmuId);
-               return throwException(env, "setIntegerValue: Model id " + message + " not found");
+  (JNIEnv *env, jobject obj, jint id, jint vr, jint value) {
+       
+       const char *error = "";
+       FMI1 fmi = fmus[id];
+       if (fmi.version == 1) {
+               FMI1_CS_SET_INTEGER(fmi.fmu, vr, value, &error);
        }
-       */
-         return 1;
+       else if (fmi.version == 2) {
+               FMI2_CS_SET_INTEGER(fmi.fmu, vr, value, &error);
+       }
+       if (!isEmpty(error)) {
+               string message = "Could not set integer value: ";
+               return throwFMILException(env, message += error);
+       }
+       return 0;
 }
 
 JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_setBooleanValue_1
-  (JNIEnv *env, jobject obj, jstring id, jstring parameter, jboolean value) {
-         /*
-       const char *fmuId = env->GetStringUTFChars(id, 0);
-       if(exists(fmuId)) {
-               FMUControlStruct& fmuStruct = fmus[fmuId];
-               const char *name = env->GetStringUTFChars(parameter, 0);
-               string nameString = name;
-               string modelId = fmuId;
-               if(!referenceExists(fmuStruct, name)) {
-                       string errorMessage = "setBooleanValue: Model (id " + modelId + ") does not contain variable: " + nameString;
-                       env->ReleaseStringUTFChars(parameter, name);
-                       env->ReleaseStringUTFChars(id, fmuId);
-                       return throwException(env, errorMessage);
-               } else {
-                       // Check variable type
-                       ScalarVariable* sv = fmuStruct.vars[fmuStruct.indexes[name]];
-                       switch (sv->typeSpec->type){
-                               case elm_Boolean:
-                                       break; // ok
-                               default: {
-                                       string errorMessage = "setBooleanValue: " + nameString + " is not of type Boolean. (type: + " + getTypeString(sv) + ")";
-                                       env->ReleaseStringUTFChars(parameter, name);
-                                       env->ReleaseStringUTFChars(id, fmuId);
-                                       return throwException(env, errorMessage);
-                               }
-                       }
+  (JNIEnv *env, jobject obj, jint id, jint vr, jboolean value) {
 
-                       // Change value
-                       fmiValueReference vr = getReference(fmuStruct, name);
-                       fmiBoolean result = 1;
-                       if(value == 0)
-                               result = 0;
-                       fmuStruct.fmu.setBoolean(fmuStruct.c, &vr, 1, &result);
-                       env->ReleaseStringUTFChars(parameter, name);
-                       env->ReleaseStringUTFChars(id, fmuId);
-                       return 1;
-               }
-       }  else {
-               string message = fmuId;
-               env->ReleaseStringUTFChars(id, fmuId);
-               return throwException(env, "setBooleanValue: Model id " + message + " not found");
-       }*/
-         return 1;
+       const char *error = "";
+       FMI1 fmi = fmus[id];
+       if (fmi.version == 1) {
+               FMI1_CS_SET_BOOLEAN(fmi.fmu, vr, value != 0, &error);
+       }
+       else if (fmi.version == 2) {
+               FMI2_CS_SET_BOOLEAN(fmi.fmu, vr, value != 0, &error);
+       }
+       if (!isEmpty(error)) {
+               string message = "Could not set boolean value: ";
+               return throwFMILException(env, message += error);
+       }
+       return 0;
+}
+
+JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_setStringValue_1
+(JNIEnv *env, jobject obj, jint id, jint vr, jstring value) {
+
+       const char *error = "";
+       const char *valueChars = env->GetStringUTFChars(value, 0);
+       FMI1 fmi = fmus[id];
+       if (fmi.version == 1) {
+               FMI1_CS_SET_STRING(fmi.fmu, vr, valueChars, &error);
+       }
+       else if (fmi.version == 2) {
+               FMI2_CS_SET_STRING(fmi.fmu, vr, valueChars, &error);
+       }
+       env->ReleaseStringUTFChars(value, valueChars);
+       if (!isEmpty(error)) {
+               string message = "Could not set string value: ";
+               return throwFMILException(env, message += error);
+       }
+       return 0;
 }
 
 JNIEXPORT jboolean JNICALL Java_org_simantics_fmil_core_FMIL_isInitialized_1
@@ -472,14 +445,16 @@ JNIEXPORT jdoubleArray JNICALL Java_org_simantics_fmil_core_FMIL_getSubscribedRe
 JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_instantiateSimulation_1
   (JNIEnv *env, jobject obj, jint id) {
 
+         int uniqueId = create_id();
+         std::string instanceName = std::to_string(uniqueId);
          int returnValue;
          const char *error = "";
 
          FMI1 &fmi = fmus[id];
          if (fmi.version == 1) {
-               returnValue = FMI1_CS_INSTANTIATE(fmi.fmu, "", &error);
+                 returnValue = FMI1_CS_INSTANTIATE(fmi.fmu, instanceName.c_str(), &error);
          } else if (fmi.version == 2) {
-                 returnValue = FMI2_CS_INSTANTIATE(fmi.fmu, "", &error);
+                 returnValue = FMI2_CS_INSTANTIATE(fmi.fmu, instanceName.c_str(), &error);
          }
          if(returnValue != 0) {
                string message = "No FMU loaded: ";
@@ -516,7 +491,7 @@ JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_setTime_1
 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariables_1
   (JNIEnv *env, jobject obj, jint id) {
 
-       jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].variables.size(),  
+       jobjectArray ret= (jobjectArray)env->NewObjectArray((jsize)fmus[id].variables.size(),  
                        env->FindClass("java/lang/String"),  
                        env->NewStringUTF(""));  
    
@@ -531,7 +506,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariables
 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariableDescriptions_1
   (JNIEnv *env, jobject obj, jint id) {
 
-       jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].descriptions.size(),  
+       jobjectArray ret= (jobjectArray)env->NewObjectArray((jsize)fmus[id].descriptions.size(),
                        env->FindClass("java/lang/String"),  
                        env->NewStringUTF(""));  
    
@@ -546,7 +521,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariableD
 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariableDeclaredTypes_1
   (JNIEnv *env, jobject obj, jint id) {
 
-       jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].declaredTypes.size(),  
+       jobjectArray ret= (jobjectArray)env->NewObjectArray((jsize)fmus[id].declaredTypes.size(),
                        env->FindClass("java/lang/String"),  
                        env->NewStringUTF(""));
    
@@ -639,7 +614,7 @@ JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariableCaus
 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllDeclaredTypes_1
   (JNIEnv *env, jobject obj, jint id) {
 
-       jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].declaredTypeNames.size(),  
+       jobjectArray ret= (jobjectArray)env->NewObjectArray((jsize)fmus[id].declaredTypeNames.size(),
                        env->FindClass("java/lang/String"),  
                        env->NewStringUTF(""));
    
@@ -654,7 +629,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllDeclaredT
 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllDeclaredTypeDescriptions_1
   (JNIEnv *env, jobject obj, jint id) {
 
-       jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].typeDescriptions.size(),  
+       jobjectArray ret= (jobjectArray)env->NewObjectArray((jsize)fmus[id].typeDescriptions.size(),
                        env->FindClass("java/lang/String"),  
                        env->NewStringUTF(""));
    
@@ -669,7 +644,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllDeclaredT
 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllDeclaredTypeQuantities_1
   (JNIEnv *env, jobject obj, jint id) {
 
-       jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].quantities.size(),  
+       jobjectArray ret= (jobjectArray)env->NewObjectArray((jsize)fmus[id].quantities.size(),
                        env->FindClass("java/lang/String"),  
                        env->NewStringUTF(""));
    
@@ -684,7 +659,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllDeclaredT
 JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllDeclaredTypeUnits_1
   (JNIEnv *env, jobject obj, jint id) {
 
-       jobjectArray ret= (jobjectArray)env->NewObjectArray(fmus[id].units.size(),  
+       jobjectArray ret= (jobjectArray)env->NewObjectArray((jsize)fmus[id].units.size(),
                        env->FindClass("java/lang/String"),  
                        env->NewStringUTF(""));
    
@@ -718,14 +693,14 @@ JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_simulateStep_1
          } else if (fmi.version == 2) {
                  returnValue = FMI2_CS_STEP(fmi.fmu, fmi.currentTime, fmi.timeStep, &error);
          }
-         if(returnValue != 0) {
+         if(returnValue == 1) {
                  string message = "Could not simulate step: ";
                  return throwException(env,  message += error);
          }
 
          fmi.currentTime += fmi.timeStep;
 
-         return 0;
+         return returnValue; //Pass return value up. 0 is OK, 1 is error, 2 is pending
 
          /*
        const char *fmuId = env->GetStringUTFChars(id, 0);
@@ -873,105 +848,73 @@ JNIEXPORT jdouble JNICALL Java_org_simantics_fmil_core_FMIL_getRealValue_1
          }
          if (!isEmpty(error)) {
                  string message = "Could not get real value: ";
-                 return throwFMILException(env, message += error);
+                 throwFMILException(env, message += error);
+                 return 0.0;
          }
          return value;
 }
 
 JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_getIntegerValue_1
-  (JNIEnv *env, jobject obj, jstring id, jstring variable) {
-         /*
-       const char *fmuId = env->GetStringUTFChars(id, 0);
-       if(exists(fmuId)) {
-               FMUControlStruct fmuStruct = fmus[fmuId];
-               env->ReleaseStringUTFChars(id, fmuId);
-               const char *name = env->GetStringUTFChars(variable, 0);
-
-               if(referenceExists(fmuStruct, name)) {
-                       fmiValueReference vr = getReference(fmuStruct, name);
-                       int result;
-                       fmuStruct.fmu.getInteger(fmuStruct.c, &vr, 1, &result);
-                       env->ReleaseStringUTFChars(variable, name);
-                       return result;
-
-               } else {
-                        string nameString = name;
-                        string message = "Variable " + nameString + " not found";
-                        env->ReleaseStringUTFChars(variable, name);
-                        return throwException(env, message);
-               }
+  (JNIEnv *env, jobject obj, jint id, jint vr) {
 
-       } else {
-               string message = fmuId;
-               env->ReleaseStringUTFChars(id, fmuId);
-               return throwException(env, "unloadFMU: Model id " + message + " not found");
-       }
-       */
-         return 1;
+       int value;
+       const char *error = "";
 
+       FMI1 fmi = fmus[id];
+       if (fmi.version == 1) {
+               value = FMI1_CS_GET_INTEGER(fmi.fmu, vr, &error);
+       }
+       else if (fmi.version == 2) {
+               value = FMI2_CS_GET_INTEGER(fmi.fmu, vr, &error);
+       }
+       if (!isEmpty(error)) {
+               string message = "Could not get integer value: ";
+               throwFMILException(env, message += error);
+               return 0;
+       }
+       return value;
 }
 
 JNIEXPORT jboolean JNICALL Java_org_simantics_fmil_core_FMIL_getBooleanValue_1
-  (JNIEnv *env, jobject obj, jstring id, jstring variable) {
-         /*
-       const char *fmuId = env->GetStringUTFChars(id, 0);
-       if(exists(fmuId)) {
-               FMUControlStruct fmuStruct = fmus[fmuId];
-               env->ReleaseStringUTFChars(id, fmuId);
-               const char *name = env->GetStringUTFChars(variable, 0);
-
-               if(referenceExists(fmuStruct, name)) {
-                       fmiValueReference vr = getReference(fmuStruct, name);
-                       fmiBoolean result;
-                       fmuStruct.fmu.getBoolean(fmuStruct.c, &vr, 1, &result);
-                       env->ReleaseStringUTFChars(variable, name);
-                       return result;
-
-               } else {
-                        string nameString = name;
-                        string message = "Variable " + nameString + " not found";
-                        env->ReleaseStringUTFChars(variable, name);
-                        return throwException(env, message);
-               }
+  (JNIEnv *env, jobject obj, jint id, jint vr) {
 
-       } else {
-               string message = fmuId;
-               env->ReleaseStringUTFChars(id, fmuId);
-               return throwException(env, "unloadFMU: Model id " + message + " not found");
-       }*/
-         return 1;
+       int value;
+       const char *error = "";
+
+       FMI1 fmi = fmus[id];
+       if (fmi.version == 1) {
+               value = FMI1_CS_GET_BOOLEAN(fmi.fmu, vr, &error);
+       }
+       else if (fmi.version == 2) {
+               value = FMI2_CS_GET_BOOLEAN(fmi.fmu, vr, &error);
+       }
+       if (!isEmpty(error)) {
+               string message = "Could not get boolean value: ";
+               throwFMILException(env, message += error);
+               return 0;
+       }
 
+       return value != 0;
 }
 
 JNIEXPORT jstring JNICALL Java_org_simantics_fmil_core_FMIL_getStringValue_1
-  (JNIEnv *env, jobject obj, jstring id, jstring variable) {
-         /*
-       const char *fmuId = env->GetStringUTFChars(id, 0);
-       if(exists(fmuId)) {
-               FMUControlStruct fmuStruct = fmus[fmuId];
-               env->ReleaseStringUTFChars(id, fmuId);
-               const char *name = env->GetStringUTFChars(variable, 0);
-
-               if(referenceExists(fmuStruct, name)) {
-                       fmiValueReference vr = getReference(fmuStruct, name);
-                       fmiString result;
-                       fmuStruct.fmu.getString(fmuStruct.c, &vr, 1, &result);
-                       env->ReleaseStringUTFChars(variable, name);
-                       return env->NewStringUTF(result);
-
-               } else {
-                        string nameString = name;
-                        string message = "Variable " + nameString + " not found";
-                        env->ReleaseStringUTFChars(variable, name);
-                        return 0; //throwException(env, message);
-               }
+  (JNIEnv *env, jobject obj, jint id, jint vr) {
 
-       } else {
-               string message = fmuId;
-               env->ReleaseStringUTFChars(id, fmuId);
-               return 0; //throwException(env, "unloadFMU: Model id " + message + " not found");
+       const char *value;
+       const char *error = "";
+
+       FMI1 fmi = fmus[id];
+       if (fmi.version == 1) {
+               value = FMI1_CS_GET_STRING(fmi.fmu, vr, &error);
+       }
+       else if (fmi.version == 2) {
+               value = FMI2_CS_GET_STRING(fmi.fmu, vr, &error);
+       }
+       if (!isEmpty(error)) {
+               string message = "Could not get string value: ";
+               throwFMILException(env, message += error);
+               return nullptr;
        }
-       */
-         return 0;
 
+       return env->NewStringUTF(value);
 }