diff --git a/dist/java/src/mp/code/Workspace.java b/dist/java/src/mp/code/Workspace.java index dcc94f0d..a122c4a2 100644 --- a/dist/java/src/mp/code/Workspace.java +++ b/dist/java/src/mp/code/Workspace.java @@ -1,6 +1,7 @@ package mp.code; import java.util.Optional; +import java.util.UUID; import mp.code.data.DetachResult; import mp.code.exceptions.CodeMPException; @@ -57,8 +58,8 @@ public void fetchUsers() throws CodeMPException { fetch_buffers(this.ptr); } - private static native String[] list_buffer_users(long self, String path) throws CodeMPException; - public String[] listBufferUsers(String path) throws CodeMPException { + private static native UUID[] list_buffer_users(long self, String path) throws CodeMPException; + public UUID[] listBufferUsers(String path) throws CodeMPException { return list_buffer_users(this.ptr, path); } @@ -104,8 +105,10 @@ public Optional getUserLeft() { } else return Optional.empty(); } - public boolean hasFileTreeUpdated() { - return type == Type.FILE_TREE_UPDATED; + public Optional getTargetBuffer() { + if(this.type == Type.FILE_TREE_UPDATED) { + return Optional.of(this.argument); + } else return Optional.empty(); } private enum Type { diff --git a/src/ffi/java/buffer.rs b/src/ffi/java/buffer.rs index 01dec829..41e915df 100644 --- a/src/ffi/java/buffer.rs +++ b/src/ffi/java/buffer.rs @@ -1,4 +1,4 @@ -use jni::{objects::{JClass, JObject, JString, JValueGen}, sys::{jlong, jobject, jstring}, JNIEnv}; +use jni::{objects::{JClass, JObject, JValueGen}, sys::{jlong, jobject, jstring}, JNIEnv}; use crate::api::Controller; diff --git a/src/ffi/java/mod.rs b/src/ffi/java/mod.rs index 982f1161..368c4fa2 100644 --- a/src/ffi/java/mod.rs +++ b/src/ffi/java/mod.rs @@ -79,3 +79,25 @@ impl JExceptable for Result where T: Default { self.unwrap_or_default() } } + +/// Allows easy conversion for various types into Java objects. +/// This is essentially the same as [TryInto], but that can't be emplemented on non-local types. +pub(crate) trait JObjectify<'local> { + /// The error type, likely to be [jni::errors::Error]. + type Error; + + /// Attempts to convert the given object to a [jni::objects::JObject]. + fn jobjectify(self, env: &mut jni::JNIEnv<'local>) -> Result, Self::Error>; +} + +impl<'local> JObjectify<'local> for uuid::Uuid { + type Error = jni::errors::Error; + fn jobjectify(self, env: &mut jni::JNIEnv<'local>) -> Result, jni::errors::Error> { + env.find_class("java/util/UUID").and_then(|class| { + let (msb, lsb) = self.as_u64_pair(); + let msb = i64::from_ne_bytes(msb.to_ne_bytes()); + let lsb = i64::from_ne_bytes(lsb.to_ne_bytes()); + env.new_object(&class, "(JJ)V", &[jni::objects::JValueGen::Long(msb), jni::objects::JValueGen::Long(lsb)]) + }) + } +} diff --git a/src/ffi/java/workspace.rs b/src/ffi/java/workspace.rs index 6dd2cb70..de8cf88d 100644 --- a/src/ffi/java/workspace.rs +++ b/src/ffi/java/workspace.rs @@ -1,7 +1,7 @@ use jni::{objects::{JClass, JObject, JString, JValueGen}, sys::{jlong, jobject, jobjectArray, jstring}, JNIEnv}; use crate::Workspace; -use super::{JExceptable, RT}; +use super::{JExceptable, JObjectify, RT}; /// Gets the workspace id. #[no_mangle] @@ -166,11 +166,11 @@ pub extern "system" fn Java_mp_code_Workspace_list_1buffer_1users<'local>( let users = RT.block_on(workspace.list_buffer_users(&buffer)) .jexcept(&mut env); - env.find_class("java/lang/String") - .and_then(|class| env.new_object_array(users.len() as i32, class, JObject::null())) + env.find_class("java/util/UUID") + .and_then(|class| env.new_object_array(users.len() as i32, &class, JObject::null())) .map(|arr| { for (idx, user) in users.iter().enumerate() { - env.new_string(&user.id) + user.id.jobjectify(&mut env) .and_then(|id| env.set_object_array_element(&arr, idx as i32, id)) .jexcept(&mut env); } @@ -204,17 +204,14 @@ pub extern "system" fn Java_mp_code_Workspace_event( RT.block_on(workspace.event()) .map(|event| { let (name, arg) = match event { - crate::api::Event::FileTreeUpdated => ("FILE_TREE_UPDATED", None), - crate::api::Event::UserJoin(arg) => ("USER_JOIN", Some(arg)), - crate::api::Event::UserLeave(arg) => ("USER_LEAVE", Some(arg)), + crate::api::Event::FileTreeUpdated(arg) => ("FILE_TREE_UPDATED", env.new_string(arg).unwrap_or_default()), + crate::api::Event::UserJoin(arg) => ("USER_JOIN", env.new_string(arg).unwrap_or_default()), + crate::api::Event::UserLeave(arg) => ("USER_LEAVE", env.new_string(arg).unwrap_or_default()), }; let event_type = env.find_class("mp/code/Workspace$Event$Type") .and_then(|class| env.get_static_field(class, name, "Lmp/code/Workspace/Event/Type;")) .and_then(|f| f.l()) .jexcept(&mut env); - let arg = arg.map(|s| env.new_string(s).jexcept(&mut env)) - .unwrap_or_default(); - env.find_class("mp/code/Workspace$Event").and_then(|class| env.new_object( class,