Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
LeuisKen committed Dec 14, 2024
1 parent af797fd commit b38a5b4
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 49 deletions.
10 changes: 10 additions & 0 deletions bridge/rusty_webf_sys/src/executing_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,16 @@ impl ExecutingContext {

}

impl Clone for ExecutingContext {
fn clone(&self) -> ExecutingContext {
ExecutingContext {
ptr: self.ptr,
method_pointer: self.method_pointer,
status: self.status,
}
}
}

impl Drop for ExecutingContext {
fn drop(&mut self) {
unsafe {
Expand Down
20 changes: 13 additions & 7 deletions bridge/rusty_webf_sys/src/frame/async_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,52 +23,58 @@ impl AsyncStorage {
unsafe { &*self.context }
}

pub fn get_item(&self, key: &str, callback: GetItemCallback, exception_state: &ExceptionState) {
pub fn get_item(&self, key: &str, exception_state: &ExceptionState) -> WebFNativeFuture<String> {
let key_string = NativeValue::new_string(key);
let future = WebFNativeFuture::<String>::new();
let future_clone = future.clone();
let general_callback: WebFNativeFunction = Box::new(move |argc, argv| {
if argc == 1 {
let error_string = unsafe { (*argv).clone() };
let error_string = error_string.to_string();
callback(Err(error_string));
future_clone.set_result(Err(error_string));
return NativeValue::new_null();
}
if argc == 2 {
let item_string = unsafe { (*argv.wrapping_add(1)).clone() };
if item_string.is_null() {
callback(Ok(None));
future_clone.set_result(Ok(None));
return NativeValue::new_null();
}
let item_string = item_string.to_string();
callback(Ok(Some(item_string)));
future_clone.set_result(Ok(Some(item_string)));
return NativeValue::new_null();
}
println!("Invalid argument count for async storage callback");
NativeValue::new_null()
});
self.context().webf_invoke_module_with_params_and_callback("AsyncStorage", "getItem", &key_string, general_callback, exception_state).unwrap();
future
}

pub fn set_item(&self, key: &str, value: &str, callback: SetItemCallback, exception_state: &ExceptionState) {
pub fn set_item(&self, key: &str, value: &str, exception_state: &ExceptionState) -> WebFNativeFuture<String> {
let key_string = NativeValue::new_string(key);
let value_string = NativeValue::new_string(value);
let params_vec = vec![key_string, value_string];
let params = NativeValue::new_list(params_vec);
let future = WebFNativeFuture::<String>::new();
let future_clone = future.clone();
let general_callback: WebFNativeFunction = Box::new(move |argc, argv| {
if argc == 1 {
let error_string = unsafe { (*argv).clone() };
let error_string = error_string.to_string();
callback(Err(error_string));
future_clone.set_result(Err(error_string));
return NativeValue::new_null();
}
if argc == 2 {
let result = unsafe { (*argv.wrapping_add(1)).clone() };
let result = result.to_string();
callback(Ok(Some(result)));
future_clone.set_result(Ok(Some(result)));
return NativeValue::new_null();
}
println!("Invalid argument count for async storage callback");
NativeValue::new_null()
});
self.context().webf_invoke_module_with_params_and_callback("AsyncStorage", "setItem", &params, general_callback, exception_state).unwrap();
future
}
}
2 changes: 2 additions & 0 deletions bridge/rusty_webf_sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ mod memory_utils;
pub mod native_value;
pub mod script_value_ref;
pub mod webf_event_listener;
pub mod webf_future;
pub mod webf_function;

pub use dom::*;
Expand All @@ -28,6 +29,7 @@ pub use executing_context::*;
pub use native_value::*;
pub use script_value_ref::*;
pub use webf_event_listener::*;
pub use webf_future::*;
pub use webf_function::*;

#[repr(C)]
Expand Down
59 changes: 59 additions & 0 deletions bridge/rusty_webf_sys/src/webf_future.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use std::future::Future;
use std::task::{Context, Poll, Waker};
use std::pin::Pin;
use std::sync::{Arc, Mutex};
use std::cell::RefCell;

pub struct WebFNativeFuture<T> {
inner: Arc<Mutex<Inner<T>>>,
}

struct Inner<T> {
waker: Option<Waker>,
result: Option<Result<Option<T>, String>>,
}

impl<T> WebFNativeFuture<T> {
pub fn new() -> WebFNativeFuture<T> {
WebFNativeFuture {
inner: Arc::new(Mutex::new(Inner {
waker: None,
result: None,
})),
}
}

pub fn set_result(&self, result: Result<Option<T>, String>) {
let mut inner = self.inner.lock().unwrap();
inner.result = Some(result);
if let Some(waker) = inner.waker.take() {
waker.wake();
}
}
}

impl<T> Future for WebFNativeFuture<T>
where
T: 'static,
{
type Output = Result<Option<T>, String>;

fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
let mut inner = self.inner.lock().unwrap();

if let Some(result) = inner.result.take() {
Poll::Ready(result)
} else {
inner.waker = Some(cx.waker().clone());
Poll::Pending
}
}
}

impl Clone for WebFNativeFuture<String> {
fn clone(&self) -> Self {
WebFNativeFuture {
inner: self.inner.clone(),
}
}
}
1 change: 1 addition & 0 deletions webf/example/rust_builder/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ crate-type = ["cdylib", "staticlib"]

[dependencies]
webf-sys = "0.16.0"
tokio = { version = "1", features = ["full"] }

[patch.crates-io]
webf-sys = { path = "../../../../bridge/rusty_webf_sys" }
50 changes: 8 additions & 42 deletions webf/example/rust_builder/rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::ffi::{c_void, CString};
use std::ffi::c_void;
use tokio::runtime;
use webf_sys::event::Event;
use webf_sys::executing_context::ExecutingContextRustMethods;
use webf_sys::{async_storage, element, initialize_webf_api, navigator, AddEventListenerOptions, EventMethods, EventTargetMethods, NativeValue, RustValue};
use webf_sys::{initialize_webf_api, AddEventListenerOptions, EventTargetMethods, RustValue};
use webf_sys::element::Element;
use webf_sys::node::NodeMethods;

Expand All @@ -14,17 +15,7 @@ pub extern "C" fn init_webf_app(handle: RustValue<ExecutingContextRustMethods>)
let navigator = context.navigator();

let ua_string = navigator.user_agent(&exception_state);
let platform = navigator.platform(&exception_state);
let language = navigator.language(&exception_state);
let app_name = navigator.app_name(&exception_state);
let app_version = navigator.app_version(&exception_state);
let hardware_concurrency = navigator.hardware_concurrency(&exception_state);
println!("User Agent: {}", ua_string);
println!("Platform: {}", platform);
println!("Language: {}", language);
println!("App Name: {}", app_name);
println!("App Version: {}", app_version);
println!("Hardware Concurrency: {}", hardware_concurrency);

let local_storage = context.local_storage();

Expand All @@ -46,41 +37,15 @@ pub extern "C" fn init_webf_app(handle: RustValue<ExecutingContextRustMethods>)

local_storage.clear(&exception_state);

let async_storage_1 = context.async_storage();

let async_storage_set_item_callback = Box::new(|value: Result<Option<String>, String>| {
match value {
Ok(value) => {
println!("Async Storage Set Item Success: {:?}", value);
},
Err(err) => {
println!("Async Storage Set Item Failed: {:?}", err);
}
}
});

async_storage_1.set_item("a", "b", async_storage_set_item_callback, &exception_state);

let async_storage_2 = context.async_storage();

let async_storage_get_item_callback = Box::new(|value: Result<Option<String>, String>| {
match value {
Ok(value) => {
println!("Async Storage Get Item Success: {:?}", value);
},
Err(err) => {
println!("Async Storage Get Item Failed: {:?}", err);
}
}
});

async_storage_2.get_item("a", async_storage_get_item_callback, &exception_state);
let async_storage = context.async_storage();
let exception_state = context.create_exception_state();
let _future = async_storage.get_item("a", &exception_state);

let timer_callback = Box::new(move || {
println!("Timer Callback");
});

context.set_interval_with_callback_and_timeout(timer_callback, 1000, &exception_state).unwrap();
context.set_timeout_with_callback_and_timeout(timer_callback, 1000, &exception_state).unwrap();

let click_event = document.create_event("custom_click", &exception_state).unwrap();
document.dispatch_event(&click_event, &exception_state);
Expand Down Expand Up @@ -163,5 +128,6 @@ pub extern "C" fn init_webf_app(handle: RustValue<ExecutingContextRustMethods>)
event_cleaner_element.add_event_listener("click", event_cleaner_handler, &event_listener_options, &exception_state).unwrap();

document.body().append_child(&event_cleaner_element.as_node(), &exception_state).unwrap();

std::ptr::null_mut()
}

0 comments on commit b38a5b4

Please sign in to comment.