2024-08-07 01:44:27 +02:00
|
|
|
use jni::{objects::{JClass, JObject, JString, JValueGen}, sys::{jlong, jobject}, JNIEnv};
|
2024-08-10 02:45:20 +02:00
|
|
|
use crate::api::Controller;
|
2024-08-06 23:55:57 +02:00
|
|
|
|
2024-08-10 02:45:20 +02:00
|
|
|
use super::{JExceptable, RT};
|
2024-08-07 10:22:01 +02:00
|
|
|
|
2024-09-05 02:45:33 +02:00
|
|
|
/// Try to fetch a [crate::api::Cursor], or returns null if there's nothing.
|
2024-08-06 23:55:57 +02:00
|
|
|
#[no_mangle]
|
2024-08-07 00:37:58 +02:00
|
|
|
pub extern "system" fn Java_mp_code_CursorController_try_1recv(
|
2024-08-06 23:55:57 +02:00
|
|
|
mut env: JNIEnv,
|
2024-08-07 00:37:58 +02:00
|
|
|
_class: JClass,
|
2024-08-06 23:55:57 +02:00
|
|
|
self_ptr: jlong,
|
|
|
|
) -> jobject {
|
2024-08-07 00:37:58 +02:00
|
|
|
let controller = unsafe { Box::leak(Box::from_raw(self_ptr as *mut crate::cursor::Controller)) };
|
2024-08-14 00:27:26 +02:00
|
|
|
let cursor = RT.block_on(controller.try_recv()).jexcept(&mut env);
|
2024-08-07 10:22:01 +02:00
|
|
|
jni_recv(&mut env, cursor)
|
|
|
|
}
|
|
|
|
|
2024-09-05 02:45:33 +02:00
|
|
|
/// Block until it receives a [crate::api::Cursor].
|
2024-08-07 10:22:01 +02:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "system" fn Java_mp_code_CursorController_recv(
|
|
|
|
mut env: JNIEnv,
|
|
|
|
_class: JClass,
|
|
|
|
self_ptr: jlong,
|
|
|
|
) -> jobject {
|
|
|
|
let controller = unsafe { Box::leak(Box::from_raw(self_ptr as *mut crate::cursor::Controller)) };
|
|
|
|
let cursor = RT.block_on(controller.recv()).map(Some).jexcept(&mut env);
|
|
|
|
jni_recv(&mut env, cursor)
|
|
|
|
}
|
|
|
|
|
2024-08-08 00:29:54 +02:00
|
|
|
/// Utility method to convert a [crate::api::Cursor] to its Java equivalent.
|
2024-08-07 10:22:01 +02:00
|
|
|
fn jni_recv(env: &mut JNIEnv, cursor: Option<crate::api::Cursor>) -> jobject {
|
|
|
|
match cursor {
|
2024-08-10 02:45:20 +02:00
|
|
|
None => JObject::default(),
|
2024-08-07 00:37:58 +02:00
|
|
|
Some(event) => {
|
2024-08-10 02:45:20 +02:00
|
|
|
env.find_class("mp/code/data/Cursor")
|
|
|
|
.and_then(|class| {
|
|
|
|
let buffer = env.new_string(&event.buffer).jexcept(env);
|
|
|
|
let user = event.user
|
|
|
|
.map(|uuid| uuid.to_string())
|
|
|
|
.map(|user| env.new_string(user).jexcept(env))
|
|
|
|
.unwrap_or_default();
|
|
|
|
env.new_object(
|
|
|
|
class,
|
|
|
|
"(IIIILjava/lang/String;Ljava/lang/String;)V",
|
|
|
|
&[
|
|
|
|
JValueGen::Int(event.start.0),
|
|
|
|
JValueGen::Int(event.start.1),
|
|
|
|
JValueGen::Int(event.end.0),
|
|
|
|
JValueGen::Int(event.end.1),
|
|
|
|
JValueGen::Object(&buffer),
|
|
|
|
JValueGen::Object(&user)
|
|
|
|
]
|
|
|
|
)
|
|
|
|
}).jexcept(env)
|
2024-08-07 00:37:58 +02:00
|
|
|
}
|
2024-08-10 02:45:20 +02:00
|
|
|
}.as_raw()
|
2024-08-06 23:55:57 +02:00
|
|
|
}
|
|
|
|
|
2024-09-05 02:45:33 +02:00
|
|
|
/// Receive from Java, converts and sends a [crate::api::Cursor].
|
2024-08-06 23:55:57 +02:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern "system" fn Java_mp_code_CursorController_send<'local>(
|
|
|
|
mut env: JNIEnv,
|
|
|
|
_class: JClass<'local>,
|
|
|
|
self_ptr: jlong,
|
|
|
|
input: JObject<'local>,
|
|
|
|
) {
|
2024-08-10 02:45:20 +02:00
|
|
|
let start_row = env.get_field(&input, "startRow", "I")
|
|
|
|
.and_then(|sr| sr.i())
|
|
|
|
.jexcept(&mut env);
|
|
|
|
let start_col = env.get_field(&input, "startCol", "I")
|
|
|
|
.and_then(|sc| sc.i())
|
|
|
|
.jexcept(&mut env);
|
|
|
|
let end_row = env.get_field(&input, "endRow", "I")
|
|
|
|
.and_then(|er| er.i())
|
|
|
|
.jexcept(&mut env);
|
|
|
|
let end_col = env.get_field(&input, "endCol", "I")
|
|
|
|
.and_then(|ec| ec.i())
|
|
|
|
.jexcept(&mut env);
|
2024-08-07 01:44:27 +02:00
|
|
|
|
|
|
|
let buffer = env.get_field(&input, "buffer", "Ljava/lang/String;")
|
2024-08-10 02:45:20 +02:00
|
|
|
.and_then(|b| b.l())
|
|
|
|
.map(|b| b.into())
|
|
|
|
.jexcept(&mut env);
|
|
|
|
let buffer = env.get_string(&buffer)
|
|
|
|
.map(|b| b.into())
|
|
|
|
.jexcept(&mut env);
|
|
|
|
|
2024-08-07 01:44:27 +02:00
|
|
|
let user: JString = env.get_field(&input, "user", "Ljava/lang/String;")
|
2024-08-10 02:45:20 +02:00
|
|
|
.and_then(|u| u.l())
|
|
|
|
.map(|u| u.into())
|
|
|
|
.jexcept(&mut env);
|
2024-08-07 01:44:27 +02:00
|
|
|
let user = if user.is_null() {
|
|
|
|
None
|
|
|
|
} else {
|
2024-09-06 00:12:31 +02:00
|
|
|
Some(env.get_string(&user)
|
2024-08-10 02:45:20 +02:00
|
|
|
.map(|u| u.into())
|
2024-09-06 00:12:31 +02:00
|
|
|
.jexcept(&mut env)
|
|
|
|
)
|
2024-08-07 01:44:27 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
let controller = unsafe { Box::leak(Box::from_raw(self_ptr as *mut crate::cursor::Controller)) };
|
2024-08-14 18:51:34 +02:00
|
|
|
RT.block_on(controller.send(crate::api::Cursor {
|
2024-08-07 01:44:27 +02:00
|
|
|
start: (start_row, start_col),
|
|
|
|
end: (end_row, end_col),
|
|
|
|
buffer,
|
|
|
|
user
|
2024-08-14 18:51:34 +02:00
|
|
|
})).jexcept(&mut env);
|
2024-08-06 23:55:57 +02:00
|
|
|
}
|
|
|
|
|
2024-08-08 00:29:54 +02:00
|
|
|
/// Called by the Java GC to drop a [crate::cursor::Controller].
|
2024-08-06 23:55:57 +02:00
|
|
|
#[no_mangle]
|
2024-08-07 01:44:27 +02:00
|
|
|
pub extern "system" fn Java_mp_code_CursorController_free(
|
2024-08-06 23:55:57 +02:00
|
|
|
_env: JNIEnv,
|
2024-08-07 01:44:27 +02:00
|
|
|
_class: JClass,
|
2024-08-06 23:55:57 +02:00
|
|
|
self_ptr: jlong,
|
|
|
|
) {
|
2024-08-07 00:37:58 +02:00
|
|
|
let _ = unsafe { Box::from_raw(self_ptr as *mut crate::cursor::Controller) };
|
2024-08-06 23:55:57 +02:00
|
|
|
}
|