-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuffer.rs
More file actions
108 lines (91 loc) · 3.39 KB
/
Copy pathbuffer.rs
File metadata and controls
108 lines (91 loc) · 3.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use jni_toolbox::jni;
use crate::{
errors::ControllerError,
prelude::*
};
/// Get the name of the buffer.
#[jni(package = "mp.code", class = "BufferController")]
fn path(controller: &mut CodempBufferController) -> String {
controller.path().to_string()
}
/// Get the [WorkspaceIdentifier] of the workspace that contains this buffer.
#[jni(package = "mp.code", class = "BufferController")]
fn workspace_id(controller: &mut CodempBufferController) -> CodempWorkspaceIdentifier {
controller.workspace_id().clone()
}
/// Get the contents of the buffers.
#[jni(package = "mp.code", class = "BufferController")]
fn content(controller: &mut CodempBufferController) -> Result<String, ControllerError> {
super::tokio().block_on(controller.content())
}
/// Try to fetch a [TextChange], or return null if there's nothing.
#[jni(package = "mp.code", class = "BufferController")]
fn try_recv(controller: &mut CodempBufferController) -> Result<Option<CodempBufferUpdate>, ControllerError> {
super::tokio().block_on(controller.try_recv())
}
/// Block until it receives a [TextChange].
#[jni(package = "mp.code", class = "BufferController")]
fn recv(controller: &mut CodempBufferController) -> Result<CodempBufferUpdate, ControllerError> {
super::tokio().block_on(controller.recv())
}
/// Send a [TextChange] to the server.
#[jni(package = "mp.code", class = "BufferController")]
fn send(controller: &mut CodempBufferController, change: CodempTextChange) -> Result<(), ControllerError> {
controller.send(change)
}
/// Register a callback for buffer changes.
#[jni(package = "mp.code", class = "BufferController")]
fn callback<'local>(
env: &mut jni::Env<'local>,
controller: &mut CodempBufferController,
cb: jni::objects::JObject<'local>,
) -> Result<(), jni::errors::Error> {
if cb.is_null() {
return Err(jni::errors::Error::NullPtr(
"null pointer to buffer callback",
));
}
let cb_ref = env.new_global_ref(cb)?;
let jvm = env.get_java_vm()?;
controller.callback(move |controller: CodempBufferController| {
let result: Result<(), jni::errors::Error> = jvm.attach_current_thread(|env| {
env.with_local_frame(5, |env| {
use jni_toolbox::IntoJavaObject;
let jcontroller = controller.into_java_object(env)?;
env.call_method(
&cb_ref,
jni::jni_str!("accept"),
jni::jni_sig!((buf: java.lang.Object) -> ()),
&[jni::objects::JValue::Object(&jcontroller)],
)?;
Ok::<(), jni::errors::Error>(())
})?;
Ok(())
});
if let Err(e) = result {
tracing::error!("error invoking buffer callback: {e}");
}
});
Ok(())
}
/// Clear the callback for buffer changes.
#[jni(package = "mp.code", class = "BufferController")]
fn clear_callback(controller: &mut CodempBufferController) {
controller.clear_callback()
}
/// Block until there is a new value available.
#[jni(package = "mp.code", class = "BufferController")]
fn poll(controller: &mut CodempBufferController) -> Result<(), ControllerError> {
super::tokio().block_on(controller.poll())
}
/// Acknowledge that a change has been correctly applied.
#[jni(package = "mp.code", class = "BufferController")]
fn ack(controller: &mut CodempBufferController, version: Vec<i64>) {
controller.ack(version)
}
/// Called by the Java GC to drop a [crate::buffer::Controller].
#[allow(unsafe_code)]
#[jni(package = "mp.code", class = "BufferController")]
fn free(input: jni::sys::jlong) {
let _ = unsafe { Box::from_raw(input as *mut CodempBufferController) };
}