#![windows_subsystem = "windows"] use crate::{ net::{NetHandle, NetSender}, rsc::{CLIENT_DATA, ClientData}, state::{ClientState, LoggedIn, Login}, ui::*, }; use iris::{prelude::*, winit::*}; use openworm::{ net::{ClientMsg, ServerMsg, install_crypto_provider}, rsc::DataDir, }; use winit::{ event::{ElementState, MouseButton, WindowEvent}, window::WindowAttributes, }; mod account; mod debug; mod net; mod rsc; mod state; mod ui; fn main() { install_crypto_provider(); DefaultApp::::run(); } pub struct Client { dir: DataDir, data: ClientData, state: ClientState, main_ui: WidgetRef, notif: WidgetRef, proxy: Proxy, } pub enum ClientEvent { Connect { send: NetSender }, ServerMsg(ServerMsg), Err(String), } impl DefaultAppState for Client { type Event = ClientEvent; fn window_attrs() -> WindowAttributes { WindowAttributes::default().with_title("OPENWORM") } fn new(ui: &mut Ui, _state: &UiState, proxy: Proxy) -> Self { let dir = DataDir::default(); let notif = WidgetPtr::default().add(ui); let main_ui = WidgetPtr::default().add(ui); let bg = ( image(include_bytes!("./assets/fuit.jpg")), rect(Color::BLACK.alpha((0.8 * 255.0) as u8)), ) .stack(); ( bg, main_ui.clone(), notif.clone().pad(Padding::top(10)).align(Align::TOP_CENTER), ) .stack() .set_root(ui); let mut s = Self { data: dir.load(CLIENT_DATA), state: Default::default(), dir, main_ui: main_ui.clone(), notif, proxy, }; start_screen(&mut s, ui).set_ptr(&s.main_ui, ui); s } fn event(&mut self, event: ClientEvent, ui: &mut Ui, _state: &UiState) { match event { ClientEvent::Connect { send } => { let ClientState::Connect(connect) = self.state.take() else { panic!("invalid state"); }; let th = connect.handle.unwrap(); self.state = ClientState::Login(Login { handle: NetHandle { send: send.clone(), thread: th, }, }); // login_screen(self, ui).set_ptr(&self.main_ui, ui); } ClientEvent::ServerMsg(msg) => match msg { ServerMsg::SendMsg(msg) => { if let ClientState::LoggedIn(state) = &mut self.state && let Some(msg_area) = &state.channel { let msg = msg_widget(&msg.user, &msg.content).add(ui); msg_area.get_mut().children.push(msg.any()); } } ServerMsg::LoadMsgs(msgs) => { if let ClientState::LoggedIn(state) = &mut self.state && let Some(msg_area) = &state.channel { for msg in msgs { state.msgs.push(msg.clone()); let msg = msg_widget(&msg.user, &msg.content).add(ui); msg_area.get_mut().children.push(msg.any()); } } } ServerMsg::Login { username } => { let ClientState::Login(state) = self.state.take() else { panic!("invalid state"); }; state.handle.send(ClientMsg::RequestMsgs); self.state = ClientState::LoggedIn(LoggedIn { network: state.handle, channel: None, msgs: Vec::new(), username, }); main_view(self, ui).set_ptr(&self.main_ui, ui); } ServerMsg::Error(error) => { let msg = format!("{error:?}"); self.notif.get_mut().inner = Some(werror(ui, &msg)); } }, ClientEvent::Err(msg) => { self.notif.get_mut().inner = Some(werror(ui, &msg)); } } } fn exit(&mut self, _ui: &mut Ui, _state: &UiState) { self.state.exit(); self.dir.save(CLIENT_DATA, &self.data); } fn window_event(&mut self, event: WindowEvent, ui: &mut Ui, state: &UiState) { if let WindowEvent::MouseInput { state: ElementState::Pressed, button: MouseButton::Middle, .. } = event { debug::debug(self, ui, state); } } }