158 lines
4.8 KiB
Rust
158 lines
4.8 KiB
Rust
#![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::<Client>::run();
|
|
}
|
|
|
|
pub struct Client {
|
|
dir: DataDir,
|
|
data: ClientData,
|
|
state: ClientState,
|
|
main_ui: WidgetRef<WidgetPtr>,
|
|
notif: WidgetRef<WidgetPtr>,
|
|
proxy: Proxy<ClientEvent>,
|
|
}
|
|
|
|
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::Event>) -> 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);
|
|
}
|
|
}
|
|
}
|