Skip to content

Instantly share code, notes, and snippets.

@anna-is-cute
Last active August 10, 2016 16:26
Show Gist options
  • Save anna-is-cute/24bfd02390093d34366544d979e49e08 to your computer and use it in GitHub Desktop.
Save anna-is-cute/24bfd02390093d34366544d979e49e08 to your computer and use it in GitHub Desktop.
fn generate_command_executor<'a, S: Into<&'a str>>(env: *mut JNIEnv, shim: jobject, fqcn: S) -> command_spec_CommandExecutor {
let fqcn = fqcn.into();
let jni = get_jni(env, shim);
let fqcn_java = rust_string_to_java_string(env, fqcn);
let object = java_method!(env, jni.object, "generateCommandExecutor", "(Ljava/lang/String;)Lorg/spongepowered/api/command/spec/CommandExecutor;", CallObjectMethodA, fqcn_java);
unsafe { command_spec_CommandExecutor::from(env, object) }
}
#[allow(non_snake_case)]
#[no_mangle]
pub extern fn Java_me_kyleclemens_spongejni_SpongeJNIShim_init(env: *mut JNIEnv, this: jobject) -> jboolean {
println!("Hello from Rust!");
let genv = unwrap_env!(env);
let jni = get_jni(env, this);
let game = get_game(env, this);
println!("Sneakily generating a command...");
let executor = generate_command_executor(
env,
this,
"me.kyleclemens.spongejni.rust.generated.HelloCommandExecutor"
);
println!("{:#?}", executor);
println!("Sneakily registering said command...");
let command = command_spec_CommandSpec::builder(env)
.executor(executor)
.build();
println!("{:#?}", command);
let list = unsafe {
let string_class = (genv.FindClass)(env, CString::new("java/lang/String").unwrap().as_ptr());
let array = (genv.NewObjectArray)(env, 1, string_class, std::ptr::null_mut());
(genv.SetObjectArrayElement)(env, array, 0, rust_string_to_java_string(env, "rusty"));
let ret = static_java_method!(env, "java/util/Arrays", "asList", "([Ljava/lang/Object;)Ljava/util/List;", CallStaticObjectMethodA, array);
(genv.DeleteLocalRef)(env, string_class);
ret
};
let callable = unsafe { command_CommandCallable::from(env, command.object) };
game.get_command_manager().register_1(jni.object, callable, list);
return 1;
}
#[allow(non_snake_case)]
#[no_mangle]
pub extern fn Java_me_kyleclemens_spongejni_rust_generated_HelloCommandExecutor_execute(env: *mut JNIEnv, this: jobject, src: jobject, args: jobject) -> jobject {
// This uses the static from method, which is inherently unsafe (no checks – can crash JVM)
unsafe {
// Convert the src jobject to a CommandSource
let src = command_CommandSource::from(env, src);
// Convert the args jobject to a CommandContext
let args = command_args_CommandContext::from(env, args);
// Wrap the src jobject in a MessageReceiver struct
let receiver = text_channel_MessageReceiver::from(env, src.object);
// Send a message to the receiver
receiver.send_message(
// Convert LiteralText to Text (generated code has a hard time with inheritance, interfaces, etc.)
text_Text::from(
// Create some new text to send to the receiver
env, text_Text::of_1(env,
// Convert our Rust string into a Java string for the method
rust_string_to_java_string(env,
// Create our string to send
&format!(
"Hello, {}!",
// Convert the Java name String to Rust
java_string_to_rust_string(env, src.get_name())
)
)
// Get the jobject from the Text struct for wrapping
).object
)
);
// Return success
command_CommandResult::success(env).object
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment