Skip to content

Commit 5309aa6

Browse files
committed
WIP
1 parent 6dfa6d8 commit 5309aa6

File tree

2 files changed

+41
-61
lines changed

2 files changed

+41
-61
lines changed

src/main/rust/src/fs_monitor.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::{
1111
ptr,
1212
fs,
1313
os::raw::{c_char, c_void},
14-
sync::atomic::{AtomicBool, Ordering}
14+
sync::atomic::{AtomicBool, Ordering},
1515
};
1616
use dispatch2::ffi::{dispatch_object_t, dispatch_queue_t, DISPATCH_QUEUE_SERIAL, dispatch_queue_create};
1717
use core_foundation::{
@@ -75,8 +75,7 @@ impl NativeEventStream {
7575

7676
pub fn stop(&self) {
7777
if self.closed.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst).is_err() {
78-
// we weren't the first one to close it
79-
return;
78+
return; // The stream has already been closed
8079
}
8180
match self.stream {
8281
Some(stream) => unsafe{
@@ -94,7 +93,7 @@ impl NativeEventStream {
9493
}
9594

9695
struct ContextInfo {
97-
handler: Box<dyn Fn(&String, Kind)>
96+
handler: Box<dyn Fn(&String, Kind)>,
9897
}
9998

10099
const FLAGS : fse::FSEventStreamCreateFlags

src/main/rust/src/lib.rs

Lines changed: 38 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,76 @@
11
mod fs_monitor;
22

33
use jni::{Executor, JNIEnv};
4-
54
use jni::objects::{GlobalRef, JClass, JMethodID, JObject, JString, JValue};
6-
7-
use jni::sys::{jboolean, jlong, jint, jvalue, JNI_FALSE};
5+
use jni::sys::{jint, jlong};
86

97
use crate::fs_monitor::{Kind, NativeEventStream};
108

11-
struct Runnable2 {
12-
obj: GlobalRef,
13-
class: GlobalRef, // just making sure we don't lose reference to this Runnable class
9+
#[allow(dead_code)]
10+
struct HandlerExecutor {
1411
executor: Executor,
15-
root_path: String
12+
obj: GlobalRef,
13+
method: JMethodID,
14+
path: String,
15+
class: GlobalRef, // Ensure the reference to the class (of `obj`) isn't lost
1616
}
1717

18-
impl Runnable2 {
19-
pub fn new<'local>(env: &mut JNIEnv<'local>, root_path: String, local_recv: JObject<'local>) -> Result<Self, jni::errors::Error> {
20-
let recv = env.new_global_ref(local_recv)?;
21-
let class = env.new_global_ref(env.get_object_class(&recv)?)?;
18+
impl HandlerExecutor {
19+
pub fn new<'local>(env: &mut JNIEnv<'local>, path: String, obj: JObject<'local>) -> Result<Self, jni::errors::Error> {
2220
let executor = Executor::new(Into::into(env.get_java_vm()?));
21+
let obj = env.new_global_ref(obj)?;
22+
let class = env.new_global_ref(env.get_object_class(&obj)?)?;
23+
let method = env.get_method_id(
24+
&class, "handle", "(Ljava/lang/String;Ljava/lang/String;I)V")?;
2325

24-
Ok(Self {
25-
obj: recv,
26-
class,
27-
executor,
28-
root_path
29-
})
26+
Ok(Self { executor, obj, method, path, class })
3027
}
3128

32-
pub fn run2<'local>(&self, path: &String, kind: Kind) {
29+
pub fn execute<'local>(&self, path: &String, kind: Kind) {
3330
self.executor.with_attached(|env: &mut JNIEnv<'_>| -> Result<(), jni::errors::Error> {
34-
// let message = env.new_string(&path).unwrap();
35-
// eprintln!("Message: {:?}", &message.as_raw());
36-
// let class = env.find_class("java/nio/file/StandardWatchEventKinds").unwrap();
37-
// eprintln!("Class: {:?}", &class);
38-
// let field = env.get_static_field(class, "ENTRY_CREATE", "Ljava/nio/file/WatchEvent$Kind;").unwrap();
39-
// eprintln!("Field: {:?}", &field);
40-
41-
42-
env.call_method(
43-
self.obj.as_obj(),
44-
"handle",
45-
"(Ljava/lang/String;Ljava/lang/String;I)V",
46-
&[
47-
JValue::Object(&env.new_string(&self.root_path).unwrap()),
48-
JValue::Object(&env.new_string(&path).unwrap()),
49-
JValue::Int(kind as jint)]);
50-
51-
// "(Ljava/lang/String;Ljava/nio/file/WatchEvent$Kind;)V",
52-
// &[JValue::Object(&message), field.borrow()]);
53-
31+
unsafe {
32+
env.call_method_unchecked(
33+
self.obj.as_obj(),
34+
self.method,
35+
jni::signature::ReturnType::Primitive(jni::signature::Primitive::Void),
36+
&[
37+
JValue::from(&env.new_string(&self.path).unwrap()).as_jni(),
38+
JValue::from(&env.new_string(&path).unwrap()).as_jni(),
39+
JValue::from(kind as jint).as_jni()]
40+
)?;
41+
}
5442
Ok(())
55-
});
43+
}).unwrap();
5644
}
5745
}
5846

59-
6047
#[unsafe(no_mangle)]
6148
#[allow(unused_variables)]
6249
pub extern "system" fn Java_engineering_swat_watch_impl_mac_jni_FileSystemEvents_start<'local>(
6350
mut env: JNIEnv<'local>,
6451
class: JClass<'local>,
6552
path: JString<'local>,
66-
test: JObject<'local>
67-
) -> jlong {
68-
69-
let asdf: String = env.get_string(&path).expect("Should not fail to get string").into();
70-
71-
let g = Runnable2::new(&mut env, asdf.clone(), test).unwrap();
72-
// let h = move |path: String, flags: u32| g.run2(path, flags);
73-
let h = move |path: &String, kind: Kind| g.run2(path, kind);
74-
75-
let mut mon = NativeEventStream::new(
76-
asdf,
77-
h
78-
);
79-
53+
handler: JObject<'local>,
54+
) -> jlong
55+
{
56+
let path: String = env.get_string(&path).expect("Should not fail to get string").into();
57+
let handler_executor = HandlerExecutor::new(&mut env, path.clone(), handler).unwrap();
58+
let handler = move |path: &String, kind: Kind| handler_executor.execute(path, kind);
59+
let mut mon = NativeEventStream::new(path, handler);
8060
mon.start();
8161
Box::into_raw(Box::new(mon)) as jlong
8262
}
8363

8464
#[unsafe(no_mangle)]
8565
#[allow(unused_variables)]
8666
pub extern "system" fn Java_engineering_swat_watch_impl_mac_jni_FileSystemEvents_stop<'local>(
87-
mut env: JNIEnv<'local>,
67+
env: JNIEnv<'local>,
8868
class: JClass<'local>,
8969
stream: jlong,
90-
) {
70+
)
71+
{
9172
let mon_ptr = stream as *mut NativeEventStream;
9273
let mon = unsafe { Box::from_raw(mon_ptr) };
9374
mon.stop();
94-
// after this the mon will be released, as we took it back into the box
75+
// After this, the mon will be released, as it has been taken out of the box
9576
}

0 commit comments

Comments
 (0)