restoring back the type state pattern introduced by Richard

This commit is contained in:
Ivan Folgueira Bande 2024-11-22 21:57:58 +01:00
parent dad471a114
commit daf1cb6b08
No known key found for this signature in database
GPG Key ID: 3C117481F89E24A7
4 changed files with 63 additions and 42 deletions

View File

@ -7,7 +7,7 @@ use std::time::{SystemTime, Duration};
use tokio::sync::mpsc;
use waku::{
waku_new, Encoding, Event, LibwakuResponse, WakuContentTopic,
WakuMessage, WakuNodeConfig, WakuNodeHandle,
WakuMessage, WakuNodeConfig, WakuNodeHandle, Initialized, Running
};
#[derive(Serialize, Deserialize, PartialEq, Debug, Copy, Clone)]
@ -23,17 +23,17 @@ struct GameState {
moves_left: usize,
}
struct TicTacToeApp {
struct TicTacToeApp<State> {
game_state: Arc<Mutex<GameState>>,
waku: WakuNodeHandle,
waku: WakuNodeHandle<State>,
game_topic: &'static str,
tx: mpsc::Sender<String>, // Sender to send `msg` to main thread
player_role: Option<Player>, // Store the player's role (X or O)
}
impl TicTacToeApp {
impl TicTacToeApp<Initialized> {
fn new(
waku: WakuNodeHandle,
waku: WakuNodeHandle<Initialized>,
game_topic: &'static str,
game_state: Arc<Mutex<GameState>>,
tx: mpsc::Sender<String>,
@ -47,10 +47,7 @@ impl TicTacToeApp {
}
}
fn start(&mut self) {
// Start the waku node
self.waku.start().expect("waku should start");
fn start(self) -> TicTacToeApp<Running> {
let tx_clone = self.tx.clone();
let my_closure = move |response| {
@ -83,13 +80,18 @@ impl TicTacToeApp {
};
// Establish a closure that handles the incoming messages
self.waku.ctx.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");
let _ = self.waku.version();
// Start the waku node
let waku = self.waku.start().expect("waku should start");
// Subscribe to desired topic using the relay protocol
// self.waku.relay_subscribe(&self.game_topic.to_string()).expect("waku should subscribe");
let content_topic = WakuContentTopic::new("waku", "2", "tictactoegame", Encoding::Proto);
self.waku.filter_subscribe(&self.game_topic.to_string(), &content_topic.to_string()).expect("waku should subscribe");
waku.filter_subscribe(&self.game_topic.to_string(), &content_topic.to_string()).expect("waku should subscribe");
// Connect to hard-coded node
// let target_node_multi_addr =
@ -100,8 +102,18 @@ impl TicTacToeApp {
// self.waku.connect(&target_node_multi_addr, None)
// .expect("waku should connect to other node");
}
TicTacToeApp {
game_state: self.game_state,
waku: waku,
game_topic: self.game_topic,
tx: self.tx,
player_role: self.player_role,
}
}
}
impl TicTacToeApp<Running> {
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);
@ -193,7 +205,7 @@ impl TicTacToeApp {
}
}
impl eframe::App for TicTacToeApp {
impl eframe::App for TicTacToeApp<Running> {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
// Request a repaint every second
@ -325,9 +337,9 @@ async fn main() -> eframe::Result<()> {
let shared_state = Arc::new(Mutex::new(game_state));
let clone = shared_state.clone();
let mut app = TicTacToeApp::new(waku, game_topic, clone, tx);
let app = TicTacToeApp::new(waku, game_topic, clone, tx);
app.start();
let app = app.start();
let clone = shared_state.clone();
// Listen for messages in the main thread

View File

@ -14,7 +14,6 @@ pub type WakuMessageVersion = usize;
/// Waku message hash, hex encoded sha256 digest of the message
pub type MessageHash = String;
/// Waku response, just a `Result` with an `String` error.
pub type Result<T> = std::result::Result<T, String>;
// TODO: Properly type and deserialize payload form base64 encoded string

View File

@ -17,7 +17,6 @@ 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

@ -13,13 +13,15 @@ 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::utils::LibwakuResponse;
use crate::node::context::WakuNodeContext;
pub use config::RLNConfig;
pub use config::WakuNodeConfig;
pub use context::WakuNodeContext;
pub use events::{Event, WakuMessageEvent};
pub use relay::waku_create_content_topic;
@ -27,48 +29,62 @@ use crate::Encoding;
use crate::WakuContentTopic;
use std::time::SystemTime;
/// Marker trait to disallow undesired waku node states in the handle
pub trait WakuNodeState {}
/// Waku node initialized state
// Define state marker types
pub struct Initialized;
/// Waku node running state
pub struct Running;
impl WakuNodeState for Initialized {}
impl WakuNodeState for Running {}
/// Handle to the underliying waku node
pub struct WakuNodeHandle {
pub ctx: WakuNodeContext,
pub struct WakuNodeHandle<State> {
ctx: WakuNodeContext,
_state: 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> {
pub fn waku_new(config: Option<WakuNodeConfig>) -> Result<WakuNodeHandle<Initialized>> {
Ok(WakuNodeHandle {
ctx: management::waku_new(config)?,
_state: PhantomData,
})
}
pub fn waku_destroy(node: WakuNodeHandle) -> Result<()> {
pub fn waku_destroy(node: WakuNodeHandle<Initialized>) -> Result<()> {
management::waku_destroy(&node.ctx)
}
// unsafe impl Send for WakuNodeHandle<Running> {}
impl<State> WakuNodeHandle<State> {
/// Get the nwaku version
pub fn version(&self) -> Result<String> {
management::waku_version(&self.ctx)
}
}
impl WakuNodeHandle {
impl WakuNodeHandle<Initialized> {
/// 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<()> {
management::waku_start(&self.ctx)
pub fn start(self) -> Result<WakuNodeHandle<Running>> {
management::waku_start(&self.ctx).map(|_| WakuNodeHandle {
ctx: self.ctx,
_state: PhantomData,
})
}
pub fn set_event_callback<F: FnMut(LibwakuResponse) + 'static + Sync + Send>(
&self,
closure: F,
) -> Result<()> {
self.ctx.waku_set_event_callback(closure)
}
}
impl 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<()> {
management::waku_stop(&self.ctx)
pub fn stop(self) -> Result<WakuNodeHandle<Initialized>> {
management::waku_stop(&self.ctx).map(|_| WakuNodeHandle {
ctx: self.ctx,
_state: PhantomData,
})
}
/// Get the multiaddresses the Waku node is listening to
@ -77,11 +93,6 @@ impl WakuNodeHandle {
management::waku_listen_addresses(&self.ctx)
}
/// Get the nwaku version
pub fn version(&self) -> Result<String> {
management::waku_version(&self.ctx)
}
/// Dial peer using a multiaddress
/// If `timeout` as milliseconds doesn't fit into a `i32` it is clamped to [`i32::MAX`]
/// If the function execution takes longer than `timeout` value, the execution will be canceled and an error returned.