hul ignennem

This commit is contained in:
2023-06-11 14:36:21 +02:00
parent bfabcc0abc
commit fb1b863746
13 changed files with 189 additions and 43 deletions

View File

@@ -0,0 +1,4 @@
fn main() {
wasm_logger::init(wasm_logger::Config::default());
yew::Renderer::<frontend::App>::new().render();
}

View File

@@ -0,0 +1,6 @@
use frontend::event_bus::EventBus;
use yew_agent::PublicWorker;
fn main() {
EventBus::register();
}

View File

@@ -1,26 +1,75 @@
use crate::event_bus::EventBus;
use crate::services::websocket::WebsocketService;
use crate::AppState;
use crate::Route;
use common::Achievement;
use std::rc::Rc;
use yew::functional::*;
use yew::prelude::*;
use yew_agent::Bridge;
use yew_agent::Bridged;
use yew_router::prelude::*;
#[function_component(Root)]
pub fn root() -> Html {
let app_state = use_context::<crate::AppState>().expect("no context found");
pub struct Root {
wss: WebsocketService,
_producer: Box<dyn Bridge<EventBus>>,
achievements: Vec<Achievement>,
}
let achievements = app_state
.state
.achievements
.iter()
.map(|a| {
html! {
<p>{format!("{}", a.goal)}</p>
pub enum Msg {
HandleMsg(String),
}
impl Component for Root {
type Message = Msg;
type Properties = ();
fn create(ctx: &Context<Self>) -> Self {
// let ctx_link = ctx
// .link()
// .context::<AppState>(Callback::noop())
// .expect("context to be set");
let wss = WebsocketService::new();
let cb = {
let link = ctx.link().clone();
move |e| link.send_message(Msg::HandleMsg(e))
};
Self {
wss,
_producer: EventBus::bridge(Rc::new(cb)),
achievements: vec![],
}
}
fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
Msg::HandleMsg(s) => {
let msg: common::WebSocketMessage = serde_json::from_str(&s).unwrap();
self.achievements = msg.achievements;
true
}
})
.collect::<Html>();
}
}
html! {
<div>
{achievements}
</div>
fn view(&self, ctx: &Context<Self>) -> Html {
let achievements = self
.achievements
.iter()
.map(|a| {
html! {
<p>{format!("{}", a.goal)}</p>
}
})
.collect::<Html>();
html! {
<div>
{achievements}
</div>
}
}
}

View File

@@ -0,0 +1,54 @@
use serde::Deserialize;
use serde::Serialize;
use std::collections::HashSet;
use yew_agent::HandlerId;
use yew_agent::Public;
use yew_agent::WorkerLink;
pub struct EventBus {
link: WorkerLink<Self>,
subscribers: HashSet<HandlerId>,
}
#[derive(Serialize, Deserialize)]
pub enum EventBusInput {
EventBusMsg(String),
}
impl yew_agent::Worker for EventBus {
type Reach = Public<Self>;
type Input = EventBusInput;
type Output = String;
type Message = ();
fn create(link: WorkerLink<Self>) -> Self {
Self {
link,
subscribers: HashSet::new(),
}
}
fn update(&mut self, _msg: Self::Message) {}
fn handle_input(&mut self, msg: Self::Input, id: HandlerId) {
match msg {
EventBusInput::EventBusMsg(s) => {
for sub in &self.subscribers {
self.link.respond(*sub, s.clone());
}
}
}
}
fn connected(&mut self, id: HandlerId) {
self.subscribers.insert(id);
}
fn disconnected(&mut self, id: HandlerId) {
self.subscribers.remove(&id);
}
fn name_of_resource() -> &'static str {
"event_bus.js"
}
}

View File

@@ -7,6 +7,7 @@ use yew_router::Routable;
use yew_router::Switch;
mod components;
pub mod event_bus;
mod services;
#[derive(Debug, Clone, Copy, PartialEq, Routable)]
@@ -35,16 +36,7 @@ struct AppStateInner {
type AppState = Rc<AppStateInner>;
#[function_component]
fn App() -> Html {
// let counter = use_state(|| 0);
// let onclick = {
// let counter = counter.clone();
// move |_| {
// let value = *counter + 1;
// counter.set(value);
// }
// };
pub fn App() -> Html {
let ctx = use_state(|| Rc::new(AppStateInner::default()));
html! {
@@ -57,8 +49,3 @@ fn App() -> Html {
</ContextProvider<AppState>>
}
}
fn main() {
wasm_logger::init(wasm_logger::Config::default());
yew::Renderer::<App>::new().render();
}

View File

@@ -1,9 +1,12 @@
use crate::event_bus::EventBus;
use crate::event_bus::EventBusInput;
use futures::channel::mpsc::Sender;
use futures::SinkExt;
use futures::StreamExt;
use reqwasm::websocket::futures::WebSocket;
use reqwasm::websocket::Message;
use wasm_bindgen_futures::spawn_local;
use yew_agent::Dispatched;
pub struct WebsocketService {
pub tx: Sender<String>,
@@ -11,11 +14,12 @@ pub struct WebsocketService {
impl WebsocketService {
pub fn new() -> Self {
let ws = WebSocket::open("ws://127.0.0.1:4000").unwrap();
let ws = WebSocket::open("ws://127.0.0.1:4000/ws").unwrap();
let (mut write, mut read) = ws.split();
let (in_tx, mut in_rx) = futures::channel::mpsc::channel::<String>(1000);
let mut event_bus = EventBus::dispatcher();
spawn_local(async move {
while let Some(s) = in_rx.next().await {
@@ -29,15 +33,17 @@ impl WebsocketService {
match msg {
Ok(Message::Text(data)) => {
log::debug!("from websocket: {}", data);
event_bus.send(EventBusInput::EventBusMsg(data));
}
Ok(Message::Bytes(b)) => {
let decoded = std::str::from_utf8(&b);
if let Ok(val) = decoded {
log::debug!("from websocket: {}", val);
event_bus.send(EventBusInput::EventBusMsg(val.into()));
}
}
Err(e) => {
log::error!("ws: {:?}", e)
log::error!("ws: {:?}", e);
}
}
}