#include <vector>
#include <iostream>
#include <regex>
+#include <atomic>
#include <org_simantics_fmil_FMILJNI.h>
#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;
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;
env->ReleaseStringUTFChars(path, fmuPath);
env->ReleaseStringUTFChars(tempDir, fmuTempDir);
- return fmus.size() - 1;
+ return (jint)fmus.size() - 1;
}
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
jsize n = env -> GetArrayLength(result);
int *vrs;
const char *error = "";
- int returnValue = 0;
FMI1 fmi = fmus[id];
if(n > 0) {
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: ";
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()));
}
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()));
}
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()));
}
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];
}
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];
}
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()));
}
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()));
}
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()));
}
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()));
}
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) {
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);
}
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);
+}