aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Audron <audron@cocaine.farm>2021-11-29 14:27:27 +0100
committerMax Audron <audron@cocaine.farm>2021-11-29 14:28:02 +0100
commit9df7c5c0e6d03579fa90735adf316d7e563340d7 (patch)
tree43118348a34a8f1715aaa384cc8e966c3af97506
parentadd feature list to readme (diff)
statetracker: add bufferview widget and do some reorganization
-rw-r--r--examples/statetracker/Cargo.toml2
-rw-r--r--examples/statetracker/src/command.rs14
-rw-r--r--examples/statetracker/src/formatter.rs3
-rw-r--r--examples/statetracker/src/main.rs123
-rw-r--r--examples/statetracker/src/server.rs46
-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.rs96
-rw-r--r--examples/statetracker/src/widgets/mod.rs5
8 files changed, 211 insertions, 78 deletions
diff --git a/examples/statetracker/Cargo.toml b/examples/statetracker/Cargo.toml
index 3ac9668..8290032 100644
--- a/examples/statetracker/Cargo.toml
+++ b/examples/statetracker/Cargo.toml
@@ -19,6 +19,8 @@ either = "1"
time = "0.2"
log = "*"
+crossbeam-channel = "0.5"
+
tokio = { version = "1", features = ["full", "rt-multi-thread"]}
tokio-util = { version = "0.6", features = ["codec"] }
tokio-rustls = { version = "0.22" }
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::*;