temporary changes - some interesting

This commit is contained in:
Ivan Folgueira Bande 2024-11-09 16:14:28 +07:00
parent d828948e85
commit 434b5c1e73
No known key found for this signature in database
GPG Key ID: 3C117481F89E24A7
11 changed files with 563 additions and 104 deletions

View File

@ -0,0 +1,16 @@
[package]
name = "tic-tac-toe-gui"
version = "0.1.0"
edition = "2021"
[dependencies]
waku = { path = "../../waku-bindings", package = "waku-bindings" }
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
ark-std = "0.4"
ctrlc = "3.2.4"
tokio = { version = "1", features = ["full"] }
tokio-util = "0.6" # for utility functions if needed
egui = "0.22"
eframe = "0.22"

View File

@ -0,0 +1,366 @@
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 waku::{
waku_new, Event, WakuNodeConfig,
LibwakuResponse, Multiaddr, Running, WakuNodeHandle,
Initialized, WakuContentTopic, WakuMessage, Encoding,
WakuNodeContext,
};
#[derive(Serialize, Deserialize, PartialEq, Copy, Clone)]
enum Player {
X,
O,
}
#[derive(Serialize, Deserialize, Clone)]
struct GameState {
board: [[Option<Player>; 3]; 3],
current_turn: Player,
moves_left: usize,
}
#[derive(Clone)]
struct MoveMessage {
row: usize,
col: usize,
player: Player,
}
struct TicTacToeApp {
game_state: Arc<Mutex<GameState>>,
val: Arc<Mutex<String>>,
waku: WakuNodeHandle,
game_topic: &'static str,
tx: Arc<Mutex<mpsc::Sender<String>>>, // Sender to send `msg` to main thread
}
impl TicTacToeApp {
fn new(waku: WakuNodeHandle,
game_topic: &'static str,
tx: Arc<Mutex<mpsc::Sender<String>>>,) -> Self {
Self {
game_state: Arc::new(Mutex::new(GameState {
board: [[None; 3]; 3],
current_turn: Player::X,
moves_left: 9,
})),
val: Arc::new(Mutex::new("".to_string())),
waku,
game_topic,
tx: tx,
}
}
fn start(&mut self) {
// Start the waku node
self.waku.start().expect("waku should start");
// let default_pubsub_topic = Arc::new(Mutex::new("".to_string()));
// let shared_data_clone = Arc::clone(&default_pubsub_topic);
// // Establish a closure that handles the incoming messages
// self.waku.ctx.waku_set_event_callback(|response| {
// let mut data = shared_data_clone.lock().unwrap();
// *data = "Updated from another thread".to_string(); // Write access
// println!("funciona ?");
let mut cloned = Arc::clone(&self.val);
// Establish a closure that handles the incoming messages
self.waku.ctx.waku_set_event_callback(|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() {
// eprintln!("Failed to send message to async task");
// }
// } else {
// eprintln!("Failed to acquire lock on tx_clone");
// }
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);
// }
// }
if let LibwakuResponse::Success(v) = response {
let event: Event =
serde_json::from_str(v.unwrap().as_str()).expect("Parsing event to succeed");
// let mut game_state = self.game_state.lock().unwrap();
match event {
Event::WakuMessage(evt) => {
// println!("WakuMessage event received: {:?}", evt.waku_message);
let message = evt.waku_message;
let payload = message.payload.to_vec().clone();
match from_utf8(&payload) {
Ok(msg) => {
println!("::::::::::::::::::::::::::::::::::::::::::::::::::::");
println!("Message Received: {}", msg);
println!("::::::::::::::::::::::::::::::::::::::::::::::::::::");
// 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() {
// eprintln!("Failed to send message to async task");
// }
// } 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::<GameState>(msg) {
// Ok(parsed_value) => {
// // Handle the parsed value here
// // self.game_state = parsed_value;
// println!("Parsed correctly");
// }
// Err(e) => {
// eprintln!("Failed to parse JSON: {}", e);
// // Handle the error as needed, such as retrying, defaulting, etc.
// }
// }
// *game_state = serde_json::from_str(msg).expect("Failed to deserialize JSON");
// let tx_inner = tx_cloned.clone();
// let msg_inner = msg.to_string();
// tokio::spawn(async move {
// println!("do nothing");
// if tx_inner.send(msg_inner.to_string()).await.is_err() {
// eprintln!("Failed to send message");
// }
// });
}
Err(e) => {
eprintln!("Failed to decode payload as UTF-8: {}", e);
// Handle the error as needed, or just log and skip
}
}
}
Event::Unrecognized(err) => panic!("Unrecognized waku event: {:?}", err),
_ => panic!("event case not expected"),
};
}
});
// 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"
.parse::<Multiaddr>().expect("parse multiaddress");
self.waku.connect(&target_node_multi_addr, None)
.expect("waku should connect to other node");
}
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);
let message = WakuMessage::new(
&serialized_game_state,
content_topic,
0,
SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_millis()
.try_into()
.unwrap(),
Vec::new(),
false,
);
// let waku_handle = self.waku.lock().unwrap();
self.waku.relay_publish_message(&message, &self.game_topic.to_string(), None)
.expect("Failed to send message");
}
fn make_move(&mut self, row: usize, col: usize) {
if let Ok(mut game_state) = self.game_state.try_lock() {
if (*game_state).board[row][col].is_none() && (*game_state).moves_left > 0 {
(*game_state).board[row][col] = Some((*game_state).current_turn);
(*game_state).moves_left -= 1;
if let Some(winner) = self.check_winner(&game_state) {
(*game_state).current_turn = winner;
} else {
(*game_state).current_turn = match (*game_state).current_turn {
Player::X => Player::O,
Player::O => Player::X,
};
}
self.send_game_state(&game_state); // Send updated state after a move
}
}
}
fn check_winner(&self, game_state: &GameState) -> Option<Player> {
// 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 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 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 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 let Some(player) = game_state.board[0][2] {
return Some(player);
}
}
None
}
fn reset_game(&mut self) {
self.game_state = Arc::new(Mutex::new(GameState {
board: [[None; 3]; 3],
current_turn: Player::X,
moves_left: 9,
}));
}
}
impl eframe::App for TicTacToeApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("Tic-Tac-Toe");
let text_size = 32.0;
let board_size = ui.available_size();
let cell_size = board_size.x / 4.0;
ui.horizontal(|ui| {
for row in 0..3 {
ui.vertical(|ui| {
for col in 0..3 {
let label;
{
if let Ok(game_state) = self.game_state.try_lock() {
label = match game_state.board[row][col] {
Some(Player::X) => "X",
Some(Player::O) => "O",
None => "-",
};
}
else {
label = "#";
}
}
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);
}
}
});
if row < 2 {
ui.add_space(4.0);
}
}
});
if let Ok(game_state) = self.game_state.try_lock() {
if let Some(winner) = self.check_winner(&game_state) {
ui.label(format!(
"Player {} wins!",
match winner {
Player::X => "X",
Player::O => "O",
}
));
} else if game_state.moves_left == 0 {
ui.label("It's a tie!");
} else {
ui.label(format!(
"Player {}'s turn",
match game_state.current_turn {
Player::X => "X",
Player::O => "O",
}
));
}
}
if ui.add(egui::Button::new("Restart Game")).clicked() {
self.reset_game();
}
});
}
}
fn main() -> eframe::Result<()> {
let (tx, mut rx) = mpsc::channel::<String>(3200); // Channel to communicate between threads
// Create a Waku instance
let waku = waku_new(Some(WakuNodeConfig {
port: Some(60010),
cluster_id: Some(16),
log_level: Some("DEBUG"), // Supported: TRACE, DEBUG, INFO, NOTICE, WARN, ERROR or FATAL
..Default::default()
}))
.expect("should instantiate");
// Initialize Waku
let game_topic = "/waku/2/rs/16/64";
let mut app = TicTacToeApp::new(waku, game_topic, Arc::new(Mutex::new(tx)));
app.start();
eframe::run_native(
"Tic-Tac-Toe Multiplayer via Waku",
eframe::NativeOptions {
initial_window_size: Some(egui::vec2(400.0, 400.0)),
..Default::default()
},
Box::new(|_cc| Box::new(app)),
)?;
// Listen for messages in the main thread
tokio::spawn(async move {
while let Some(msg) = rx.recv().await {
println!("Main thread received: {}", msg);
// Handle the received message, e.g., update the UI or game state
}
});
Ok(())
}

