progressing on tic-tac-toe-gui
This commit is contained in:
parent
0bd436cf45
commit
156cdfc295
|
@ -13,4 +13,5 @@ tokio = { version = "1", features = ["full"] }
|
|||
tokio-util = "0.6" # for utility functions if needed
|
||||
egui = "0.22"
|
||||
eframe = "0.22"
|
||||
secp256k1 = { version = "0.26", features = ["rand", "recovery", "serde"] }
|
||||
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
use eframe::egui;
|
||||
use secp256k1::SecretKey;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cell::OnceCell;
|
||||
use std::str::from_utf8;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use std::str::FromStr;
|
||||
use std::time::SystemTime;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use tokio::sync::mpsc;
|
||||
use waku::{
|
||||
waku_new, Encoding, Event, Initialized, LibwakuResponse, Multiaddr, Running, WakuContentTopic,
|
||||
|
@ -33,28 +37,23 @@ struct MoveMessage {
|
|||
|
||||
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
|
||||
tx: 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>>>,
|
||||
game_state: Arc<Mutex<GameState>>,
|
||||
tx: 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())),
|
||||
game_state,
|
||||
waku,
|
||||
game_topic,
|
||||
tx: tx,
|
||||
tx,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,94 +61,24 @@ impl TicTacToeApp {
|
|||
// 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);
|
||||
|
||||
let tx_clone = self.tx.clone();
|
||||
|
||||
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() {
|
||||
// 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();
|
||||
let payload = message.payload.to_vec();
|
||||
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.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");
|
||||
// Lock succeeded, proceed to send the message
|
||||
if tx_clone.blocking_send(msg.to_string()).is_err() {
|
||||
eprintln!("Failed to send message to async task");
|
||||
}
|
||||
// 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);
|
||||
|
@ -170,12 +99,14 @@ impl TicTacToeApp {
|
|||
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");
|
||||
// let target_node_multi_addr =
|
||||
// "/ip4/159.223.242.94/tcp/30303/p2p/16Uiu2HAmAUdrQ3uwzuE4Gy4D56hX6uLKEeerJAnhKEHZ3DxF1EfT"
|
||||
// // "/dns4/store-01.do-ams3.status.prod.status.im/tcp/30303/p2p/16Uiu2HAmAUdrQ3uwzuE4Gy4D56hX6uLKEeerJAnhKEHZ3DxF1EfT"
|
||||
// // "/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");
|
||||
// self.waku.connect(&target_node_multi_addr, None)
|
||||
// .expect("waku should connect to other node");
|
||||
}
|
||||
|
||||
fn send_game_state(&self, game_state: &GameState) {
|
||||
|
@ -263,6 +194,10 @@ 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));
|
||||
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.heading("Tic-Tac-Toe");
|
||||
|
||||
|
@ -334,20 +269,61 @@ impl eframe::App for TicTacToeApp {
|
|||
async fn main() -> eframe::Result<()> {
|
||||
let (tx, mut rx) = mpsc::channel::<String>(3200); // Channel to communicate between threads
|
||||
|
||||
let game_topic = "/waku/2/rs/16/32";
|
||||
// Create a Waku instance
|
||||
let waku = waku_new(Some(WakuNodeConfig {
|
||||
port: Some(60010),
|
||||
cluster_id: Some(16),
|
||||
shards: vec![1, 32, 64, 128, 256],
|
||||
// node_key: Some(SecretKey::from_str("2fc0515879e52b7b73297cfd6ab3abf7c344ef84b7a90ff6f4cc19e05a198027").unwrap()),
|
||||
max_message_size: Some("1024KiB".to_string()),
|
||||
relay_topics: vec![game_topic.to_string()],
|
||||
log_level: Some("DEBUG"), // 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(9000),
|
||||
discv5_enr_auto_update: Some(false),
|
||||
|
||||
..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)));
|
||||
|
||||
let game_state = GameState {
|
||||
board: [[None; 3]; 3],
|
||||
current_turn: Player::X,
|
||||
moves_left: 9,
|
||||
};
|
||||
let shared_state = Arc::new(Mutex::new(game_state));
|
||||
|
||||
let clone = shared_state.clone();
|
||||
let mut app = TicTacToeApp::new(waku, game_topic, clone, tx);
|
||||
|
||||
app.start();
|
||||
|
||||
let clone = shared_state.clone();
|
||||
// Listen for messages in the main thread
|
||||
tokio::spawn(async move {
|
||||
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::<GameState>(&msg)
|
||||
{
|
||||
if let Ok(mut unclocked_game_state) = clone.lock(){
|
||||
*unclocked_game_state = parsed_value;
|
||||
}
|
||||
}
|
||||
else {
|
||||
eprintln!("Failed to parse JSON: ");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
eframe::run_native(
|
||||
"Tic-Tac-Toe Multiplayer via Waku",
|
||||
eframe::NativeOptions {
|
||||
|
@ -357,13 +333,6 @@ async fn main() -> eframe::Result<()> {
|
|||
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(())
|
||||
}
|
||||
|
|
|
@ -23,16 +23,37 @@ pub struct WakuNodeConfig {
|
|||
/// Cluster id that the node is running in
|
||||
#[default(Some(0))]
|
||||
pub cluster_id: Option<usize>,
|
||||
/// Enable relay protocol. Default `true`
|
||||
|
||||
/// Relay protocol
|
||||
#[default(Some(true))]
|
||||
pub relay: Option<bool>,
|
||||
pub relay_topics: Vec<String>,
|
||||
pub shards: Vec<usize>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub max_message_size: Option<String>,
|
||||
|
||||
/// RLN configuration
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub rln_relay: Option<RLNConfig>,
|
||||
|
||||
// Discovery
|
||||
#[default(Some(false))]
|
||||
pub dns_discovery: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub dns_discovery_url: Option<&'static str>,
|
||||
|
||||
#[default(Some(false))]
|
||||
pub discv5_discovery: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub discv5_udp_port: Option<usize>,
|
||||
#[default(Some(false))]
|
||||
pub discv5_enr_auto_update: Option<bool>,
|
||||
|
||||
// other settings
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub log_level: Option<&'static str>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub keep_alive: Option<bool>,
|
||||
}
|
||||
|
||||
/// RLN Relay configuration
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
//! When an event is emitted, this callback will be triggered receiving an [`Event`]
|
||||
|
||||
// std
|
||||
use std::ffi::{c_char, c_int, c_void, CStr};
|
||||
use std::ffi::c_void;
|
||||
// crates
|
||||
use serde::{Deserialize, Serialize};
|
||||
// internal
|
||||
use crate::general::WakuMessage;
|
||||
use std::{slice, str};
|
||||
|
||||
use crate::utils::{get_trampoline, LibwakuResponse};
|
||||
use crate::utils::LibwakuResponse;
|
||||
use crate::MessageHash;
|
||||
use std::ops::Deref;
|
||||
use std::sync::Mutex;
|
||||
|
|
Loading…
Reference in New Issue