// // Created by david on 03.03.2026. // #include #include "step_detector.h" #include #include extern "C" { jint throwIllegalArgumentException(JNIEnv *env, const char *message) { jclass exClass; const char *className = "java/lang/IllegalArgumentException"; exClass = env->FindClass(className); if (exClass == nullptr) { return -1; } return env->ThrowNew(exClass, message); } JNIEXPORT jlong JNICALL Java_at_lockstep_filter_StepDetector_native_1create( JNIEnv *env, jclass /*unused*/, jlong engineHandle) { auto *listener = reinterpret_cast(engineHandle); // We use std::nothrow so `new` returns a nullptr if the engine creation fails // the hardcoded 'fps' is only an initial value, which is re-computed in StepDetector auto *detector = new(std::nothrow) StepDetector(60.0 /* FPS */, listener); return reinterpret_cast(detector); } JNIEXPORT void JNICALL Java_at_lockstep_filter_StepDetector_native_1delete( JNIEnv *env, jclass /*unused*/, jlong handle) { delete reinterpret_cast(handle); } JNIEXPORT void JNICALL Java_at_lockstep_filter_StepDetector_native_1filter( JNIEnv *env, jclass /*unused*/, jlong handle, jlong timestamp, jfloatArray values) { if(values == nullptr) throwIllegalArgumentException(env, "values == null"); float* nativeValues = (float *)env->GetFloatArrayElements(values, 0); jsize length = env->GetArrayLength(values); std::vector vecValues(nativeValues, nativeValues + length); auto *detector = reinterpret_cast(handle); detector->filter((double) timestamp, vecValues); } }