diff --git a/examples/tic-tac-toe-gui/src/main.rs b/examples/tic-tac-toe-gui/src/main.rs index 53db0ad..b13571a 100644 --- a/examples/tic-tac-toe-gui/src/main.rs +++ b/examples/tic-tac-toe-gui/src/main.rs @@ -7,9 +7,8 @@ use tokio::task; use tokio::sync::mpsc; use waku::{ - waku_new, Encoding, WakuEvent, LibwakuResponse, WakuContentTopic, - WakuMessage, WakuNodeConfig, WakuNodeHandle, Initialized, Running, - general::pubsubtopic::PubsubTopic, + general::pubsubtopic::PubsubTopic, waku_new, Encoding, Initialized, LibwakuResponse, Running, + WakuContentTopic, WakuEvent, WakuMessage, WakuNodeConfig, WakuNodeHandle, }; #[derive(Serialize, Deserialize, PartialEq, Debug, Copy, Clone)] @@ -29,7 +28,7 @@ struct TicTacToeApp { game_state: Arc>, waku: WakuNodeHandle, game_topic: PubsubTopic, - tx: mpsc::Sender, // Sender to send `msg` to main thread + tx: mpsc::Sender, // Sender to send `msg` to main thread player_role: Option, // Store the player's role (X or O) } @@ -51,7 +50,8 @@ impl TicTacToeApp { async fn start(self) -> TicTacToeApp { let tx_clone = self.tx.clone(); - let game_content_topic = WakuContentTopic::new("waku", "2", "tictactoegame", Encoding::Proto); + let game_content_topic = + WakuContentTopic::new("waku", "2", "tictactoegame", Encoding::Proto); let my_closure = move |response| { if let LibwakuResponse::Success(v) = response { @@ -78,13 +78,13 @@ impl TicTacToeApp { // Handle the error as needed, or just log and skip } } - }, + } WakuEvent::RelayTopicHealthChange(_evt) => { // dbg!("Relay topic change evt", evt); - }, + } WakuEvent::ConnectionChange(_evt) => { // dbg!("Conn change evt", evt); - }, + } WakuEvent::Unrecognized(err) => panic!("Unrecognized waku event: {:?}", err), _ => panic!("event case not expected"), }; @@ -92,13 +92,17 @@ impl TicTacToeApp { }; // Establish a closure that handles the incoming messages - self.waku.set_event_callback(my_closure).expect("set event call back working"); + self.waku + .set_event_callback(my_closure) + .expect("set event call back working"); // Start the waku node let waku = self.waku.start().await.expect("waku should start"); // Subscribe to desired topic using the relay protocol - waku.relay_subscribe(&self.game_topic).await.expect("waku should subscribe"); + waku.relay_subscribe(&self.game_topic) + .await + .expect("waku should subscribe"); // Example filter subscription. This is needed in edge nodes (resource-restricted devices) // Nodes usually use either relay or lightpush/filter protocols @@ -138,15 +142,13 @@ impl TicTacToeApp { let serialized_game_state = serde_json::to_string(game_state).unwrap(); let content_topic = WakuContentTopic::new("waku", "2", "tictactoegame", Encoding::Proto); - let message = WakuMessage::new( - &serialized_game_state, - content_topic, - 0, - Vec::new(), - false, - ); + let message = WakuMessage::new(&serialized_game_state, content_topic, 0, Vec::new(), false); - if let Ok(msg_hash) = self.waku.relay_publish_message(&message, &self.game_topic, None).await { + if let Ok(msg_hash) = self + .waku + .relay_publish_message(&message, &self.game_topic, None) + .await + { dbg!(format!("message hash published: {}", msg_hash)); } @@ -163,7 +165,6 @@ impl TicTacToeApp { fn make_move(&mut self, row: usize, col: usize) { if let Ok(mut game_state) = self.game_state.try_lock() { - if let Some(my_role) = self.player_role { if game_state.current_turn != my_role { return; // skip click if not my turn @@ -201,27 +202,31 @@ impl TicTacToeApp { fn check_winner(&self, game_state: &GameState) -> Option { // Check rows, columns, and diagonals for i in 0..3 { - if game_state.board[i][0] == game_state.board[i][1] && - game_state.board[i][1] == game_state.board[i][2] { + if game_state.board[i][0] == game_state.board[i][1] + && game_state.board[i][1] == game_state.board[i][2] + { if let Some(player) = game_state.board[i][0] { return Some(player); } } - if game_state.board[0][i] == game_state.board[1][i] && - game_state.board[1][i] == game_state.board[2][i] { + if game_state.board[0][i] == game_state.board[1][i] + && game_state.board[1][i] == game_state.board[2][i] + { if let Some(player) = game_state.board[0][i] { return Some(player); } } } - if game_state.board[0][0] == game_state.board[1][1] && - game_state.board[1][1] == game_state.board[2][2] { + if game_state.board[0][0] == game_state.board[1][1] + && game_state.board[1][1] == game_state.board[2][2] + { if let Some(player) = game_state.board[0][0] { return Some(player); } } - if game_state.board[0][2] == game_state.board[1][1] && - game_state.board[1][1] == game_state.board[2][0] { + if game_state.board[0][2] == game_state.board[1][1] + && game_state.board[1][1] == game_state.board[2][0] + { if let Some(player) = game_state.board[0][2] { return Some(player); } @@ -241,7 +246,6 @@ impl TicTacToeApp { impl eframe::App for TicTacToeApp { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { - // Request a repaint every second ctx.request_repaint_after(Duration::from_secs(1)); @@ -286,13 +290,16 @@ impl eframe::App for TicTacToeApp { Some(Player::O) => "O", None => "-", }; - } - else { + } else { label = "#"; } } - let button = ui.add(egui::Button::new(label).min_size(egui::vec2(cell_size, cell_size)).sense(egui::Sense::click())); + let button = ui.add( + egui::Button::new(label) + .min_size(egui::vec2(cell_size, cell_size)) + .sense(egui::Sense::click()), + ); if button.clicked() { self.make_move(row, col); @@ -384,13 +391,11 @@ async fn main() -> eframe::Result<()> { while let Some(msg) = rx.recv().await { // println!("MSG received: {}", msg); // Handle the received message, e.g., update the UI or game state - if let Ok(parsed_value) = serde_json::from_str::(&msg) - { - if let Ok(mut unclocked_game_state) = clone.lock(){ + if let Ok(parsed_value) = serde_json::from_str::(&msg) { + if let Ok(mut unclocked_game_state) = clone.lock() { *unclocked_game_state = parsed_value; } - } - else { + } else { eprintln!("Failed to parse JSON"); } } diff --git a/examples/toy-chat/src/main.rs b/examples/toy-chat/src/main.rs index 2872645..16ef060 100644 --- a/examples/toy-chat/src/main.rs +++ b/examples/toy-chat/src/main.rs @@ -1,19 +1,19 @@ mod protocol; use crate::protocol::{Chat2Message, TOY_CHAT_CONTENT_TOPIC}; -use tokio::task; +use chrono::Utc; use crossterm::{ event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode}, execute, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, }; use prost::Message; -use chrono::Utc; use std::io::Write; use std::os::unix::io::IntoRawFd; use std::sync::{Arc, RwLock}; -use std::{error::Error, io}; use std::time::Duration; +use std::{error::Error, io}; +use tokio::task; use tui::{ backend::{Backend, CrosstermBackend}, layout::{Constraint, Direction, Layout}, @@ -24,8 +24,8 @@ use tui::{ }; use unicode_width::UnicodeWidthStr; use waku::{ - general::pubsubtopic::PubsubTopic, general::Result, waku_new, Initialized, LibwakuResponse, Running, WakuEvent, - WakuMessage, WakuNodeConfig, WakuNodeHandle, + general::pubsubtopic::PubsubTopic, general::Result, waku_new, Initialized, LibwakuResponse, + Running, WakuEvent, WakuMessage, WakuNodeConfig, WakuNodeHandle, }; enum InputMode { @@ -61,19 +61,16 @@ impl App { max_message_size: Some("1024KiB".to_string()), relay_topics: vec![String::from(&pubsub_topic)], log_level: Some("FATAL"), // Supported: TRACE, DEBUG, INFO, NOTICE, WARN, ERROR or FATAL - keep_alive: Some(true), - // Discovery dns_discovery: Some(true), dns_discovery_url: Some("enrtree://AMOJVZX4V6EXP7NTJPMAYJYST2QP6AJXYW76IU6VGJS7UVSNDYZG4@boot.prod.status.nodes.status.im"), // discv5_discovery: Some(true), // discv5_udp_port: Some(9001), // discv5_enr_auto_update: Some(false), - ..Default::default() })).await?; - + Ok(App { input: String::new(), input_mode: InputMode::Normal, @@ -84,17 +81,15 @@ impl App { } async fn start_waku_node(self) -> Result> { - let shared_messages = Arc::clone(&self.messages); - self.waku.set_event_callback(move|response| { + self.waku.set_event_callback(move |response| { if let LibwakuResponse::Success(v) = response { - let event: WakuEvent = - serde_json::from_str(v.unwrap().as_str()).expect("failed parsing event in set_event_callback"); + let event: WakuEvent = serde_json::from_str(v.unwrap().as_str()) + .expect("failed parsing event in set_event_callback"); match event { WakuEvent::WakuMessage(evt) => { - if evt.waku_message.content_topic != TOY_CHAT_CONTENT_TOPIC { return; // skip the messages that don't belong to the toy chat } @@ -112,14 +107,14 @@ impl App { write!(out, "{e:?}").unwrap(); } } - }, + } WakuEvent::RelayTopicHealthChange(_evt) => { // dbg!("Relay topic change evt", evt); - }, + } WakuEvent::ConnectionChange(_evt) => { // dbg!("Conn change evt", evt); - }, - WakuEvent::NodeHealthChange(_evt) => {}, + } + WakuEvent::NodeHealthChange(_evt) => {} WakuEvent::Unrecognized(err) => eprintln!("Unrecognized waku event: {:?}", err), _ => eprintln!("event case not expected"), }; @@ -139,32 +134,37 @@ impl App { } impl App { - async fn retrieve_history(&mut self) { let one_day_in_secs = 60 * 60 * 24; let time_start = (Duration::from_secs(Utc::now().timestamp() as u64) - Duration::from_secs(one_day_in_secs)) - .as_nanos() as u64; + .as_nanos() as u64; let include_data = true; - let messages = self.waku.store_query(None, - vec![TOY_CHAT_CONTENT_TOPIC.clone()], - STORE_NODE, - include_data, - Some(time_start), - None, - None).await.unwrap(); + let messages = self + .waku + .store_query( + None, + vec![TOY_CHAT_CONTENT_TOPIC.clone()], + STORE_NODE, + include_data, + Some(time_start), + None, + None, + ) + .await + .unwrap(); let messages: Vec<_> = messages - .into_iter() - // we expect messages because the query was passed with include_data == true - .filter(|item| item.message.is_some()) - .map(|store_resp_msg| { - ::decode(store_resp_msg.message.unwrap().payload()) - .expect("Toy chat messages should be decodeable") - }) - .collect(); + .into_iter() + // we expect messages because the query was passed with include_data == true + .filter(|item| item.message.is_some()) + .map(|store_resp_msg| { + ::decode(store_resp_msg.message.unwrap().payload()) + .expect("Toy chat messages should be decodeable") + }) + .collect(); if !messages.is_empty() { *self.messages.write().unwrap() = messages; @@ -214,14 +214,18 @@ impl App { handle.block_on(async { // Assuming `self` is available in the current context let pubsub_topic = PubsubTopic::new(DEFAULT_PUBSUB_TOPIC); - if let Err(e) = self.waku.relay_publish_message( - &waku_message, - &pubsub_topic, - None, - ).await { - let mut out = std::io::stderr(); - write!(out, "{e:?}").unwrap(); - } + if let Err(e) = self + .waku + .relay_publish_message( + &waku_message, + &pubsub_topic, + None, + ) + .await + { + let mut out = std::io::stderr(); + write!(out, "{e:?}").unwrap(); + } }); }); } @@ -243,7 +247,10 @@ impl App { } async fn stop_app(self) { - self.waku.stop().await.expect("the node should stop properly"); + self.waku + .stop() + .await + .expect("the node should stop properly"); } } @@ -256,7 +263,9 @@ async fn main() -> std::result::Result<(), Box> { // Redirect stderr to /dev/null so nwaku discovery/LSQUIC logs don't corrupt the TUI let devnull = std::fs::OpenOptions::new().write(true).open("/dev/null")?; - unsafe { libc::dup2(devnull.into_raw_fd(), 2); } + unsafe { + libc::dup2(devnull.into_raw_fd(), 2); + } // setup terminal enable_raw_mode()?; diff --git a/waku-bindings/tests/node.rs b/waku-bindings/tests/node.rs index 8f8ef1e..b46a825 100644 --- a/waku-bindings/tests/node.rs +++ b/waku-bindings/tests/node.rs @@ -58,6 +58,9 @@ async fn test_echo_messages( WakuEvent::ConnectionChange(_evt) => { // dbg!("Conn change evt", evt); } + WakuEvent::NodeHealthChange(_evt) => { + // dbg!("Node health change evt", evt); + } WakuEvent::Unrecognized(err) => panic!("Unrecognized waku event: {:?}", err), _ => panic!("event case not expected"), }; diff --git a/waku-sys/build.rs b/waku-sys/build.rs index 89e1226..afb3084 100644 --- a/waku-sys/build.rs +++ b/waku-sys/build.rs @@ -105,10 +105,7 @@ fn generate_bindgen_code(project_dir: &Path) { let name_str = name.to_string_lossy(); if name_str.starts_with("librln_") && name_str.ends_with(".a") { let lib_name = name_str.trim_start_matches("lib").trim_end_matches(".a"); - println!( - "cargo:rustc-link-search=native={}", - nwaku_path.display() - ); + println!("cargo:rustc-link-search=native={}", nwaku_path.display()); println!("cargo:rustc-link-lib=static={}", lib_name); break; }