From e0340a71b6ed7d5db96ca42cc5b0bae165c5633c Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Sun, 10 Nov 2024 10:22:30 +0700 Subject: [PATCH] test --- examples/tic-tac-toe-gui/src/main.rs | 76 ++++++++++++++-------------- examples/tic-tac-toe/src/main.rs | 2 +- waku-bindings/src/node/events.rs | 55 ++++++++++++++++++-- 3 files changed, 89 insertions(+), 44 deletions(-) diff --git a/examples/tic-tac-toe-gui/src/main.rs b/examples/tic-tac-toe-gui/src/main.rs index 86b0003..ff8b538 100644 --- a/examples/tic-tac-toe-gui/src/main.rs +++ b/examples/tic-tac-toe-gui/src/main.rs @@ -1,18 +1,16 @@ use eframe::egui; use serde::{Deserialize, Serialize}; -use tokio::sync::mpsc; -use std::sync::Arc; -use tokio::sync::Mutex; -use std::str::from_utf8; -use std::time::SystemTime; use std::cell::OnceCell; +use std::str::from_utf8; +use std::sync::Arc; +use std::sync::Mutex; +use std::time::SystemTime; +use tokio::sync::mpsc; use waku::{ - waku_new, Event, WakuNodeConfig, - LibwakuResponse, Multiaddr, Running, WakuNodeHandle, - Initialized, WakuContentTopic, WakuMessage, Encoding, - WakuNodeContext, + waku_new, Encoding, Event, Initialized, LibwakuResponse, Multiaddr, Running, WakuContentTopic, + WakuMessage, WakuNodeConfig, WakuNodeContext, WakuNodeHandle, }; - +use waku_sys::waku_setup; #[derive(Serialize, Deserialize, PartialEq, Copy, Clone)] enum Player { X, @@ -42,9 +40,11 @@ struct TicTacToeApp { } impl TicTacToeApp { - fn new(waku: WakuNodeHandle, - game_topic: &'static str, - tx: Arc>>,) -> Self { + fn new( + waku: WakuNodeHandle, + game_topic: &'static str, + tx: Arc>>, + ) -> Self { Self { game_state: Arc::new(Mutex::new(GameState { board: [[None; 3]; 3], @@ -76,8 +76,8 @@ impl TicTacToeApp { // let mut cloned = Arc::clone(&self.val); let tx_clone = self.tx.clone(); - // Establish a closure that handles the incoming messages - self.waku.ctx.waku_set_event_callback(move |response| { + + let my_closure = move |response| { // if let Ok(mut tx) = tx_clone.try_lock() { // // Lock succeeded, proceed to send the message // if tx.try_send(msg.to_string()).is_err() { @@ -86,20 +86,19 @@ impl TicTacToeApp { // } else { // eprintln!("Failed to acquire lock on tx_clone"); // } - // if let Ok(mut aa) = cloned.try_lock() { + // if let Ok(mut aa) = cloned.try_lock() { - // } - - // match cloned.lock() { - // Ok(mut data) => { - // *data = "Modified Value".to_string(); - // println!("Thread updated value to: {}", data); - // }, - // Err(e) => { - // eprintln!("Failed to lock the mutex in thread: {}", e); - // } - // } + // } + // match cloned.lock() { + // Ok(mut data) => { + // *data = "Modified Value".to_string(); + // println!("Thread updated value to: {}", data); + // }, + // Err(e) => { + // eprintln!("Failed to lock the mutex in thread: {}", e); + // } + // } if let LibwakuResponse::Success(v) = response { let event: Event = @@ -119,14 +118,15 @@ impl TicTacToeApp { // Send the message to the main thread if let Ok(mut tx) = tx_clone.try_lock() { - // Lock succeeded, proceed to send the message - if tx.try_send(msg.to_string()).is_err() { + // Lock succeeded, proceed to send the message + if tx.blocking_send(msg.to_string()).is_err() { eprintln!("Failed to send message to async task"); + } else { + eprintln!("Sent!!!!"); } } else { eprintln!("Failed to acquire lock on tx_clone"); } - // Deserialize the JSON into the GameState struct // Lock the game_state and update it // match serde_json::from_str::(msg) { @@ -161,11 +161,14 @@ impl TicTacToeApp { _ => panic!("event case not expected"), }; } - }); - + }; + + // Establish a closure that handles the incoming messages + self.waku.ctx.waku_set_event_callback(my_closure); + // Subscribe to desired topic self.waku.relay_subscribe(&self.game_topic.to_string()).expect("waku should subscribe"); - + // Connect to hard-coded node let target_node_multi_addr = "/ip4/24.144.78.119/tcp/30303/p2p/16Uiu2HAm3xVDaz6SRJ6kErwC21zBJEZjavVXg7VSkoWzaV1aMA3F" @@ -176,7 +179,6 @@ impl TicTacToeApp { } fn send_game_state(&self, game_state: &GameState) { - let serialized_game_state = serde_json::to_string(game_state).unwrap(); let content_topic = WakuContentTopic::new("waku", "2", "tictactoegame", Encoding::Proto); @@ -328,7 +330,8 @@ impl eframe::App for TicTacToeApp { } } -fn main() -> eframe::Result<()> { +#[tokio::main] +async fn main() -> eframe::Result<()> { let (tx, mut rx) = mpsc::channel::(3200); // Channel to communicate between threads // Create a Waku instance @@ -356,9 +359,6 @@ fn main() -> eframe::Result<()> { // Listen for messages in the main thread tokio::spawn(async move { - unsafe { - waku_sys::waku_setup(); - } while let Some(msg) = rx.recv().await { println!("Main thread received: {}", msg); // Handle the received message, e.g., update the UI or game state diff --git a/examples/tic-tac-toe/src/main.rs b/examples/tic-tac-toe/src/main.rs index e401a86..6ffa0cb 100644 --- a/examples/tic-tac-toe/src/main.rs +++ b/examples/tic-tac-toe/src/main.rs @@ -212,7 +212,7 @@ async fn main() { let _ = tokio::join!(setter, reader); // Establish a closure that handles the incoming messages - waku.set_event_callback(&|response| { + waku.set_event_callback(|response| { if let LibwakuResponse::Success(v) = response { let event: Event = serde_json::from_str(v.unwrap().as_str()).expect("Parsing event to succeed"); diff --git a/waku-bindings/src/node/events.rs b/waku-bindings/src/node/events.rs index 47d114d..6095477 100644 --- a/waku-bindings/src/node/events.rs +++ b/waku-bindings/src/node/events.rs @@ -5,13 +5,19 @@ //! When an event is emitted, this callback will be triggered receiving an [`Event`] // std -use std::ffi::c_void; +use std::ffi::{c_char, c_int, c_void, CStr}; // crates use serde::{Deserialize, Serialize}; // internal use crate::general::WakuMessage; +use std::{slice, str}; + use crate::utils::{get_trampoline, LibwakuResponse}; use crate::MessageHash; +use std::ops::Deref; +use std::sync::Mutex; +// crates +use once_cell::sync::Lazy; pub struct WakuNodeContext { pub obj_ptr: *mut c_void, @@ -40,14 +46,53 @@ pub struct WakuMessageEvent { pub waku_message: WakuMessage, } +#[allow(clippy::type_complexity)] +static CALLBACK: Lazy>> = + Lazy::new(|| Mutex::new(Box::new(|_| {}))); + +/// Register global callback +fn set_callback(f: F) { + *CALLBACK.lock().unwrap() = Box::new(f); +} + +unsafe extern "C" fn callback( + ret_code: ::std::os::raw::c_int, + data: *const ::std::os::raw::c_char, + data_len: usize, + user_data: *mut ::std::os::raw::c_void, +) { + let response = if data.is_null() { + "" + } else { + str::from_utf8(slice::from_raw_parts(data as *mut u8, data_len)) + .expect("could not retrieve response") + }; + + let result = LibwakuResponse::try_from((ret_code as u32, response)) + .expect("invalid response obtained from libwaku"); + + (CALLBACK + .deref() + .lock() + .expect("Access to the shared callback") + .as_mut())(result); +} + impl WakuNodeContext { /// Register callback to act as event handler and receive application events, /// which are used to react to asynchronous events in Waku - pub fn waku_set_event_callback(&self, mut closure: F) { + pub fn waku_set_event_callback( + &self, + mut closure: F, + ) { + set_callback(closure); unsafe { - let cb = get_trampoline(&closure); - waku_sys::waku_set_event_callback(self.obj_ptr, cb, &mut closure as *mut _ as *mut c_void) - }; + waku_sys::waku_set_event_callback( + self.obj_ptr, + Some(callback), + callback as *mut c_void, + ); + } } }