View File

@ -1,5 +1,16 @@
extern crate termcolor;
use std::sync::mpsc; // For standard channels
use std::thread;
use tokio::sync::mpsc as tokio_mpsc; // For tokio's asynchronous channels
use tokio::io::{self, AsyncBufReadExt}; // For async I/O
use tokio::time::{sleep, Duration};
use tokio::task::LocalSet;
use tokio::runtime::Builder;
use tokio::sync::OnceCell;
use std::sync::{Arc, Mutex};
use std::io::Write;
use std::str::from_utf8;
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
@ -18,20 +29,20 @@ fn greeting() {
)
}
fn print_player(player: &char) {
fn print_player(current_player: &char) {
let mut stdout = StandardStream::stdout(ColorChoice::Always);
if player == &'X' {
if current_player == &'X' {
stdout
.set_color(ColorSpec::new().set_fg(Some(Color::Blue)))
.unwrap();
} else if player == &'O' {
} else if current_player == &'O' {
stdout
.set_color(ColorSpec::new().set_fg(Some(Color::Green)))
.unwrap();
}
write!(&mut stdout, "{}", player).unwrap();
write!(&mut stdout, "{}", current_player).unwrap();
stdout.reset().unwrap();
}
@ -53,40 +64,68 @@ fn draw(board: &[char]) {
println!("-------------");
}
fn ask_user(board: &mut [char], player: char) {
loop {
print!("Player '");
print_player(&player);
println!("', enter a number: ");
fn ask_game_name_to_user(game_name: &mut String) {
println!("Indicate the game name (arbitrary word)");
let mut input = String::new();
if std::io::stdin().read_line(&mut input).is_err() {
println!("Couldn't read line! Try again.");
continue;
let mut input = String::new();
if std::io::stdin().read_line(&mut input).is_err() {
println!("Couldn't read line! Try again.");
}
if let Ok(val) = input.trim().parse::<String>() {
*game_name = val;
} else {
println!("Only chars are allowed.");
}
}
fn ask_role_to_user(role: &mut char) {
println!("Select your role, X or O:");
let mut input = String::new();
if std::io::stdin().read_line(&mut input).is_err() {
println!("Couldn't read line! Try again.");
}
if let Ok(val) = input.trim().parse::<char>() {
if val != 'X' && val != 'O' {
println!("The user role must be either X or O.");
return;
}
if let Ok(number) = input.trim().parse::<usize>() {
if number < 1 || number > 9 {
println!("The field number must be between 1 and 9.");
continue;
}
*role = val;
} else {
println!("Only chars are allowed.");
}
}
let number = number - 1;
fn ask_user(board: &mut [char], current_player: char) {
print!("Player '");
print_player(&current_player);
println!("', enter a number: ");
if board[number] == 'X' || board[number] == 'O' {
print!("This field is already taken by '");
print_player(&board[number]);
println!("'.");
continue;
}
let mut input = String::new();
if std::io::stdin().read_line(&mut input).is_err() {
println!("Couldn't read line! Try again.");
return;
}
board[number] = player;
break;
} else {
println!("Only numbers are allowed.");
continue;
if let Ok(number) = input.trim().parse::<usize>() {
if number < 1 || number > 9 {
println!("The field number must be between 1 and 9.");
}
let number = number - 1;
if board[number] == 'X' || board[number] == 'O' {
print!("This field is already taken by '");
print_player(&board[number]);
println!("'.");
}
board[number] = current_player;
} else {
println!("Only numbers are allowed.");
}
}
@ -119,21 +158,14 @@ fn is_over(board: &[char]) -> bool {
// Return true if the game should end.
// false otherwise
fn game_logic(player: &mut char, board: &mut [char],
fn game_logic(current_player: &mut char, board: &mut [char],
topic: &str, waku: &WakuNodeHandle<Running>) -> bool {
// Ask for user input
ask_user(board, *player);
let board_string: String = board.iter().collect();
let board_str_slice: &str = &board_string;
let _ = waku.relay_publish_txt(topic, &board_str_slice, "tic-tac-toe-example", None);
// Check if a player won
if has_won(&board) {
draw(&board);
print!("Player '");
print_player(&player);
print_player(&current_player);
println!("' won! \\(^.^)/");
return true;
}
@ -145,20 +177,26 @@ fn game_logic(player: &mut char, board: &mut [char],
return true;
}
// Switch player
*player = if *player == 'X' { 'O' } else { 'X' };
return false;
}
fn main() {
#[tokio::main]
async fn main() {
// Create a channel for communication
let buffer_size = 256;
// let (tx, mut rx) = tokio_mpsc::channel(buffer_size);
let mut board = ['1', '2', '3', '4', '5', '6', '7', '8', '9'];
let mut player = 'X';
let topic = "/waku/2/rs/16/64";
let mut current_player = 'X';
let mut my_role = 'X'; // Keeps track of my role, X or O.
let mut game_name = "anonymous".to_string();
let topic = "/waku/2/rs/16/64".to_string();
// Create a Waku instance
let waku = waku_new(Some(WakuNodeConfig {
port: Some(60010),
cluster_id: Some(16),
log_level: Some("ERROR"), // Supported: TRACE, DEBUG, INFO, NOTICE, WARN, ERROR or FATAL
..Default::default()
}))
.expect("should instantiate");
@ -167,9 +205,12 @@ fn main() {
// println!("Ctrl+C detected. Exiting gracefully...");
// // waku.stop();
// }).expect("Error setting Ctrl+C handler");
let waku = waku.start().expect("waku should start");
// let tx_cloned = tx.clone();
// Wait for tasks to complete
let _ = tokio::join!(setter, reader);
// Establish a closure that handles the incoming messages
waku.set_event_callback(&|response| {
if let LibwakuResponse::Success(v) = response {
@ -180,14 +221,21 @@ fn main() {
Event::WakuMessage(evt) => {
println!("WakuMessage event received: {:?}", evt.waku_message);
let message = evt.waku_message;
let payload = message.payload.to_vec();
let payload = message.payload.to_vec().clone();
match from_utf8(&payload) {
Ok(msg) => {
println!("::::::::::::::::::::::::::::::::::::::::::::::::::::");
println!("Message Received: {}", msg);
println!("::::::::::::::::::::::::::::::::::::::::::::::::::::");
// game_logic(&mut player, &mut board, topic, &waku);
// let tx_inner = tx_cloned.clone();
let msg_inner = msg.to_string();
// tokio::spawn(async move {
// println!("do nothing");
// if tx_inner.send(msg_inner.to_string()).await.is_err() {
// eprintln!("Failed to send message");
// }
// });
}
Err(e) => {
eprintln!("Failed to decode payload as UTF-8: {}", e);
@ -203,8 +251,11 @@ fn main() {
waku.relay_subscribe(&topic).expect("waku should subscribe");
// let target_node_multi_addr =
// "/dns4/store-01.do-ams3.status.staging.status.im/tcp/30303/p2p/16Uiu2HAm3xVDaz6SRJ6kErwC21zBJEZjavVXg7VSkoWzaV1aMA3F"
// .parse::<Multiaddr>().expect("parse multiaddress");
let target_node_multi_addr =
"/dns4/store-01.do-ams3.status.staging.status.im/tcp/30303/p2p/16Uiu2HAm3xVDaz6SRJ6kErwC21zBJEZjavVXg7VSkoWzaV1aMA3F"
"/ip4/24.144.78.119/tcp/30303/p2p/16Uiu2HAm3xVDaz6SRJ6kErwC21zBJEZjavVXg7VSkoWzaV1aMA3F"
.parse::<Multiaddr>().expect("parse multiaddress");
waku.connect(&target_node_multi_addr, None)
@ -212,13 +263,51 @@ fn main() {
// Welcome the player
greeting();
// Draw the field
draw(&board);
loop {
// Draw the field
draw(&board);
ask_role_to_user(&mut my_role);
ask_game_name_to_user(&mut game_name);
println!("AAAA 1");
let board_string: String = board.iter().collect();
println!("AAAA 2");
let _ = waku.relay_publish_txt(&topic,
&board_string,
"tic-tac-toe-example",
None);
println!("AAAA 3");
// Main receiver task
// tokio::spawn(async move {
// loop {
// // Draw the field
// draw(&board);
// if my_role == current_player {
// // is my turn
// // Ask for user input
// ask_user(&mut board, current_player);
// }
// else {
// // other player's turn
// println!("Waiting oponent's movement");
// while let Some(message) = rx.recv().await {
// println!("Received: {}", message);
// break;
// }
// }
// if game_logic(&mut current_player, &mut board, topic, &waku) {
// break;
// }
// // Switch current_player
// current_player = if current_player == 'X' { 'O' } else { 'X' };
// }
// });
// .await
// .expect("Receiver task panicked");
}
if game_logic(&mut player, &mut board, topic, &waku) {
break;
}
}
}

View File

@ -17,6 +17,7 @@ use rln;
pub use node::{
waku_create_content_topic, waku_destroy, waku_new, Event, Initialized, Key, Multiaddr,
PublicKey, RLNConfig, Running, SecretKey, WakuMessageEvent, WakuNodeConfig, WakuNodeHandle,
WakuNodeContext,
};
pub use general::{

View File

@ -30,6 +30,9 @@ pub struct WakuNodeConfig {
/// RLN configuration
#[serde(skip_serializing_if = "Option::is_none")]
pub rln_relay: Option<RLNConfig>,
// other settings
#[serde(skip_serializing_if = "Option::is_none")]
pub log_level: Option<&'static str>,
}
/// RLN Relay configuration

View File

@ -1,6 +0,0 @@
// crates
use libc::c_void;
pub struct WakuNodeContext {
pub obj_ptr: *mut c_void,
}

View File

@ -10,10 +10,13 @@ use std::ffi::c_void;
use serde::{Deserialize, Serialize};
// internal
use crate::general::WakuMessage;
use crate::node::context::WakuNodeContext;
use crate::utils::{get_trampoline, LibwakuResponse};
use crate::MessageHash;
pub struct WakuNodeContext {
pub obj_ptr: *mut c_void,
}
/// Waku event
/// For now just WakuMessage is supported
#[non_exhaustive]
@ -37,13 +40,15 @@ pub struct WakuMessageEvent {
pub waku_message: WakuMessage,
}
/// 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<F: FnMut(LibwakuResponse)>(ctx: &WakuNodeContext, closure: &F) {
unsafe {
let cb = get_trampoline(closure);
waku_sys::waku_set_event_callback(ctx.obj_ptr, cb, closure as *const _ as *mut c_void)
};
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<F: FnMut(LibwakuResponse)>(&self, mut closure: F) {
unsafe {
let cb = get_trampoline(&closure);
waku_sys::waku_set_event_callback(self.obj_ptr, cb, &mut closure as *mut _ as *mut c_void)
};
}
}
#[cfg(test)]

View File

@ -8,10 +8,10 @@ use multiaddr::Multiaddr;
// internal
use super::config::WakuNodeConfig;
use crate::general::Result;
use crate::node::context::WakuNodeContext;
use crate::utils::LibwakuResponse;
use crate::utils::{get_trampoline, handle_json_response, handle_no_response, handle_response};
use crate::utils::WakuDecode;
use crate::node::events::WakuNodeContext;
/// Instantiates a Waku node
/// as per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_newchar-jsonconfig)

View File

@ -1,7 +1,6 @@
//! Waku node implementation
mod config;
mod context;
mod events;
mod management;
mod peers;
@ -11,16 +10,13 @@ mod relay;
pub use aes_gcm::Key;
pub use multiaddr::Multiaddr;
pub use secp256k1::{PublicKey, SecretKey};
use std::marker::PhantomData;
use std::time::Duration;
// internal
use crate::general::{MessageHash, Result, WakuMessage};
use crate::LibwakuResponse;
use context::WakuNodeContext;
pub use config::RLNConfig;
pub use config::WakuNodeConfig;
pub use events::{Event, WakuMessageEvent};
pub use events::{Event, WakuMessageEvent, WakuNodeContext};
pub use relay::waku_create_content_topic;
use crate::WakuContentTopic;
@ -40,43 +36,35 @@ impl WakuNodeState for Initialized {}
impl WakuNodeState for Running {}
/// Handle to the underliying waku node
pub struct WakuNodeHandle<State: WakuNodeState> {
pub struct WakuNodeHandle {
pub ctx: WakuNodeContext,
phantom: PhantomData<State>,
}
/// Spawn a new Waku node with the given configuration (default configuration if `None` provided)
/// as per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_newchar-jsonconfig)
pub fn waku_new(config: Option<WakuNodeConfig>) -> Result<WakuNodeHandle<Initialized>> {
pub fn waku_new(config: Option<WakuNodeConfig>) -> Result<WakuNodeHandle> {
Ok(WakuNodeHandle {
ctx: management::waku_new(config)?,
phantom: PhantomData,
})
}
pub fn waku_destroy(node: WakuNodeHandle<Initialized>) -> Result<()> {
pub fn waku_destroy(node: WakuNodeHandle) -> Result<()> {
management::waku_destroy(&node.ctx)
}
impl WakuNodeHandle<Initialized> {
// unsafe impl Send for WakuNodeHandle<Running> {}
impl WakuNodeHandle {
/// Start a Waku node mounting all the protocols that were enabled during the Waku node instantiation.
/// as per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_start)
pub fn start(self) -> Result<WakuNodeHandle<Running>> {
management::waku_start(&self.ctx).map(|_| WakuNodeHandle {
ctx: self.ctx,
phantom: PhantomData,
})
pub fn start(&self) -> Result<()> {
management::waku_start(&self.ctx)
}
}
impl<Running: WakuNodeState> WakuNodeHandle<Running> {
/// Stops a Waku node
/// as per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_stop)
pub fn stop(self) -> Result<WakuNodeHandle<Initialized>> {
management::waku_stop(&self.ctx).map(|_| WakuNodeHandle {
ctx: self.ctx,
phantom: PhantomData,
})
pub fn stop(&self) -> Result<()> {
management::waku_stop(&self.ctx)
}
/// Get the multiaddresses the Waku node is listening to
@ -101,8 +89,8 @@ impl<Running: WakuNodeState> WakuNodeHandle<Running> {
pub fn relay_publish_txt(
&self,
pubsub_topic: &str,
msg_txt: &str,
pubsub_topic: &String,
msg_txt: &String,
content_topic_name: &'static str,
timeout: Option<Duration>,
) -> Result<MessageHash> {
@ -130,14 +118,14 @@ impl<Running: WakuNodeState> WakuNodeHandle<Running> {
pub fn relay_publish_message(
&self,
message: &WakuMessage,
pubsub_topic: &str,
pubsub_topic: &String,
timeout: Option<Duration>,
) -> Result<MessageHash> {
relay::waku_relay_publish_message(&self.ctx, message, pubsub_topic, timeout)
}
/// Subscribe to WakuRelay to receive messages matching a content filter.
pub fn relay_subscribe(&self, pubsub_topic: &str) -> Result<()> {
pub fn relay_subscribe(&self, pubsub_topic: &String) -> Result<()> {
relay::waku_relay_subscribe(&self.ctx, pubsub_topic)
}
@ -146,7 +134,4 @@ impl<Running: WakuNodeState> WakuNodeHandle<Running> {
relay::waku_relay_unsubscribe(&self.ctx, pubsub_topic)
}
pub fn set_event_callback<F: Fn(LibwakuResponse)>(&self, closure: &F) {
events::waku_set_event_callback(&self.ctx, closure)
}
}

View File

@ -8,9 +8,9 @@ use libc::*;
use multiaddr::Multiaddr;
// internal
use crate::general::Result;
use crate::node::context::WakuNodeContext;
use crate::utils::LibwakuResponse;
use crate::utils::{get_trampoline, handle_no_response};
use crate::node::events::WakuNodeContext;
/// Dial peer using a multiaddress
/// If `timeout` as milliseconds doesn't fit into a `i32` it is clamped to [`i32::MAX`]

View File

@ -7,7 +7,7 @@ use std::time::Duration;
use libc::*;
// internal
use crate::general::{Encoding, MessageHash, Result, WakuContentTopic, WakuMessage};
use crate::node::context::WakuNodeContext;
use crate::node::events::WakuNodeContext;
use crate::utils::{get_trampoline, handle_no_response, handle_response, LibwakuResponse};
/// Create a content topic according to [RFC 23](https://rfc.vac.dev/spec/23/)