feat(java): UUID-based users, fixed event api

This commit is contained in:
zaaarf 2024-08-19 11:36:51 +02:00
parent f9d8ed6dbb
commit 3b45c4ddb6
No known key found for this signature in database
GPG key ID: 102E445F4C3F829B
4 changed files with 37 additions and 15 deletions

View file

@ -1,6 +1,7 @@
package mp.code; package mp.code;
import java.util.Optional; import java.util.Optional;
import java.util.UUID;
import mp.code.data.DetachResult; import mp.code.data.DetachResult;
import mp.code.exceptions.CodeMPException; import mp.code.exceptions.CodeMPException;
@ -57,8 +58,8 @@ public class Workspace {
fetch_buffers(this.ptr); fetch_buffers(this.ptr);
} }
private static native String[] list_buffer_users(long self, String path) throws CodeMPException; private static native UUID[] list_buffer_users(long self, String path) throws CodeMPException;
public String[] listBufferUsers(String path) throws CodeMPException { public UUID[] listBufferUsers(String path) throws CodeMPException {
return list_buffer_users(this.ptr, path); return list_buffer_users(this.ptr, path);
} }
@ -104,8 +105,10 @@ public class Workspace {
} else return Optional.empty(); } else return Optional.empty();
} }
public boolean hasFileTreeUpdated() { public Optional<String> getTargetBuffer() {
return type == Type.FILE_TREE_UPDATED; if(this.type == Type.FILE_TREE_UPDATED) {
return Optional.of(this.argument);
} else return Optional.empty();
} }
private enum Type { private enum Type {

View file

@ -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; use crate::api::Controller;

View file

@ -79,3 +79,25 @@ impl<T> JExceptable<T> for Result<T, uuid::Error> where T: Default {
self.unwrap_or_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<jni::objects::JObject<'local>, Self::Error>;
}
impl<'local> JObjectify<'local> for uuid::Uuid {
type Error = jni::errors::Error;
fn jobjectify(self, env: &mut jni::JNIEnv<'local>) -> Result<jni::objects::JObject<'local>, 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)])
})
}
}

View file

@ -1,7 +1,7 @@
use jni::{objects::{JClass, JObject, JString, JValueGen}, sys::{jlong, jobject, jobjectArray, jstring}, JNIEnv}; use jni::{objects::{JClass, JObject, JString, JValueGen}, sys::{jlong, jobject, jobjectArray, jstring}, JNIEnv};
use crate::Workspace; use crate::Workspace;
use super::{JExceptable, RT}; use super::{JExceptable, JObjectify, RT};
/// Gets the workspace id. /// Gets the workspace id.
#[no_mangle] #[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)) let users = RT.block_on(workspace.list_buffer_users(&buffer))
.jexcept(&mut env); .jexcept(&mut env);
env.find_class("java/lang/String") env.find_class("java/util/UUID")
.and_then(|class| env.new_object_array(users.len() as i32, class, JObject::null())) .and_then(|class| env.new_object_array(users.len() as i32, &class, JObject::null()))
.map(|arr| { .map(|arr| {
for (idx, user) in users.iter().enumerate() { 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)) .and_then(|id| env.set_object_array_element(&arr, idx as i32, id))
.jexcept(&mut env); .jexcept(&mut env);
} }
@ -204,17 +204,14 @@ pub extern "system" fn Java_mp_code_Workspace_event(
RT.block_on(workspace.event()) RT.block_on(workspace.event())
.map(|event| { .map(|event| {
let (name, arg) = match event { let (name, arg) = match event {
crate::api::Event::FileTreeUpdated => ("FILE_TREE_UPDATED", None), crate::api::Event::FileTreeUpdated(arg) => ("FILE_TREE_UPDATED", env.new_string(arg).unwrap_or_default()),
crate::api::Event::UserJoin(arg) => ("USER_JOIN", Some(arg)), crate::api::Event::UserJoin(arg) => ("USER_JOIN", env.new_string(arg).unwrap_or_default()),
crate::api::Event::UserLeave(arg) => ("USER_LEAVE", Some(arg)), 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") 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(|class| env.get_static_field(class, name, "Lmp/code/Workspace/Event/Type;"))
.and_then(|f| f.l()) .and_then(|f| f.l())
.jexcept(&mut env); .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.find_class("mp/code/Workspace$Event").and_then(|class|
env.new_object( env.new_object(
class, class,