1  #![allow(dead_code)]
2  
3  use jni::{
4      errors::*,
5      objects::{GlobalRef, JValue},
6      sys::jint,
7      Executor, JNIEnv,
8  };
9  
10  /// A test example of a native-to-JNI proxy
11  #[derive(Clone)]
12  pub struct AtomicIntegerProxy {
13      exec: Executor,
14      obj: GlobalRef,
15  }
16  
17  impl AtomicIntegerProxy {
18      /// Creates a new instance of `AtomicIntegerProxy`
new(exec: Executor, init_value: jint) -> Result<Self>19      pub fn new(exec: Executor, init_value: jint) -> Result<Self> {
20          let obj = exec.with_attached(|env: &mut JNIEnv| {
21              let i = env.new_object(
22                  "java/util/concurrent/atomic/AtomicInteger",
23                  "(I)V",
24                  &[JValue::from(init_value)],
25              )?;
26              env.new_global_ref(i)
27          })?;
28          Ok(AtomicIntegerProxy { exec, obj })
29      }
30  
31      /// Gets a current value from java object
get(&mut self) -> Result<jint>32      pub fn get(&mut self) -> Result<jint> {
33          self.exec
34              .with_attached(|env| env.call_method(&self.obj, "get", "()I", &[])?.i())
35      }
36  
37      /// Increments a value of java object and then gets it
increment_and_get(&mut self) -> Result<jint>38      pub fn increment_and_get(&mut self) -> Result<jint> {
39          self.exec.with_attached(|env| {
40              env.call_method(&self.obj, "incrementAndGet", "()I", &[])?
41                  .i()
42          })
43      }
44  
45      /// Adds some value to the value of java object and then gets a resulting value
add_and_get(&mut self, delta: jint) -> Result<jint>46      pub fn add_and_get(&mut self, delta: jint) -> Result<jint> {
47          let delta = JValue::from(delta);
48          self.exec.with_attached(|env| {
49              env.call_method(&self.obj, "addAndGet", "(I)I", &[delta])?
50                  .i()
51          })
52      }
53  }
54