feat(java): get_user, active_workspaces

This commit is contained in:
zaaarf 2024-09-15 02:00:04 +02:00
parent 963f2b698c
commit 05fbbe6f9d
No known key found for this signature in database
GPG key ID: C91CFF9E2262BBA1
8 changed files with 100 additions and 13 deletions

View file

@ -1,5 +1,6 @@
package mp.code;
import mp.code.data.Callback;
import mp.code.data.Cursor;
import mp.code.data.TextChange;
import mp.code.exceptions.ControllerException;
@ -38,6 +39,11 @@ public class BufferController {
send(this.ptr, change);
}
private static native void callback(long self, Callback<BufferController> cb);
public void callback(Callback<BufferController> cb) {
callback(this.ptr, cb);
}
private static native void free(long self);
@Override
protected void finalize() {

View file

@ -1,6 +1,7 @@
package mp.code;
import cz.adamh.utils.NativeUtils;
import mp.code.data.User;
import mp.code.exceptions.ConnectionException;
import mp.code.exceptions.ConnectionRemoteException;
@ -17,9 +18,9 @@ public class Client {
this.ptr = ptr;
}
private static native String get_url(long self);
public String getUrl() {
return get_url(this.ptr);
private static native User get_user(long self);
public User getUser() {
return get_user(this.ptr);
}
private static native Workspace join_workspace(long self, String id) throws ConnectionException;
@ -47,6 +48,11 @@ public class Client {
return list_workspaces(this.ptr, owned, invited);
}
private static native String[] active_workspaces(long self);
public String[] activeWorkspaces() {
return active_workspaces(this.ptr);
}
private static native boolean leave_workspace(long self, String id);
public boolean leaveWorkspace(String id) {
return leave_workspace(this.ptr, id);
@ -57,9 +63,9 @@ public class Client {
return Optional.ofNullable(get_workspace(this.ptr, workspace));
}
private static native void refresh_native(long self) throws ConnectionRemoteException;
private static native void refresh(long self) throws ConnectionRemoteException;
public void refresh() throws ConnectionRemoteException {
refresh_native(this.ptr);
refresh(this.ptr);
}
private static native void free(long self);

View file

@ -1,5 +1,6 @@
package mp.code;
import mp.code.data.Callback;
import mp.code.data.Cursor;
import mp.code.exceptions.ControllerException;
@ -27,6 +28,11 @@ public class CursorController {
send(this.ptr, cursor);
}
private static native void callback(long self, Callback<CursorController> cb);
public void callback(Callback<CursorController> cb) {
callback(this.ptr, cb);
}
private static native void free(long self);
@Override
protected void finalize() {

View file

@ -0,0 +1,6 @@
package mp.code.data;
@FunctionalInterface
public interface Callback<T> {
void invoke(T controller);
}

13
dist/java/src/mp/code/data/User.java vendored Normal file
View file

@ -0,0 +1,13 @@
package mp.code.data;
import java.util.UUID;
public class User {
public final UUID id;
public final String name;
public User(UUID id, String name) {
this.id = id;
this.name = name;
}
}

View file

@ -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, RT};
use super::{JExceptable, JObjectify, RT};
/// Connect using the given credentials to the default server, and return a [Client] to interact with it.
#[no_mangle]
@ -72,6 +72,20 @@ fn connect_internal(mut env: JNIEnv, config: Config) -> jobject {
}).jexcept(&mut env).as_raw()
}
/// Gets the current [crate::api::User].
#[no_mangle]
pub extern "system" fn Java_mp_code_Client_get_1user(
mut env: JNIEnv,
_class: JClass,
self_ptr: jlong
) -> jobject {
let client = unsafe { Box::leak(Box::from_raw(self_ptr as *mut Client)) };
client.user().clone()
.jobjectify(&mut env)
.jexcept(&mut env)
.as_raw()
}
/// Join a [Workspace] and return a pointer to it.
#[no_mangle]
pub extern "system" fn Java_mp_code_Client_join_1workspace<'local>(
@ -162,7 +176,26 @@ pub extern "system" fn Java_mp_code_Client_list_1workspaces<'local>(
let list = RT
.block_on(client.list_workspaces(owned != 0, invited != 0))
.jexcept(&mut env);
env.find_class("java/lang/String")
.and_then(|class| env.new_object_array(list.len() as i32, class, JObject::null()))
.inspect(|arr| {
for (idx, path) in list.iter().enumerate() {
env.new_string(path)
.and_then(|path| env.set_object_array_element(arr, idx as i32, path))
.jexcept(&mut env)
}
}).jexcept(&mut env).as_raw()
}
/// List available workspaces.
#[no_mangle]
pub extern "system" fn Java_mp_code_Client_active_1workspaces<'local>(
mut env: JNIEnv<'local>,
_class: JClass<'local>,
self_ptr: jlong
) -> jobjectArray {
let client = unsafe { Box::leak(Box::from_raw(self_ptr as *mut Client)) };
let list = client.active_workspaces();
env.find_class("java/lang/String")
.and_then(|class| env.new_object_array(list.len() as i32, class, JObject::null()))
.inspect(|arr| {

View file

@ -114,12 +114,29 @@ pub(crate) trait JObjectify<'local> {
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>, Self::Error> {
env.find_class("java/util/UUID").and_then(|class| {
let class = env.find_class("java/util/UUID")?;
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)])
})
}
}
impl<'local> JObjectify<'local> for crate::api::User {
type Error = jni::errors::Error;
fn jobjectify(self, env: &mut jni::JNIEnv<'local>) -> Result<jni::objects::JObject<'local>, Self::Error> {
let id_field = self.id.jobjectify(env)?;
let name_field = env.new_string(self.name)?;
let class = env.find_class("mp/code/data/User")?;
env.new_object(
&class,
"(Ljava/util/UUID;Ljava/lang/String;)V",
&[
jni::objects::JValueGen::Object(&id_field),
jni::objects::JValueGen::Object(&name_field)
]
)
}
}

View file

@ -285,7 +285,7 @@ impl Workspace {
self.0.filetree.iter()
.filter(|f| filter.map_or(true, |flt| {
if strict {
f.eq(flt)
f.as_str() == flt
} else {
f.starts_with(flt)
}