mirror of
https://github.com/hexedtech/codemp.git
synced 2024-12-26 06:44:54 +01:00
feat(java): callback API
Co-authored-by: alemi <me@alemi.dev>
This commit is contained in:
parent
b7680b15c1
commit
795423de2a
10 changed files with 197 additions and 102 deletions
17
dist/java/src/mp/code/Extensions.java
vendored
Normal file
17
dist/java/src/mp/code/Extensions.java
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
package mp.code;
|
||||
|
||||
public class Extensions {
|
||||
/**
|
||||
* Hashes the given {@link String} using CodeMP's hashing algorithm (xxh3).
|
||||
* @param input the string to hash
|
||||
* @return the hash
|
||||
*/
|
||||
public static native long hash(String input);
|
||||
|
||||
/**
|
||||
* Drive the underlying library's asynchronous event loop.
|
||||
* @param block true if it should use the current thread, false if it should
|
||||
* spawn a separate one
|
||||
*/
|
||||
public static native void drive(boolean block);
|
||||
}
|
10
dist/java/src/mp/code/Utils.java
vendored
10
dist/java/src/mp/code/Utils.java
vendored
|
@ -1,10 +0,0 @@
|
|||
package mp.code;
|
||||
|
||||
public class Utils {
|
||||
/**
|
||||
* Hashes the given {@link String} using CodeMP's hashing algorithm (xxh3).
|
||||
* @param input the string to hash
|
||||
* @return the hash
|
||||
*/
|
||||
public static native long hash(String input);
|
||||
}
|
2
dist/java/src/mp/code/Workspace.java
vendored
2
dist/java/src/mp/code/Workspace.java
vendored
|
@ -95,7 +95,7 @@ public class Workspace {
|
|||
this.argument = argument;
|
||||
}
|
||||
|
||||
public Optional<String > getUserJoined() {
|
||||
public Optional<String> getUserJoined() {
|
||||
if(this.type == Type.USER_JOIN) {
|
||||
return Optional.of(this.argument);
|
||||
} else return Optional.empty();
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use jni::{objects::{JClass, JObject, JValueGen}, sys::{jlong, jobject, jstring}, JNIEnv};
|
||||
|
||||
use crate::{api::Controller, ffi::java::handle_callback};
|
||||
use crate::api::Controller;
|
||||
|
||||
use super::{JExceptable, RT};
|
||||
use super::JExceptable;
|
||||
|
||||
/// Gets the name of the buffer.
|
||||
#[no_mangle]
|
||||
|
@ -26,7 +26,7 @@ pub extern "system" fn Java_mp_code_BufferController_get_1content(
|
|||
self_ptr: jlong,
|
||||
) -> jstring {
|
||||
let controller = unsafe { Box::leak(Box::from_raw(self_ptr as *mut crate::buffer::Controller)) };
|
||||
let content = RT.block_on(controller.content())
|
||||
let content = super::tokio().block_on(controller.content())
|
||||
.jexcept(&mut env);
|
||||
env.new_string(content)
|
||||
.jexcept(&mut env)
|
||||
|
@ -41,7 +41,7 @@ pub extern "system" fn Java_mp_code_BufferController_try_1recv(
|
|||
self_ptr: jlong,
|
||||
) -> jobject {
|
||||
let controller = unsafe { Box::leak(Box::from_raw(self_ptr as *mut crate::buffer::Controller)) };
|
||||
let change = RT.block_on(controller.try_recv()).jexcept(&mut env);
|
||||
let change = super::tokio().block_on(controller.try_recv()).jexcept(&mut env);
|
||||
recv_jni(&mut env, change)
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ pub extern "system" fn Java_mp_code_BufferController_recv(
|
|||
self_ptr: jlong,
|
||||
) -> jobject {
|
||||
let controller = unsafe { Box::leak(Box::from_raw(self_ptr as *mut crate::buffer::Controller)) };
|
||||
let change = RT.block_on(controller.recv()).map(Some).jexcept(&mut env);
|
||||
let change = super::tokio().block_on(controller.recv()).map(Some).jexcept(&mut env);
|
||||
recv_jni(&mut env, change)
|
||||
}
|
||||
|
||||
|
@ -88,6 +88,18 @@ fn recv_jni(env: &mut JNIEnv, change: Option<crate::api::TextChange>) -> jobject
|
|||
}.as_raw()
|
||||
}
|
||||
|
||||
/// Clears the callback for buffer changes.
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_mp_code_BufferController_clear_1callback(
|
||||
_env: JNIEnv,
|
||||
_class: JClass,
|
||||
self_ptr: jlong,
|
||||
) {
|
||||
unsafe { Box::leak(Box::from_raw(self_ptr as *mut crate::buffer::Controller)) }
|
||||
.clear_callback();
|
||||
}
|
||||
|
||||
/// Registers a callback for buffer changes.
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_mp_code_BufferController_callback<'local>(
|
||||
mut env: JNIEnv,
|
||||
|
@ -95,7 +107,36 @@ pub extern "system" fn Java_mp_code_BufferController_callback<'local>(
|
|||
self_ptr: jlong,
|
||||
cb: JObject<'local>,
|
||||
) {
|
||||
handle_callback!("mp/code/BufferController", env, self_ptr, cb, crate::buffer::Controller);
|
||||
let controller = unsafe { Box::leak(Box::from_raw(self_ptr as *mut crate::buffer::Controller)) };
|
||||
|
||||
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| {
|
||||
use crate::ffi::java::JObjectify;
|
||||
let jcontroller = controller.jobjectify(env)?;
|
||||
let sig = format!("(L{};)V", "java/lang/Object");
|
||||
if let Err(e) = env.call_method(
|
||||
&cb_ref,
|
||||
"invoke",
|
||||
&sig,
|
||||
&[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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Receive from Java, converts and sends a [crate::api::TextChange].
|
||||
|
@ -147,7 +188,7 @@ pub extern "system" fn Java_mp_code_BufferController_send<'local>(
|
|||
}).jexcept(&mut env);
|
||||
|
||||
let controller = unsafe { Box::leak(Box::from_raw(self_ptr as *mut crate::buffer::Controller)) };
|
||||
RT.block_on(controller.send(crate::api::TextChange {
|
||||
super::tokio().block_on(controller.send(crate::api::TextChange {
|
||||
start,
|
||||
end,
|
||||
content,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use jni::{objects::{JClass, JObject, JString, JValueGen}, sys::{jboolean, jint, jlong, jobject, jobjectArray}, JNIEnv};
|
||||
use crate::{api::Config, client::Client, Workspace};
|
||||
|
||||
use super::{JExceptable, JObjectify, RT};
|
||||
use super::{JExceptable, JObjectify};
|
||||
|
||||
/// Connect using the given credentials to the default server, and return a [Client] to interact with it.
|
||||
#[no_mangle]
|
||||
|
@ -63,7 +63,7 @@ pub extern "system" fn Java_mp_code_Client_connectToServer<'local>(
|
|||
}
|
||||
|
||||
fn connect_internal(mut env: JNIEnv, config: Config) -> jobject {
|
||||
RT.block_on(Client::connect(config))
|
||||
super::tokio().block_on(Client::connect(config))
|
||||
.map(|client| Box::into_raw(Box::new(client)) as jlong)
|
||||
.map(|ptr| {
|
||||
env.find_class("mp/code/Client")
|
||||
|
@ -98,7 +98,7 @@ pub extern "system" fn Java_mp_code_Client_join_1workspace<'local>(
|
|||
let workspace_id = unsafe { env.get_string_unchecked(&input) }
|
||||
.map(|wid| wid.to_string_lossy().to_string())
|
||||
.jexcept(&mut env);
|
||||
RT.block_on(client.join_workspace(workspace_id))
|
||||
super::tokio().block_on(client.join_workspace(workspace_id))
|
||||
.map(|workspace| spawn_updater(workspace.clone()))
|
||||
.map(|workspace| Box::into_raw(Box::new(workspace)) as jlong)
|
||||
.map(|ptr| {
|
||||
|
@ -120,7 +120,7 @@ pub extern "system" fn Java_mp_code_Client_create_1workspace<'local>(
|
|||
let workspace_id = unsafe { env.get_string_unchecked(&input) }
|
||||
.map(|wid| wid.to_string_lossy().to_string())
|
||||
.jexcept(&mut env);
|
||||
RT
|
||||
super::tokio()
|
||||
.block_on(client.create_workspace(workspace_id))
|
||||
.jexcept(&mut env);
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ pub extern "system" fn Java_mp_code_Client_delete_1workspace<'local>(
|
|||
let workspace_id = unsafe { env.get_string_unchecked(&input) }
|
||||
.map(|wid| wid.to_string_lossy().to_string())
|
||||
.jexcept(&mut env);
|
||||
RT
|
||||
super::tokio()
|
||||
.block_on(client.delete_workspace(workspace_id))
|
||||
.jexcept(&mut env);
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ pub extern "system" fn Java_mp_code_Client_invite_1to_1workspace<'local>(
|
|||
let user_name = unsafe { env.get_string_unchecked(&usr) }
|
||||
.map(|wid| wid.to_string_lossy().to_string())
|
||||
.jexcept(&mut env);
|
||||
RT
|
||||
super::tokio()
|
||||
.block_on(client.invite_to_workspace(workspace_id, user_name))
|
||||
.jexcept(&mut env);
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ pub extern "system" fn Java_mp_code_Client_list_1workspaces<'local>(
|
|||
invited: jboolean
|
||||
) -> jobjectArray {
|
||||
let client = unsafe { Box::leak(Box::from_raw(self_ptr as *mut Client)) };
|
||||
let list = RT
|
||||
let list = super::tokio()
|
||||
.block_on(client.list_workspaces(owned != 0, invited != 0))
|
||||
.jexcept(&mut env);
|
||||
env.find_class("java/lang/String")
|
||||
|
@ -210,7 +210,7 @@ pub extern "system" fn Java_mp_code_Client_active_1workspaces<'local>(
|
|||
// TODO: this stays until we get rid of the arc then i'll have to find a better way
|
||||
fn spawn_updater(workspace: Workspace) -> Workspace {
|
||||
let w = workspace.clone();
|
||||
RT.spawn(async move {
|
||||
super::tokio().spawn(async move {
|
||||
loop {
|
||||
tokio::time::sleep(std::time::Duration::from_secs(60)).await;
|
||||
w.fetch_buffers().await.unwrap();
|
||||
|
@ -264,7 +264,7 @@ pub extern "system" fn Java_mp_code_Client_refresh<'local>(
|
|||
self_ptr: jlong,
|
||||
) {
|
||||
let client = unsafe { Box::leak(Box::from_raw(self_ptr as *mut Client)) };
|
||||
RT.block_on(client.refresh())
|
||||
super::tokio().block_on(client.refresh())
|
||||
.jexcept(&mut env);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use jni::{objects::{JClass, JObject, JString, JValueGen}, sys::{jlong, jobject}, JNIEnv};
|
||||
use crate::api::Controller;
|
||||
|
||||
use super::{handle_callback, JExceptable, RT};
|
||||
use super::JExceptable;
|
||||
|
||||
/// Try to fetch a [crate::api::Cursor], or returns null if there's nothing.
|
||||
#[no_mangle]
|
||||
|
@ -11,7 +11,7 @@ pub extern "system" fn Java_mp_code_CursorController_try_1recv(
|
|||
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.try_recv()).jexcept(&mut env);
|
||||
let cursor = super::tokio().block_on(controller.try_recv()).jexcept(&mut env);
|
||||
jni_recv(&mut env, cursor)
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ pub extern "system" fn Java_mp_code_CursorController_recv(
|
|||
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);
|
||||
let cursor = super::tokio().block_on(controller.recv()).map(Some).jexcept(&mut env);
|
||||
jni_recv(&mut env, cursor)
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,18 @@ fn jni_recv(env: &mut JNIEnv, cursor: Option<crate::api::Cursor>) -> jobject {
|
|||
}.as_raw()
|
||||
}
|
||||
|
||||
/// Clears the callback for cursor changes.
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_mp_code_CursorController_clear_1callback(
|
||||
_env: JNIEnv,
|
||||
_class: JClass,
|
||||
self_ptr: jlong,
|
||||
) {
|
||||
unsafe { Box::leak(Box::from_raw(self_ptr as *mut crate::cursor::Controller)) }
|
||||
.clear_callback();
|
||||
}
|
||||
|
||||
/// Registers a callback for cursor changes.
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_mp_code_CursorController_callback<'local>(
|
||||
mut env: JNIEnv,
|
||||
|
@ -63,7 +75,36 @@ pub extern "system" fn Java_mp_code_CursorController_callback<'local>(
|
|||
self_ptr: jlong,
|
||||
cb: JObject<'local>,
|
||||
) {
|
||||
handle_callback!("mp/code/CursorController", env, self_ptr, cb, crate::cursor::Controller);
|
||||
let controller = unsafe { Box::leak(Box::from_raw(self_ptr as *mut crate::cursor::Controller)) };
|
||||
|
||||
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::cursor::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| {
|
||||
use crate::ffi::java::JObjectify;
|
||||
let jcontroller = controller.jobjectify(env)?;
|
||||
let sig = format!("(L{};)V", "java/lang/Object");
|
||||
if let Err(e) = env.call_method(
|
||||
&cb_ref,
|
||||
"invoke",
|
||||
&sig,
|
||||
&[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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Receive from Java, converts and sends a [crate::api::Cursor].
|
||||
|
@ -109,7 +150,7 @@ pub extern "system" fn Java_mp_code_CursorController_send<'local>(
|
|||
};
|
||||
|
||||
let controller = unsafe { Box::leak(Box::from_raw(self_ptr as *mut crate::cursor::Controller)) };
|
||||
RT.block_on(controller.send(crate::api::Cursor {
|
||||
super::tokio().block_on(controller.send(crate::api::Cursor {
|
||||
start: (start_row, start_col),
|
||||
end: (end_row, end_col),
|
||||
buffer,
|
||||
|
|
34
src/ffi/java/ext.rs
Normal file
34
src/ffi/java/ext.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
use jni::{objects::{JClass, JString}, sys::{jboolean, jlong}, JNIEnv};
|
||||
|
||||
use super::JExceptable;
|
||||
|
||||
/// Calculate the XXH3 hash for a given String.
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_mp_code_Extensions_hash<'local>(
|
||||
mut env: JNIEnv,
|
||||
_class: JClass<'local>,
|
||||
content: JString<'local>,
|
||||
) -> jlong {
|
||||
let content: String = env.get_string(&content)
|
||||
.map(|s| s.into())
|
||||
.jexcept(&mut env);
|
||||
let hash = crate::ext::hash(content.as_bytes());
|
||||
i64::from_ne_bytes(hash.to_ne_bytes())
|
||||
}
|
||||
|
||||
/// Tells the [tokio] runtime how to drive the event loop.
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_mp_code_Extensions_drive(
|
||||
_env: JNIEnv,
|
||||
_class: JClass,
|
||||
block: jboolean
|
||||
) {
|
||||
if block != 0 {
|
||||
super::tokio().block_on(std::future::pending::<()>());
|
||||
} else {
|
||||
std::thread::spawn(|| {
|
||||
super::tokio().block_on(std::future::pending::<()>());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -2,10 +2,37 @@ pub mod client;
|
|||
pub mod workspace;
|
||||
pub mod cursor;
|
||||
pub mod buffer;
|
||||
pub mod utils;
|
||||
pub mod ext;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
pub(crate) static ref RT: tokio::runtime::Runtime = tokio::runtime::Runtime::new().expect("could not create tokio runtime");
|
||||
/// Gets or creates the relevant [tokio::runtime::Runtime].
|
||||
fn tokio() -> &'static tokio::runtime::Runtime {
|
||||
use std::sync::OnceLock;
|
||||
static RT: OnceLock<tokio::runtime::Runtime> = OnceLock::new();
|
||||
RT.get_or_init(||
|
||||
tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.expect("could not create tokio runtime")
|
||||
)
|
||||
}
|
||||
|
||||
/// A static reference to [jni::JavaVM] that is set on JNI load.
|
||||
static mut JVM: Option<std::sync::Arc<jni::JavaVM>> = None;
|
||||
|
||||
/// Safe accessor for the [jni::JavaVM] static.
|
||||
pub(crate) fn jvm() -> std::sync::Arc<jni::JavaVM> {
|
||||
unsafe { JVM.clone() }.unwrap()
|
||||
}
|
||||
|
||||
/// Called upon initialisation of the JVM.
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub extern "system" fn JNI_OnLoad(
|
||||
vm: jni::JavaVM,
|
||||
_: *mut std::ffi::c_void
|
||||
) -> jni::sys::jint {
|
||||
unsafe { JVM = Some(std::sync::Arc::new(vm)) };
|
||||
jni::sys::JNI_VERSION_1_1
|
||||
}
|
||||
|
||||
/// Set up logging. Useful for debugging.
|
||||
|
@ -149,7 +176,7 @@ impl<'local> JObjectify<'local> for crate::cursor::Controller {
|
|||
class,
|
||||
"(J)V",
|
||||
&[
|
||||
jni::objects::JValueGen::Long(Box::into_raw(Box::new(&self)) as jni::sys::jlong)
|
||||
jni::objects::JValueGen::Long(Box::into_raw(Box::new(self)) as jni::sys::jlong)
|
||||
]
|
||||
)
|
||||
}
|
||||
|
@ -164,46 +191,8 @@ impl<'local> JObjectify<'local> for crate::buffer::Controller {
|
|||
class,
|
||||
"(J)V",
|
||||
&[
|
||||
jni::objects::JValueGen::Long(Box::into_raw(Box::new(&self)) as jni::sys::jlong)
|
||||
jni::objects::JValueGen::Long(Box::into_raw(Box::new(self)) as jni::sys::jlong)
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! handle_callback {
|
||||
($jtype:literal, $env:ident, $self_ptr:ident, $cb:ident, $t:ty) => {
|
||||
let controller = unsafe { Box::leak(Box::from_raw($self_ptr as *mut $t)) };
|
||||
|
||||
let Ok(jvm) = $env.get_java_vm() else {
|
||||
$env.throw_new("mp/code/exceptions/JNIException", "Failed to get JVM reference!")
|
||||
.expect("Failed to throw exception!");
|
||||
return;
|
||||
};
|
||||
|
||||
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: $t| {
|
||||
use std::ops::DerefMut;
|
||||
use crate::ffi::java::JObjectify;
|
||||
let mut guard = jvm.attach_current_thread().unwrap();
|
||||
let jcontroller = match controller.jobjectify(guard.deref_mut()) {
|
||||
Err(e) => return tracing::error!("could not convert callback argument: {e:?}"),
|
||||
Ok(x) => x,
|
||||
};
|
||||
let sig = format!("(L{};)V", $jtype);
|
||||
if let Err(e) = guard.call_method(&cb_ref,
|
||||
"invoke",
|
||||
&sig,
|
||||
&[jni::objects::JValueGen::Object(&jcontroller)]
|
||||
) {
|
||||
tracing::error!("error invoking callback: {e:?}");
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use handle_callback;
|
||||
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
use jni::{objects::{JClass, JString}, sys::jlong, JNIEnv};
|
||||
|
||||
use super::JExceptable;
|
||||
|
||||
/// Calculate the XXH3 hash for a given String.
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_mp_code_Utils_hash<'local>(
|
||||
mut env: JNIEnv,
|
||||
_class: JClass<'local>,
|
||||
content: JString<'local>,
|
||||
) -> jlong {
|
||||
let content: String = env.get_string(&content)
|
||||
.map(|s| s.into())
|
||||
.jexcept(&mut env);
|
||||
let hash = crate::ext::hash(content.as_bytes());
|
||||
i64::from_ne_bytes(hash.to_ne_bytes())
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
use jni::{objects::{JClass, JObject, JString, JValueGen}, sys::{jboolean, jlong, jobject, jobjectArray, jstring}, JNIEnv};
|
||||
use crate::Workspace;
|
||||
|
||||
use super::{JExceptable, JObjectify, RT};
|
||||
use super::{JExceptable, JObjectify};
|
||||
|
||||
/// Get the workspace id.
|
||||
#[no_mangle]
|
||||
|
@ -55,7 +55,7 @@ pub extern "system" fn Java_mp_code_Workspace_create_1buffer<'local>(
|
|||
let path = unsafe { env.get_string_unchecked(&input) }
|
||||
.map(|path| path.to_string_lossy().to_string())
|
||||
.jexcept(&mut env);
|
||||
RT.block_on(ws.create(&path))
|
||||
super::tokio().block_on(ws.create(&path))
|
||||
.jexcept(&mut env);
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ pub extern "system" fn Java_mp_code_Workspace_attach_1to_1buffer<'local>(
|
|||
let path = unsafe { env.get_string_unchecked(&input) }
|
||||
.map(|path| path.to_string_lossy().to_string())
|
||||
.jexcept(&mut env);
|
||||
RT.block_on(workspace.attach(&path))
|
||||
super::tokio().block_on(workspace.attach(&path))
|
||||
.map(|buffer| buffer.jobjectify(&mut env).jexcept(&mut env))
|
||||
.jexcept(&mut env)
|
||||
.as_raw()
|
||||
|
@ -142,7 +142,7 @@ pub extern "system" fn Java_mp_code_Workspace_fetch_1buffers(
|
|||
self_ptr: jlong,
|
||||
) {
|
||||
let workspace = unsafe { Box::leak(Box::from_raw(self_ptr as *mut Workspace)) };
|
||||
RT.block_on(workspace.fetch_buffers()).jexcept(&mut env);
|
||||
super::tokio().block_on(workspace.fetch_buffers()).jexcept(&mut env);
|
||||
}
|
||||
|
||||
/// Update the local user list.
|
||||
|
@ -153,7 +153,7 @@ pub extern "system" fn Java_mp_code_Workspace_fetch_1users(
|
|||
self_ptr: jlong,
|
||||
) {
|
||||
let workspace = unsafe { Box::leak(Box::from_raw(self_ptr as *mut Workspace)) };
|
||||
RT.block_on(workspace.fetch_users()).jexcept(&mut env);
|
||||
super::tokio().block_on(workspace.fetch_users()).jexcept(&mut env);
|
||||
}
|
||||
|
||||
/// List users attached to a buffer.
|
||||
|
@ -168,7 +168,7 @@ pub extern "system" fn Java_mp_code_Workspace_list_1buffer_1users<'local>(
|
|||
let buffer = unsafe { env.get_string_unchecked(&input) }
|
||||
.map(|buffer| buffer.to_string_lossy().to_string())
|
||||
.jexcept(&mut env);
|
||||
let users = RT.block_on(workspace.list_buffer_users(&buffer))
|
||||
let users = super::tokio().block_on(workspace.list_buffer_users(&buffer))
|
||||
.jexcept(&mut env);
|
||||
|
||||
env.find_class("java/util/UUID")
|
||||
|
@ -194,7 +194,7 @@ pub extern "system" fn Java_mp_code_Workspace_delete_1buffer<'local>(
|
|||
let buffer = unsafe { env.get_string_unchecked(&input) }
|
||||
.map(|buffer| buffer.to_string_lossy().to_string())
|
||||
.jexcept(&mut env);
|
||||
RT.block_on(workspace.delete(&buffer))
|
||||
super::tokio().block_on(workspace.delete(&buffer))
|
||||
.jexcept(&mut env);
|
||||
}
|
||||
|
||||
|
@ -206,7 +206,7 @@ pub extern "system" fn Java_mp_code_Workspace_event(
|
|||
self_ptr: jlong
|
||||
) -> jobject {
|
||||
let workspace = unsafe { Box::leak(Box::from_raw(self_ptr as *mut Workspace)) };
|
||||
RT.block_on(workspace.event())
|
||||
super::tokio().block_on(workspace.event())
|
||||
.map(|event| {
|
||||
let (name, arg) = match event {
|
||||
crate::api::Event::FileTreeUpdated(arg) => ("FILE_TREE_UPDATED", env.new_string(arg).unwrap_or_default()),
|
||||
|
@ -247,10 +247,10 @@ pub extern "system" fn Java_mp_code_Workspace_select_1buffer(
|
|||
}
|
||||
}
|
||||
|
||||
RT.block_on(crate::ext::select_buffer(
|
||||
super::tokio().block_on(crate::ext::select_buffer(
|
||||
&controllers,
|
||||
Some(std::time::Duration::from_millis(timeout as u64)),
|
||||
&RT,
|
||||
super::tokio(),
|
||||
)).jexcept(&mut env)
|
||||
.map(|buf| {
|
||||
env.find_class("mp/code/BufferController").and_then(|class|
|
||||
|
|
Loading…
Reference in a new issue