diff options
| author | Max Audron <audron@cocaine.farm> | 2021-11-29 14:27:27 +0100 |
|---|---|---|
| committer | Max Audron <audron@cocaine.farm> | 2021-11-29 14:28:02 +0100 |
| commit | 9df7c5c0e6d03579fa90735adf316d7e563340d7 (patch) | |
| tree | 43118348a34a8f1715aaa384cc8e966c3af97506 /examples/statetracker/src | |
| parent | add feature list to readme (diff) | |
statetracker: add bufferview widget and do some reorganization
Diffstat (limited to '')
| -rw-r--r-- | examples/statetracker/src/command.rs | 14 | ||||
| -rw-r--r-- | examples/statetracker/src/formatter.rs | 3 | ||||
| -rw-r--r-- | examples/statetracker/src/main.rs | 123 | ||||
| -rw-r--r-- | examples/statetracker/src/server.rs | 46 | ||||
| -rw-r--r-- | examples/statetracker/src/widgets/aliasmanager.rs (renamed from examples/statetracker/src/aliasmanager.rs) | 0 | ||||
| -rw-r--r-- | examples/statetracker/src/widgets/bufferview.rs | 96 | ||||
| -rw-r--r-- | examples/statetracker/src/widgets/mod.rs | 5 |
7 files changed, 209 insertions, 78 deletions
diff --git a/examples/statetracker/src/command.rs b/examples/statetracker/src/command.rs index 09b49d7..b10aa90 100644 --- a/examples/statetracker/src/command.rs +++ b/examples/statetracker/src/command.rs @@ -1,19 +1,13 @@ use druid::{Selector, SingleUse}; -use libquassel::{ - message::{ - objects::{Alias, AliasManager}, - SyncMessage, - }, - primitive::VariantMap, -}; +use libquassel::message::{objects::Alias, InitData, SyncMessage}; use crate::server::Direction; pub const CONNECT: Selector = Selector::new("connect"); pub const ADD_MESSAGE: Selector<SingleUse<crate::Message>> = Selector::new("add_message"); -pub const ALIASMANAGER_INIT: Selector<SingleUse<AliasManager>> = Selector::new("aliasmanager_init"); -pub const ALIASMANAGER_UPDATE: Selector<SingleUse<(Direction, SyncMessage)>> = - Selector::new("aliasmanager_update"); pub const ALIASMANAGER_ADD_ALIAS: Selector<SingleUse<Alias>> = Selector::new("aliasmanager_add_alias"); + +pub const SYNCMESSAGE: Selector<SingleUse<(Direction, SyncMessage)>> = Selector::new("syncmessage"); +pub const INITDATA: Selector<SingleUse<(Direction, InitData)>> = Selector::new("initdata"); diff --git a/examples/statetracker/src/formatter.rs b/examples/statetracker/src/formatter.rs index 4ceb68f..dc81887 100644 --- a/examples/statetracker/src/formatter.rs +++ b/examples/statetracker/src/formatter.rs @@ -40,7 +40,8 @@ pub enum U16ValidationError { impl std::fmt::Display for U16ValidationError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", std::any::type_name_of_val(self)) + // TODO set correct display based on actual value + write!(f, "U16ValidationError::WrongNumberOfCharacters") } } diff --git a/examples/statetracker/src/main.rs b/examples/statetracker/src/main.rs index 65ee4ce..a56d054 100644 --- a/examples/statetracker/src/main.rs +++ b/examples/statetracker/src/main.rs @@ -1,19 +1,16 @@ -#![feature(type_name_of_val)] +use std::{collections::HashMap, sync::Arc}; -use std::{ops::Deref, sync::Arc}; - -use aliasmanager::AliasManagerWidget; use druid::{ - lens, widget::{Align, Either, Flex, Label, List, Split}, AppDelegate, Command, }; use druid::{AppLauncher, Data, Env, Lens, LocalizedString, Widget, WidgetExt, WindowDesc}; +use widgets::{AliasManagerWidget, BufferViewWidget}; -use libquassel::message::{NetworkMap, StatefulSyncableServer}; -use libquassel::{ - message::{objects::AliasManager, StatefulSyncableClient}, - session::Session, +use libquassel::message::{objects::AliasManager, StatefulSyncableClient, SyncProxy}; +use libquassel::message::{ + objects::{self, BufferViewManager}, + StatefulSyncableServer, }; use tracing::debug; @@ -25,18 +22,19 @@ const SPACING: f64 = 10.0; const VERTICAL_WIDGET_SPACING: f64 = 20.0; const WINDOW_TITLE: LocalizedString<StateTracker> = LocalizedString::new("StateTracker"); +mod widgets; + mod command; mod connect; mod formatter; mod server; -mod aliasmanager; - #[derive(Clone, Data, Lens)] struct StateTracker { server: server::Server, messages: Arc<Vec<server::Message>>, alias_manager: Arc<AliasManager>, + buffer_view_manager: Arc<BufferViewManager>, connected: bool, #[data(ignore)] syncer: Syncer, @@ -44,14 +42,22 @@ struct StateTracker { impl StateTracker { fn new() -> StateTracker { + let (sync_channel, rpc_channel) = SyncProxy::init(1024); + StateTracker { server: server::Server::default(), messages: Arc::new(Vec::new()), alias_manager: Arc::new(AliasManager { aliases: Vec::new(), }), + buffer_view_manager: Arc::new(BufferViewManager { + buffer_view_configs: HashMap::new(), + }), connected: false, - syncer: Syncer {}, + syncer: Syncer { + sync_channel, + rpc_channel, + }, } } @@ -61,7 +67,10 @@ impl StateTracker { Split::columns( Flex::column() .with_child(Label::new("AliasManager")) - .with_child(AliasManagerWidget::new().lens(StateTracker::alias_manager)), + .with_child(AliasManagerWidget::new().lens(StateTracker::alias_manager)) + .with_spacer(SPACING) + .with_child(Label::new("BufferViewManager")) + .with_child(BufferViewWidget::new().lens(StateTracker::buffer_view_manager)), List::new(|| { Label::new(|item: &Message, _env: &_| format!("{:#?}", item)).padding(10.0) }) @@ -83,6 +92,12 @@ impl StateTracker { } } +impl Default for StateTracker { + fn default() -> Self { + Self::new() + } +} + struct StateTrackerDelegate; impl AppDelegate<StateTracker> for StateTrackerDelegate { fn command( @@ -107,22 +122,66 @@ impl AppDelegate<StateTracker> for StateTrackerDelegate { let mut alias_manager = Arc::make_mut(&mut data.alias_manager).clone(); alias_manager.add_alias(alias.take().unwrap()); data.alias_manager = Arc::new(alias_manager); - } else if let Some(alias_manager) = cmd.get(command::ALIASMANAGER_INIT) { - data.alias_manager = Arc::new(alias_manager.take().unwrap()); - } else if let Some(msg) = cmd.get(command::ALIASMANAGER_UPDATE) { + } else if let Some(initdata) = cmd.get(command::INITDATA) { + let (_, initdata) = initdata.take().unwrap(); + match initdata.init_data { + objects::Types::AliasManager(alias_manager) => { + data.alias_manager = Arc::new(alias_manager) + } + objects::Types::BufferViewManager(buffer_view_manager) => { + data.buffer_view_manager = Arc::new(buffer_view_manager) + } + objects::Types::BufferViewConfig(config) => { + let id: i32 = initdata.object_name.parse().unwrap(); + + let mut buffer_view_manager = + Arc::make_mut(&mut data.buffer_view_manager).clone(); + + buffer_view_manager.buffer_view_configs.insert(id, config); + + data.buffer_view_manager = Arc::new(buffer_view_manager) + } + _ => (), + } + } else if let Some(msg) = cmd.get(command::SYNCMESSAGE) { let (direction, msg) = msg.take().unwrap(); debug!("direction: {:#?}, msg: {:#?}", direction, msg); - let mut alias_manager = Arc::make_mut(&mut data.alias_manager).clone(); + match msg.class_name.as_str() { + "AliasManager" => { + let mut alias_manager = Arc::make_mut(&mut data.alias_manager).clone(); - if direction == Direction::ServerToClient { - StatefulSyncableClient::sync(&mut alias_manager, &data, msg); - } else { - StatefulSyncableServer::sync(&mut alias_manager, &data, msg); - } + if direction == Direction::ServerToClient { + StatefulSyncableClient::sync(&mut alias_manager, msg); + } else { + StatefulSyncableServer::sync(&mut alias_manager, msg); + } - data.alias_manager = Arc::new(alias_manager); + data.alias_manager = Arc::new(alias_manager); + } + "BufferViewConfig" => { + let mut buffer_view_manager = + Arc::make_mut(&mut data.buffer_view_manager).clone(); + + let id: i32 = msg.object_name.parse().unwrap(); + + let buffer_view_config = buffer_view_manager + .buffer_view_configs + .get_mut(&id) + .unwrap(); + + if direction == Direction::ServerToClient { + StatefulSyncableClient::sync(buffer_view_config, msg); + } else { + StatefulSyncableServer::sync(buffer_view_config, msg); + } + + data.buffer_view_manager = Arc::new(buffer_view_manager); + } + + _ => (), + } } druid::Handled::No @@ -137,21 +196,9 @@ impl AppDelegate<StateTracker> for StateTrackerDelegate { // TODO make this somehow deref or smth #[derive(Clone)] -pub struct Syncer; -impl libquassel::message::SyncProxy for StateTracker { - fn sync( - &self, - class_name: &str, - object_name: Option<&str>, - function: &str, - params: libquassel::primitive::VariantList, - ) { - todo!() - } - - fn rpc(&self, function: &str, params: libquassel::primitive::VariantList) { - todo!() - } +pub struct Syncer { + sync_channel: crossbeam_channel::Receiver<libquassel::message::SyncMessage>, + rpc_channel: crossbeam_channel::Receiver<libquassel::message::RpcCall>, } fn main() { diff --git a/examples/statetracker/src/server.rs b/examples/statetracker/src/server.rs index 63b36f7..f95a5fe 100644 --- a/examples/statetracker/src/server.rs +++ b/examples/statetracker/src/server.rs @@ -1,7 +1,5 @@ use anyhow::{bail, Error}; -use std::convert::TryFrom; - use druid::{ widget::{ Align, Button, Checkbox, Container, Controller, ControllerHost, Flex, Label, TextBox, @@ -12,8 +10,7 @@ use druid::{ use libquassel::{ deserialize::Deserialize, frame::QuasselCodec, - message::{self, objects, ConnAck, HandshakeMessage, Init}, - primitive::VariantMap, + message::{self, ConnAck, HandshakeMessage, Init}, }; use futures::{ @@ -26,7 +23,7 @@ use tokio::{ }; use tokio_util::codec::Framed; -use tracing::{debug, info, trace}; +use tracing::{debug, trace}; use crate::{command, formatter}; @@ -147,7 +144,7 @@ impl Server { async fn handle_login_message( buf: &[u8], state: &mut ClientState, - direction: Direction, + _direction: Direction, _ctx: ExtEventSink, ) -> Result<Message, Error> { use libquassel::HandshakeDeserialize; @@ -183,31 +180,22 @@ impl Server { #[allow(unused_variables)] match res { - message::Message::SyncMessage(msg) => match msg.class_name.as_str() { - "AliasManager" => match msg.slot_name.as_str() { - "update" => ctx - .submit_command( - command::ALIASMANAGER_UPDATE, - SingleUse::new((direction, msg)), - Target::Global, - ) - .unwrap(), - _ => (), - }, - _ => (), - }, + message::Message::SyncMessage(msg) => ctx + .submit_command( + command::SYNCMESSAGE, + SingleUse::new((direction, msg)), + Target::Global, + ) + .unwrap(), message::Message::RpcCall(msg) => (), message::Message::InitRequest(msg) => (), - message::Message::InitData(msg) => match msg.init_data { - objects::Types::AliasManager(alias_manager) => ctx - .submit_command( - command::ALIASMANAGER_INIT, - SingleUse::new(alias_manager), - Target::Global, - ) - .unwrap(), - _ => (), - }, + message::Message::InitData(msg) => ctx + .submit_command( + command::INITDATA, + SingleUse::new((direction, msg)), + Target::Global, + ) + .unwrap(), message::Message::HeartBeat(msg) => (), message::Message::HeartBeatReply(msg) => (), } diff --git a/examples/statetracker/src/aliasmanager.rs b/examples/statetracker/src/widgets/aliasmanager.rs index afa8c91..afa8c91 100644 --- a/examples/statetracker/src/aliasmanager.rs +++ b/examples/statetracker/src/widgets/aliasmanager.rs diff --git a/examples/statetracker/src/widgets/bufferview.rs b/examples/statetracker/src/widgets/bufferview.rs new file mode 100644 index 0000000..c96f8d5 --- /dev/null +++ b/examples/statetracker/src/widgets/bufferview.rs @@ -0,0 +1,96 @@ +use std::sync::Arc; + +use druid::widget::{Align, Label}; +use druid::{lens, Lens, Point, WidgetPod}; +use druid::{widget::Flex, Widget}; + +use libquassel::message::objects::BufferViewManager; + +pub struct BufferViewWidget { + inner: WidgetPod<Arc<BufferViewManager>, Box<dyn Widget<Arc<BufferViewManager>>>>, +} + +impl BufferViewWidget { + pub fn new() -> Self { + let widget = WidgetPod::new(Flex::column()).boxed(); + + BufferViewWidget { inner: widget } + } +} + +impl Widget<Arc<BufferViewManager>> for BufferViewWidget { + fn event( + &mut self, + ctx: &mut druid::EventCtx, + event: &druid::Event, + data: &mut Arc<BufferViewManager>, + env: &druid::Env, + ) { + self.inner.event(ctx, event, data, env) + } + + fn lifecycle( + &mut self, + ctx: &mut druid::LifeCycleCtx, + event: &druid::LifeCycle, + data: &Arc<BufferViewManager>, + env: &druid::Env, + ) { + self.inner.lifecycle(ctx, event, data, env) + } + + fn update( + &mut self, + ctx: &mut druid::UpdateCtx, + _old_data: &Arc<BufferViewManager>, + data: &Arc<BufferViewManager>, + _env: &druid::Env, + ) { + let buffer_view_configs = lens!(BufferViewManager, buffer_view_configs); + + let mut names: Flex<Arc<BufferViewManager>> = Flex::column(); + let mut buffers: Flex<Arc<BufferViewManager>> = Flex::column(); + // let mut expansions: Flex<Arc<BufferViewManager>> = Flex::column(); + + // TODO optimise this whole thing + buffer_view_configs.with(data, |configs| { + for (_id, config) in configs { + names.add_child(Label::new(config.buffer_view_name.clone())); + buffers.add_child(Label::new(format!("{:?}", config.buffers))); + // expansions.add_child(Align::left(Label::new(alias.expansion.clone()))); + } + }); + + let widget: Flex<Arc<BufferViewManager>> = Flex::row() + .with_flex_child(names, 1.0) + .with_flex_child(buffers, 1.0); + // .with_flex_child(expansions, 1.0); + + self.inner = WidgetPod::new(widget).boxed(); + + ctx.children_changed(); + ctx.request_layout(); + ctx.request_paint(); + } + + fn layout( + &mut self, + ctx: &mut druid::LayoutCtx, + bc: &druid::BoxConstraints, + data: &Arc<BufferViewManager>, + env: &druid::Env, + ) -> druid::Size { + let size = self.inner.layout(ctx, bc, data, env); + self.inner.set_origin(ctx, data, env, Point::ZERO); + return size; + } + + fn paint( + &mut self, + ctx: &mut druid::PaintCtx, + data: &Arc<BufferViewManager>, + env: &druid::Env, + ) { + self.inner.paint(ctx, data, env) + } +} diff --git a/examples/statetracker/src/widgets/mod.rs b/examples/statetracker/src/widgets/mod.rs new file mode 100644 index 0000000..c837e5d --- /dev/null +++ b/examples/statetracker/src/widgets/mod.rs @@ -0,0 +1,5 @@ +mod aliasmanager; +mod bufferview; + +pub use aliasmanager::*; +pub use bufferview::*; |
