]> gerrit.simantics Code Review - simantics/fmil.git/blobdiff - org.simantics.fmil.core/native/FMUSimulator/src/fmu_control.cpp
Added getters and setters for all FMI data types.
[simantics/fmil.git] / org.simantics.fmil.core / native / FMUSimulator / src / fmu_control.cpp
index 310e9066fa7bdb0137ed280ff2c2b5f47a56a6e3..dba9da20edab7b03defb68584249a0e823fbdca3 100644 (file)
@@ -19,6 +19,7 @@
 #include <vector>
 #include <iostream>
 #include <regex>
+#include <atomic>
 
 #include <org_simantics_fmil_FMILJNI.h>
 
@@ -31,11 +32,14 @@ extern "C" {
 
 #define PRINT(fmt,args) { FILE *fp = fopen("R:\\Simantics\\Sysdyn\\log.txt", "ab"); fprintf(fp, fmt, args); fclose(fp); }
 
-#include <direct.h>
-#define GetCurrentDir _getcwd
-
 using namespace std;
 
+static std::atomic<int> instanceNameID;
+
+int create_id() {
+    return instanceNameID++;
+}
+
 struct FMI1 {
 
        void *fmu;
@@ -142,7 +146,6 @@ bool exists(string id) {
 JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_loadFMUFile_1 
        (JNIEnv *env, jobject obj, jstring path, jstring tempDir) {
 
-       HMODULE module = NULL;
        FMI1 fmi1;
        FMIL_Variable *vars;
        FMIL_DeclaredType *types;
@@ -230,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;
 
 }
 
@@ -293,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_INTEGER(fmi.fmu, vr, value != 0, &error);
+       }
+       else if (fmi.version == 2) {
+               FMI2_CS_SET_INTEGER(fmi.fmu, vr, value != 0, &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
@@ -455,7 +424,6 @@ JNIEXPORT jdoubleArray JNICALL Java_org_simantics_fmil_core_FMIL_getSubscribedRe
        jsize n = env -> GetArrayLength(result);
        int *vrs;
        const char *error = "";
-       int returnValue = 0;
 
        FMI1 fmi = fmus[id];
        if(n > 0) {
@@ -477,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];
+         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: ";
@@ -521,11 +491,11 @@ 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(""));  
    
-       for(int i=0;i<fmus[id].variables.size();i++) {  
+       for(unsigned int i=0;i<fmus[id].variables.size();i++) {  
                env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].variables[i].c_str()));  
        }  
 
@@ -536,11 +506,11 @@ 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(""));  
    
-       for(int i=0;i<fmus[id].descriptions.size();i++) {  
+       for(unsigned int i=0;i<fmus[id].descriptions.size();i++) {  
                env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].descriptions[i].c_str()));  
        }  
 
@@ -551,11 +521,11 @@ 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(""));
    
-       for(int i=0;i<fmus[id].declaredTypes.size();i++) {  
+       for(unsigned int i=0;i<fmus[id].declaredTypes.size();i++) {  
                env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].declaredTypes[i].c_str()));  
        }  
 
@@ -610,8 +580,7 @@ JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariableVari
        jint* resultElements = env -> GetIntArrayElements(result, &isCopy);
        jsize n = env -> GetArrayLength(result);
 
-       int i;
-       for (i = 0; i < n; i++) {
+       for (jsize i = 0; i < n; i++) {
                resultElements[i] = fmus[id].variabilities[i];
        } 
          
@@ -630,8 +599,7 @@ JNIEXPORT jintArray JNICALL Java_org_simantics_fmil_core_FMIL_getAllVariableCaus
        jint* resultElements = env -> GetIntArrayElements(result, &isCopy);
        jsize n = env -> GetArrayLength(result);
 
-       int i;
-       for (i = 0; i < n; i++) {
+       for (jsize i = 0; i < n; i++) {
                resultElements[i] = fmus[id].causalities[i];
        } 
          
@@ -646,11 +614,11 @@ 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(""));
    
-       for(int i=0;i<fmus[id].declaredTypeNames.size();i++) {  
+       for(unsigned int i=0;i<fmus[id].declaredTypeNames.size();i++) {  
                env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].declaredTypeNames[i].c_str()));  
        }  
 
@@ -661,11 +629,11 @@ 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(""));
    
-       for(int i=0;i<fmus[id].typeDescriptions.size();i++) {  
+       for(unsigned int i=0;i<fmus[id].typeDescriptions.size();i++) {  
                env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].typeDescriptions[i].c_str()));  
        }  
 
@@ -676,11 +644,11 @@ 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(""));
    
-       for(int i=0;i<fmus[id].quantities.size();i++) {  
+       for(unsigned int i=0;i<fmus[id].quantities.size();i++) {  
                env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].quantities[i].c_str()));  
        }  
 
@@ -691,11 +659,11 @@ 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(""));
    
-       for(int i=0;i<fmus[id].units.size();i++) {  
+       for(unsigned int i=0;i<fmus[id].units.size();i++) {  
                env->SetObjectArrayElement(ret,i,env->NewStringUTF(fmus[id].units[i].c_str()));  
        }  
 
@@ -719,7 +687,7 @@ JNIEXPORT jint JNICALL Java_org_simantics_fmil_core_FMIL_simulateStep_1
          int returnValue;
          const char *error = "";
 
-         FMI1 fmi = fmus[id];
+         FMI1 &fmi = fmus[id];
          if (fmi.version == 1) {
                  returnValue = FMI1_CS_STEP(fmi.fmu, fmi.currentTime, fmi.timeStep, &error);
          } else if (fmi.version == 2) {
@@ -880,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;
 
-}
\ No newline at end of file
+       return env->NewStringUTF(value);
+}