2024-09-23 00:26:11 +02:00
|
|
|
use jni::{objects::JObject, JNIEnv};
|
|
|
|
use jni_toolbox::jni;
|
2024-08-06 23:55:57 +02:00
|
|
|
|
2024-09-23 00:26:11 +02:00
|
|
|
use crate::{api::{Controller, TextChange}, errors::ControllerError};
|
2024-08-06 23:55:57 +02:00
|
|
|
|
2024-09-23 00:26:11 +02:00
|
|
|
use super::null_check;
|
2024-08-06 23:55:57 +02:00
|
|
|
|
2024-09-23 00:26:11 +02:00
|
|
|
/// Get the name of the buffer.
|
2024-09-23 18:12:13 +02:00
|
|
|
#[jni(package = "mp.code", class = "BufferController")]
|
|
|
|
fn get_name(controller: crate::buffer::Controller) -> String {
|
2024-09-23 00:26:11 +02:00
|
|
|
controller.path().to_string() //TODO: &str is built into the newer version
|
2024-08-06 23:55:57 +02:00
|
|
|
}
|
|
|
|
|
2024-09-23 00:26:11 +02:00
|
|
|
/// Get the contents of the buffers.
|
2024-09-23 18:12:13 +02:00
|
|
|
#[jni(package = "mp.code", class = "BufferController")]
|
|
|
|
fn get_content(controller: crate::buffer::Controller) -> Result<String, ControllerError> {
|
2024-09-23 00:26:11 +02:00
|
|
|
super::tokio().block_on(controller.content())
|
2024-08-06 23:55:57 +02:00
|
|
|
}
|
|
|
|
|
2024-09-23 00:26:11 +02:00
|
|
|
/// Try to fetch a [TextChange], or return null if there's nothing.
|
2024-09-23 18:12:13 +02:00
|
|
|
#[jni(package = "mp.code", class = "BufferController")]
|
|
|
|
fn try_recv(controller: crate::buffer::Controller) -> Result<Option<TextChange>, ControllerError> {
|
2024-09-23 00:26:11 +02:00
|
|
|
super::tokio().block_on(controller.try_recv())
|
2024-08-07 10:22:01 +02:00
|
|
|
}
|
|
|
|
|
2024-09-23 00:26:11 +02:00
|
|
|
/// Block until it receives a [TextChange].
|
2024-09-23 18:12:13 +02:00
|
|
|
#[jni(package = "mp.code", class = "BufferController")]
|
|
|
|
fn recv(controller: crate::buffer::Controller) -> Result<TextChange, ControllerError> {
|
2024-09-23 00:26:11 +02:00
|
|
|
super::tokio().block_on(controller.recv())
|
2024-08-06 23:55:57 +02:00
|
|
|
}
|
2024-09-15 01:56:51 +02:00
|
|
|
|
2024-09-23 00:26:11 +02:00
|
|
|
/// Send a [TextChange] to the server.
|
|
|
|
#[jni(package = "mp.code", class = "BufferController")]
|
2024-09-23 18:12:13 +02:00
|
|
|
fn send(controller: crate::buffer::Controller, change: TextChange) -> Result<(), ControllerError> {
|
2024-09-23 00:26:11 +02:00
|
|
|
super::tokio().block_on(controller.send(change))
|
2024-09-16 00:20:03 +02:00
|
|
|
}
|
|
|
|
|
2024-09-23 00:26:11 +02:00
|
|
|
/// Register a callback for buffer changes.
|
|
|
|
#[jni(package = "mp.code", class = "BufferController")]
|
2024-09-23 18:12:13 +02:00
|
|
|
fn callback<'local>(env: &mut JNIEnv<'local>, controller: crate::buffer::Controller, cb: JObject<'local>) {
|
2024-09-17 17:37:22 +02:00
|
|
|
null_check!(env, cb, {});
|
2024-09-16 00:20:03 +02:00
|
|
|
let Ok(cb_ref) = env.new_global_ref(cb) else {
|
|
|
|
env.throw_new("mp/code/exceptions/JNIException", "Failed to pin callback reference!")
|
|
|
|
.expect("Failed to throw exception!");
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
|
|
|
|
controller.callback(move |controller: crate::buffer::Controller| {
|
|
|
|
let jvm = super::jvm();
|
|
|
|
let mut env = jvm.attach_current_thread_permanently()
|
|
|
|
.expect("failed attaching to main JVM thread");
|
|
|
|
if let Err(e) = env.with_local_frame(5, |env| {
|
2024-09-23 00:26:11 +02:00
|
|
|
use jni_toolbox::IntoJavaObject;
|
2024-09-23 18:12:13 +02:00
|
|
|
let jcontroller = controller.into_java_object(env)?;
|
2024-09-16 00:20:03 +02:00
|
|
|
if let Err(e) = env.call_method(
|
|
|
|
&cb_ref,
|
2024-09-17 23:16:39 +02:00
|
|
|
"accept",
|
|
|
|
"(Ljava/lang/Object;)V",
|
2024-09-16 00:20:03 +02:00
|
|
|
&[jni::objects::JValueGen::Object(&jcontroller)]
|
|
|
|
) {
|
|
|
|
tracing::error!("error invoking callback: {e:?}");
|
|
|
|
};
|
|
|
|
Ok::<(), jni::errors::Error>(())
|
|
|
|
}) {
|
|
|
|
tracing::error!("error invoking callback: {e}");
|
|
|
|
let _ = env.exception_describe();
|
|
|
|
}
|
|
|
|
});
|
2024-09-15 01:56:51 +02:00
|
|
|
}
|
|
|
|
|
2024-09-23 00:26:11 +02:00
|
|
|
/// Clear the callback for buffer changes.
|
|
|
|
#[jni(package = "mp.code", class = "BufferController")]
|
2024-09-23 18:12:13 +02:00
|
|
|
fn clear_callback(controller: crate::buffer::Controller) {
|
2024-09-23 00:26:11 +02:00
|
|
|
controller.clear_callback()
|
2024-09-17 02:40:03 +02:00
|
|
|
}
|
2024-09-15 01:56:51 +02:00
|
|
|
|
2024-09-23 00:26:11 +02:00
|
|
|
/// Block until there is a new value available.
|
|
|
|
#[jni(package = "mp.code", class = "BufferController")]
|
2024-09-23 18:12:13 +02:00
|
|
|
fn poll(controller: crate::buffer::Controller) -> Result<(), ControllerError> {
|
2024-09-23 00:26:11 +02:00
|
|
|
super::tokio().block_on(controller.poll())
|
2024-09-17 02:40:03 +02:00
|
|
|
}
|
2024-09-15 01:56:51 +02:00
|
|
|
|
2024-09-23 00:26:11 +02:00
|
|
|
/// Stop the controller.
|
|
|
|
#[jni(package = "mp.code", class = "BufferController")]
|
2024-09-23 18:12:13 +02:00
|
|
|
fn stop(controller: crate::buffer::Controller) -> bool {
|
2024-09-23 00:26:11 +02:00
|
|
|
controller.stop()
|
2024-09-17 02:40:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Called by the Java GC to drop a [crate::buffer::Controller].
|
2024-09-23 00:26:11 +02:00
|
|
|
#[jni(package = "mp.code", class = "BufferController")]
|
|
|
|
fn free(input: jni::sys::jlong) {
|
|
|
|
let _ = unsafe { Box::from_raw(input as *mut crate::buffer::Controller) };
|
2024-09-15 01:56:51 +02:00
|
|
|
}
|