From 6f942c89404242301225537bba2d6f816ef54c83 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Mon, 13 Feb 2023 18:39:45 +0100 Subject: [PATCH] factor out r3vi and shell crates --- Cargo.toml | 14 +- nested/Cargo.toml | 1 + nested/src/commander.rs | 4 +- nested/src/core/channel.rs | 223 ---------- nested/src/core/mod.rs | 12 - nested/src/core/observer.rs | 179 -------- nested/src/core/port.rs | 341 --------------- nested/src/core/view.rs | 26 -- nested/src/diagnostics.rs | 8 +- nested/src/{ => editors}/char/mod.rs | 13 +- nested/src/{ => editors}/integer/add.rs | 14 +- nested/src/{ => editors}/integer/editor.rs | 105 +++-- nested/src/{ => editors}/integer/mod.rs | 0 nested/src/{ => editors}/integer/radix.rs | 10 +- nested/src/editors/list/commander.rs | 43 ++ nested/src/{ => editors}/list/cursor.rs | 0 nested/src/editors/list/editor.rs | 280 +++++++++++++ nested/src/editors/list/mod.rs | 15 + nested/src/{ => editors}/list/nav.rs | 17 +- nested/src/editors/list/pty_editor.rs | 432 +++++++++++++++++++ nested/src/{ => editors}/list/segment.rs | 14 +- nested/src/editors/mod.rs | 7 + nested/src/{ => editors}/product/editor.rs | 31 +- nested/src/{ => editors}/product/mod.rs | 0 nested/src/{ => editors}/product/nav.rs | 9 +- nested/src/{ => editors}/product/segment.rs | 6 +- nested/src/{ => editors}/sum/editor.rs | 27 +- nested/src/{ => editors}/sum/mod.rs | 0 nested/src/grid/buffer.rs | 90 ---- nested/src/grid/flatten.rs | 244 ----------- nested/src/grid/mod.rs | 74 ---- nested/src/grid/offset.rs | 15 - nested/src/grid/window_iterator.rs | 58 --- nested/src/index/buffer.rs | 156 ------- nested/src/index/map_item.rs | 107 ----- nested/src/index/map_key.rs | 145 ------- nested/src/index/mod.rs | 130 ------ nested/src/lib.rs | 55 +-- nested/src/list/editor.rs | 163 -------- nested/src/list/mod.rs | 12 - nested/src/list/pty_editor.rs | 216 ---------- nested/src/projection.rs | 239 ----------- nested/src/sequence/decorator.rs | 256 ------------ nested/src/sequence/enumerate.rs | 86 ---- nested/src/sequence/filter.rs | 160 ------- nested/src/sequence/flatten.rs | 183 -------- nested/src/sequence/map.rs | 105 ----- nested/src/sequence/mod.rs | 97 ----- nested/src/sequence/seq2idx.rs | 99 ----- nested/src/singleton/buffer.rs | 124 ------ nested/src/singleton/flatten.rs | 88 ---- nested/src/singleton/map.rs | 81 ---- nested/src/singleton/mod.rs | 66 --- nested/src/singleton/to_index.rs | 91 ---- nested/src/singleton/to_sequence.rs | 81 ---- nested/src/terminal/ansi_parser.rs | 13 +- nested/src/terminal/compositor.rs | 12 +- nested/src/terminal/mod.rs | 22 +- nested/src/terminal/terminal.rs | 12 +- nested/src/tree/cursor.rs | 2 +- nested/src/tree/nav.rs | 44 +- nested/src/tree/node.rs | 53 ++- nested/src/type_system/context.rs | 48 ++- nested/src/type_system/make_editor.rs | 188 ++++++--- nested/src/type_system/mod.rs | 1 + nested/src/type_system/repr_tree.rs | 9 +- nested/src/type_system/type_term_editor.rs | 59 +-- nested/src/vec/buffer.rs | 166 -------- nested/src/vec/mod.rs | 19 - nested/src/vec/vec2bin.rs | 81 ---- nested/src/vec/vec2json.rs | 110 ----- nested/src/vec/vec2seq.rs | 118 ------ rust-toolchain | 4 +- sdf_editor/Cargo.toml | 19 - sdf_editor/src/main.rs | 438 -------------------- shell/Cargo.toml | 16 - shell/gram2 | 93 ----- shell/grammar | 10 - shell/src/command.rs | 330 --------------- shell/src/incubator.rs | 18 - shell/src/main.rs | 302 -------------- shell/src/process.rs | 277 ------------- shell/src/pty.rs | 167 -------- 83 files changed, 1294 insertions(+), 6389 deletions(-) delete mode 100644 nested/src/core/channel.rs delete mode 100644 nested/src/core/mod.rs delete mode 100644 nested/src/core/observer.rs delete mode 100644 nested/src/core/port.rs delete mode 100644 nested/src/core/view.rs rename nested/src/{ => editors}/char/mod.rs (93%) rename nested/src/{ => editors}/integer/add.rs (89%) rename nested/src/{ => editors}/integer/editor.rs (65%) rename nested/src/{ => editors}/integer/mod.rs (100%) rename nested/src/{ => editors}/integer/radix.rs (94%) create mode 100644 nested/src/editors/list/commander.rs rename nested/src/{ => editors}/list/cursor.rs (100%) create mode 100644 nested/src/editors/list/editor.rs create mode 100644 nested/src/editors/list/mod.rs rename nested/src/{ => editors}/list/nav.rs (97%) create mode 100644 nested/src/editors/list/pty_editor.rs rename nested/src/{ => editors}/list/segment.rs (95%) create mode 100644 nested/src/editors/mod.rs rename nested/src/{ => editors}/product/editor.rs (94%) rename nested/src/{ => editors}/product/mod.rs (100%) rename nested/src/{ => editors}/product/nav.rs (98%) rename nested/src/{ => editors}/product/segment.rs (97%) rename nested/src/{ => editors}/sum/editor.rs (87%) rename nested/src/{ => editors}/sum/mod.rs (100%) delete mode 100644 nested/src/grid/buffer.rs delete mode 100644 nested/src/grid/flatten.rs delete mode 100644 nested/src/grid/mod.rs delete mode 100644 nested/src/grid/offset.rs delete mode 100644 nested/src/grid/window_iterator.rs delete mode 100644 nested/src/index/buffer.rs delete mode 100644 nested/src/index/map_item.rs delete mode 100644 nested/src/index/map_key.rs delete mode 100644 nested/src/index/mod.rs delete mode 100644 nested/src/list/editor.rs delete mode 100644 nested/src/list/mod.rs delete mode 100644 nested/src/list/pty_editor.rs delete mode 100644 nested/src/projection.rs delete mode 100644 nested/src/sequence/decorator.rs delete mode 100644 nested/src/sequence/enumerate.rs delete mode 100644 nested/src/sequence/filter.rs delete mode 100644 nested/src/sequence/flatten.rs delete mode 100644 nested/src/sequence/map.rs delete mode 100644 nested/src/sequence/mod.rs delete mode 100644 nested/src/sequence/seq2idx.rs delete mode 100644 nested/src/singleton/buffer.rs delete mode 100644 nested/src/singleton/flatten.rs delete mode 100644 nested/src/singleton/map.rs delete mode 100644 nested/src/singleton/mod.rs delete mode 100644 nested/src/singleton/to_index.rs delete mode 100644 nested/src/singleton/to_sequence.rs delete mode 100644 nested/src/vec/buffer.rs delete mode 100644 nested/src/vec/mod.rs delete mode 100644 nested/src/vec/vec2bin.rs delete mode 100644 nested/src/vec/vec2json.rs delete mode 100644 nested/src/vec/vec2seq.rs delete mode 100644 sdf_editor/Cargo.toml delete mode 100644 sdf_editor/src/main.rs delete mode 100644 shell/Cargo.toml delete mode 100644 shell/gram2 delete mode 100644 shell/grammar delete mode 100644 shell/src/command.rs delete mode 100644 shell/src/incubator.rs delete mode 100644 shell/src/main.rs delete mode 100644 shell/src/process.rs delete mode 100644 shell/src/pty.rs diff --git a/Cargo.toml b/Cargo.toml index 30c441b..641b295 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,10 @@ [workspace] members = [ "nested", - "terminal/display_server", - "terminal/ansi_parser", - "shell", - "sdf_editor", - "math/str2int", - "math/int2str", - "math/radix_transform", - "math/fib" +# "terminal/display_server", +# "terminal/ansi_parser", +# "math/str2int", +# "math/int2str", +# "math/radix_transform", +# "math/fib" ] diff --git a/nested/Cargo.toml b/nested/Cargo.toml index 0be90e1..90d6432 100644 --- a/nested/Cargo.toml +++ b/nested/Cargo.toml @@ -5,6 +5,7 @@ name = "nested" version = "0.1.0" [dependencies] +r3vi = { git = "https://git.exobiont.de/senvas/r3vi.git" } no_deadlocks = "*" cgmath = { version = "0.18.0", features = ["serde"] } termion = "1.5.5" diff --git a/nested/src/commander.rs b/nested/src/commander.rs index a274d2a..2a22027 100644 --- a/nested/src/commander.rs +++ b/nested/src/commander.rs @@ -7,9 +7,9 @@ pub trait Commander { use std::sync::{Arc, RwLock}; use crate::{ - type_system::ReprTree, - singleton::SingletonView + type_system::ReprTree }; +use r3vi::view::singleton::*; pub trait ObjCommander { fn send_cmd_obj(&mut self, cmd_obj: Arc>); diff --git a/nested/src/core/channel.rs b/nested/src/core/channel.rs deleted file mode 100644 index 806739a..0000000 --- a/nested/src/core/channel.rs +++ /dev/null @@ -1,223 +0,0 @@ -use { - crate::core::Observer, - async_std::stream::Stream, - core::{ - pin::Pin, - task::{Context, Poll, Waker}, - }, - std::{ - collections::HashSet, - hash::Hash, - sync::{Arc, Mutex}, - }, -}; - -/*\ -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - Traits -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - \*/ -pub trait ChannelData: Default + IntoIterator + Send + Sync { - fn channel_insert(&mut self, x: Self::Item); -} - -/*\ -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - Queue Channel -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - \*/ -impl ChannelData for Vec -where - T: Send + Sync, -{ - fn channel_insert(&mut self, x: T) { - self.push(x); - } -} - -/*\ -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - Set Channel -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - \*/ -impl ChannelData for HashSet -where - T: Eq + Hash + Send + Sync, -{ - fn channel_insert(&mut self, x: T) { - self.insert(x); - } -} - -/*\ -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - Singleton Channel -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - \*/ -impl ChannelData for Option -where - T: Send + Sync, -{ - fn channel_insert(&mut self, x: T) { - *self = Some(x); - } -} - -/*\ -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - Channel -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - \*/ -struct ChannelState { - send_buf: Option, - recv_iter: Option, - num_senders: usize, - waker: Option, -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct ChannelSender(Arc>>); -pub struct ChannelReceiver(Arc>>); - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl ChannelSender -where - Data::IntoIter: Send + Sync, -{ - pub fn send(&self, msg: Data::Item) { - let mut state = self.0.lock().unwrap(); - - if state.send_buf.is_none() { - state.send_buf = Some(Data::default()); - } - - state.send_buf.as_mut().unwrap().channel_insert(msg); - - if let Some(waker) = state.waker.take() { - waker.wake(); - } - } -} - -use crate::core::View; -impl> Observer for ChannelSender -where - V::Msg: Clone, - Data::IntoIter: Send + Sync, -{ - fn notify(&mut self, msg: &V::Msg) { - self.send(msg.clone()); - } -} - -impl Clone for ChannelSender { - fn clone(&self) -> Self { - self.0.lock().unwrap().num_senders += 1; - ChannelSender(self.0.clone()) - } -} - -impl Drop for ChannelSender { - fn drop(&mut self) { - let mut state = self.0.lock().unwrap(); - state.num_senders -= 1; - if let Some(waker) = state.waker.take() { - waker.wake(); - } - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl ChannelReceiver { - pub async fn recv(&self) -> Option { - ChannelRead(self.0.clone()).await - } - - pub fn try_recv(&self) -> Option { - let mut state = self.0.lock().unwrap(); - if let Some(buf) = state.send_buf.take() { - Some(buf) - } else { - None - } - } -} - -struct ChannelRead(Arc>>); -impl std::future::Future for ChannelRead { - type Output = Option; - - fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { - let mut state = self.0.lock().unwrap(); - if let Some(buf) = state.send_buf.take() { - Poll::Ready(Some(buf)) - } else if state.num_senders == 0 { - Poll::Ready(None) - } else { - state.waker = Some(cx.waker().clone()); - Poll::Pending - } - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl Stream for ChannelReceiver { - type Item = Data::Item; - - fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - let mut state = self.0.lock().unwrap(); - - if let Some(recv_iter) = state.recv_iter.as_mut() { - if let Some(val) = recv_iter.next() { - return Poll::Ready(Some(val)); - } else { - state.recv_iter = None - } - } - - if let Some(send_buf) = state.send_buf.take() { - state.recv_iter = Some(send_buf.into_iter()); - // recv_iter.next() is guaranteed to be Some(x) - Poll::Ready(state.recv_iter.as_mut().unwrap().next()) - } else if state.num_senders == 0 { - Poll::Ready(None) - } else { - state.waker = Some(cx.waker().clone()); - Poll::Pending - } - } -} - -/*\ -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - Factory Functions -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - \*/ -pub fn channel() -> (ChannelSender, ChannelReceiver) { - let state = Arc::new(Mutex::new(ChannelState { - send_buf: None, - recv_iter: None, - num_senders: 1, - waker: None, - })); - - (ChannelSender(state.clone()), ChannelReceiver(state)) -} - -pub fn set_channel( -) -> (ChannelSender>, ChannelReceiver>) { - channel::>() -} - -pub fn queue_channel() -> (ChannelSender>, ChannelReceiver>) { - channel::>() -} - -pub fn singleton_channel() -> (ChannelSender>, ChannelReceiver>) -{ - channel::>() -} diff --git a/nested/src/core/mod.rs b/nested/src/core/mod.rs deleted file mode 100644 index fb89afb..0000000 --- a/nested/src/core/mod.rs +++ /dev/null @@ -1,12 +0,0 @@ -pub mod channel; -pub mod observer; -pub mod port; -pub mod view; - -pub use { - channel::{queue_channel, set_channel, singleton_channel, ChannelReceiver, ChannelSender}, - observer::{NotifyFnObserver, Observer, ObserverBroadcast, ObserverExt, ResetFnObserver}, - port::{AnyInnerViewPort, AnyOuterViewPort, AnyViewPort, InnerViewPort, OuterViewPort, ViewPort}, - view::View -}; - diff --git a/nested/src/core/observer.rs b/nested/src/core/observer.rs deleted file mode 100644 index 510f44f..0000000 --- a/nested/src/core/observer.rs +++ /dev/null @@ -1,179 +0,0 @@ -use { - crate::core::{ - channel::{channel, ChannelReceiver, ChannelSender}, - View, - }, - std::sync::RwLock, - std::sync::{Arc, Weak}, -}; - - /*\ -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - Observer -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - \*/ -pub trait Observer: Send + Sync { - fn reset(&mut self, _view: Option>) {} - fn notify(&mut self, msg: &V::Msg); -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl> Observer for Arc> { - fn reset(&mut self, view: Option>) { - self.write().unwrap().reset(view); - } - - fn notify(&mut self, msg: &V::Msg) { - self.write().unwrap().notify(msg); - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub trait ObserverExt: Observer { - fn notify_each(&mut self, it: impl IntoIterator); -} - -impl> ObserverExt for T { - fn notify_each(&mut self, it: impl IntoIterator) { - for msg in it { - self.notify(&msg); - } - } -} - - /*\ -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - Broadcast -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - \*/ -pub struct ObserverBroadcast -where - V::Msg: Send + Sync, -{ - rx: ChannelReceiver>, - tx: ChannelSender>, - observers: Vec>>>, -} - -impl ObserverBroadcast -where - V::Msg: Clone + Send + Sync, -{ - pub fn new() -> Self { - let (tx, rx) = channel::>(); - ObserverBroadcast { - rx, - tx, - observers: Vec::new(), - } - } - - pub fn add_observer(&mut self, obs: Weak>>) { - self.cleanup(); - self.observers.push(obs); - } - - fn cleanup(&mut self) { - self.observers.retain(|o| o.strong_count() > 0); - } - - fn iter(&self) -> impl Iterator>>> + '_ { - self.observers.iter().filter_map(|o| o.upgrade()) - } - - pub fn update(&self) { - if let Some(msg_vec) = self.rx.try_recv() { - for msg in msg_vec { - for o in self.iter() { - o.write().unwrap().notify(&msg); - } - } - } - } -} - -impl Observer for ObserverBroadcast -where - V::Msg: Clone, -{ - fn reset(&mut self, view: Option>) { - for o in self.iter() { - o.write().unwrap().reset(view.clone()); - } - } - - fn notify(&mut self, msg: &V::Msg) { - self.tx.send(msg.clone()); - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct NotifyFnObserver -where - V: View + ?Sized, - F: Fn(&V::Msg) + Send + Sync, -{ - f: F, - _phantom: std::marker::PhantomData, -} - -impl NotifyFnObserver -where - V: View + ?Sized, - F: Fn(&V::Msg) + Send + Sync, -{ - pub fn new(f: F) -> Self { - NotifyFnObserver { - f, - _phantom: std::marker::PhantomData, - } - } -} - -impl Observer for NotifyFnObserver -where - V: View + ?Sized, - F: Fn(&V::Msg) + Send + Sync, -{ - fn notify(&mut self, msg: &V::Msg) { - (self.f)(msg); - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct ResetFnObserver -where - V: View + ?Sized, - F: Fn(Option>) + Send + Sync, -{ - f: F, - _phantom: std::marker::PhantomData, -} - -impl ResetFnObserver -where - V: View + ?Sized, - F: Fn(Option>) + Send + Sync, -{ - pub fn new(f: F) -> Self { - ResetFnObserver { - f, - _phantom: std::marker::PhantomData, - } - } -} - -impl Observer for ResetFnObserver -where - V: View + ?Sized, - F: Fn(Option>) + Send + Sync, -{ - fn notify(&mut self, _msg: &V::Msg) {} - fn reset(&mut self, view: Option>) { - (self.f)(view); - } -} diff --git a/nested/src/core/port.rs b/nested/src/core/port.rs deleted file mode 100644 index b148e04..0000000 --- a/nested/src/core/port.rs +++ /dev/null @@ -1,341 +0,0 @@ -use { - crate::core::{NotifyFnObserver, Observer, ObserverBroadcast, ResetFnObserver, View}, - std::any::Any, - std::sync::Arc, - std::sync::RwLock, -}; - -pub trait UpdateTask: Send + Sync { - fn update(&self); -} - - /*\ -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - View Port -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - \*/ -pub struct ViewPort { - view: Arc>>>, - cast: Arc>>, - pub update_hooks: Arc>>>, -} - -impl ViewPort -where - V::Msg: Clone, -{ - pub fn new() -> Self { - ViewPort { - view: Arc::new(RwLock::new(None)), - cast: Arc::new(RwLock::new(ObserverBroadcast::new())), - update_hooks: Arc::new(RwLock::new(Vec::new())), - } - } - - pub fn with_view(view: Arc) -> Self { - let port = ViewPort::new(); - port.set_view(Some(view)); - port - } - - pub fn set_view(&self, view: Option>) { - self.update(); - *self.view.write().unwrap() = view.clone(); - self.cast.write().unwrap().reset(view); - } - - pub fn get_cast(&self) -> Arc>> { - self.cast.clone() - } - - pub fn add_observer(&self, observer: Arc>>) { - self.update(); - self.cast - .write() - .unwrap() - .add_observer(Arc::downgrade(&observer)); - - observer - .write() - .unwrap() - .reset(self.view.read().unwrap().clone()); - } - - pub fn add_update_hook(&self, hook_cast: Arc) { - self.update_hooks.write().unwrap().push(hook_cast); - } - - pub fn inner(&self) -> InnerViewPort { - InnerViewPort(ViewPort { - view: self.view.clone(), - cast: self.cast.clone(), - update_hooks: self.update_hooks.clone(), - }) - } - - pub fn outer(&self) -> OuterViewPort { - OuterViewPort(ViewPort { - view: self.view.clone(), - cast: self.cast.clone(), - update_hooks: self.update_hooks.clone(), - }) - } - - pub fn into_inner(self) -> InnerViewPort { - InnerViewPort(ViewPort { - view: self.view, - cast: self.cast, - update_hooks: self.update_hooks, - }) - } - - pub fn into_outer(self) -> OuterViewPort { - OuterViewPort(ViewPort { - view: self.view, - cast: self.cast, - update_hooks: self.update_hooks, - }) - } -} - -impl UpdateTask for ViewPort -where - V::Msg: Clone + Send + Sync, -{ - fn update(&self) { - let v = { - let t = self.update_hooks.read().unwrap(); - t.iter().cloned().collect::>() - }; - - for hook in v { - hook.update(); - } - - self.cast.read().unwrap().update(); - } -} - -impl Clone for ViewPort -where - V::Msg: Clone, -{ - fn clone(&self) -> Self { - ViewPort { - view: self.view.clone(), - cast: self.cast.clone(), - update_hooks: self.update_hooks.clone(), - } - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct InnerViewPort(pub ViewPort) -where - V::Msg: Clone; -pub struct OuterViewPort(pub ViewPort) -where - V::Msg: Clone; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl InnerViewPort -where - V::Msg: Clone, -{ - pub fn get_broadcast(&self) -> Arc>> { - self.0.cast.clone() - } - - pub fn set_view(&self, view: Option>) -> Arc>> { - self.0.set_view(view); - self.get_broadcast() - } - - pub fn get_view(&self) -> Option> { - self.0.view.read().unwrap().clone() - } - - pub fn notify(&self, msg: &V::Msg) { - self.0.cast.write().unwrap().notify(msg); - } -} - -impl Clone for InnerViewPort -where - V::Msg: Clone, -{ - fn clone(&self) -> Self { - InnerViewPort(self.0.clone()) - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl OuterViewPort -where - V::Msg: Clone, -{ - pub fn get_view(&self) -> Option> { - self.0.view.read().unwrap().clone() - } - - pub fn get_view_arc(&self) -> Arc>>> { - self.0.view.clone() - } - - pub fn add_observer( - &self, - observer: Arc>>, - ) -> Arc>>> { - self.0.add_observer(observer); - self.get_view_arc() - } - - pub fn add_reset_fn>) + Send + Sync + 'static>( - &self, - reset: F, - ) -> Arc>> { - let obs = Arc::new(RwLock::new(ResetFnObserver::new(reset))); - self.add_observer(obs.clone()); - obs - } - - pub fn add_notify_fn( - &self, - notify: F, - ) -> Arc>> { - let obs = Arc::new(RwLock::new(NotifyFnObserver::new(notify))); - self.add_observer(obs.clone()); - obs - } -} - -impl Clone for OuterViewPort -where - V::Msg: Clone, -{ - fn clone(&self) -> Self { - OuterViewPort(self.0.clone()) - } -} - -impl Default for OuterViewPort -where V::Msg: Clone -{ - fn default() -> Self { - ViewPort::new().into_outer() - } -} - -/* -impl OuterViewPort -where V::Msg: Clone { - pub fn into_stream( - self, - reset: impl Fn(Option>, ChannelSender) + Send + Sync + 'static - ) -> ChannelReceiver - where Data: ChannelData + 'static, - Data::IntoIter: Send + Sync + 'static - { - let (s, r) = crate::core::channel::channel::(); - self.add_observer(Arc::new(s.clone())); - self.add_reset_fn( - move |view| { reset(view, s.clone()); } - ); - r - } -} -*/ - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -#[derive(Clone)] -pub struct AnyViewPort { - view: Arc, - cast: Arc, - update_hooks: Arc>>>, -} - -impl AnyViewPort { - pub fn downcast(self) -> Result, AnyViewPort> { - match ( - self.view.clone().downcast::>>>(), - self.cast.clone().downcast::>>(), - self.update_hooks.clone(), - ) { - (Ok(view), Ok(cast), update_hooks) => Ok(ViewPort { - view, - cast, - update_hooks, - }), - _ => Err(self), - } - } -} - -impl From> for AnyViewPort { - fn from(port: ViewPort) -> Self { - AnyViewPort { - view: port.view as Arc, - cast: port.cast as Arc, - update_hooks: port.update_hooks, - } - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -#[derive(Clone)] -pub struct AnyOuterViewPort(AnyViewPort); - -#[derive(Clone)] -pub struct AnyInnerViewPort(AnyViewPort); - -impl AnyOuterViewPort { - pub fn downcast(self) -> Result, AnyViewPort> - where - V::Msg: Clone, - { - Ok(OuterViewPort(self.0.downcast::()?)) - } -} - -impl From> for AnyOuterViewPort -where - V::Msg: Clone, -{ - fn from(port: OuterViewPort) -> Self { - AnyOuterViewPort(AnyViewPort { - view: port.0.view as Arc, - cast: port.0.cast as Arc, - update_hooks: port.0.update_hooks, - }) - } -} - -impl AnyInnerViewPort { - pub fn downcast(self) -> Result, AnyViewPort> - where - V::Msg: Clone, - { - Ok(InnerViewPort(self.0.downcast::()?)) - } -} - -impl From> for AnyInnerViewPort -where - V::Msg: Clone, -{ - fn from(port: InnerViewPort) -> Self { - AnyInnerViewPort(AnyViewPort { - view: port.0.view as Arc, - cast: port.0.cast as Arc, - update_hooks: port.0.update_hooks, - }) - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - diff --git a/nested/src/core/view.rs b/nested/src/core/view.rs deleted file mode 100644 index 109999d..0000000 --- a/nested/src/core/view.rs +++ /dev/null @@ -1,26 +0,0 @@ - /*\ -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - View -<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - \*/ -pub trait View: Send + Sync { - /// Notification message for the observers - type Msg: Send + Sync; -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -use std::sync::Arc; -use std::sync::RwLock; - -impl View for RwLock { - type Msg = V::Msg; -} - -impl View for Arc { - type Msg = V::Msg; -} - -impl View for Option { - type Msg = V::Msg; -} diff --git a/nested/src/diagnostics.rs b/nested/src/diagnostics.rs index 0706538..638bdbe 100644 --- a/nested/src/diagnostics.rs +++ b/nested/src/diagnostics.rs @@ -1,9 +1,9 @@ use { + r3vi::{ + view::{OuterViewPort, sequence::*}, + buffer::{vec::*, index_hashmap::*} + }, crate::{ - core::{OuterViewPort}, - sequence::{SequenceView}, - vec::{VecBuffer}, - index::{buffer::IndexBuffer}, terminal::{ TerminalView, TerminalStyle, make_label } diff --git a/nested/src/char/mod.rs b/nested/src/editors/char/mod.rs similarity index 93% rename from nested/src/char/mod.rs rename to nested/src/editors/char/mod.rs index 53ab476..cee05de 100644 --- a/nested/src/char/mod.rs +++ b/nested/src/editors/char/mod.rs @@ -1,8 +1,13 @@ use { + r3vi::{ + view::{ + OuterViewPort, + singleton::*, + }, + buffer::singleton::* + }, crate::{ - core::{OuterViewPort}, type_system::{Context}, - singleton::{SingletonBuffer, SingletonView}, terminal::{TerminalAtom, TerminalEvent, TerminalStyle}, tree::NestedNode, commander::Commander @@ -70,11 +75,11 @@ impl CharEditor { ) } } - +/* use crate::StringGen; impl StringGen for CharEditor { fn get_string(&self) -> String { String::from(self.get()) } } - +*/ diff --git a/nested/src/integer/add.rs b/nested/src/editors/integer/add.rs similarity index 89% rename from nested/src/integer/add.rs rename to nested/src/editors/integer/add.rs index 888234a..a1ef911 100644 --- a/nested/src/integer/add.rs +++ b/nested/src/editors/integer/add.rs @@ -1,9 +1,13 @@ use { - crate::{ - core::{InnerViewPort, OuterViewPort}, - projection::ProjectionHelper, - sequence::SequenceView, - vec::VecBuffer, + r3vi::{ + view::{ + InnerViewPort, OuterViewPort, + sequence::*, + }, + buffer::{ + vec::* + }, + projection::projection_helper::*, }, std::sync::{Arc, RwLock}, }; diff --git a/nested/src/integer/editor.rs b/nested/src/editors/integer/editor.rs similarity index 65% rename from nested/src/integer/editor.rs rename to nested/src/editors/integer/editor.rs index c500899..7578b16 100644 --- a/nested/src/integer/editor.rs +++ b/nested/src/editors/integer/editor.rs @@ -1,26 +1,29 @@ use { - crate::{ - core::{OuterViewPort}, - type_system::{Context, TypeTerm}, - list::{PTYListEditor}, - sequence::{SequenceView, SequenceViewExt, decorator::{PTYSeqDecorate, SeqDecorStyle}}, - singleton::{SingletonBuffer, SingletonView}, - vec::{VecBuffer}, - index::{buffer::IndexBuffer}, - terminal::{ - TerminalAtom, TerminalEditor, TerminalEditorResult, TerminalEvent, TerminalStyle, - TerminalView, make_label + r3vi::{ + view::{ + OuterViewPort, + singleton::*, }, - tree::{TreeCursor, TreeNav, TreeNavResult}, - diagnostics::{Diagnostics, Message}, + buffer::{ + singleton::*, + vec::*, + index_hashmap::* + } + }, + crate::{ + type_system::{Context, TypeTerm, ReprTree}, + editors::list::{PTYListEditor, ListStyle}, + terminal::{ + TerminalAtom, TerminalEvent, TerminalStyle, make_label + }, + diagnostics::{Message}, tree::NestedNode, - Nested, commander::Commander }, std::sync::Arc, std::sync::RwLock, termion::event::{Event, Key}, - cgmath::{Vector2, Point2} + cgmath::{Point2} }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> @@ -74,13 +77,15 @@ impl DigitEditor { } pub fn into_node(self) -> NestedNode { + let data = self.get_data(); let editor = Arc::new(RwLock::new(self)); - let ed = editor.read().unwrap(); + let mut ed = editor.write().unwrap(); let r = ed.radix; NestedNode::new() .set_ctx(ed.ctx.clone()) .set_cmd(editor.clone()) + .set_data(data) .set_view( ed.data .get_port() @@ -106,6 +111,26 @@ impl DigitEditor { let radix = self.radix; self.data.get_port().map(move |c| c?.to_digit(radix)) } + + pub fn get_type(&self) -> TypeTerm { + TypeTerm::Type { + id: self.ctx.read().unwrap().get_typeid("Digit").unwrap(), + args: vec![ + TypeTerm::Num(self.radix as i64) + ] + } + } + + pub fn get_data(&self) -> Arc> { + let data_view = self.get_data_port(); + ReprTree::ascend( + &ReprTree::new_leaf( + self.ctx.read().unwrap().type_term_from_str("( u32 )").unwrap(), + data_view.into() + ), + self.get_type() + ) + } } pub struct PosIntEditor { @@ -115,24 +140,40 @@ pub struct PosIntEditor { impl PosIntEditor { pub fn new(ctx: Arc>, radix: u32) -> Self { + let mut node = PTYListEditor::new( + ctx.clone(), + TypeTerm::Type { + id: ctx.read().unwrap().get_typeid("Digit").unwrap(), + args: vec![ + TypeTerm::Num(radix as i64) + ] + }, + match radix { + 16 => ListStyle::Hex, + _ => ListStyle::Plain + }, + 0 + ).into_node(); + + // Set Type + let data = node.data.clone().unwrap(); + node = node.set_data(ReprTree::ascend( + &data, + TypeTerm::Type { + id: ctx.read().unwrap().get_typeid("PosInt").unwrap(), + args: vec![ + TypeTerm::Num(radix as i64), + TypeTerm::Type { + id: ctx.read().unwrap().get_typeid("BigEndian").unwrap(), + args: vec![] + } + ] + } + )); + PosIntEditor { radix, - digits: PTYListEditor::new( - ctx.clone(), - TypeTerm::Type { - id: ctx.read().unwrap().get_typeid("Digit").unwrap(), - args: vec![ - TypeTerm::Num(radix as i64) - ] - }, - None, - 0 - ).into_node( - match radix { - 16 => SeqDecorStyle::Hex, - _ => SeqDecorStyle::Plain - } - ) + digits: node } } diff --git a/nested/src/integer/mod.rs b/nested/src/editors/integer/mod.rs similarity index 100% rename from nested/src/integer/mod.rs rename to nested/src/editors/integer/mod.rs diff --git a/nested/src/integer/radix.rs b/nested/src/editors/integer/radix.rs similarity index 94% rename from nested/src/integer/radix.rs rename to nested/src/editors/integer/radix.rs index 9d53504..bcc12da 100644 --- a/nested/src/integer/radix.rs +++ b/nested/src/editors/integer/radix.rs @@ -1,8 +1,10 @@ use { - crate::{ - core::{InnerViewPort, Observer, OuterViewPort}, - sequence::SequenceView, - vec::VecBuffer, + r3vi::{ + view::{ + InnerViewPort, Observer, OuterViewPort, + sequence::*, + }, + buffer::{vec::*} }, std::sync::{Arc, RwLock}, }; diff --git a/nested/src/editors/list/commander.rs b/nested/src/editors/list/commander.rs new file mode 100644 index 0000000..be4cca2 --- /dev/null +++ b/nested/src/editors/list/commander.rs @@ -0,0 +1,43 @@ + +use { + crate::{ + editors::list::ListEditor + }, + std::sync::{Arc, RwLock} +}; + +pub enum ListEditorCmd { + ItemCmd(Arc>) + Split, + Join +} + +impl ObjCommander for ListEditor { + fn send_cmd_obj(&mut self, cmd_obj: Arc>) { + let cmd_repr = cmd_obj.read().unrwap(); + + if let Some(cmd) = cmd_repr.get_view>() { + match cmd.get() { + ListEditorCmd::Split => { + + } + ListEditorCmd::Join => { + + } + ListEditorCmd::ItemCmd => { + if let Some(cur_item) = self.get_item_mut() { + drop(cmd); + drop(cmd_repr); + cur_item.send_cmd_obj(cmd_obj); + } + } + } + } else { + if let Some(cur_item) = self.get_item_mut() { + drop(cmd_repr); + cur_item.send_cmd_obj(cmd_obj); + } + } + } +} + diff --git a/nested/src/list/cursor.rs b/nested/src/editors/list/cursor.rs similarity index 100% rename from nested/src/list/cursor.rs rename to nested/src/editors/list/cursor.rs diff --git a/nested/src/editors/list/editor.rs b/nested/src/editors/list/editor.rs new file mode 100644 index 0000000..43b8656 --- /dev/null +++ b/nested/src/editors/list/editor.rs @@ -0,0 +1,280 @@ +use { + r3vi::{ + view::{ + OuterViewPort, + singleton::*, + sequence::*, + }, + buffer::{ + singleton::*, + vec::*, + } + }, + crate::{ + type_system::{Context, TypeTerm, ReprTree}, + editors::list::{ + ListCursor, + ListCursorMode + }, + tree::{NestedNode, TreeNav} + }, + std::sync::{Arc, RwLock}, +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +pub struct ListEditor { + pub(super) cursor: SingletonBuffer, + pub(crate) data: VecBuffer, + + pub(super) addr_port: OuterViewPort>, + pub(super) mode_port: OuterViewPort>, + + pub(crate) ctx: Arc>, + + /// item type + pub(super) typ: TypeTerm, +} + +impl ListEditor { + pub fn new( + ctx: Arc>, + typ: TypeTerm, + ) -> Self { + let cursor = SingletonBuffer::new(ListCursor::default()); + let data = VecBuffer::::new(); + + ListEditor { + mode_port: cursor + .get_port() + .map({ + let data = data.clone(); + move |c| { + let ip = SingletonBuffer::new(c.mode).get_port(); + match c.mode { + ListCursorMode::Insert => ip, + ListCursorMode::Select => { + if let Some(idx) = c.idx { + data.get(idx as usize).get_mode_view() + } else { + ip + } + } + } + } + }) + .flatten(), + + addr_port: VecBuffer::>>::with_data( + vec![ + cursor.get_port() + .to_sequence() + .filter_map(|cur| cur.idx), + cursor.get_port() + .map({ + let data = data.clone(); + move |cur| { + if cur.mode == ListCursorMode::Select { + if let Some(idx) = cur.idx { + if idx >= 0 && idx < data.len() as isize { + return data.get(idx as usize).get_addr_view(); + } + } + } + OuterViewPort::default() + } + }) + .to_sequence() + .flatten() + ]) + .get_port() + .to_sequence() + .flatten(), + cursor, + data, + ctx, + typ, + } + } + + pub fn get_item_type(&self) -> TypeTerm { + self.typ.clone() + } + + pub fn get_seq_type(&self) -> TypeTerm { + TypeTerm::Type { + id: self.ctx.read().unwrap().get_typeid("Sequence").unwrap(), + args: vec![ self.get_item_type() ] + } + } + + pub fn into_node(self) -> NestedNode { + let data = self.get_data(); + let editor = Arc::new(RwLock::new(self)); + + NestedNode::new() + .set_data(data) + .set_editor(editor.clone()) + .set_nav(editor.clone()) +// .set_cmd(editor.clone()) + } + + pub fn get_cursor_port(&self) -> OuterViewPort> { + self.cursor.get_port() + } + + pub fn get_data_port(&self) -> OuterViewPort> { + self.data.get_port().to_sequence() + } + + pub fn get_data(&self) -> Arc> { + let data_view = self.get_data_port(); + ReprTree::new_leaf( + self.get_seq_type(), + data_view.into() + ) + } + + pub fn get_item(&self) -> Option { + if let Some(idx) = self.cursor.get().idx { + let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize; + if idx < self.data.len() { + Some(self.data.get(idx)) + } else { + None + } + } else { + None + } + } + + pub fn get_item_mut(&mut self) -> Option> { + if let Some(idx) = self.cursor.get().idx { + let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize; + if idx < self.data.len() { + Some(self.data.get_mut(idx)) + } else { + None + } + } else { + None + } + } + + pub fn is_listlist(&self) -> bool { + self.ctx.read().unwrap().is_list_type(&self.typ) + /* + match self.typ.clone() { + TypeTerm::Type { id, args } => { + id == self.ctx.read().unwrap().get_typeid("List").unwrap() + }, + TypeTerm::Num(_) => false + } + */ + } + + /// delete all items + pub fn clear(&mut self) { + self.data.clear(); + self.cursor.set(ListCursor::home()); + } + + /// delete item before the cursor + pub fn delete_pxev(&mut self) { + let mut cur = self.cursor.get(); + if let Some(idx) = cur.idx { + if idx > 0 && idx <= self.data.len() as isize { + cur.idx = Some(idx as isize - 1); + self.cursor.set(cur); + self.data.remove(idx as usize - 1); + } + } + } + + /// delete item after the cursor + pub fn delete_nexd(&mut self) { + if let Some(idx) = self.cursor.get().idx { + if idx < self.data.len() as isize { + self.data.remove(idx as usize); + } + } + } + + /// insert a new element + pub fn insert(&mut self, item: NestedNode) { + let mut cur = self.cursor.get(); + if let Some(idx) = cur.idx { + + match cur.mode { + ListCursorMode::Insert => { + self.data.insert(idx as usize, item.clone()); + if self.is_listlist() { + cur.mode = ListCursorMode::Select; + } else { + cur.idx = Some(idx + 1); + } + } + + ListCursorMode::Select => { + self.data.insert(1 + idx as usize, item.clone()); + if self.is_listlist() { + cur.idx = Some(idx + 1); + } + } + } + + self.cursor.set(cur); + } + } + + /// split the list off at the current cursor position and return the second half + pub fn split(&mut self) -> ListEditor { + let mut le = ListEditor::new(self.ctx.clone(), self.typ.clone()); + + let cur = self.cursor.get(); + if let Some(idx) = cur.idx { + let idx = idx as usize; + for _ in idx .. self.data.len() { + le.data.push( self.data.get(idx) ); + self.data.remove(idx); + } + } + + le + } + + /// append data of other editor at the end and set cursor accordingly + pub fn join(&mut self, other: &ListEditor) { + let selfcur = self.cursor.get(); + let othercur = other.cursor.get(); + + let is_bottom = self.get_cursor().tree_addr.len() == 1 || + other.get_cursor().tree_addr.len() == 1; + + let is_insert = + selfcur.mode == ListCursorMode::Insert + || othercur.mode == ListCursorMode::Insert; + + let is_primary = self.get_cursor().tree_addr.len() > 1; + + self.cursor.set(ListCursor { + mode: if is_insert && is_bottom { + ListCursorMode::Insert + } else { + ListCursorMode::Select + }, + idx: Some(self.data.len() as isize - + if is_primary { + 1 + } else { + 0 + } + ) + }); + + for i in 0 .. other.data.len() { + self.data.push(other.data.get(i)); + } + } +} + diff --git a/nested/src/editors/list/mod.rs b/nested/src/editors/list/mod.rs new file mode 100644 index 0000000..e67db33 --- /dev/null +++ b/nested/src/editors/list/mod.rs @@ -0,0 +1,15 @@ + + +pub mod cursor; +pub mod editor; +pub mod nav; +pub mod segment; +pub mod pty_editor; + +pub use { + cursor::{ListCursor, ListCursorMode}, + editor::ListEditor, + segment::{ListSegment, ListSegmentSequence}, + pty_editor::{ListStyle, PTYListEditor} +}; + diff --git a/nested/src/list/nav.rs b/nested/src/editors/list/nav.rs similarity index 97% rename from nested/src/list/nav.rs rename to nested/src/editors/list/nav.rs index 920d174..a2a3b74 100644 --- a/nested/src/list/nav.rs +++ b/nested/src/editors/list/nav.rs @@ -1,14 +1,17 @@ use { + r3vi::{ + view::{ + OuterViewPort, + singleton::*, + sequence::* + } + }, crate::{ - core::{OuterViewPort}, - sequence::{SequenceView}, - list::{ + editors::list::{ ListCursor, ListCursorMode, - ListEditor + editor::ListEditor }, - tree::{TreeCursor, TreeNav, TreeNavResult}, - singleton::SingletonView, - Nested + tree::{TreeCursor, TreeNav, TreeNavResult} }, cgmath::Vector2 }; diff --git a/nested/src/editors/list/pty_editor.rs b/nested/src/editors/list/pty_editor.rs new file mode 100644 index 0000000..3e81118 --- /dev/null +++ b/nested/src/editors/list/pty_editor.rs @@ -0,0 +1,432 @@ +use { + r3vi::{ + view::{ + OuterViewPort, + sequence::*, + }, + projection::decorate_sequence::*, + }, + crate::{ + type_system::{Context, TypeTerm, ReprTree}, + editors::list::{ + ListCursor, ListCursorMode, + segment::{ListSegmentSequence}, + editor::ListEditor + }, + terminal::{ + TerminalEditor, TerminalEvent, + TerminalView, + make_label + }, + tree::{TreeCursor, TreeNav}, + diagnostics::{Diagnostics, make_error}, + tree::NestedNode, + commander::Commander, + PtySegment + }, + std::sync::{Arc, RwLock}, + termion::event::{Event, Key} +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +#[derive(Clone, Copy)] +pub enum ListStyle { + Plain, + HorizontalSexpr, + VerticalSexpr, + DoubleQuote, + Tuple, + EnumSet, + Path, + Hex +} + +pub fn list_style_from_type( + ctx: &Arc>, + typ: &TypeTerm +) -> Option { + let ctx = ctx.read().unwrap(); + + match typ { + TypeTerm::Type { + id, args + } => { + if *id == ctx.get_typeid("List").unwrap() { + Some(ListStyle::HorizontalSexpr) + } else if *id == ctx.get_typeid("String").unwrap() { + Some(ListStyle::DoubleQuote) + } else if *id == ctx.get_typeid("Symbol").unwrap() { + Some(ListStyle::Plain) + } else if *id == ctx.get_typeid("PathSegment").unwrap() { + Some(ListStyle::Plain) + } else if *id == ctx.get_typeid("Path").unwrap() { + Some(ListStyle::Path) + } else if *id == ctx.get_typeid("PosInt").unwrap() { + if args.len() > 0 { + match args[0] { + TypeTerm::Num(radix) => { + match radix { + 16 => Some(ListStyle::Hex), + _ => Some(ListStyle::Plain) + } + } + _ => None + } + } else { + None + } + } else { + None + } + } + + _ => None + } +} + +impl ListStyle { + fn get_split_char(&self) -> Option { + match self { + ListStyle::Plain => None, + ListStyle::DoubleQuote => None, + ListStyle::HorizontalSexpr => Some(' '), + ListStyle::VerticalSexpr => Some('\n'), + ListStyle::Tuple => Some(','), + ListStyle::EnumSet => Some(','), + ListStyle::Path => Some('/'), + ListStyle::Hex => None + } + } + + fn get_wrapper(&self) -> (&str, &str) { + match self { + ListStyle::Plain => ("", ""), + ListStyle::HorizontalSexpr => ("(", ")"), + ListStyle::VerticalSexpr => ("(", ")"), + ListStyle::DoubleQuote => ("\"", "\""), + ListStyle::Tuple => ("(", ")"), + ListStyle::EnumSet => ("{", "}"), + ListStyle::Path => ("<", ">"), + ListStyle::Hex => ("0x", "") + } + } +} + +pub struct PTYListEditor { + pub editor: Arc>, + style: ListStyle, + depth: usize +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl PTYListEditor { + pub fn new( + ctx: Arc>, + typ: TypeTerm, + style: ListStyle, + depth: usize + ) -> Self { + Self::from_editor( + Arc::new(RwLock::new(ListEditor::new(ctx, typ))), style, depth) + } + + pub fn from_editor( + editor: Arc>, + style: ListStyle, + depth: usize + ) -> Self { + PTYListEditor { + style, + depth, + editor, + } + } + + pub fn get_seg_seq_view(&self) -> OuterViewPort>> { + let seg_seq = ListSegmentSequence::new( + self.editor.read().unwrap().get_cursor_port(), + self.editor.read().unwrap().get_data_port(), + self.depth + ); + let se = seg_seq.read().unwrap(); + se.get_view().map(move |segment| segment.pty_view()) + } + + pub fn pty_view(&self) -> OuterViewPort { + let editor = self.editor.read().unwrap(); + + let seg_seq = ListSegmentSequence::new( + editor.get_cursor_port(), + editor.get_data_port(), + self.depth + ); + let seg_seq = seg_seq.read().unwrap(); + + seg_seq + .get_view() + .map(move |segment| segment.pty_view()) + .separate(make_label(&if let Some(c) = self.style.get_split_char() { format!("{}", c) } else { "".to_string() } )) + .wrap(make_label(self.style.get_wrapper().0), make_label(self.style.get_wrapper().1)) + .to_grid_horizontal() + .flatten() + } + + pub fn into_node(self) -> NestedNode { + let view = self.pty_view(); + let editor = Arc::new(RwLock::new(self)); + + let ed = editor.read().unwrap(); + let edd = ed.editor.read().unwrap(); + + + NestedNode::new() + .set_data(edd.get_data()) + .set_cmd(editor.clone()) + .set_editor(ed.editor.clone()) + .set_nav(ed.editor.clone()) + .set_ctx(edd.ctx.clone()) + .set_view(view) + .set_diag( + edd.get_data_port() + .enumerate() + .map( + |(idx, item_editor)| { + let idx = *idx; + item_editor + .get_msg_port() + .map( + move |msg| { + let mut msg = msg.clone(); + msg.addr.insert(0, idx); + msg + } + ) + } + ) + .flatten() + ) + } + + pub fn get_data_port(&self) -> OuterViewPort> { + self.editor.read().unwrap().get_data_port() + } + + pub fn clear(&mut self) { + self.editor.write().unwrap().clear(); + } + + pub fn get_item(&self) -> Option { + self.editor.read().unwrap().get_item() + } + + pub fn set_depth(&mut self, depth: usize) { + self.depth = depth; + } + + pub fn split(e: &mut ListEditor, depth: usize) { + let cur = e.get_cursor(); + if let Some(item) = e.get_item_mut() { + if let Some(head_editor) = item.editor.clone() { + + let head = head_editor.downcast::>().unwrap(); + let mut head = head.write().unwrap(); + + if cur.tree_addr.len() > 2 { + PTYListEditor::split(&mut head, depth+1); + } + + let mut tail = head.split(); + + head.goto(TreeCursor::none()); + + tail.cursor.set( + ListCursor { + idx: Some(0), + mode: if cur.tree_addr.len() > 2 { + ListCursorMode::Select + } else { + ListCursorMode::Insert + } + } + ); + + let item_type = + if let Some(data) = item.data.clone() { + let data = data.read().unwrap(); + Some(data.get_type().clone()) + } else { + None + }; + + let style = + if let Some(item_type) = &item_type { + list_style_from_type(&tail.ctx, item_type) + .unwrap_or( + ListStyle::HorizontalSexpr + ) + } else { + ListStyle::HorizontalSexpr + }; + + let mut tail_node = PTYListEditor::from_editor( + Arc::new(RwLock::new(tail)), + style, + depth+1 + ).into_node(); + + if let Some(item_type) = item_type { + tail_node.data = Some(ReprTree::ascend( + &tail_node.data.unwrap(), + item_type.clone() + )); + } + + e.insert( + tail_node + ); + } + } + } + + fn join_pxev(e: &mut ListEditor, idx: isize, item: &NestedNode) { + { + let prev_editor = e.data.get_mut(idx as usize-1); + let prev_editor = prev_editor.editor.clone(); + let prev_editor = prev_editor.unwrap().downcast::>().unwrap(); + let mut prev_editor = prev_editor.write().unwrap(); + + let cur_editor = item.editor.clone().unwrap(); + let cur_editor = cur_editor.downcast::>().unwrap(); + let cur_editor = cur_editor.write().unwrap(); + + prev_editor.join(&cur_editor); + } + + e.cursor.set( + ListCursor { + idx: Some(idx - 1), mode: ListCursorMode::Select + } + ); + + e.data.remove(idx as usize); + } + + fn join_nexd(e: &mut ListEditor, next_idx: usize, item: &NestedNode) { + { + let next_editor = e.data.get_mut(next_idx).editor.clone(); + let next_editor = next_editor.unwrap().downcast::>().unwrap(); + let next_editor = next_editor.write().unwrap(); + + let cur_editor = item.editor.clone().unwrap(); + let cur_editor = cur_editor.downcast::>().unwrap(); + let mut cur_editor = cur_editor.write().unwrap(); + + cur_editor.join(&next_editor); + } + e.data.remove(next_idx); + } +} + +impl Commander for PTYListEditor { + type Cmd = TerminalEvent; + + fn send_cmd(&mut self, event: &TerminalEvent) { + let mut e = self.editor.write().unwrap(); + + match event { + TerminalEvent::Input(Event::Key(Key::Char('\t'))) + | TerminalEvent::Input(Event::Key(Key::Insert)) => { + e.toggle_leaf_mode(); + e.set_leaf_mode(ListCursorMode::Select); + } + _ => { + let cur = e.cursor.get(); + if let Some(idx) = cur.idx { + match cur.mode { + ListCursorMode::Insert => { + match event { + TerminalEvent::Input(Event::Key(Key::Backspace)) => { + e.delete_pxev(); + } + TerminalEvent::Input(Event::Key(Key::Delete)) => { + e.delete_nexd(); + } + _ => { + let mut new_edit = Context::make_editor(&e.ctx, e.typ.clone(), self.depth).unwrap(); + new_edit.goto(TreeCursor::home()); + new_edit.handle_terminal_event(event); + + e.insert(new_edit); + } + } + }, + ListCursorMode::Select => { + if let Some(mut item) = e.get_item().clone() { + if e.is_listlist() { + match event { + TerminalEvent::Input(Event::Key(Key::Backspace)) => { + let item_cur = item.get_cursor(); + + if idx > 0 + && item_cur.tree_addr.iter().fold( + true, + |is_zero, x| is_zero && (*x == 0) + ) + { + PTYListEditor::join_pxev(&mut e, idx, &item); +/* + if item_cur.tree_addr.len() > 1 { + let mut item = e.get_item_mut().unwrap(); + item.handle_terminal_event(event); + } + */ + } else { + item.handle_terminal_event(event); + } + } + TerminalEvent::Input(Event::Key(Key::Delete)) => { + let item_cur = item.get_cursor_warp(); + let next_idx = idx as usize + 1; + + if next_idx < e.data.len() + && item_cur.tree_addr.iter().fold( + true, + |is_end, x| is_end && (*x == -1) + ) + { + PTYListEditor::join_nexd(&mut e, next_idx, &item); +/* + if item_cur.tree_addr.len() > 1 { + let mut item = e.get_item_mut().unwrap(); + item.handle_terminal_event(event); + } + */ + } else { + item.handle_terminal_event(event); + } + } + + TerminalEvent::Input(Event::Key(Key::Char(c))) => { + if Some(*c) == self.style.get_split_char() { + PTYListEditor::split(&mut e, self.depth); + } else { + item.handle_terminal_event(event); + } + } + _ => { + item.handle_terminal_event(event); + } + } + } else { + item.handle_terminal_event(event); + } + } + } + } + } + } + } + } +} diff --git a/nested/src/list/segment.rs b/nested/src/editors/list/segment.rs similarity index 95% rename from nested/src/list/segment.rs rename to nested/src/editors/list/segment.rs index fa22663..aba00c0 100644 --- a/nested/src/list/segment.rs +++ b/nested/src/editors/list/segment.rs @@ -1,10 +1,14 @@ use { + r3vi::{ + view::{ + Observer, ObserverBroadcast, ObserverExt, OuterViewPort, View, ViewPort, + singleton::*, + sequence::*, + }, + projection::projection_helper::* + }, crate::{ - core::{InnerViewPort, Observer, ObserverBroadcast, ObserverExt, OuterViewPort, View, ViewPort}, - list::{ListCursor, ListCursorMode}, - projection::ProjectionHelper, - sequence::SequenceView, - singleton::SingletonView, + editors::list::{ListCursor, ListCursorMode}, terminal::{TerminalView, TerminalStyle, make_label}, tree::{NestedNode, TreeNav}, utils::color::{bg_style_from_depth, fg_style_from_depth}, diff --git a/nested/src/editors/mod.rs b/nested/src/editors/mod.rs new file mode 100644 index 0000000..b126643 --- /dev/null +++ b/nested/src/editors/mod.rs @@ -0,0 +1,7 @@ + +pub mod char; +pub mod integer; + +pub mod list; +pub mod product; +pub mod sum; diff --git a/nested/src/product/editor.rs b/nested/src/editors/product/editor.rs similarity index 94% rename from nested/src/product/editor.rs rename to nested/src/editors/product/editor.rs index e44cd63..0f69cfd 100644 --- a/nested/src/product/editor.rs +++ b/nested/src/editors/product/editor.rs @@ -1,16 +1,26 @@ use { + r3vi::{ + view::{ + OuterViewPort, + sequence::* + }, + buffer::{ + vec::*, + index_hashmap::* + } + }, crate::{ - core::{OuterViewPort}, type_system::{TypeLadder, Context}, terminal::{ TerminalEditor, TerminalEditorResult, TerminalEvent, TerminalView }, - vec::{VecBuffer}, - index::{buffer::{IndexBuffer, MutableIndexAccess}}, - list::ListCursorMode, - product::{segment::ProductEditorSegment}, - sequence::{SequenceView}, + editors::{ + list::ListCursorMode, + product::{ + segment::ProductEditorSegment + } + }, tree::{TreeNav, TreeNavResult}, diagnostics::{Diagnostics}, terminal::{TerminalStyle}, @@ -177,6 +187,15 @@ impl ProductEditor { } } +use crate::commander::Commander; +impl Commander for ProductEditor { + type Cmd = TerminalEvent; + + fn send_cmd(&mut self, ev: &TerminalEvent) { + self.handle_terminal_event(ev); + } +} + impl TerminalEditor for ProductEditor { fn get_term_view(&self) -> OuterViewPort { let ctx = self.ctx.clone(); diff --git a/nested/src/product/mod.rs b/nested/src/editors/product/mod.rs similarity index 100% rename from nested/src/product/mod.rs rename to nested/src/editors/product/mod.rs diff --git a/nested/src/product/nav.rs b/nested/src/editors/product/nav.rs similarity index 98% rename from nested/src/product/nav.rs rename to nested/src/editors/product/nav.rs index 5a6c073..ac855e7 100644 --- a/nested/src/product/nav.rs +++ b/nested/src/editors/product/nav.rs @@ -1,10 +1,11 @@ use { crate::{ type_system::Context, - list::ListCursorMode, tree::{TreeNav, TreeNavResult, TreeCursor}, - product::{segment::ProductEditorSegment, ProductEditor}, - Nested + editors::{ + list::ListCursorMode, + product::{segment::ProductEditorSegment, ProductEditor}, + } }, cgmath::{Vector2}, std::{ops::{DerefMut}}, @@ -245,5 +246,3 @@ impl TreeNav for ProductEditor { } } -impl Nested for ProductEditor {} - diff --git a/nested/src/product/segment.rs b/nested/src/editors/product/segment.rs similarity index 97% rename from nested/src/product/segment.rs rename to nested/src/editors/product/segment.rs index d1a883f..2f15410 100644 --- a/nested/src/product/segment.rs +++ b/nested/src/editors/product/segment.rs @@ -1,6 +1,10 @@ use { + r3vi::{ + view::{ + OuterViewPort + } + }, crate::{ - core::{OuterViewPort}, type_system::{TypeLadder, Context}, terminal::{ TerminalStyle, TerminalView, diff --git a/nested/src/sum/editor.rs b/nested/src/editors/sum/editor.rs similarity index 87% rename from nested/src/sum/editor.rs rename to nested/src/editors/sum/editor.rs index bc3ddf0..bb4d432 100644 --- a/nested/src/sum/editor.rs +++ b/nested/src/editors/sum/editor.rs @@ -1,11 +1,19 @@ use { + r3vi::{ + view::{ + ViewPort, OuterViewPort, + sequence::*, + }, + buffer::{ + vec::* + } + }, crate::{ - core::{ViewPort, OuterViewPort}, terminal::{ TerminalEditor, TerminalEditorResult, TerminalEvent, TerminalView }, - sequence::{SequenceView}, + type_system::{Context}, tree::{TreeNav, TreeCursor, TreeNavResult}, diagnostics::{Diagnostics, Message}, tree::NestedNode, @@ -30,25 +38,26 @@ impl SumEditor { editors: Vec< NestedNode > ) -> Self { let port = ViewPort::new(); - //let mut diag_buf = VecBuffer::new(); SumEditor { cur: 0, editors, port, - diag_port: ViewPort::new()//diag_buf.get_port().to_sequence() + diag_port: ViewPort::new() } } -/* - pub fn into_node(self) -> NestedNode { + + pub fn into_node(self, ctx: Arc>) -> NestedNode { + let view = self.pty_view(); let editor = Arc::new(RwLock::new(self)); NestedNode::new() - .set_view() + .set_ctx(ctx) + .set_view(view) .set_cmd(editor.clone()) .set_nav(editor.clone()) - .set_diag(editor.read().unwrap().diag.clone()) +// .set_diag(editor.read().unwrap().diag.clone()) } -*/ + pub fn get(&self) -> NestedNode { self.editors[ self.cur ].clone() } diff --git a/nested/src/sum/mod.rs b/nested/src/editors/sum/mod.rs similarity index 100% rename from nested/src/sum/mod.rs rename to nested/src/editors/sum/mod.rs diff --git a/nested/src/grid/buffer.rs b/nested/src/grid/buffer.rs deleted file mode 100644 index 613c858..0000000 --- a/nested/src/grid/buffer.rs +++ /dev/null @@ -1,90 +0,0 @@ - -use { - std::{ - sync::Arc, - collections::HashMap, - hash::Hash - }, - std::sync::RwLock, - crate::{ - core::{ - Observer, - ObserverBroadcast, - View, - InnerViewPort - }, - index::{IndexArea, IndexView} - } -}; - - -struct GridBuffer { - data: HashMap, Item>, - limit: Point2 -} - -impl View for GridBuffer -where Item: Clone + Send + Sync + 'static -{ - type Msg = IndexArea>; -} - -impl IndexView> for GridBufferView -where Item: Clone + Send + Sync + 'static -{ - type Item = Item; - - fn get(&self, key: &Point2) -> Option { - self.data.get(key).cloned() - } - - fn area(&self) -> IndexArea> { - IndexArea::Range( - Point2::new(0, 0) - ..= self.limit - ) - } -} - -pub struct GridBufferController -where Item: Clone + Send + Sync + 'static -{ - data: Arc, Item>>>, - cast: Arc, Item = Item>>>> -} - -impl GridBuffer -where Key: Clone + Hash + Eq + Send + Sync + 'static, - Item: Clone + Send + Sync + 'static -{ - pub fn new(port: InnerViewPort, Item = Item>>) -> Self { - let data = Arc::new(RwLock::new(HashMap::, Item>::new())); - port.set_view(Some(Arc::new(GridBufferView(data.clone())))); - - GridBuffer { - data, - cast: port.get_broadcast() - } - } - - pub fn insert(&mut self, key: Point2, item: Item) { - self.data.write().unwrap().insert(key.clone(), item); - - if - - self.cast.notify(&IndexArea::Set(vec![ key ])); - } - - pub fn insert_iter(&mut self, iter: T) - where T: IntoIterator, Item)> { - for (key, item) in iter { - self.insert(key, item); - } - } - - pub fn remove(&mut self, key: Point2) { - self.data.write().unwrap().remove(&key); - self.cast.notify(&IndexArea::Set(vec![ key ])); - } -} - diff --git a/nested/src/grid/flatten.rs b/nested/src/grid/flatten.rs deleted file mode 100644 index bbcc325..0000000 --- a/nested/src/grid/flatten.rs +++ /dev/null @@ -1,244 +0,0 @@ -use { - crate::{ - core::{InnerViewPort, Observer, ObserverBroadcast, OuterViewPort, View, ViewPort}, - grid::{GridView, GridWindowIterator}, - index::{IndexArea, IndexView}, - projection::ProjectionHelper, - }, - cgmath::{Point2, Vector2}, - std::sync::RwLock, - std::{cmp::max, collections::HashMap, sync::Arc}, -}; - -impl OuterViewPort>>> -where - Item: 'static, -{ - pub fn flatten(&self) -> OuterViewPort> { - let port = ViewPort::new(); - port.add_update_hook(Arc::new(self.0.clone())); - Flatten::new(self.clone(), port.inner()); - port.into_outer() - } -} - -pub struct Chunk -where - Item: 'static, -{ - offset: Vector2, - limit: Point2, - view: Arc>, -} - -pub struct Flatten -where - Item: 'static, -{ - limit: Point2, - top: Arc>>>, - chunks: HashMap, Chunk>, - cast: Arc>>>, - proj_helper: ProjectionHelper, Self>, -} - -impl View for Flatten -where - Item: 'static, -{ - type Msg = IndexArea>; -} - -impl IndexView> for Flatten -where - Item: 'static, -{ - type Item = Item; - - fn get(&self, idx: &Point2) -> Option { - let chunk_idx = self.get_chunk_idx(*idx)?; - let chunk = self.chunks.get(&chunk_idx)?; - chunk.view.get(&(*idx - chunk.offset)) - } - - fn area(&self) -> IndexArea> { - IndexArea::Range(Point2::new(0, 0)..=self.limit) - } -} - -/* TODO: remove unused projection args (bot-views) if they get replaced by a new viewport */ -impl Flatten -where - Item: 'static, -{ - pub fn new( - top_port: OuterViewPort>>>, - out_port: InnerViewPort>, - ) -> Arc> { - let mut proj_helper = ProjectionHelper::new(out_port.0.update_hooks.clone()); - - let flat = Arc::new(RwLock::new(Flatten { - limit: Point2::new(0, 0), - top: proj_helper.new_index_arg( - Point2::new(-1, -1), - top_port, - |s: &mut Self, chunk_area| { - for chunk_idx in chunk_area.iter() { - s.update_chunk(chunk_idx); - } - }, - ), - chunks: HashMap::new(), - cast: out_port.get_broadcast(), - proj_helper, - })); - - flat.write().unwrap().proj_helper.set_proj(&flat); - out_port.set_view(Some(flat.clone())); - flat - } - - /// the top-sequence has changed the item at chunk_idx, - /// create a new observer for the contained sub sequence - fn update_chunk(&mut self, chunk_idx: Point2) { - if let Some(chunk_port) = self.top.get(&chunk_idx) { - let view = self.proj_helper.new_index_arg( - chunk_idx, - chunk_port.clone(), - move |s: &mut Self, area| { - if let Some(chunk) = s.chunks.get(&chunk_idx) { - if chunk.limit != *chunk.view.area().range().end() { - s.update_all_offsets(); - } - } - - if let Some(chunk) = s.chunks.get(&chunk_idx) { - s.cast.notify(&area.map(|pt| pt + chunk.offset)); - } - }, - ); - - if let Some(chunk) = self.chunks.get_mut(&chunk_idx) { - chunk.view = view; - - let old_limit = chunk.limit; - let new_limit = *chunk.view.area().range().end(); - - self.cast.notify( - &IndexArea::Range( - Point2::new(chunk.offset.x, chunk.offset.y) ..= Point2::new(chunk.offset.x + max(old_limit.x, new_limit.x), chunk.offset.y + max(old_limit.y, new_limit.y) ))); - - } else { - self.chunks.insert( - chunk_idx, - Chunk { - offset: Vector2::new(-1, -1), - limit: Point2::new(-1, -1), - view, - }, - ); - } - - self.update_all_offsets(); - } else { - self.proj_helper.remove_arg(&chunk_idx); - - if let Some(_chunk) = self.chunks.remove(&chunk_idx) { - self.update_all_offsets(); - } - } - } - - /// recalculate all chunk offsets - /// and update size of flattened grid - fn update_all_offsets(&mut self) { - let top_range = self.top.area().range(); - let mut col_widths = vec![0 as i16; (top_range.end().x + 1) as usize]; - let mut row_heights = vec![0 as i16; (top_range.end().y + 1) as usize]; - - for chunk_idx in GridWindowIterator::from(top_range.clone()) { - if let Some(chunk) = self.chunks.get_mut(&chunk_idx) { - let chunk_range = chunk.view.area().range(); - let lim = *chunk_range.end(); - - col_widths[chunk_idx.x as usize] = max( - col_widths[chunk_idx.x as usize], - if lim.x < 0 { 0 } else { lim.x + 1 }, - ); - row_heights[chunk_idx.y as usize] = max( - row_heights[chunk_idx.y as usize], - if lim.y < 0 { 0 } else { lim.y + 1 }, - ); - } - } - - for chunk_idx in GridWindowIterator::from(top_range.clone()) { - if let Some(chunk) = self.chunks.get_mut(&chunk_idx) { - let _old_offset = chunk.offset; - let _old_limit = chunk.limit; - - //chunk.limit = Point2::new( col_widths[chunk_idx.x as usize]-1, row_heights[chunk_idx.y as usize]-1 ); - chunk.limit = *chunk.view.area().range().end(); - - chunk.offset = Vector2::new( - (0..chunk_idx.x as usize).map(|x| col_widths[x]).sum(), - (0..chunk_idx.y as usize).map(|y| row_heights[y]).sum(), - ); -/* - - if old_offset != chunk.offset { - self.cast.notify( - &IndexArea::Range( - Point2::new( - std::cmp::min(old_offset.x, chunk.offset.x), - std::cmp::min(old_offset.y, chunk.offset.y) - ) - ..= Point2::new( - std::cmp::max(old_offset.x + old_limit.x, chunk.offset.x + chunk.limit.x), - std::cmp::max(old_offset.y + old_limit.y, chunk.offset.y + chunk.limit.y) - ) - ) - ); - } -*/ - } - } - - let old_limit = self.limit; - self.limit = Point2::new( - (0..=top_range.end().x) - .map(|x| col_widths.get(x as usize).unwrap_or(&0)) - .sum::() - - 1, - (0..=top_range.end().y) - .map(|y| row_heights.get(y as usize).unwrap_or(&0)) - .sum::() - - 1, - ); - - self.cast.notify(&IndexArea::Range( - Point2::new(0, 0) - ..=Point2::new( - max(self.limit.x, old_limit.x), - max(self.limit.y, old_limit.y), - ), - )); - - } - - /// given an index in the flattened sequence, - /// which sub-sequence does it belong to? - fn get_chunk_idx(&self, glob_pos: Point2) -> Option> { - for chunk_idx in GridWindowIterator::from(self.top.area().range()) { - if let Some(chunk) = self.chunks.get(&chunk_idx) { - let end = chunk.limit + chunk.offset; - - if glob_pos.x <= end.x && glob_pos.y <= end.y { - return Some(chunk_idx); - } - } - } - - None - } -} diff --git a/nested/src/grid/mod.rs b/nested/src/grid/mod.rs deleted file mode 100644 index 5eec2ae..0000000 --- a/nested/src/grid/mod.rs +++ /dev/null @@ -1,74 +0,0 @@ -use { - crate::index::{IndexArea, IndexView}, - cgmath::Point2, - std::{ - cmp::{max, min}, - ops::RangeInclusive, - }, -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub trait GridView = IndexView>; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub mod flatten; -pub mod offset; -pub mod window_iterator; - -pub use window_iterator::GridWindowIterator; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl IndexArea> { - // todo: this is not perfect (e.g. diagonals are inefficient) - pub fn iter(&self) -> GridWindowIterator { - GridWindowIterator::from(self.range()) - } - - pub fn range(&self) -> RangeInclusive> { - match self { - IndexArea::Empty => Point2::new(0, 0)..=Point2::new(-1, -1), - IndexArea::Full => panic!("range from full grid area"), - IndexArea::Set(v) => { - Point2::new( - v.iter().map(|p| p.x).min().unwrap_or(i16::MAX), - v.iter().map(|p| p.y).min().unwrap_or(i16::MAX), - ) - ..=Point2::new( - v.iter().map(|p| p.x).max().unwrap_or(i16::MIN), - v.iter().map(|p| p.y).max().unwrap_or(i16::MIN), - ) - } - IndexArea::Range(r) => r.clone(), - } - } - - pub fn union(self, other: IndexArea>) -> IndexArea> { - match (self, other) { - (IndexArea::Empty, a) | (a, IndexArea::Empty) => a, - - (IndexArea::Full, _) | (_, IndexArea::Full) => IndexArea::Full, - - (IndexArea::Set(mut va), IndexArea::Set(vb)) => { - va.extend(vb.into_iter()); - IndexArea::Set(va) - } - - (IndexArea::Range(r), IndexArea::Set(mut v)) - | (IndexArea::Set(mut v), IndexArea::Range(r)) => { - v.extend(GridWindowIterator::from(r)); - IndexArea::Set(v) - } - - (IndexArea::Range(ra), IndexArea::Range(rb)) => IndexArea::Range( - Point2::new( - min(ra.start().x, rb.start().x), - min(ra.start().y, rb.start().y), - ) - ..=Point2::new(max(ra.end().x, rb.end().x), max(ra.end().y, rb.end().y)), - ), - } - } -} diff --git a/nested/src/grid/offset.rs b/nested/src/grid/offset.rs deleted file mode 100644 index d3e40f7..0000000 --- a/nested/src/grid/offset.rs +++ /dev/null @@ -1,15 +0,0 @@ -use { - crate::{core::OuterViewPort, grid::GridView}, - cgmath::Vector2, -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl OuterViewPort> -where - Item: 'static, -{ - pub fn offset(&self, offset: Vector2) -> OuterViewPort> { - self.map_key(move |pt| pt + offset, move |pt| Some(pt - offset)) - } -} diff --git a/nested/src/grid/window_iterator.rs b/nested/src/grid/window_iterator.rs deleted file mode 100644 index 831456d..0000000 --- a/nested/src/grid/window_iterator.rs +++ /dev/null @@ -1,58 +0,0 @@ -use { - cgmath::Point2, - std::ops::{Range, RangeInclusive}, -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct GridWindowIterator { - next: Point2, - range: Range>, -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl From>> for GridWindowIterator { - fn from(range: Range>) -> Self { - GridWindowIterator { - next: range.start, - range, - } - } -} - -impl From>> for GridWindowIterator { - fn from(range: RangeInclusive>) -> Self { - GridWindowIterator { - next: *range.start(), - range: *range.start()..Point2::new(range.end().x + 1, range.end().y + 1), - } - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl Iterator for GridWindowIterator { - type Item = Point2; - - fn next(&mut self) -> Option> { - if self.next.y < self.range.end.y { - if self.next.x < self.range.end.x { - let next = self.next; - - if self.next.x + 1 < self.range.end.x { - self.next.x += 1; - } else { - self.next.x = self.range.start.x; - self.next.y += 1; - } - - Some(next) - } else { - None - } - } else { - None - } - } -} diff --git a/nested/src/index/buffer.rs b/nested/src/index/buffer.rs deleted file mode 100644 index 061175d..0000000 --- a/nested/src/index/buffer.rs +++ /dev/null @@ -1,156 +0,0 @@ -use { - crate::{ - core::{InnerViewPort, OuterViewPort, ViewPort, Observer, View}, - index::{IndexArea, IndexView}, - }, - std::sync::RwLock, - std::{collections::HashMap, hash::Hash, sync::Arc, ops::{Deref, DerefMut}}, -}; - -pub struct IndexBufferView(Arc>>) -where - Key: Clone + Hash + Eq + Send + Sync + 'static, - Item: Clone + Send + Sync + 'static; - -impl View for IndexBufferView -where - Key: Clone + Hash + Eq + Send + Sync + 'static, - Item: Clone + Send + Sync + 'static, -{ - type Msg = IndexArea; -} - -impl IndexView for IndexBufferView -where - Key: Clone + Hash + Eq + Send + Sync + 'static, - Item: Clone + Send + Sync + 'static, -{ - type Item = Item; - - fn get(&self, key: &Key) -> Option { - self.0.read().unwrap().get(key).cloned() - } - - fn area(&self) -> IndexArea { - IndexArea::Set(self.0.read().unwrap().keys().cloned().collect()) - } -} - -#[derive(Clone)] -pub struct IndexBuffer -where - Key: Clone + Hash + Eq + Send + Sync + 'static, - Item: Clone + Send + Sync + 'static, -{ - data: Arc>>, - port: InnerViewPort>, -} - -impl IndexBuffer -where - Key: Clone + Hash + Eq + Send + Sync + 'static, - Item: Clone + Send + Sync + 'static, -{ - pub fn with_port(port: InnerViewPort>) -> Self { - let data = Arc::new(RwLock::new(HashMap::::new())); - port.set_view(Some(Arc::new(IndexBufferView(data.clone())))); - - IndexBuffer { - data, - port - } - } - - pub fn new() -> Self { - IndexBuffer::with_port(ViewPort::new().into_inner()) - } - - pub fn get_port(&self) -> OuterViewPort> { - self.port.0.outer() - } - - pub fn get(&self, key: &Key) -> Option { - self.data.read().unwrap().get(key).cloned() - } - - pub fn get_mut(&mut self, key: &Key) -> MutableIndexAccess { - MutableIndexAccess { - buf: self.clone(), - key: key.clone(), - val: self.get(key) - } - } - - pub fn update(&mut self, key: Key, item: Option) { - if let Some(item) = item { - self.data.write().unwrap().insert(key.clone(), item); - } else { - self.data.write().unwrap().remove(&key); - } - self.port.notify(&IndexArea::Set(vec![key])); - } - - pub fn insert(&mut self, key: Key, item: Item) { - self.data.write().unwrap().insert(key.clone(), item); - self.port.notify(&IndexArea::Set(vec![key])); - } - - pub fn insert_iter(&mut self, iter: T) - where - T: IntoIterator, - { - for (key, item) in iter { - self.insert(key, item); - } - } - - pub fn remove(&mut self, key: Key) { - self.data.write().unwrap().remove(&key); - self.port.notify(&IndexArea::Set(vec![key])); - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct MutableIndexAccess -where - Key: Clone + Hash + Eq + Send + Sync + 'static, - Item: Clone + Send + Sync + 'static, -{ - buf: IndexBuffer, - key: Key, - val: Option, -} - -impl Deref for MutableIndexAccess -where - Key: Clone + Hash + Eq + Send + Sync + 'static, - Item: Clone + Send + Sync + 'static, -{ - type Target = Option; - - fn deref(&self) -> &Option { - &self.val - } -} - -impl DerefMut for MutableIndexAccess -where - Key: Clone + Hash + Eq + Send + Sync + 'static, - Item: Clone + Send + Sync + 'static, -{ - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.val - } -} - -impl Drop for MutableIndexAccess -where - Key: Clone + Hash + Eq + Send + Sync + 'static, - Item: Clone + Send + Sync + 'static, -{ - fn drop(&mut self) { - self.buf.update(self.key.clone(), self.val.clone()); - } -} - diff --git a/nested/src/index/map_item.rs b/nested/src/index/map_item.rs deleted file mode 100644 index 48f3507..0000000 --- a/nested/src/index/map_item.rs +++ /dev/null @@ -1,107 +0,0 @@ -pub use { - crate::{ - core::{ - InnerViewPort, Observer, ObserverBroadcast, ObserverExt, OuterViewPort, View, ViewPort, - }, - index::{IndexArea, IndexView}, - }, - std::sync::RwLock, - std::{boxed::Box, sync::Arc}, -}; - -impl OuterViewPort> -where - Key: Clone + Send + Sync + 'static, - Item: Send + Sync + 'static, -{ - pub fn map_item DstItem + Send + Sync + 'static>( - &self, - f: F, - ) -> OuterViewPort> { - let port = ViewPort::new(); - port.add_update_hook(Arc::new(self.0.clone())); - - let map = MapIndexItem::new(port.inner(), f); - self.add_observer(map.clone()); - port.into_outer() - } -} - -pub struct MapIndexItem -where - Key: Clone + Send + Sync, - SrcView: IndexView + ?Sized, - F: Fn(&Key, &SrcView::Item) -> DstItem + Send + Sync, -{ - src_view: Option>, - f: F, - cast: Arc>>>, -} - -impl MapIndexItem -where - Key: Clone + Send + Sync + 'static, - DstItem: 'static, - SrcView: IndexView + ?Sized + 'static, - F: Fn(&Key, &SrcView::Item) -> DstItem + Send + Sync + 'static, -{ - fn new(port: InnerViewPort>, f: F) -> Arc> { - let map = Arc::new(RwLock::new(MapIndexItem { - src_view: None, - f, - cast: port.get_broadcast(), - })); - - port.set_view(Some(map.clone())); - map - } -} - -impl View for MapIndexItem -where - Key: Clone + Send + Sync, - SrcView: IndexView + ?Sized, - F: Fn(&Key, &SrcView::Item) -> DstItem + Send + Sync, -{ - type Msg = IndexArea; -} - -impl IndexView for MapIndexItem -where - Key: Clone + Send + Sync, - SrcView: IndexView + ?Sized, - F: Fn(&Key, &SrcView::Item) -> DstItem + Send + Sync, -{ - type Item = DstItem; - - fn get(&self, key: &Key) -> Option { - self.src_view - .get(key) - .as_ref() - .map(|item| (self.f)(key, item)) - } - - fn area(&self) -> IndexArea { - self.src_view.area() - } -} - -impl Observer for MapIndexItem -where - Key: Clone + Send + Sync, - SrcView: IndexView + ?Sized, - F: Fn(&Key, &SrcView::Item) -> DstItem + Send + Sync, -{ - fn reset(&mut self, view: Option>) { - let old_area = self.area(); - - self.src_view = view; - - self.cast.notify(&old_area); - self.cast.notify(&self.src_view.area()) - } - - fn notify(&mut self, area: &IndexArea) { - self.cast.notify(area); - } -} diff --git a/nested/src/index/map_key.rs b/nested/src/index/map_key.rs deleted file mode 100644 index f6990e5..0000000 --- a/nested/src/index/map_key.rs +++ /dev/null @@ -1,145 +0,0 @@ -pub use { - crate::{ - core::{ - InnerViewPort, Observer, ObserverBroadcast, ObserverExt, OuterViewPort, View, ViewPort, - }, - grid::GridView, - index::{IndexArea, IndexView}, - }, - std::sync::RwLock, - std::{boxed::Box, sync::Arc}, -}; - -impl OuterViewPort> -where - SrcKey: Clone + Send + Sync + 'static, - Item: 'static, -{ - pub fn map_key< - DstKey: Clone + Send + Sync + 'static, - F1: Fn(&SrcKey) -> DstKey + Send + Sync + 'static, - F2: Fn(&DstKey) -> Option + Send + Sync + 'static, - >( - &self, - f1: F1, - f2: F2, - ) -> OuterViewPort> { - let port = ViewPort::new(); - port.add_update_hook(Arc::new(self.0.clone())); - - let map = MapIndexKey::new(port.inner(), f1, f2); - self.add_observer(map.clone()); - port.into_outer() - } -} - -impl OuterViewPort> -where - Item: 'static, -{ - pub fn to_grid_horizontal(&self) -> OuterViewPort> { - self.map_key( - |idx| cgmath::Point2::new(*idx as i16, 0), - |pt| if pt.y == 0 { Some(pt.x as usize) } else { None }, - ) - } - - pub fn to_grid_vertical(&self) -> OuterViewPort> { - self.map_key( - |idx| cgmath::Point2::new(0, *idx as i16), - |pt| if pt.x == 0 { Some(pt.y as usize) } else { None }, - ) - } -} - -pub struct MapIndexKey -where - DstKey: Clone + Send + Sync, - SrcKey: Clone + Send + Sync, - SrcView: IndexView + ?Sized, - F1: Fn(&SrcKey) -> DstKey + Send + Sync, - F2: Fn(&DstKey) -> Option + Send + Sync, -{ - src_view: Option>, - f1: F1, - f2: F2, - cast: Arc>>>, -} - -impl MapIndexKey -where - DstKey: Clone + Send + Sync + 'static, - SrcKey: Clone + Send + Sync + 'static, - SrcView: IndexView + ?Sized + 'static, - SrcView::Item: 'static, - F1: Fn(&SrcKey) -> DstKey + Send + Sync + 'static, - F2: Fn(&DstKey) -> Option + Send + Sync + 'static, -{ - fn new( - port: InnerViewPort>, - f1: F1, - f2: F2, - ) -> Arc> { - let map = Arc::new(RwLock::new(MapIndexKey { - src_view: None, - f1, - f2, - cast: port.get_broadcast(), - })); - - port.set_view(Some(map.clone())); - map - } -} - -impl View for MapIndexKey -where - DstKey: Clone + Send + Sync, - SrcKey: Clone + Send + Sync, - SrcView: IndexView + ?Sized, - F1: Fn(&SrcKey) -> DstKey + Send + Sync, - F2: Fn(&DstKey) -> Option + Send + Sync, -{ - type Msg = IndexArea; -} - -impl IndexView - for MapIndexKey -where - DstKey: Clone + Send + Sync, - SrcKey: Clone + Send + Sync, - SrcView: IndexView + ?Sized, - F1: Fn(&SrcKey) -> DstKey + Send + Sync, - F2: Fn(&DstKey) -> Option + Send + Sync, -{ - type Item = SrcView::Item; - - fn get(&self, key: &DstKey) -> Option { - self.src_view.get(&(self.f2)(key)?) - } - - fn area(&self) -> IndexArea { - self.src_view.area().map(&self.f1) - } -} - -impl Observer - for MapIndexKey -where - DstKey: Clone + Send + Sync, - SrcKey: Clone + Send + Sync, - SrcView: IndexView + ?Sized, - F1: Fn(&SrcKey) -> DstKey + Send + Sync, - F2: Fn(&DstKey) -> Option + Send + Sync, -{ - fn reset(&mut self, view: Option>) { - let old_area = self.area(); - self.src_view = view; - self.cast.notify(&old_area); - self.cast.notify(&self.area()); - } - - fn notify(&mut self, msg: &IndexArea) { - self.cast.notify(&msg.map(&self.f1)); - } -} diff --git a/nested/src/index/mod.rs b/nested/src/index/mod.rs deleted file mode 100644 index dc584d9..0000000 --- a/nested/src/index/mod.rs +++ /dev/null @@ -1,130 +0,0 @@ -pub mod buffer; -pub mod map_item; -pub mod map_key; - -use { - crate::core::View, - std::sync::RwLock, - std::{ - ops::{Deref, RangeInclusive}, - sync::Arc, - }, -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -#[derive(Clone)] -pub enum IndexArea { - Empty, - Full, - Set(Vec), - Range(RangeInclusive), - //Procedural(Arc Box>>) -} - -impl IndexArea { - pub fn map(&self, f: impl Fn(&Key) -> T) -> IndexArea { - match self { - IndexArea::Empty => IndexArea::Empty, - IndexArea::Full => IndexArea::Full, - IndexArea::Set(v) => IndexArea::Set(v.iter().map(&f).collect()), - IndexArea::Range(r) => IndexArea::Range(f(&r.start())..=f(&r.end())), - } - } -} - -pub trait IndexView: View> -where - Key: Send + Sync, -{ - type Item; - - fn get(&self, key: &Key) -> Option; - - fn area(&self) -> IndexArea { - IndexArea::Full - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl IndexView for RwLock -where - Key: Send + Sync, - V: IndexView + ?Sized, -{ - type Item = V::Item; - - fn get(&self, key: &Key) -> Option { - self.read().unwrap().get(key) - } - - fn area(&self) -> IndexArea { - self.read().unwrap().area() - } -} - -impl IndexView for Arc -where - Key: Send + Sync, - V: IndexView + ?Sized, -{ - type Item = V::Item; - - fn get(&self, key: &Key) -> Option { - self.deref().get(key) - } - - fn area(&self) -> IndexArea { - self.deref().area() - } -} - -impl IndexView for Option -where - Key: Send + Sync, - V: IndexView, -{ - type Item = V::Item; - - fn get(&self, key: &Key) -> Option { - self.as_ref()?.get(key) - } - - fn area(&self) -> IndexArea { - if let Some(v) = self.as_ref() { - v.area() - } else { - IndexArea::Empty - } - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -/* -pub trait ImplIndexView : Send + Sync { - type Key : Send + Sync; - type Value; - - fn get(&self, key: &Self::Key) -> Option; - fn area(&self) -> Option> { - None - } -} - -impl View for V { - type Msg = V::Key; -} - -impl IndexView for V { - type Item = V::Value; - - fn get(&self, key: &V::Key) -> Option { - (self as &V).get(key) - } - - fn area(&self) -> Option> { - (self as &V).area() - } -} -*/ diff --git a/nested/src/lib.rs b/nested/src/lib.rs index f7b4da6..c81e77d 100644 --- a/nested/src/lib.rs +++ b/nested/src/lib.rs @@ -1,57 +1,34 @@ #![feature(trait_alias)] -// general -pub mod core; -pub mod type_system; -pub mod projection; -pub mod commander; -pub mod utils; - -// semantics -pub mod singleton; -pub mod sequence; -pub mod index; -pub mod grid; - -// implementation -pub mod vec; - -// editors -pub mod product; -pub mod sum; -pub mod list; -pub mod tree; -pub mod diagnostics; - -// high-level types -pub mod char; -pub mod integer; - -// display pub mod terminal; +pub mod utils; +pub mod editors; +pub mod tree; +pub mod type_system; + +pub mod diagnostics; +pub mod commander; +//pub mod product; +//pub mod sum; +//pub mod list; + pub fn magic_header() { eprintln!("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>"); } +/* pub trait StringGen { fn get_string(&self) -> String; } -use crate::terminal::TerminalEditor; use crate::{tree::{TreeNav}, diagnostics::Diagnostics, terminal::TerminalView, core::{OuterViewPort}}; + */ + +use r3vi::view::OuterViewPort; +use crate::terminal::TerminalView; pub trait PtySegment { fn pty_view(&self) -> OuterViewPort; } -pub trait Nested - : TerminalEditor - + TreeNav - // + TreeType - + Diagnostics - + Send - + Sync - + std::any::Any -{} - diff --git a/nested/src/list/editor.rs b/nested/src/list/editor.rs deleted file mode 100644 index b9b3ae6..0000000 --- a/nested/src/list/editor.rs +++ /dev/null @@ -1,163 +0,0 @@ -use { - crate::{ - core::{OuterViewPort, ViewPort}, - type_system::{Context, TypeTerm}, - list::{ - ListCursor, - ListSegment, - ListSegmentSequence, - ListCursorMode - }, - sequence::{SequenceView}, - singleton::{SingletonBuffer, SingletonView}, - terminal::{TerminalView}, - tree::{NestedNode, TreeNav}, - vec::{VecBuffer, MutableVecAccess}, - PtySegment - }, - std::sync::{Arc, RwLock}, -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct ListEditor { - pub(super) cursor: SingletonBuffer, - pub(crate) data: VecBuffer, - - pub(super) addr_port: OuterViewPort>, - pub(super) mode_port: OuterViewPort>, - - pub(crate) ctx: Arc>, - pub(super) typ: TypeTerm, - pub(super) depth: usize, - pub(super) cur_dist: Arc>, -} - -impl ListEditor { - pub fn new( - ctx: Arc>, - typ: TypeTerm, - depth: usize - ) -> Self { - let mut cursor = SingletonBuffer::new(ListCursor::default()); - let mut data = VecBuffer::::new(); - - ListEditor { - mode_port: cursor - .get_port() - .map({ - let data = data.clone(); - move |c| { - let ip = SingletonBuffer::new(c.mode).get_port(); - match c.mode { - ListCursorMode::Insert => ip, - ListCursorMode::Select => { - if let Some(idx) = c.idx { - data.get(idx as usize).get_mode_view() - } else { - ip - } - } - } - } - }) - .flatten(), - - addr_port: VecBuffer::>>::with_data( - vec![ - cursor.get_port() - .to_sequence() - .filter_map(|cur| cur.idx), - cursor.get_port() - .map({ - let data = data.clone(); - move |cur| { - if cur.mode == ListCursorMode::Select { - if let Some(idx) = cur.idx { - if idx >= 0 && idx < data.len() as isize { - return data.get(idx as usize).get_addr_view(); - } - } - } - OuterViewPort::default() - } - }) - .to_sequence() - .flatten() - ]) - .get_port() - .to_sequence() - .flatten(), - cursor, - data, - ctx, - typ, - depth, - cur_dist: Arc::new(RwLock::new(0)), - } - } - - pub fn get_seg_seq_view( - &self, - ) -> OuterViewPort>> { - let seg_seq = ListSegmentSequence::new( - self.get_cursor_port(), - self.get_data_port(), - self.depth - ); - let se = seg_seq.read().unwrap(); - se.get_view().map(move |segment| segment.pty_view()) - } - - pub fn get_data_port(&self) -> OuterViewPort> { - self.data.get_port().to_sequence() - } - - pub fn get_cursor_port(&self) -> OuterViewPort> { - self.cursor.get_port() - } - - pub fn get_item(&self) -> Option { - if let Some(idx) = self.cursor.get().idx { - let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize; - if idx < self.data.len() { - Some(self.data.get(idx)) - } else { - None - } - } else { - None - } - } - - pub fn get_item_mut(&mut self) -> Option> { - if let Some(idx) = self.cursor.get().idx { - let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize; - if idx < self.data.len() { - Some(self.data.get_mut(idx)) - } else { - None - } - } else { - None - } - } - - /// split the list off at the current cursor position and return the second half - /* - pub fn split(&mut self) -> ListEditor { - let mut le = ListEditor::new(self.make_item_editor.clone()); - let p = self.cursor.get(); - for i in p.idx .. self.data.len() { - le.data.push( self.data[p.idx] ); - self.data.remove(p.idx); - } - le.goto(TreeCursor::home()); - le - } - */ - - pub fn clear(&mut self) { - self.data.clear(); - } -} diff --git a/nested/src/list/mod.rs b/nested/src/list/mod.rs deleted file mode 100644 index fd5a86f..0000000 --- a/nested/src/list/mod.rs +++ /dev/null @@ -1,12 +0,0 @@ - -pub mod cursor; -pub mod segment; -pub mod editor; -pub mod nav; -pub mod pty_editor; - -pub use cursor::{ListCursor, ListCursorMode}; -pub use segment::{ListSegment, ListSegmentSequence}; -pub use editor::ListEditor; -pub use pty_editor::PTYListEditor; - diff --git a/nested/src/list/pty_editor.rs b/nested/src/list/pty_editor.rs deleted file mode 100644 index 560b4f2..0000000 --- a/nested/src/list/pty_editor.rs +++ /dev/null @@ -1,216 +0,0 @@ -use { - crate::{ - core::{OuterViewPort}, - type_system::{Context, TypeTerm}, - list::{ - ListCursor, ListCursorMode, - ListEditor - }, - sequence::{SequenceView, decorator::{SeqDecorStyle, PTYSeqDecorate}}, - terminal::{ - TerminalEditor, TerminalEditorResult, TerminalEvent, - TerminalView, - }, - tree::{TreeCursor, TreeNav, TreeNavResult}, - diagnostics::{Diagnostics}, - tree::NestedNode, Nested, - commander::Commander - }, - std::sync::{Arc, RwLock}, - termion::event::{Event, Key}, - cgmath::Vector2 -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct PTYListEditor { - pub editor: Arc>, - split_char: Option, - depth: usize -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl PTYListEditor { - pub fn new( - ctx: Arc>, - typ: TypeTerm, - split_char: Option, - depth: usize - ) -> Self { - Self::from_editor( - ListEditor::new(ctx, typ, depth), split_char, depth) - } - - pub fn from_editor( - editor: ListEditor, - split_char: Option, - depth: usize - ) -> Self { - PTYListEditor { - split_char, - depth, - editor: Arc::new(RwLock::new(editor)), - } - } - - pub fn into_node(self, style: SeqDecorStyle) -> NestedNode { - let editor = Arc::new(RwLock::new(self)); - - let ed = editor.read().unwrap(); - let edd = ed.editor.read().unwrap(); - - NestedNode::new() - .set_cmd(editor.clone()) - .set_nav(ed.editor.clone()) - .set_ctx(edd.ctx.clone()) - .set_view(edd.get_seg_seq_view().pty_decorate(style, ed.depth)) - .set_diag( - edd.get_data_port() - .enumerate() - .map( - |(idx, item_editor)| { - let idx = *idx; - item_editor - .get_msg_port() - .map( - move |msg| { - let mut msg = msg.clone(); - msg.addr.insert(0, idx); - msg - } - ) - } - ) - .flatten() - ) - } - - pub fn get_data_port(&self) -> OuterViewPort> { - self.editor.read().unwrap().get_data_port() - } - - pub fn clear(&mut self) { - self.editor.write().unwrap().clear(); - } - - pub fn get_item(&self) -> Option { - self.editor.read().unwrap().get_item() - } - - pub fn set_depth(&mut self, depth: usize) { - self.depth = depth; - } -} - -impl Commander for PTYListEditor { - type Cmd = TerminalEvent; - - fn send_cmd(&mut self, event: &TerminalEvent) { - let mut e = self.editor.write().unwrap(); - - let mut cur = e.cursor.get(); - if let Some(idx) = cur.idx { - match cur.mode { - ListCursorMode::Insert => match event { - TerminalEvent::Input(Event::Key(Key::Backspace)) => { - if idx > 0 && idx <= e.data.len() as isize { - cur.idx = Some(idx as isize - 1); - e.cursor.set(cur); - e.data.remove(idx as usize - 1); - } - } - TerminalEvent::Input(Event::Key(Key::Delete)) => { - if idx < e.data.len() as isize { - e.data.remove(idx as usize); - } - } - TerminalEvent::Input(Event::Key(Key::Char('\t'))) - | TerminalEvent::Input(Event::Key(Key::Insert)) => { - e.set_leaf_mode(ListCursorMode::Select); - } - TerminalEvent::Input(Event::Key(Key::Char('\n'))) => { - e.goto(TreeCursor::none()); - } - _ => { - let mut new_edit = Context::make_editor(&e.ctx, e.typ.clone(), self.depth+1).unwrap(); - e.data.insert(idx as usize, new_edit.clone()); - e.set_leaf_mode(ListCursorMode::Select); - - new_edit.goto(TreeCursor::home()); - new_edit.handle_terminal_event(event); - - if self.split_char.is_none() { - e.cursor.set(ListCursor { - mode: ListCursorMode::Insert, - idx: Some(idx as isize + 1), - }); - } - } - }, - ListCursorMode::Select => { - match event { - TerminalEvent::Input(Event::Key(Key::Char('\t'))) - | TerminalEvent::Input(Event::Key(Key::Insert)) => { - e.set_leaf_mode(ListCursorMode::Insert); - } - - TerminalEvent::Input(Event::Key(Key::Char(c))) => { - if Some(*c) == self.split_char { - let c = e.cursor.get(); - e.goto(TreeCursor::none()); - e.cursor.set(ListCursor { - mode: ListCursorMode::Insert, - idx: Some(1 + c.idx.unwrap_or(0)) - }); - } else { - if let Some(mut ce) = e.get_item_mut() { - ce.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char(*c)))); - //match - if self.split_char.is_none() { - // TerminalEditorResult::Exit => - { - e.cursor.set(ListCursor { - mode: ListCursorMode::Insert, - idx: Some(idx as isize + 1), - }); - } - // TerminalEditorResult::Continue => { - // } - } - } - } - } - ev => { - if let Some(mut ce) = e.get_item_mut() { - ce.handle_terminal_event(ev); -/* - TerminalEvent::Input(Event::Key(Key::Backspace)) => { - e.data.remove(idx as usize); - e.cursor.set(ListCursor { - mode: ListCursorMode::Insert, - idx: Some(idx as isize), - }); - } - _ => { - e.cursor.set(ListCursor { - mode: ListCursorMode::Insert, - idx: Some(idx as isize + 1), - }); - } - } - } - TerminalEditorResult::Continue => { - - } - } - */ - } - } - } - } - } - } - } -} - diff --git a/nested/src/projection.rs b/nested/src/projection.rs deleted file mode 100644 index dfdc7bf..0000000 --- a/nested/src/projection.rs +++ /dev/null @@ -1,239 +0,0 @@ -use { - crate::{ - core::{ - channel::{queue_channel, set_channel, ChannelData, ChannelReceiver, ChannelSender}, - port::UpdateTask, - Observer, ObserverExt, OuterViewPort, View, - }, - index::{IndexArea, IndexView}, - sequence::SequenceView, - singleton::SingletonView, - }, - std::sync::RwLock, - std::{ - any::Any, - cmp::max, - collections::HashMap, - hash::Hash, - sync::{Arc, Weak}, - }, -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct ProjectionHelper -where - ArgKey: Clone + Hash + Eq, - P: Send + Sync + 'static, -{ - keepalive: HashMap)>, - proj: Arc>>>, - update_hooks: Arc>>>, -} - -impl ProjectionHelper -where - ArgKey: Clone + Hash + Eq, - P: Send + Sync + 'static, -{ - pub fn new(update_hooks: Arc>>>) -> Self { - ProjectionHelper { - keepalive: HashMap::new(), - proj: Arc::new(RwLock::new(Weak::new())), - update_hooks, - } - } - - pub fn set_proj(&mut self, proj: &Arc>) { - *self.proj.write().unwrap() = Arc::downgrade(proj); - } - - // todo: make this functions generic over the View - // this does currently not work because Observer is not implemented for ProjectionArg for *all* V. - - pub fn new_singleton_arg( - &mut self, - arg_key: ArgKey, - port: OuterViewPort>, - notify: impl Fn(&mut P, &()) + Send + Sync + 'static, - ) -> Arc>>>> { - port.add_observer(self.new_arg(arg_key, Arc::new(port.0.clone()), notify, set_channel())); - port.get_view_arc() - } - - pub fn new_sequence_arg( - &mut self, - arg_key: ArgKey, - port: OuterViewPort>, - notify: impl Fn(&mut P, &usize) + Send + Sync + 'static, - ) -> Arc>>>> { - port.add_observer(self.new_arg(arg_key, Arc::new(port.0.clone()), notify, set_channel())); - port.get_view_arc() - } - - pub fn new_index_arg( - &mut self, - arg_key: ArgKey, - port: OuterViewPort>, - notify: impl Fn(&mut P, &IndexArea) + Send + Sync + 'static, - ) -> Arc>>>> { - port.add_observer(self.new_arg(arg_key, Arc::new(port.0.clone()), notify, queue_channel())); - port.get_view_arc() - } - - pub fn new_arg + 'static>( - &mut self, - arg_key: ArgKey, - src_update: Arc, - notify: impl Fn(&mut P, &V::Msg) + Send + Sync + 'static, - (tx, rx): (ChannelSender, ChannelReceiver), - ) -> Arc>> - where - V::Msg: Send + Sync, - D::IntoIter: Send + Sync + 'static, - { - self.remove_arg(&arg_key); - - let arg = Arc::new(RwLock::new(ProjectionArg { - src: None, - notify: Box::new(notify), - proj: self.proj.clone(), - rx, - tx, - })); - - let mut hooks = self.update_hooks.write().unwrap(); - let idx = hooks.len(); - hooks.push(src_update); - hooks.push(arg.clone()); - self.keepalive.insert(arg_key, (idx, arg.clone())); - - arg - } - - pub fn remove_arg(&mut self, arg_key: &ArgKey) { - let mut hooks = self.update_hooks.write().unwrap(); - if let Some((idx, _arg)) = self.keepalive.remove(arg_key) { - hooks.remove(idx); - hooks.remove(idx); - for (_, (j, _)) in self.keepalive.iter_mut() { - if *j > idx { - *j -= 2; - } - } - } - } -} - -/// Special Observer which can access the state of the projection on notify -/// also handles the reset() -pub struct ProjectionArg -where - P: Send + Sync + 'static, - V: View + ?Sized, - D: ChannelData, - D::IntoIter: Send + Sync, -{ - src: Option>, - notify: Box, - proj: Arc>>>, - rx: ChannelReceiver, - tx: ChannelSender, -} - -impl UpdateTask for ProjectionArg -where - P: Send + Sync + 'static, - V: View + ?Sized, - D: ChannelData, - D::IntoIter: Send + Sync, -{ - fn update(&self) { - if let Some(p) = self.proj.read().unwrap().upgrade() { - if let Some(data) = self.rx.try_recv() { - for msg in data { - //eprintln!("proj update {:?}", msg); - (self.notify)(&mut *p.write().unwrap(), &msg); - } - } - } else { - //eprintln!("proj update: upgrade fail"); - } - } -} - -impl UpdateTask for RwLock> -where - P: Send + Sync + 'static, - V: View + ?Sized, - D: ChannelData, - D::IntoIter: Send + Sync, -{ - fn update(&self) { - self.read().unwrap().update(); - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl Observer> - for ProjectionArg, D> -where - P: Send + Sync + 'static, - D: ChannelData, - D::IntoIter: Send + Sync, -{ - fn reset(&mut self, new_src: Option>>) { - self.src = new_src; - self.notify(&()); - } - - fn notify(&mut self, msg: &()) { - self.tx.send(msg.clone()); - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl Observer> - for ProjectionArg, D> -where - P: Send + Sync + 'static, - D: ChannelData, - D::IntoIter: Send + Sync, -{ - fn reset(&mut self, new_src: Option>>) { - let old_len = self.src.len().unwrap_or(0); - self.src = new_src; - let new_len = self.src.len().unwrap_or(0); - - self.notify_each(0..max(old_len, new_len)); - } - - fn notify(&mut self, msg: &usize) { - self.tx.send(*msg); - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl Observer> - for ProjectionArg, D> -where - P: Send + Sync + 'static, - Key: Clone + Send + Sync, - D: ChannelData>, - D::IntoIter: Send + Sync, -{ - fn reset(&mut self, new_src: Option>>) { - let old_area = self.src.area(); - self.src = new_src; - - self.notify(&old_area); - self.notify(&self.src.area()) - } - - fn notify(&mut self, msg: &IndexArea) { - self.tx.send(msg.clone()); - } -} diff --git a/nested/src/sequence/decorator.rs b/nested/src/sequence/decorator.rs deleted file mode 100644 index ca86862..0000000 --- a/nested/src/sequence/decorator.rs +++ /dev/null @@ -1,256 +0,0 @@ -use { - crate::{ - core::{View, OuterViewPort, Observer, ViewPort, ObserverBroadcast}, - projection::ProjectionHelper, - sequence::SequenceView, - terminal::{make_label, TerminalView}, - }, - std::sync::Arc, - std::sync::RwLock, -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -// Wrap -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct Wrapped -where T: Send + Sync + 'static -{ - pub(super) opening: T, - pub(super) closing: T, - pub(super) items: Arc>, - - pub(super) cast: Arc>>>, - pub(super) proj_helper: ProjectionHelper<(), Self>, -} - -impl View for Wrapped -where T: Clone + Send + Sync + 'static -{ - type Msg = usize; -} - -impl SequenceView for Wrapped -where T: Clone + Send + Sync + 'static -{ - type Item = T; - - fn len(&self) -> Option { - Some(self.items.len()? + 2) - } - - fn get(&self, idx: &usize) -> Option { - let l = self.items.len().unwrap_or((-2 as i32) as usize); - if *idx < l+2 { - Some( - if *idx == 0 { - self.opening.clone() - } else if *idx < l+1 { - self.items.get(&(*idx - 1))? - } else { - self.closing.clone() - }) - } else { - None - } - } -} - - -pub trait Wrap { - fn wrap(&self, opening: T, closing: T) -> OuterViewPort>; -} - -impl Wrap for OuterViewPort> -where T: Clone + Send + Sync + 'static -{ - fn wrap(&self, opening: T, closing: T) -> OuterViewPort> { - let port = ViewPort::new(); - - let mut proj_helper = ProjectionHelper::new(port.update_hooks.clone()); - let w = Arc::new(RwLock::new(Wrapped { - opening, - closing, - items: proj_helper.new_sequence_arg((), self.clone(), |s: &mut Wrapped, item_idx| { - s.cast.notify(&(*item_idx + 1)); - s.cast.notify(&(*item_idx + 2)); - }), - cast: port.get_cast(), - proj_helper, - })); - - w.write().unwrap().proj_helper.set_proj(&w); - port.set_view(Some(w.clone())); - port.into_outer() - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -// Separate -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct Separated -where T: Send + Sync + 'static -{ - pub(super) delimiter: T, - pub(super) items: Arc>, - - pub(super) cast: Arc>>>, - pub(super) proj_helper: ProjectionHelper<(), Self>, -} - -impl View for Separated -where T: Clone + Send + Sync + 'static -{ - type Msg = usize; -} - -impl SequenceView for Separated -where T: Clone + Send + Sync + 'static -{ - type Item = T; - - fn len(&self) -> Option { - let l = self.items.len()?; - if l == 0 { - Some(0) - } else if l == 1 { - Some(1) - } else { - Some(l*2 - 1) - } - } - - fn get(&self, idx: &usize) -> Option { - let l = self.items.len().unwrap_or(usize::MAX); - if *idx+1 < l*2 { - if *idx % 2 == 0 { - self.items.get(&(*idx / 2)) - } else { - Some(self.delimiter.clone()) - } - } else { - None - } - } -} - -pub trait Separate { - fn separate(&self, delimiter: T) -> OuterViewPort>; -} - -impl Separate for OuterViewPort> -where T: Clone + Send + Sync + 'static -{ - fn separate(&self, delimiter: T) -> OuterViewPort> { - let port = ViewPort::new(); - - let mut proj_helper = ProjectionHelper::new(port.update_hooks.clone()); - let w = Arc::new(RwLock::new(Separated { - delimiter, - items: proj_helper.new_sequence_arg( - (), - self.clone(), - |s: &mut Separated, item_idx| { - s.cast.notify(&(*item_idx * 2)); - if *item_idx > 0 { - s.cast.notify(&(*item_idx * 2 - 1)); - } - }), - - cast: port.get_cast(), - proj_helper, - })); - - w.write().unwrap().proj_helper.set_proj(&w); - port.set_view(Some(w.clone())); - port.into_outer() - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -#[derive(Clone, Copy)] -pub enum SeqDecorStyle { - Plain, - HorizontalSexpr, - VerticalSexpr, - DoubleQuote, - Tuple, - EnumSet, - Path, - Hex -} - -pub trait PTYSeqDecorate { - fn pty_decorate( - &self, - style: SeqDecorStyle, - depth: usize - ) -> OuterViewPort; -} - -impl PTYSeqDecorate for OuterViewPort>> -{ - fn pty_decorate( - &self, - style: SeqDecorStyle, - _depth: usize - ) -> OuterViewPort { - match style { - SeqDecorStyle::Plain => self - .to_grid_horizontal() - .flatten(), - - SeqDecorStyle::HorizontalSexpr => self - .separate(make_label(" ")) - .wrap(make_label("("), make_label(")")) - .to_grid_horizontal() - .flatten(), - - SeqDecorStyle::VerticalSexpr => self - .wrap(make_label("("), make_label(")")) - .to_grid_vertical() - .flatten(), - - SeqDecorStyle::DoubleQuote => self - .wrap(make_label("\""), make_label("\"")) - .to_grid_horizontal() - .flatten(), - -/* - SeqDecorStyle::FlexibleSexpr => self - .line_warp(width) - .map(|v| v.decorate(make_label(""")make_label(",") ", depth).to_grid_horizontal()) - .decorate(make_label("("), make_label(")"), "", depth) - .to_grid_vertical() - .flatten(), - */ - - SeqDecorStyle::Tuple => self - .separate(make_label(", ")) - .wrap(make_label("("), make_label(")")) - .to_grid_horizontal() - .flatten(), - - SeqDecorStyle::EnumSet => self - .separate(make_label(", ")) - .wrap(make_label("{"), make_label("}")) - .to_grid_horizontal() - .flatten(), - - SeqDecorStyle::Path => self - .separate(make_label("/")) - .wrap(make_label("<"), make_label(">")) - .to_grid_horizontal() - .flatten(), - - SeqDecorStyle::Hex => self - .wrap(make_label("0x"), make_label("")) - .to_grid_horizontal() - .flatten(), - } - } -} - - diff --git a/nested/src/sequence/enumerate.rs b/nested/src/sequence/enumerate.rs deleted file mode 100644 index 9a46af8..0000000 --- a/nested/src/sequence/enumerate.rs +++ /dev/null @@ -1,86 +0,0 @@ -use { - crate::{ - core::{Observer, ObserverBroadcast, ObserverExt, OuterViewPort, View, ViewPort}, - sequence::SequenceView, - }, - std::sync::Arc, - std::sync::RwLock, -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl OuterViewPort> { - pub fn enumerate(&self) -> OuterViewPort> { - let port = ViewPort::new(); - port.add_update_hook(Arc::new(self.0.clone())); - - let view = Arc::new(RwLock::new(EnumerateSequence { - src_view: None, - cast: port.inner().get_broadcast(), - })); - - self.add_observer(view.clone()); - port.inner().set_view(Some(view)); - port.into_outer() - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct EnumerateSequence -where - SrcView: SequenceView + ?Sized, -{ - src_view: Option>, - cast: Arc>>>, -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl View for EnumerateSequence -where - SrcView: SequenceView + ?Sized, -{ - type Msg = usize; -} - -impl SequenceView for EnumerateSequence -where - SrcView: SequenceView + ?Sized -{ - type Item = (usize, SrcView::Item); - - fn len(&self) -> Option { - self.src_view.len() - } - - fn get(&self, idx: &usize) -> Option<(usize, SrcView::Item)> { - self.src_view.get(idx).map(|item| (*idx, item)) - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl Observer for EnumerateSequence -where - SrcView: SequenceView + ?Sized -{ - fn reset(&mut self, view: Option>) { - let old_len = self.len(); - self.src_view = view; - let new_len = self.len(); - - if let Some(len) = old_len { - self.cast.notify_each(0..len); - } - if let Some(len) = new_len { - self.cast.notify_each(0..len); - } - } - - fn notify(&mut self, msg: &usize) { - self.cast.notify(msg); - } -} - - diff --git a/nested/src/sequence/filter.rs b/nested/src/sequence/filter.rs deleted file mode 100644 index 0e177da..0000000 --- a/nested/src/sequence/filter.rs +++ /dev/null @@ -1,160 +0,0 @@ -use { - crate::{ - core::{Observer, ObserverBroadcast, ObserverExt, OuterViewPort, View, ViewPort}, - sequence::SequenceView, - }, - std::sync::Arc, - std::sync::RwLock, -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl OuterViewPort { - pub fn filter bool + Send + Sync + 'static>( - &self, - pred: P, - ) -> OuterViewPort> { - let port = ViewPort::new(); - port.add_update_hook(Arc::new(self.0.clone())); - - let filter = Arc::new(RwLock::new(Filter { - src_view: None, - pred, - old_preds: RwLock::new(Vec::new()), - cast: port.inner().get_broadcast(), - })); - - self.add_observer(filter.clone()); - port.inner().set_view(Some(filter)); - port.into_outer() - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -struct Filter -where - SrcView: SequenceView + ?Sized + 'static, - P: Fn(&SrcView::Item) -> bool + Send + Sync + 'static, -{ - src_view: Option>, - pred: P, - old_preds: RwLock>, - cast: Arc>>>, -} - -impl Filter -where - SrcView: SequenceView + ?Sized + 'static, - P: Fn(&SrcView::Item) -> bool + Send + Sync + 'static, -{ - fn get_offset(&self, idx: usize) -> usize { - if let Some(v) = self.src_view.clone() { - let mut i = 0; - let mut j = 0; - let mut offset = 0; - - while let (Some(x), true) = (v.get(&i), j <= idx) { - if (self.pred)(&x) { - j += 1; - } else { - offset += 1; - } - i += 1; - } - - offset - } else { - 0 - } - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl View for Filter -where - SrcView: SequenceView + ?Sized + 'static, - P: Fn(&SrcView::Item) -> bool + Send + Sync + 'static, -{ - type Msg = usize; -} - -impl SequenceView for Filter -where - SrcView: SequenceView + ?Sized + 'static, - P: Fn(&SrcView::Item) -> bool + Send + Sync + 'static, -{ - type Item = SrcView::Item; - - fn len(&self) -> Option { - if let Some(src_len) = self.src_view.len() { - Some(src_len - self.get_offset(src_len)) - } else { - None - } - } - - fn get(&self, idx: &usize) -> Option { - self.src_view.get(&(idx + self.get_offset(*idx))) - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl Observer for Filter -where - SrcView: SequenceView + ?Sized + 'static, - P: Fn(&SrcView::Item) -> bool + Send + Sync + 'static, -{ - fn reset(&mut self, new_src: Option>) { - let old_len = self.len(); - self.src_view = new_src; - self.old_preds = RwLock::new(Vec::new()); - let new_len = self.len(); - - if let Some(len) = old_len { - self.cast.notify_each(0..len); - } - if let Some(len) = new_len { - self.cast.notify_each(0..len); - } - } - - fn notify(&mut self, idx: &usize) { - let l = self.len().unwrap_or(0) + 1; - let np = if let Some(x) = self.src_view.get(idx) { - (self.pred)(&x) - } else { - false - }; - - let mut opds = self.old_preds.write().unwrap(); - - opds.resize_with(1 + *idx, || false); - let op = opds.get(*idx).cloned().unwrap_or(false); - *opds.get_mut(*idx).unwrap() = np; - - drop(opds); - - let i = (0..*idx) - .map(|j| { - if let Some(x) = self.src_view.get(&j) { - if (self.pred)(&x) { - 1 - } else { - 0 - } - } else { - 0 - } - }) - .sum(); - - if np != op { - self.cast.notify_each(i..l); - } else { - self.cast.notify(&i); - } - } -} diff --git a/nested/src/sequence/flatten.rs b/nested/src/sequence/flatten.rs deleted file mode 100644 index f59aeb2..0000000 --- a/nested/src/sequence/flatten.rs +++ /dev/null @@ -1,183 +0,0 @@ -use { - crate::{ - core::{ - port::UpdateTask, InnerViewPort, Observer, ObserverBroadcast, ObserverExt, - OuterViewPort, View, ViewPort, - }, - projection::ProjectionHelper, - sequence::SequenceView, - }, - std::sync::RwLock, - std::{collections::BTreeMap, sync::Arc}, -}; - -impl OuterViewPort>>> -where - Item: 'static, -{ - pub fn flatten(&self) -> OuterViewPort> { - let port = ViewPort::new(); - Flatten::new(self.clone(), port.inner()); - port.into_outer() - } -} - -pub struct Chunk -where - Item: 'static, -{ - offset: usize, - len: usize, - view: Arc>, -} - -pub struct Flatten -where - Item: 'static, -{ - length: usize, - top: Arc>>>, - chunks: BTreeMap>, - cast: Arc>>>, - proj_helper: ProjectionHelper, -} - -impl View for Flatten -where - Item: 'static, -{ - type Msg = usize; -} - -impl SequenceView for Flatten -where - Item: 'static, -{ - type Item = Item; - - fn get(&self, idx: &usize) -> Option { - let chunk = self.chunks.get(&self.get_chunk_idx(*idx)?)?; - chunk.view.get(&(*idx - chunk.offset)) - } - - fn len(&self) -> Option { - Some(self.length) - } -} - -impl Flatten -where - Item: 'static, -{ - pub fn new( - top_port: OuterViewPort< - dyn SequenceView>>, - >, - out_port: InnerViewPort>, - ) -> Arc> { - let mut proj_helper = ProjectionHelper::new(out_port.0.update_hooks.clone()); - - let flat = Arc::new(RwLock::new(Flatten { - length: 0, - top: proj_helper.new_sequence_arg(usize::MAX, top_port, |s: &mut Self, chunk_idx| { - s.update_chunk(*chunk_idx); - }), - chunks: BTreeMap::new(), - cast: out_port.get_broadcast(), - proj_helper, - })); - - flat.write().unwrap().proj_helper.set_proj(&flat); - out_port.set_view(Some(flat.clone())); - flat - } - - /// the top-sequence has changed the item at chunk_idx, - /// create a new observer for the contained sub sequence - fn update_chunk(&mut self, chunk_idx: usize) { - if let Some(chunk_port) = self.top.get(&chunk_idx) { - self.chunks.insert( - chunk_idx, - Chunk { - offset: 0, // will be adjusted by update_offsets() later - len: 0, - view: self.proj_helper.new_sequence_arg( - chunk_idx, - chunk_port.clone(), - move |s: &mut Self, idx| { - if let Some(chunk) = s.chunks.get(&chunk_idx) { - let chunk_offset = chunk.offset; - let chunk_len = chunk.view.len().unwrap_or(0); - - let mut dirty_idx = Vec::new(); - if chunk.len != chunk_len { - dirty_idx = s.update_all_offsets(); - } - - s.cast.notify(&(idx + chunk_offset)); - s.cast.notify_each(dirty_idx); - } else { - let dirty_idx = s.update_all_offsets(); - s.cast.notify_each(dirty_idx); - } - }, - ), - }, - ); - - chunk_port.0.update(); - let dirty_idx = self.update_all_offsets(); - self.cast.notify_each(dirty_idx); - } else { - // todo: - self.proj_helper.remove_arg(&chunk_idx); - - self.chunks.remove(&chunk_idx); - - let dirty_idx = self.update_all_offsets(); - self.cast.notify_each(dirty_idx); - } - } - - /// recalculate all chunk offsets beginning at start_idx - /// and update length of flattened sequence - fn update_all_offsets(&mut self) -> Vec { - let mut dirty_idx = Vec::new(); - let mut cur_offset = 0; - - for (_chunk_idx, chunk) in self.chunks.iter_mut() { - let old_offset = chunk.offset; - chunk.offset = cur_offset; - chunk.len = chunk.view.len().unwrap_or(0); - - if old_offset != cur_offset { - dirty_idx.extend( - std::cmp::min(old_offset, cur_offset) - ..std::cmp::max(old_offset, cur_offset) + chunk.len, - ); - } - - cur_offset += chunk.len; - } - - let old_length = self.length; - self.length = cur_offset; - - dirty_idx.extend(self.length..old_length); - - dirty_idx - } - - /// given an index in the flattened sequence, - /// which sub-sequence does it belong to? - fn get_chunk_idx(&self, glob_idx: usize) -> Option { - let mut offset = 0; - for (chunk_idx, chunk) in self.chunks.iter() { - offset += chunk.view.len().unwrap_or(0); - if glob_idx < offset { - return Some(*chunk_idx); - } - } - None - } -} diff --git a/nested/src/sequence/map.rs b/nested/src/sequence/map.rs deleted file mode 100644 index 907192e..0000000 --- a/nested/src/sequence/map.rs +++ /dev/null @@ -1,105 +0,0 @@ -use { - crate::{ - core::{Observer, ObserverBroadcast, ObserverExt, OuterViewPort, View, ViewPort}, - sequence::SequenceView, - }, - std::sync::Arc, - std::sync::RwLock, -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl OuterViewPort> { - pub fn map DstItem + Send + Sync + 'static>( - &self, - f: F, - ) -> OuterViewPort> { - let port = ViewPort::new(); - port.add_update_hook(Arc::new(self.0.clone())); - - let map = Arc::new(RwLock::new(MapSequenceItem { - src_view: None, - f, - cast: port.inner().get_broadcast(), - })); - - self.add_observer(map.clone()); - port.inner().set_view(Some(map)); - port.into_outer() - } - - pub fn filter_map< - DstItem: Clone + 'static, - F: Fn(&Item) -> Option + Send + Sync + 'static, - >( - &self, - f: F, - ) -> OuterViewPort> { - self.map(f) - .filter(|x| x.is_some()) - .map(|x| x.clone().unwrap()) - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct MapSequenceItem -where - SrcView: SequenceView + ?Sized, - F: Fn(&SrcView::Item) -> DstItem + Send + Sync, -{ - src_view: Option>, - f: F, - cast: Arc>>>, -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl View for MapSequenceItem -where - SrcView: SequenceView + ?Sized, - F: Fn(&SrcView::Item) -> DstItem + Send + Sync, -{ - type Msg = usize; -} - -impl SequenceView for MapSequenceItem -where - SrcView: SequenceView + ?Sized, - F: Fn(&SrcView::Item) -> DstItem + Send + Sync, -{ - type Item = DstItem; - - fn len(&self) -> Option { - self.src_view.len() - } - - fn get(&self, idx: &usize) -> Option { - self.src_view.get(idx).as_ref().map(|item| (self.f)(item)) - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl Observer for MapSequenceItem -where - SrcView: SequenceView + ?Sized, - F: Fn(&SrcView::Item) -> DstItem + Send + Sync, -{ - fn reset(&mut self, view: Option>) { - let old_len = self.len(); - self.src_view = view; - let new_len = self.len(); - - if let Some(len) = old_len { - self.cast.notify_each(0..len); - } - if let Some(len) = new_len { - self.cast.notify_each(0..len); - } - } - - fn notify(&mut self, msg: &usize) { - self.cast.notify(msg); - } -} diff --git a/nested/src/sequence/mod.rs b/nested/src/sequence/mod.rs deleted file mode 100644 index d3f2d2c..0000000 --- a/nested/src/sequence/mod.rs +++ /dev/null @@ -1,97 +0,0 @@ -pub mod filter; -pub mod map; -pub mod enumerate; -pub mod seq2idx; -pub mod flatten; -pub mod decorator; - -pub use seq2idx::Sequence2Index; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -use crate::core::View; - -pub trait SequenceView: View { - type Item; - - fn get(&self, idx: &usize) -> Option; - fn len(&self) -> Option; -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub trait SequenceViewExt: SequenceView { - fn iter<'a>(&'a self) -> SequenceViewIter<'a, Self> { - SequenceViewIter { view: self, cur: 0 } - } -} - -impl SequenceViewExt for V {} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct SequenceViewIter<'a, V> -where - V: SequenceView + ?Sized, -{ - view: &'a V, - cur: usize, -} - -impl<'a, V> Iterator for SequenceViewIter<'a, V> -where - V: SequenceView + ?Sized, -{ - type Item = V::Item; - - fn next(&mut self) -> Option { - let i = self.cur; - self.cur += 1; - self.view.get(&i) - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -use std::sync::RwLock; -use std::{ops::Deref, sync::Arc}; - -impl SequenceView for RwLock { - type Item = V::Item; - - fn get(&self, idx: &usize) -> Option { - self.read().unwrap().get(idx) - } - - fn len(&self) -> Option { - self.read().unwrap().len() - } -} - -impl SequenceView for Arc { - type Item = V::Item; - - fn get(&self, idx: &usize) -> Option { - self.deref().get(idx) - } - - fn len(&self) -> Option { - self.deref().len() - } -} - -impl SequenceView for Option { - type Item = V::Item; - - fn get(&self, idx: &usize) -> Option { - (self.as_ref()? as &V).get(idx) - } - - fn len(&self) -> Option { - if let Some(v) = self.as_ref() { - v.len() - } else { - Some(0) - } - } -} diff --git a/nested/src/sequence/seq2idx.rs b/nested/src/sequence/seq2idx.rs deleted file mode 100644 index 878ccf2..0000000 --- a/nested/src/sequence/seq2idx.rs +++ /dev/null @@ -1,99 +0,0 @@ -use { - crate::{ - core::{InnerViewPort, Observer, ObserverBroadcast, OuterViewPort, View, ViewPort}, - grid::GridView, - index::{IndexArea, IndexView}, - sequence::SequenceView, - }, - std::sync::Arc, - std::sync::RwLock, -}; - -/// Transforms a SequenceView into IndexView -pub struct Sequence2Index -where - SrcView: SequenceView + ?Sized + 'static, -{ - src_view: Option>, - cast: Arc>>>, -} - -impl Sequence2Index -where - SrcView: SequenceView + ?Sized + 'static, -{ - pub fn new( - port: InnerViewPort>, - ) -> Arc> { - let s2i = Arc::new(RwLock::new(Sequence2Index { - src_view: None, - cast: port.get_broadcast(), - })); - port.set_view(Some(s2i.clone())); - s2i - } -} - -impl OuterViewPort> { - pub fn to_index(&self) -> OuterViewPort> { - let port = ViewPort::new(); - port.add_update_hook(Arc::new(self.0.clone())); - self.add_observer(Sequence2Index::new(port.inner())); - port.into_outer() - } - - pub fn to_grid_horizontal(&self) -> OuterViewPort> { - self.to_index().to_grid_horizontal() - } - - pub fn to_grid_vertical(&self) -> OuterViewPort> { - self.to_index().to_grid_vertical() - } -} - -impl View for Sequence2Index -where - SrcView: SequenceView + ?Sized + 'static, -{ - type Msg = IndexArea; -} - -impl IndexView for Sequence2Index -where - SrcView: SequenceView + ?Sized + 'static, -{ - type Item = SrcView::Item; - - fn get(&self, key: &usize) -> Option { - self.src_view.get(key) - } - - fn area(&self) -> IndexArea { - if let Some(len) = self.src_view.len() { - if len > 0 { - IndexArea::Range(0..=len - 1) - } else { - IndexArea::Empty - } - } else { - IndexArea::Full - } - } -} - -impl Observer for Sequence2Index -where - SrcView: SequenceView + ?Sized + 'static, -{ - fn reset(&mut self, view: Option>) { - let old_area = self.area(); - self.src_view = view; - - self.cast.notify(&old_area); - self.cast.notify(&self.area()); - } - - fn notify(&mut self, idx: &usize) { - self.cast.notify(&IndexArea::Set(vec![*idx])); - } -} diff --git a/nested/src/singleton/buffer.rs b/nested/src/singleton/buffer.rs deleted file mode 100644 index 0f3b1f3..0000000 --- a/nested/src/singleton/buffer.rs +++ /dev/null @@ -1,124 +0,0 @@ -use { - crate::{ - core::{InnerViewPort, OuterViewPort, View, ViewPort}, - singleton::SingletonView, - }, - std::sync::RwLock, - std::{ - ops::{Deref, DerefMut}, - sync::Arc, - }, -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct SingletonBufferView(Arc>); - -impl View for SingletonBufferView -where - T: Clone + Send + Sync + 'static, -{ - type Msg = (); -} - -impl SingletonView for SingletonBufferView -where - T: Clone + Send + Sync + 'static, -{ - type Item = T; - - fn get(&self) -> Self::Item { - self.0.read().unwrap().clone() - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -#[derive(Clone)] -pub struct SingletonBuffer -where - T: Clone + Send + Sync + 'static, -{ - value: Arc>, - port: InnerViewPort> -} - -impl SingletonBuffer -where - T: Clone + Send + Sync + 'static, -{ - pub fn with_port(value: T, port: InnerViewPort>) -> Self { - let value = Arc::new(RwLock::new(value)); - port.set_view(Some(Arc::new(SingletonBufferView(value.clone())))); - - SingletonBuffer { - value, - port - } - } - - pub fn new(value: T) -> Self { - SingletonBuffer::with_port(value, ViewPort::new().into_inner()) - } - - pub fn get_port(&self) -> OuterViewPort> { - self.port.0.outer() - } - - pub fn get(&self) -> T { - self.value.read().unwrap().clone() - } - - pub fn get_mut(&self) -> MutableSingletonAccess { - MutableSingletonAccess { - buf: self.clone(), - val: self.get(), - } - } - - pub fn set(&mut self, new_value: T) { - let mut v = self.value.write().unwrap(); - *v = new_value; - drop(v); - self.port.notify(&()); - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct MutableSingletonAccess -where - T: Clone + Send + Sync + 'static, -{ - buf: SingletonBuffer, - val: T, -} - -impl Deref for MutableSingletonAccess -where - T: Clone + Send + Sync + 'static, -{ - type Target = T; - - fn deref(&self) -> &T { - &self.val - } -} - -impl DerefMut for MutableSingletonAccess -where - T: Clone + Send + Sync + 'static, -{ - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.val - } -} - -impl Drop for MutableSingletonAccess -where - T: Clone + Send + Sync + 'static, -{ - fn drop(&mut self) { - self.buf.set(self.val.clone()); - } -} diff --git a/nested/src/singleton/flatten.rs b/nested/src/singleton/flatten.rs deleted file mode 100644 index f536416..0000000 --- a/nested/src/singleton/flatten.rs +++ /dev/null @@ -1,88 +0,0 @@ -use { - crate::{ - core::{ - port::UpdateTask, InnerViewPort, Observer, ObserverBroadcast, ObserverExt, - OuterViewPort, View, ViewPort, - }, - projection::ProjectionHelper, - singleton::SingletonView, - }, - std::sync::RwLock, - std::{collections::BTreeMap, sync::Arc}, -}; - -impl OuterViewPort>>> -where - Item: 'static + Default, -{ - pub fn flatten(&self) -> OuterViewPort> { - let port = ViewPort::new(); - Flatten::new(self.clone(), port.inner()); - port.into_outer() - } -} - -pub struct Flatten -where - Item: 'static + Default, -{ - outer: Arc>>>, - inner: OuterViewPort>, - cast: Arc>>>, - proj: ProjectionHelper -} - -impl View for Flatten -where - Item: 'static + Default, -{ - type Msg = (); -} - -impl SingletonView for Flatten -where - Item: 'static + Default, -{ - type Item = Item; - - fn get(&self) -> Self::Item { - if let Some(i) = self.inner.get_view() { - i.get() - } else { - Item::default() - } - } -} - -impl Flatten -where - Item: 'static + Default, -{ - pub fn new( - top_port: OuterViewPort< - dyn SingletonView>>, - >, - out_port: InnerViewPort>, - ) -> Arc> { - let mut proj = ProjectionHelper::new(out_port.0.update_hooks.clone()); - - let flat = Arc::new(RwLock::new(Flatten { - outer: proj.new_singleton_arg(0, top_port, |s: &mut Self, _msg| { - s.inner = s.outer.get(); - s.proj.new_singleton_arg(1, s.inner.clone(), |s: &mut Self, _msg| { - s.cast.notify(&()); - }); - //s.inner.0.update(); - }), - inner: OuterViewPort::default(), - cast: out_port.get_broadcast(), - proj, - })); - - flat.write().unwrap().proj.set_proj(&flat); - out_port.set_view(Some(flat.clone())); - flat - } -} - - diff --git a/nested/src/singleton/map.rs b/nested/src/singleton/map.rs deleted file mode 100644 index 11e4d00..0000000 --- a/nested/src/singleton/map.rs +++ /dev/null @@ -1,81 +0,0 @@ -use { - crate::{ - core::{Observer, ObserverBroadcast, OuterViewPort, View, ViewPort}, - singleton::SingletonView, - }, - std::sync::Arc, - std::sync::RwLock, -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl OuterViewPort> { - pub fn map DstItem + Send + Sync + 'static>( - &self, - f: F, - ) -> OuterViewPort> { - let port = ViewPort::new(); - port.add_update_hook(Arc::new(self.0.clone())); - - let map = Arc::new(RwLock::new(MapSingleton { - src_view: None, - f, - cast: port.inner().get_broadcast(), - })); - - self.add_observer(map.clone()); - port.inner().set_view(Some(map)); - port.into_outer() - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct MapSingleton -where - SrcView: SingletonView + ?Sized, - F: Fn(SrcView::Item) -> DstItem + Send + Sync, -{ - src_view: Option>, - f: F, - cast: Arc>>>, -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl View for MapSingleton -where - SrcView: SingletonView + ?Sized, - F: Fn(SrcView::Item) -> DstItem + Send + Sync, -{ - type Msg = (); -} - -impl SingletonView for MapSingleton -where - SrcView: SingletonView + ?Sized, - F: Fn(SrcView::Item) -> DstItem + Send + Sync, -{ - type Item = DstItem; - - fn get(&self) -> DstItem { - (self.f)(self.src_view.as_ref().unwrap().get()) - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl Observer for MapSingleton -where - SrcView: SingletonView + ?Sized, - F: Fn(SrcView::Item) -> DstItem + Send + Sync, -{ - fn reset(&mut self, view: Option>) { - self.src_view = view; - self.cast.notify(&()); - } - - fn notify(&mut self, msg: &()) { - self.cast.notify(msg); - } -} diff --git a/nested/src/singleton/mod.rs b/nested/src/singleton/mod.rs deleted file mode 100644 index c0b9292..0000000 --- a/nested/src/singleton/mod.rs +++ /dev/null @@ -1,66 +0,0 @@ -pub mod buffer; -pub mod map; -pub mod flatten; -pub mod to_index; -pub mod to_sequence; - -use { - crate::core::View, - std::sync::RwLock, - std::{ops::Deref, sync::Arc}, -}; - -pub use buffer::SingletonBuffer; - -// TODO: #[ImplForArc, ImplForRwLock] -pub trait SingletonView: View { - type Item; - - fn get(&self) -> Self::Item; -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl SingletonView for RwLock { - type Item = V::Item; - - fn get(&self) -> Self::Item { - self.read().unwrap().get() - } -} - -impl SingletonView for Arc { - type Item = V::Item; - - fn get(&self) -> Self::Item { - self.deref().get() - } -} - -impl SingletonView for Option -where - V::Item: Default, -{ - type Item = V::Item; - - fn get(&self) -> Self::Item { - if let Some(s) = self.as_ref() { - s.get() - } else { - V::Item::default() - } - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -/* -impl OuterViewPort> { - pub fn get(&self) -> T { - self.get_view().unrwap().read().unwrap().get(); - } - - pub fn map(&self, f: impl Fn(T) -> U) -> OuterViewPort> { - - } -} - */ diff --git a/nested/src/singleton/to_index.rs b/nested/src/singleton/to_index.rs deleted file mode 100644 index da39758..0000000 --- a/nested/src/singleton/to_index.rs +++ /dev/null @@ -1,91 +0,0 @@ -use { - crate::{ - core::{Observer, ObserverBroadcast, OuterViewPort, View, ViewPort}, - grid::GridView, - index::{IndexArea, IndexView}, - singleton::SingletonView, - }, - std::sync::Arc, - std::sync::RwLock, -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl OuterViewPort> { - pub fn to_index(&self) -> OuterViewPort> { - let port = ViewPort::new(); - port.add_update_hook(Arc::new(self.0.clone())); - - let map = Arc::new(RwLock::new(Singleton2Index { - src_view: None, - cast: port.inner().get_broadcast(), - })); - - self.add_observer(map.clone()); - port.inner().set_view(Some(map)); - port.into_outer() - } - - pub fn to_grid(&self) -> OuterViewPort> { - self.to_index().map_key( - |_msg: &()| cgmath::Point2::new(0, 0), - |pt| { - if pt.x == 0 && pt.y == 0 { - Some(()) - } else { - None - } - }, - ) - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct Singleton2Index -where - SrcView: SingletonView + ?Sized, -{ - src_view: Option>, - cast: Arc>>>, -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl View for Singleton2Index -where - SrcView: SingletonView + ?Sized, -{ - type Msg = IndexArea<()>; -} - -impl IndexView<()> for Singleton2Index -where - SrcView: SingletonView + ?Sized, -{ - type Item = SrcView::Item; - - fn area(&self) -> IndexArea<()> { - IndexArea::Set(vec![ () ]) - } - - fn get(&self, _msg: &()) -> Option { - Some(self.src_view.as_ref().unwrap().get()) - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl Observer for Singleton2Index -where - SrcView: SingletonView + ?Sized, -{ - fn reset(&mut self, view: Option>) { - self.src_view = view; - self.cast.notify(&IndexArea::Set(vec![ () ])); - } - - fn notify(&mut self, _: &()) { - self.cast.notify(&IndexArea::Set(vec![ () ])); - } -} diff --git a/nested/src/singleton/to_sequence.rs b/nested/src/singleton/to_sequence.rs deleted file mode 100644 index 73f88ab..0000000 --- a/nested/src/singleton/to_sequence.rs +++ /dev/null @@ -1,81 +0,0 @@ -use { - crate::{ - core::{Observer, ObserverBroadcast, OuterViewPort, View, ViewPort}, - sequence::{SequenceView}, - singleton::SingletonView, - }, - std::sync::Arc, - std::sync::RwLock, -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl OuterViewPort> { - pub fn to_sequence(&self) -> OuterViewPort> { - let port = ViewPort::new(); - port.add_update_hook(Arc::new(self.0.clone())); - - let map = Arc::new(RwLock::new(Singleton2Sequence { - src_view: None, - cast: port.inner().get_broadcast(), - })); - - self.add_observer(map.clone()); - port.inner().set_view(Some(map)); - port.into_outer() - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct Singleton2Sequence -where - SrcView: SingletonView + ?Sized, -{ - src_view: Option>, - cast: Arc>>>, -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl View for Singleton2Sequence -where - SrcView: SingletonView + ?Sized, -{ - type Msg = usize; -} - -impl SequenceView for Singleton2Sequence -where - SrcView: SingletonView + ?Sized, -{ - type Item = SrcView::Item; - - fn get(&self, idx: &usize) -> Option { - if *idx == 0 { - Some(self.src_view.as_ref()?.get()) - } else { - None - } - } - - fn len(&self) -> Option { - Some(if self.src_view.is_some() { 1 } else { 0 }) - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl Observer for Singleton2Sequence -where - SrcView: SingletonView + ?Sized, -{ - fn reset(&mut self, view: Option>) { - self.src_view = view; - self.cast.notify(&0); - } - - fn notify(&mut self, _: &()) { - self.cast.notify(&0); - } -} diff --git a/nested/src/terminal/ansi_parser.rs b/nested/src/terminal/ansi_parser.rs index d7b6658..02b4e68 100644 --- a/nested/src/terminal/ansi_parser.rs +++ b/nested/src/terminal/ansi_parser.rs @@ -1,10 +1,15 @@ use { //async_std::{io::{Read, ReadExt}}, + r3vi::{ + view::{ + InnerViewPort, Observer, ObserverBroadcast, OuterViewPort, View, ViewPort, + index::*, + singleton::*, + }, + buffer::{singleton::*, index_hashmap::*}, + projection::projection_helper::ProjectionHelper, + }, crate::{ - core::{InnerViewPort, Observer, ObserverBroadcast, OuterViewPort, View, ViewPort}, - index::{buffer::IndexBuffer, IndexArea, IndexView}, - projection::ProjectionHelper, - singleton::{SingletonBuffer, SingletonView}, terminal::{TerminalAtom, TerminalStyle, TerminalView}, }, cgmath::{Point2, Vector2}, diff --git a/nested/src/terminal/compositor.rs b/nested/src/terminal/compositor.rs index 55af8f7..d8a53e4 100644 --- a/nested/src/terminal/compositor.rs +++ b/nested/src/terminal/compositor.rs @@ -1,10 +1,12 @@ use { - crate::{ - core::{InnerViewPort, Observer, ObserverBroadcast, OuterViewPort, View}, - index::{IndexArea, IndexView}, - projection::ProjectionHelper, - terminal::{TerminalAtom, TerminalView}, + r3vi::{ + view::{ + InnerViewPort, Observer, ObserverBroadcast, OuterViewPort, View, + index::*, + }, + projection::projection_helper::*, }, + crate::{terminal::{TerminalAtom, TerminalView}}, cgmath::Point2, std::sync::Arc, std::sync::RwLock, diff --git a/nested/src/terminal/mod.rs b/nested/src/terminal/mod.rs index 8a6f470..000b0ba 100644 --- a/nested/src/terminal/mod.rs +++ b/nested/src/terminal/mod.rs @@ -11,7 +11,7 @@ pub use { terminal::{Terminal, TerminalEvent}, }; -use crate::grid::GridView; +use r3vi::view::grid::*; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> @@ -32,9 +32,9 @@ pub trait TerminalEditor { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> use { - crate::{ - core::{OuterViewPort, ViewPort}, - vec::VecBuffer, + r3vi::{ + view::{OuterViewPort}, + buffer::vec::*, }, cgmath::Point2, }; @@ -54,19 +54,25 @@ pub fn make_label(s: &str) -> OuterViewPort { v } -impl OuterViewPort { - pub fn with_style(&self, style: TerminalStyle) -> OuterViewPort { +pub trait TerminalProjections { + fn with_style(&self, style: TerminalStyle) -> OuterViewPort; + fn with_fg_color(&self, col: (u8, u8, u8)) -> OuterViewPort; + fn with_bg_color(&self, col: (u8, u8, u8)) -> OuterViewPort; +} + +impl TerminalProjections for OuterViewPort { + fn with_style(&self, style: TerminalStyle) -> OuterViewPort { self.map_item( move |_idx, a| a.add_style_front(style) ) } - pub fn with_fg_color(&self, col: (u8, u8, u8)) -> OuterViewPort { + fn with_fg_color(&self, col: (u8, u8, u8)) -> OuterViewPort { self.with_style(TerminalStyle::fg_color(col)) } - pub fn with_bg_color(&self, col: (u8, u8, u8)) -> OuterViewPort { + fn with_bg_color(&self, col: (u8, u8, u8)) -> OuterViewPort { self.with_style(TerminalStyle::bg_color(col)) } } diff --git a/nested/src/terminal/terminal.rs b/nested/src/terminal/terminal.rs index 01ef62f..c83c9a6 100644 --- a/nested/src/terminal/terminal.rs +++ b/nested/src/terminal/terminal.rs @@ -1,13 +1,13 @@ use { - super::{TerminalStyle, TerminalView}, - crate::{ - core::{ + r3vi::{ + view::{ channel::{queue_channel, set_channel, ChannelReceiver, ChannelSender}, Observer, OuterViewPort, - }, - grid::GridWindowIterator, - index::IndexArea, + grid::*, + index::*, + } }, + super::{TerminalStyle, TerminalView}, async_std::{stream::StreamExt, task}, cgmath::{Point2, Vector2}, signal_hook, diff --git a/nested/src/tree/cursor.rs b/nested/src/tree/cursor.rs index 1175e9f..bd0a4fb 100644 --- a/nested/src/tree/cursor.rs +++ b/nested/src/tree/cursor.rs @@ -1,5 +1,5 @@ use { - crate::list::ListCursorMode + crate::editors::list::ListCursorMode }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> diff --git a/nested/src/tree/nav.rs b/nested/src/tree/nav.rs index 47e1275..c525065 100644 --- a/nested/src/tree/nav.rs +++ b/nested/src/tree/nav.rs @@ -1,15 +1,24 @@ use { - crate::list::ListCursorMode, - crate::tree::TreeCursor, - crate::vec::VecBuffer, - crate::core::{OuterViewPort}, - crate::sequence::{SequenceView, decorator::Separate}, - crate::singleton::{SingletonBuffer, SingletonView}, - cgmath::Vector2, + r3vi::{ + view::{ + OuterViewPort, + singleton::*, + sequence::*, + }, + buffer::{ + singleton::SingletonBuffer, + vec::VecBuffer + }, + projection::{ + decorate_sequence::*, + } + }, crate::{ - terminal::{TerminalView, TerminalStyle, make_label} - - } + editors::list::ListCursorMode, + tree::TreeCursor, + terminal::{TerminalView, TerminalProjections, make_label} + }, + cgmath::Vector2, }; #[derive(Clone, Copy, Eq, PartialEq)] @@ -76,6 +85,21 @@ pub trait TreeNav { self.goto(c) } + fn get_leaf_mode(&mut self) -> ListCursorMode { + self.get_cursor().leaf_mode + } + + fn toggle_leaf_mode(&mut self) -> TreeNavResult { + let old_mode = self.get_leaf_mode(); + self.set_leaf_mode( + match old_mode { + ListCursorMode::Insert => ListCursorMode::Select, + ListCursorMode::Select => ListCursorMode::Insert + } + ); + TreeNavResult::Continue + } + fn up(&mut self) -> TreeNavResult { self.goby(Vector2::new(0, -1)) } diff --git a/nested/src/tree/node.rs b/nested/src/tree/node.rs index 81d8a22..709d28c 100644 --- a/nested/src/tree/node.rs +++ b/nested/src/tree/node.rs @@ -1,40 +1,58 @@ use { - std::sync::{Arc, RwLock}, + std::{sync::{Arc, RwLock}, any::Any}, cgmath::Vector2, + r3vi::{ + view::{ + ViewPort, OuterViewPort, AnyOuterViewPort, + singleton::*, + sequence::* + }, + buffer::{singleton::*} + }, crate::{ - core::{ViewPort, OuterViewPort, AnyOuterViewPort}, type_system::{ReprTree, Context}, - singleton::{SingletonBuffer, SingletonView}, - sequence::SequenceView, terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult}, diagnostics::{Diagnostics, Message}, tree::{TreeNav, TreeCursor, TreeNavResult}, - list::{ListCursorMode}, + editors::list::{ListCursorMode}, commander::ObjCommander, - vec::VecBuffer, - Nested } }; #[derive(Clone)] pub struct NestedNode { + /// context pub ctx: Option>>, -// pub abs: Option>>, + /// abstract editor + pub editor: Option>, + + /// abstract data view + pub data: Option>>, + + /// display view pub view: Option>, + + /// diagnostics pub diag: Option>>, + + /// commander pub cmd: Option>>, + + /// tree navigation pub tree_nav: Option>>, } impl ObjCommander for NestedNode { fn send_cmd_obj(&mut self, cmd_obj: Arc>) { if let Some(cmd) = self.cmd.as_ref() { + // todo: filter out tree-nav cmds and send them to tree_nav cmd.write().unwrap().send_cmd_obj(cmd_obj); } } } +// todo: remove that at some point impl TerminalEditor for NestedNode { fn get_term_view(&self) -> OuterViewPort { self.get_view() @@ -109,13 +127,18 @@ impl TreeNav for NestedNode { } } -impl Diagnostics for NestedNode {} -impl Nested for NestedNode {} +impl Diagnostics for NestedNode { + fn get_msg_port(&self) -> OuterViewPort> { + self.get_diag() + } +} impl NestedNode { pub fn new() -> Self { NestedNode { ctx: None, + data: None, + editor: None, view: None, diag: None, cmd: None, @@ -128,6 +151,16 @@ impl NestedNode { self } + pub fn set_data(mut self, data: Arc>) -> Self { + self.data = Some(data); + self + } + + pub fn set_editor(mut self, editor: Arc) -> Self { + self.editor = Some(editor); + self + } + pub fn set_view(mut self, view: OuterViewPort) -> Self { self.view = Some(view); self diff --git a/nested/src/type_system/context.rs b/nested/src/type_system/context.rs index 779d0e6..a15cad4 100644 --- a/nested/src/type_system/context.rs +++ b/nested/src/type_system/context.rs @@ -1,6 +1,5 @@ use { crate::{ - core::{AnyOuterViewPort, OuterViewPort, View}, type_system::{TypeDict, TypeTerm, TypeID, ReprTree}, tree::NestedNode }, @@ -50,6 +49,9 @@ pub struct Context { /// objects objects: HashMap>>, + /// types that can be edited as lists + list_types: Vec, + /// editors editor_ctors: HashMap>, TypeTerm, usize) -> Option + Send + Sync>>, @@ -72,6 +74,10 @@ impl Context { default_constructors: HashMap::new(), morphism_constructors: HashMap::new(), objects: HashMap::new(), + list_types: match parent.as_ref() { + Some(p) => p.read().unwrap().list_types.clone(), + None => Vec::new() + }, parent, } } @@ -80,8 +86,22 @@ impl Context { Context::with_parent(None) } - pub fn add_typename(&mut self, tn: String) { - self.type_dict.write().unwrap().add_typename(tn); + pub fn add_typename(&mut self, tn: String) -> TypeID { + self.type_dict.write().unwrap().add_typename(tn) + } + + pub fn add_list_typename(&mut self, tn: String) { + let tid = self.add_typename(tn); + self.list_types.push( tid ); + } + + pub fn is_list_type(&self, t: &TypeTerm) -> bool { + match t { + TypeTerm::Type { id, args: _ } => { + self.list_types.contains(id) + } + _ => false + } } pub fn get_typeid(&self, tn: &str) -> Option { @@ -98,9 +118,12 @@ impl Context { pub fn add_editor_ctor(&mut self, tn: &str, mk_editor: Arc>, TypeTerm, usize) -> Option + Send + Sync>) { let mut dict = self.type_dict.write().unwrap(); - let tyid = dict - .get_typeid(&tn.into()) - .unwrap_or( dict.add_typename(tn.into()) ); + let tyid = + if let Some(tyid) = dict.get_typeid(&tn.into()) { + tyid + } else { + dict.add_typename(tn.into()) + }; self.editor_ctors.insert(tyid, mk_editor); } @@ -122,7 +145,20 @@ impl Context { let mk_editor = ctx.read().unwrap().get_editor_ctor(&type_term)?; mk_editor(ctx.clone(), type_term, depth) } +/* + pub fn enrich_editor( + node: NestedNode, + typ: TypeTerm + ) -> NestedNode { + + // create view + + // create commander + + + } +*/ pub fn add_morphism( &mut self, morph_type: MorphismType, diff --git a/nested/src/type_system/make_editor.rs b/nested/src/type_system/make_editor.rs index 1fd7f7c..05e1eea 100644 --- a/nested/src/type_system/make_editor.rs +++ b/nested/src/type_system/make_editor.rs @@ -1,15 +1,20 @@ use { crate::{ - type_system::{TypeTerm, Context}, - integer::{DigitEditor, PosIntEditor}, - list::{PTYListEditor}, - sequence::{decorator::{SeqDecorStyle}}, - sum::SumEditor, - char::CharEditor, + type_system::{Context, TypeTerm, ReprTree}, + editors::{ + char::*, + list::*, + integer::*, + product::*, + sum::* + }, + tree::{NestedNode}, + terminal::{TerminalEditor}, + diagnostics::{Diagnostics}, type_system::TypeTermEditor, - Nested }, std::sync::{Arc, RwLock}, + cgmath::Point2 }; pub fn init_mem_ctx(parent: Arc>) -> Arc> { @@ -30,7 +35,9 @@ pub fn init_editor_ctx(parent: Arc>) -> Arc> { } ) ); + ctx.write().unwrap().add_list_typename("Sequence".into()); + ctx.write().unwrap().add_list_typename("List".into()); ctx.write().unwrap().add_editor_ctor( "List", Arc::new( |ctx: Arc>, ty: TypeTerm, depth: usize| { @@ -39,44 +46,13 @@ pub fn init_editor_ctx(parent: Arc>) -> Arc> { id: _, args } => { if args.len() > 0 { - // todo: factor style out of type arGS - let style = if args.len() > 1 { - match args[1] { - TypeTerm::Num(0) => SeqDecorStyle::Plain, - TypeTerm::Num(1) => SeqDecorStyle::HorizontalSexpr, - TypeTerm::Num(2) => SeqDecorStyle::VerticalSexpr, - TypeTerm::Num(3) => SeqDecorStyle::DoubleQuote, - TypeTerm::Num(4) => SeqDecorStyle::Tuple, - TypeTerm::Num(5) => SeqDecorStyle::EnumSet, - TypeTerm::Num(6) => SeqDecorStyle::Path, - _ => SeqDecorStyle::HorizontalSexpr - } - } else { - SeqDecorStyle::HorizontalSexpr - }; - - let delim = if args.len() > 1 { - match args[1] { - TypeTerm::Num(0) => None, - TypeTerm::Num(1) => Some(' '), - TypeTerm::Num(2) => Some('\n'), - TypeTerm::Num(3) => None, - TypeTerm::Num(4) => Some(','), - TypeTerm::Num(5) => Some(','), - TypeTerm::Num(6) => Some('/'), - _ => None - } - }else { - None - }; - Some( PTYListEditor::new( - ctx.clone(), + ctx, args[0].clone(), - delim, - depth - ).into_node(style) + ListStyle::HorizontalSexpr, + depth + 1 + ).into_node() ) } else { None @@ -88,30 +64,49 @@ pub fn init_editor_ctx(parent: Arc>) -> Arc> { ) ); + ctx.write().unwrap().add_list_typename("Symbol".into()); ctx.write().unwrap().add_editor_ctor( "Symbol", Arc::new( |ctx: Arc>, _ty: TypeTerm, depth: usize| { - Context::make_editor( - &ctx, - ctx.read().unwrap().type_term_from_str("( List Char 0 )").unwrap(), - depth - ) + let mut node = PTYListEditor::new( + ctx.clone(), + ctx.read().unwrap().type_term_from_str("( Char )").unwrap(), + ListStyle::Plain, + depth + 1 + ).into_node(); + + node.data = Some(ReprTree::ascend( + &node.data.unwrap(), + ctx.read().unwrap().type_term_from_str("( Symbol )").unwrap() + )); + + Some(node) } ) ); + ctx.write().unwrap().add_list_typename("String".into()); ctx.write().unwrap().add_editor_ctor( "String", Arc::new( |ctx: Arc>, _ty: TypeTerm, depth: usize| { - Context::make_editor( - &ctx, - ctx.read().unwrap().type_term_from_str("( List Char 3 )").unwrap(), - depth - ) + let mut node = PTYListEditor::new( + ctx.clone(), + ctx.read().unwrap().type_term_from_str("( Char )").unwrap(), + ListStyle::DoubleQuote, + depth + 1 + ).into_node(); + + node.data = Some(ReprTree::ascend( + &node.data.unwrap(), + ctx.read().unwrap().type_term_from_str("( String )").unwrap() + )); + + Some(node) } ) ); - + + ctx.write().unwrap().add_list_typename("TypeTerm".into()); ctx.write().unwrap().add_editor_ctor( "TypeTerm", Arc::new( |ctx: Arc>, _ty: TypeTerm, depth: usize| { @@ -120,7 +115,7 @@ pub fn init_editor_ctx(parent: Arc>) -> Arc> { ) ); - ctx.write().unwrap().add_typename("TerminalEvent".into()); + ctx.write().unwrap().add_typename("TerminalEvent".into()); ctx } @@ -128,10 +123,9 @@ pub fn init_math_ctx(parent: Arc>) -> Arc> { let ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent)))); ctx.write().unwrap().add_typename("MachineInt".into()); + ctx.write().unwrap().add_typename("u32".into()); ctx.write().unwrap().add_typename("BigEndian".into()); - //ctx.write().unwrap().add_typename("Digit".into()); - ctx.write().unwrap().add_editor_ctor( "Digit", Arc::new( |ctx: Arc>, ty: TypeTerm, _depth: usize| { @@ -142,8 +136,9 @@ pub fn init_math_ctx(parent: Arc>) -> Arc> { if args.len() > 0 { match args[0] { TypeTerm::Num(radix) => { + let node = DigitEditor::new(ctx.clone(), radix as u32).into_node(); Some( - DigitEditor::new(ctx.clone(), radix as u32).into_node() + node ) }, _ => None @@ -157,7 +152,8 @@ pub fn init_math_ctx(parent: Arc>) -> Arc> { } ) ); - + + ctx.write().unwrap().add_list_typename("PosInt".into()); ctx.write().unwrap().add_editor_ctor( "PosInt", Arc::new( |ctx: Arc>, ty: TypeTerm, _depth: usize| { @@ -184,32 +180,88 @@ pub fn init_math_ctx(parent: Arc>) -> Arc> { ) ); + ctx.write().unwrap().add_list_typename("RGB".into()); + ctx.write().unwrap().add_editor_ctor( + "RGB", Arc::new( + |ctx: Arc>, ty: TypeTerm, depth: usize| { + let editor = ProductEditor::new(depth, ctx.clone()) + .with_t(Point2::new(0, 0), "r: ") + .with_n(Point2::new(1, 0), + vec![ + ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() + ]) + .with_t(Point2::new(0, 1), "g: ") + .with_n(Point2::new(1, 1), + vec![ + ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() + ]) + .with_t(Point2::new(0, 2), "b: ") + .with_n(Point2::new(1, 2), + vec![ + ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() + ] + ); + + let view = editor.get_term_view(); + let diag = editor.get_msg_port(); + let editor = Arc::new(RwLock::new(editor)); + + let node = NestedNode::new() + .set_ctx(ctx) + .set_cmd(editor.clone()) + .set_nav(editor.clone()) + .set_view(view) + .set_diag(diag) + ; + + Some(node) + } + )); + ctx } pub fn init_os_ctx(parent: Arc>) -> Arc> { let ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent)))); + ctx.write().unwrap().add_list_typename("PathSegment".into()); ctx.write().unwrap().add_editor_ctor( "PathSegment", Arc::new( |ctx: Arc>, _ty: TypeTerm, depth: usize| { - Context::make_editor( - &ctx, - ctx.read().unwrap().type_term_from_str("( List Char 0 )").unwrap(), - depth - ) + let mut node = PTYListEditor::new( + ctx.clone(), + ctx.read().unwrap().type_term_from_str("( Char )").unwrap(), + ListStyle::Plain, + depth + 1 + ).into_node(); + + node.data = Some(ReprTree::ascend( + &node.data.unwrap(), + ctx.read().unwrap().type_term_from_str("( PathSegment )").unwrap() + )); + + Some(node) } ) ); + ctx.write().unwrap().add_list_typename("Path".into()); ctx.write().unwrap().add_editor_ctor( "Path", Arc::new( |ctx: Arc>, _ty: TypeTerm, depth: usize| { - Context::make_editor( - &ctx, - ctx.read().unwrap().type_term_from_str("( List PathSegment 6 )").unwrap(), - depth+1 - ) + let mut node = PTYListEditor::new( + ctx.clone(), + ctx.read().unwrap().type_term_from_str("( PathSegment )").unwrap(), + ListStyle::Path, + depth + 1 + ).into_node(); + + node.data = Some(ReprTree::ascend( + &node.data.unwrap(), + ctx.read().unwrap().type_term_from_str("( Path )").unwrap() + )); + + Some(node) } ) ); diff --git a/nested/src/type_system/mod.rs b/nested/src/type_system/mod.rs index 5df9a61..27dc2fa 100644 --- a/nested/src/type_system/mod.rs +++ b/nested/src/type_system/mod.rs @@ -1,3 +1,4 @@ + pub mod type_term; pub mod repr_tree; pub mod context; diff --git a/nested/src/type_system/repr_tree.rs b/nested/src/type_system/repr_tree.rs index cd1d046..ad1dc25 100644 --- a/nested/src/type_system/repr_tree.rs +++ b/nested/src/type_system/repr_tree.rs @@ -1,8 +1,7 @@ use { + r3vi::view::{AnyOuterViewPort, OuterViewPort, View}, crate::{ - core::{AnyOuterViewPort, OuterViewPort, View}, - type_system::{TypeDict, TypeTerm, TypeID}, - tree::NestedNode + type_system::{TypeTerm} }, std::{ collections::HashMap, @@ -28,6 +27,10 @@ impl ReprTree { } } + pub fn get_type(&self) -> &TypeTerm { + &self.type_tag + } + pub fn new_leaf(type_tag: TypeTerm, port: AnyOuterViewPort) -> Arc> { let mut tree = ReprTree::new(type_tag); tree.insert_leaf(vec![].into_iter(), port); diff --git a/nested/src/type_system/type_term_editor.rs b/nested/src/type_system/type_term_editor.rs index 6c1881d..86e9250 100644 --- a/nested/src/type_system/type_term_editor.rs +++ b/nested/src/type_system/type_term_editor.rs @@ -1,15 +1,21 @@ use { + r3vi::{ + view::{ + OuterViewPort, + sequence::* + } + }, crate::{ - core::{OuterViewPort}, type_system::{Context}, terminal::{TerminalEvent, TerminalView, TerminalEditor, TerminalEditorResult}, - sequence::{SequenceView, decorator::SeqDecorStyle}, - list::{PTYListEditor}, + editors::{ + list::*, + sum::*, + char::CharEditor, + integer::PosIntEditor, + }, tree::{TreeNav, TreeCursor, TreeNavResult}, diagnostics::{Diagnostics, Message}, - sum::SumEditor, - char::CharEditor, - integer::PosIntEditor, tree::NestedNode, commander::Commander, PtySegment @@ -42,7 +48,7 @@ impl TypeTermEditor { ty: TypeTermVar::Any, sum_edit: Arc::new(RwLock::new(SumEditor::new( vec![ - Context::make_editor( &ctx, ctx.read().unwrap().type_term_from_str("( List TypeTerm 1 )").unwrap(), depth + 1).unwrap(), + Context::make_editor( &ctx, ctx.read().unwrap().type_term_from_str("( List TypeTerm )").unwrap(), depth + 1).unwrap(), Context::make_editor( &ctx, ctx.read().unwrap().type_term_from_str("( PosInt 10 )").unwrap(), depth + 1 ).unwrap(), Context::make_editor( &ctx, ctx.read().unwrap().type_term_from_str("( Symbol )").unwrap(), depth + 1 ).unwrap() ]))) @@ -50,19 +56,22 @@ impl TypeTermEditor { } pub fn into_node(self) -> NestedNode { + let ctx = self.ctx.clone(); + let sum_edit = self.sum_edit.clone(); + let view = sum_edit.read().unwrap().pty_view(); + let editor = Arc::new(RwLock::new(self)); + NestedNode::new() - .set_ctx(self.ctx.clone()) - .set_nav(self.sum_edit.clone()) - .set_cmd(self.sum_edit.clone()) - .set_view( - self.sum_edit.read().unwrap().pty_view() - ) + .set_ctx(ctx) + .set_nav(sum_edit) + .set_cmd(editor.clone()) + .set_view(view) } } impl Commander for TypeTermEditor { type Cmd = TerminalEvent; - + fn send_cmd(&mut self, event: &TerminalEvent) { match event { TerminalEvent::Input( termion::event::Event::Key(Key::Char(c)) ) => { @@ -89,8 +98,9 @@ impl Commander for TypeTermEditor { }; }, _ => { + /* if *c == '(' { - let _child = Arc::new(RwLock::new(TypeTermEditor { + let child = TypeTermEditor { ctx: self.ctx.clone(), ty: self.ty.clone(), sum_edit: Arc::new(RwLock::new(SumEditor::new( @@ -99,17 +109,18 @@ impl Commander for TypeTermEditor { self.sum_edit.read().unwrap().editors[1].clone(), self.sum_edit.read().unwrap().editors[2].clone(), ]))) - })); + }; + self.ty = TypeTermVar::List; self.sum_edit.write().unwrap().select(0); -/* - let l = self.node.editors[0].clone(); - let l = l.downcast::>>().unwrap(); - l.write().unwrap().data.push(child); - */ - } else { - self.sum_edit.write().unwrap().send_cmd( event ); - } + + let l = self.sum_edit.read().unwrap().editors[0].clone(); + let l = l.editor.clone().unwrap().downcast::>().unwrap(); + l.write().unwrap().insert(TypeTermEditor::new(self.ctx.clone(), 1).into_node()); + } else { + */ + self.sum_edit.write().unwrap().send_cmd( event ); + //} } } }, diff --git a/nested/src/vec/buffer.rs b/nested/src/vec/buffer.rs deleted file mode 100644 index 66a1098..0000000 --- a/nested/src/vec/buffer.rs +++ /dev/null @@ -1,166 +0,0 @@ -use { - crate::{ - core::{InnerViewPort, OuterViewPort, View, ViewPort}, - vec::VecDiff, - }, - std::sync::RwLock, - std::{ - ops::{Deref, DerefMut}, - sync::Arc, - }, -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl View for Vec -where - T: Clone + Send + Sync + 'static, -{ - type Msg = VecDiff; -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -#[derive(Clone)] -pub struct VecBuffer -where - T: Clone + Send + Sync + 'static, -{ - data: Arc>>, - port: InnerViewPort>> -} - -impl VecBuffer -where - T: Clone + Send + Sync + 'static, -{ - pub fn with_data_port(data: Vec, port: InnerViewPort>>) -> Self { - let data = Arc::new(RwLock::new(data)); - port.set_view(Some(data.clone())); - - for x in data.read().unwrap().iter().cloned() { - port.notify(&VecDiff::Push(x)); - } - - VecBuffer { - data, - port - } - } - - pub fn with_data(data: Vec) -> Self { - VecBuffer::with_data_port(data, ViewPort::new().into_inner()) - } - - pub fn with_port(port: InnerViewPort>>) -> Self { - VecBuffer::with_data_port(vec![], port) - } - - pub fn new() -> Self { - VecBuffer::with_port(ViewPort::new().into_inner()) - } - - pub fn get_port(&self) -> OuterViewPort>> { - self.port.0.outer() - } - - pub fn apply_diff(&mut self, diff: VecDiff) { - let mut data = self.data.write().unwrap(); - match &diff { - VecDiff::Clear => { - data.clear(); - } - VecDiff::Push(val) => { - data.push(val.clone()); - } - VecDiff::Remove(idx) => { - data.remove(*idx); - } - VecDiff::Insert { idx, val } => { - data.insert(*idx, val.clone()); - } - VecDiff::Update { idx, val } => { - data[*idx] = val.clone(); - } - } - drop(data); - - self.port.notify(&diff); - } - - pub fn len(&self) -> usize { - self.data.read().unwrap().len() - } - - pub fn get(&self, idx: usize) -> T { - self.data.read().unwrap()[idx].clone() - } - - pub fn clear(&mut self) { - self.apply_diff(VecDiff::Clear); - } - - pub fn push(&mut self, val: T) { - self.apply_diff(VecDiff::Push(val)); - } - - pub fn remove(&mut self, idx: usize) { - self.apply_diff(VecDiff::Remove(idx)); - } - - pub fn insert(&mut self, idx: usize, val: T) { - self.apply_diff(VecDiff::Insert { idx, val }); - } - - pub fn update(&mut self, idx: usize, val: T) { - self.apply_diff(VecDiff::Update { idx, val }); - } - - pub fn get_mut(&mut self, idx: usize) -> MutableVecAccess { - MutableVecAccess { - buf: self.clone(), - idx, - val: self.get(idx), - } - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct MutableVecAccess -where - T: Clone + Send + Sync + 'static, -{ - buf: VecBuffer, - idx: usize, - val: T, -} - -impl Deref for MutableVecAccess -where - T: Clone + Send + Sync + 'static, -{ - type Target = T; - - fn deref(&self) -> &T { - &self.val - } -} - -impl DerefMut for MutableVecAccess -where - T: Clone + Send + Sync + 'static, -{ - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.val - } -} - -impl Drop for MutableVecAccess -where - T: Clone + Send + Sync + 'static, -{ - fn drop(&mut self) { - self.buf.update(self.idx, self.val.clone()); - } -} diff --git a/nested/src/vec/mod.rs b/nested/src/vec/mod.rs deleted file mode 100644 index 2253a74..0000000 --- a/nested/src/vec/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -pub mod buffer; -pub mod vec2bin; -pub mod vec2json; -pub mod vec2seq; - -pub use buffer::{VecBuffer, MutableVecAccess}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Serialize, Deserialize)] -pub enum VecDiff { - Clear, - Push(T), - Remove(usize), - Insert { idx: usize, val: T }, - Update { idx: usize, val: T }, -} diff --git a/nested/src/vec/vec2bin.rs b/nested/src/vec/vec2bin.rs deleted file mode 100644 index 43763c6..0000000 --- a/nested/src/vec/vec2bin.rs +++ /dev/null @@ -1,81 +0,0 @@ -use { - crate::{ - core::{Observer, OuterViewPort}, - vec::VecDiff, - }, - serde::Serialize, - std::sync::RwLock, - std::{io::Write, sync::Arc}, -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -/// Serialization Observer for `Vec` -pub struct VecBinWriter -where - T: Clone + Send + Sync + 'static, - W: Write + Send + Sync, -{ - data: Option>>>, - out: RwLock, -} - -impl OuterViewPort>> -where - T: Clone + Serialize + Send + Sync + 'static, -{ - pub fn serialize_bin( - &self, - out: W, - ) -> Arc>> { - let writer = Arc::new(RwLock::new(VecBinWriter { - data: None, - out: RwLock::new(out), - })); - self.add_observer(writer.clone()); - writer - } -} - -impl Observer>> for VecBinWriter -where - T: Clone + Serialize + Send + Sync + 'static, - W: Write + Send + Sync, -{ - fn reset(&mut self, view: Option>>>) { - self.data = view; - let mut out = self.out.write().unwrap(); - - out.write( - &bincode::serialized_size(&VecDiff::::Clear) - .unwrap() - .to_le_bytes(), - ) - .expect(""); - out.write(&bincode::serialize(&VecDiff::::Clear).unwrap()) - .expect(""); - - if let Some(data) = self.data.as_ref() { - for x in data.read().unwrap().iter() { - out.write( - &bincode::serialized_size(&VecDiff::Push(x)) - .unwrap() - .to_le_bytes(), - ) - .expect(""); - out.write(&bincode::serialize(&VecDiff::Push(x)).unwrap()) - .expect(""); - } - } - - out.flush().expect(""); - } - - fn notify(&mut self, diff: &VecDiff) { - let mut out = self.out.write().unwrap(); - out.write(&bincode::serialized_size(diff).unwrap().to_le_bytes()) - .expect(""); - out.write(&bincode::serialize(diff).unwrap()).expect(""); - out.flush().expect(""); - } -} diff --git a/nested/src/vec/vec2json.rs b/nested/src/vec/vec2json.rs deleted file mode 100644 index 01a752c..0000000 --- a/nested/src/vec/vec2json.rs +++ /dev/null @@ -1,110 +0,0 @@ -use { - crate::{ - core::{Observer, OuterViewPort}, - vec::{VecBuffer, VecDiff}, - }, - async_std::{ - io::{Read, ReadExt}, - stream::StreamExt, - }, - serde::{de::DeserializeOwned, Serialize}, - std::sync::RwLock, - std::{io::Write, sync::Arc}, -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct VecJsonWriter -where - T: Clone + Send + Sync + 'static, - W: Write + Send + Sync, -{ - data: Option>>>, - out: RwLock, -} - -impl OuterViewPort>> -where - T: Clone + Serialize + Send + Sync + 'static, -{ - pub fn serialize_json( - &self, - out: W, - ) -> Arc>> { - let writer = Arc::new(RwLock::new(VecJsonWriter { - data: None, - out: RwLock::new(out), - })); - self.add_observer(writer.clone()); - writer - } -} - -impl Observer>> for VecJsonWriter -where - T: Clone + Serialize + Send + Sync + 'static, - W: Write + Send + Sync, -{ - fn reset(&mut self, view: Option>>>) { - self.data = view; - - self.out - .write() - .unwrap() - .write( - &serde_json::to_string(&VecDiff::::Clear) - .unwrap() - .as_bytes(), - ) - .expect(""); - self.out.write().unwrap().write(b"\n").expect(""); - - if let Some(data) = self.data.as_ref() { - for x in data.read().unwrap().iter() { - self.out - .write() - .unwrap() - .write(&serde_json::to_string(&VecDiff::Push(x)).unwrap().as_bytes()) - .expect(""); - self.out.write().unwrap().write(b"\n").expect(""); - } - } - - self.out.write().unwrap().flush().expect(""); - } - - fn notify(&mut self, diff: &VecDiff) { - self.out - .write() - .unwrap() - .write(serde_json::to_string(diff).unwrap().as_bytes()) - .expect(""); - self.out.write().unwrap().write(b"\n").expect(""); - self.out.write().unwrap().flush().expect(""); - } -} - -impl VecBuffer -where - T: DeserializeOwned + Clone + Send + Sync + 'static, -{ - pub async fn from_json(&mut self, read: R) { - let mut bytes = read.bytes(); - let mut s = String::new(); - while let Some(Ok(b)) = bytes.next().await { - match b { - b'\n' => { - if s.len() > 0 { - let diff = - serde_json::from_str::>(&s).expect("error parsing json"); - self.apply_diff(diff); - s.clear(); - } - } - c => { - s.push(c as char); - } - } - } - } -} diff --git a/nested/src/vec/vec2seq.rs b/nested/src/vec/vec2seq.rs deleted file mode 100644 index 78a2a37..0000000 --- a/nested/src/vec/vec2seq.rs +++ /dev/null @@ -1,118 +0,0 @@ -use { - crate::{ - core::{ - InnerViewPort, Observer, ObserverBroadcast, ObserverExt, OuterViewPort, View, ViewPort, - }, - sequence::SequenceView, - vec::VecDiff, - }, - std::sync::Arc, - std::sync::RwLock, -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -/// Adapter View implementing `Sequence` for `Vec` -pub struct VecSequence -where - T: Clone + Send + Sync + 'static, -{ - cur_len: usize, - data: Option>>>, - cast: Arc>>>, -} - -impl VecSequence -where - T: Clone + Send + Sync + 'static, -{ - pub fn new(port: InnerViewPort>) -> Arc> { - let seq = Arc::new(RwLock::new(VecSequence { - cur_len: 0, - data: None, - cast: port.get_broadcast(), - })); - port.set_view(Some(seq.clone())); - seq - } -} - -impl Observer>> for VecSequence -where - T: Clone + Send + Sync + 'static, -{ - fn reset(&mut self, view: Option>>>) { - let old_len = self.cur_len; - self.data = view; - let new_len = if let Some(data) = self.data.as_ref() { - data.read().unwrap().len() - } else { - 0 - }; - - self.cur_len = new_len; - self.cast.notify_each(0..std::cmp::max(old_len, new_len)); - } - - fn notify(&mut self, diff: &VecDiff) { - match diff { - VecDiff::Clear => { - self.cast.notify_each(0..self.cur_len); - self.cur_len = 0 - } - VecDiff::Push(_) => { - self.cast.notify(&self.cur_len); - self.cur_len += 1; - } - VecDiff::Remove(idx) => { - self.cast.notify_each(*idx..self.cur_len); - self.cur_len -= 1; - } - VecDiff::Insert { idx, val: _ } => { - self.cur_len += 1; - self.cast.notify_each(*idx..self.cur_len); - } - VecDiff::Update { idx, val: _ } => { - self.cast.notify(&idx); - } - } - } -} - -impl View for VecSequence -where - T: Clone + Send + Sync + 'static, -{ - type Msg = usize; -} - -impl SequenceView for VecSequence -where - T: Clone + Send + Sync + 'static, -{ - type Item = T; - - fn get(&self, idx: &usize) -> Option { - self.data.as_ref()?.read().unwrap().get(*idx).cloned() - } - - fn len(&self) -> Option { - Some(self.cur_len) - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -impl OuterViewPort>> -where - T: Clone + Send + Sync + 'static, -{ - pub fn to_sequence(&self) -> OuterViewPort> { - let port = ViewPort::new(); - port.add_update_hook(Arc::new(self.0.clone())); - - let vec_seq = VecSequence::new(port.inner()); - self.add_observer(vec_seq.clone()); - port.into_outer() - } -} diff --git a/rust-toolchain b/rust-toolchain index ea2cce1..77211c4 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -5,5 +5,5 @@ # to the user in the error, instead of "error: invalid channel name '[toolchain]'". [toolchain] -channel = "nightly-2021-10-26" -components = ["rust-src", "rustc-dev", "llvm-tools-preview"] +channel = "nightly" + diff --git a/sdf_editor/Cargo.toml b/sdf_editor/Cargo.toml deleted file mode 100644 index d0224df..0000000 --- a/sdf_editor/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "sdf_editor" -version = "0.1.0" -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -nako = {git= "https://git.exobiont.de/senvas/nako.git"} -nako_std = {git= "https://git.exobiont.de/senvas/nako.git"} -nakorender = {git="https://git.exobiont.de/senvas/nako.git", default-features = false} -nested = { path = "../nested" } -cgmath = "*" -termion = "*" -font-kit = "*" - -[dependencies.async-std] -version = "1.9.0" -features = ["unstable", "attributes"] diff --git a/sdf_editor/src/main.rs b/sdf_editor/src/main.rs deleted file mode 100644 index 16a2be2..0000000 --- a/sdf_editor/src/main.rs +++ /dev/null @@ -1,438 +0,0 @@ - -use{ - std::{ - sync::{Arc, RwLock, Mutex}, - collections::HashMap - }, - cgmath::{Point2, Vector2}, - termion::event::{Event, Key}, - nested::{ - core::{ - View, - ViewPort, - Observer, - ObserverExt, - OuterViewPort, - port::UpdateTask - }, - singleton::{SingletonBuffer, SingletonView}, - sequence::{SequenceView}, - integer::{PosIntEditor}, - terminal::{Terminal, TerminalAtom, TerminalStyle, TerminalView, TerminalCompositor, TerminalEvent, TerminalEditor}, - list::{ListEditor}, - tree_nav::{TreeNav} - }, - nako::{ - stream::{SecondaryStream2d, PrimaryStream2d}, - glam::{Vec2, Vec3, UVec2, IVec2}, - operations::{ - planar::primitives2d::Box2d, - volumetric::{Color, Union, Round}, - }, - }, - nakorender::{ - backend::{Backend, LayerId, LayerId2d, LayerInfo}, - marp::MarpBackend, - winit, camera::Camera2d - }, - nako_std::{ - text::Character - }, - std::{fs::File, io::Read, mem::needs_drop, path::Path}, - font_kit::font::Font, -}; - -// projects a Sequence of ints to a color tuple -struct ColorCollector { - src_view: Option>>, - color: SingletonBuffer<(u8, u8, u8)> -} - -impl ColorCollector { - fn update(&mut self) { - if let Some(l) = self.src_view.as_ref() { - let r = l.get(&0).unwrap_or(0); - let g = l.get(&1).unwrap_or(0); - let b = l.get(&2).unwrap_or(0); - - self.color.set((r as u8, g as u8, b as u8)); - } - } -} - -impl Observer> for ColorCollector { - fn reset(&mut self, new_view: Option>>) { - self.src_view = new_view; - self.update(); - } - - fn notify(&mut self, idx: &usize) { - self.update(); - } -} - -struct SdfTerm { - src_view: Option>, - bg_layers: HashMap, (bool, LayerId2d)>, - fg_layers: HashMap, (bool, LayerId2d)>, - - font_height: u32, - //font: Mutex, - - renderer: Arc> -} - -impl SdfTerm { - pub fn new(renderer: Arc>) -> Self { - SdfTerm { - src_view: None, - bg_layers: HashMap::new(), - fg_layers: HashMap::new(), - font_height: 60, - //font: Mutex::new(Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Medium.ttf"),0).unwrap()), - renderer - } - } - - pub fn get_order(&self) -> Vec { - vec![ - self.bg_layers.iter(), - self.fg_layers.iter() - ] - .into_iter() - .flatten() - .filter_map( - |(_pt,(active,id))| - if *active { - Some((*id).into()) - } else { - None - }) - .collect::>() - } - - pub fn update(&mut self, pt: &Point2) { - if self.bg_layers.get(pt).is_none() { - let id = self.renderer.lock().unwrap().new_layer_2d(); - - self.renderer.lock().unwrap().update_camera_2d( - id.into(), - Camera2d { - extent: Vec2::new(0.5, 1.0), - location: Vec2::new(0.0, 0.0), - rotation: 0.0 - }); - self.renderer.lock().unwrap().set_layer_info( - id.into(), - LayerInfo { - extent: UVec2::new(1 + self.font_height / 2, self.font_height), - location: IVec2::new(pt.x as i32 * self.font_height as i32 / 2, pt.y as i32 * self.font_height as i32) - }); - - self.bg_layers.insert(*pt, (false, id)); - } - if self.fg_layers.get(pt).is_none() { - let id = self.renderer.lock().unwrap().new_layer_2d(); - - self.renderer.lock().unwrap().update_camera_2d( - id.into(), - Camera2d { - extent: Vec2::new(0.5, 1.0), - location: Vec2::new(0.0, 0.0), - rotation: 0.0 - }); - self.renderer.lock().unwrap().set_layer_info( - id.into(), - LayerInfo { - extent: UVec2::new(1 + self.font_height / 2, self.font_height), - location: IVec2::new(pt.x as i32 * self.font_height as i32 / 2, pt.y as i32 * self.font_height as i32) - }); - - self.fg_layers.insert(*pt, (false, id)); - } - - if let Some(atom) = self.src_view.get(pt) { - - // background layer - if let Some((r,g,b)) = atom.style.bg_color { - let mut stream = PrimaryStream2d::new() - .push( - SecondaryStream2d::new( - Union, - Box2d { - extent: Vec2::new(0.6, 1.0) - } - ).push_mod( - Color( - Vec3::new( - (r as f32 / 255.0).clamp(0.0, 1.0), - (g as f32 / 255.0).clamp(0.0, 1.0), - (b as f32 / 255.0).clamp(0.0, 1.0), - ) - ) - ).build() - ); - - self.renderer.lock().unwrap().update_sdf_2d(self.bg_layers.get(pt).unwrap().1, stream.build()); - self.bg_layers.get_mut(pt).unwrap().0 = true; - } else { - self.bg_layers.get_mut(pt).unwrap().0 = false; - } - - // foreground layer - if let Some(c) = atom.c { - let font = Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Light.ttf"),0).unwrap(); - let mut ch = Character::from_font(&font, c).with_size(1.0).with_tesselation_factor(0.01); - - let (r,g,b) = atom.style.fg_color.unwrap_or((0, 0, 0)); - - ch.color = Vec3::new( - (r as f32 / 255.0).clamp(0.0, 1.0), - (g as f32 / 255.0).clamp(0.0, 1.0), - (b as f32 / 255.0).clamp(0.0, 1.0), - ); - - let mut stream = PrimaryStream2d::new(); - stream = ch.record_character(stream); - - self.renderer.lock().unwrap().update_sdf_2d(self.fg_layers.get(pt).unwrap().1, stream.build()); - self.fg_layers.get_mut(pt).unwrap().0 = true; - } else { - self.fg_layers.get_mut(pt).unwrap().0 = false; - } - - } else { - self.bg_layers.get_mut(pt).unwrap().0 = false; - self.fg_layers.get_mut(pt).unwrap().0 = false; - } - } -} - -impl Observer for SdfTerm { - fn reset(&mut self, new_view: Option>) { - self.src_view = new_view; - - for pt in self.src_view.area().unwrap_or(vec![]) { - self.notify(&pt); - } - } - - fn notify(&mut self, pt: &Point2) { - self.update(pt); - } -} - -#[async_std::main] -async fn main() { - let term_port = ViewPort::new(); - let compositor = TerminalCompositor::new(term_port.inner()); - - let mut color_editor = ListEditor::new( - || { - Arc::new(RwLock::new(PosIntEditor::new(16))) - }, - nested::list::ListEditorStyle::HorizontalSexpr - ); - - color_editor.goto(nested::tree_nav::TreeCursor { - leaf_mode: nested::list::ListCursorMode::Insert, - tree_addr: vec![ 0 ] - }); - - let color_port = ViewPort::new(); - let color_collector = Arc::new(RwLock::new(ColorCollector { - src_view: None, - color: SingletonBuffer::new((200, 200, 0), color_port.inner()) - })); - - let col_seq_port = color_editor.get_data_port().map( - |sub_editor| sub_editor.read().unwrap().get_value() - ); - color_port.add_update_hook(Arc::new(col_seq_port.0.clone())); - col_seq_port.add_observer( - color_collector.clone() - ); - - compositor.write().unwrap().push(color_editor.get_term_view().offset(Vector2::new(0, 0))); - - let event_loop = nakorender::winit::event_loop::EventLoop::new(); - let window = nakorender::winit::window::Window::new(&event_loop).unwrap(); - let mut renderer = Arc::new(Mutex::new(nakorender::marp::MarpBackend::new(&window, &event_loop))); - - // terminal view - let mut sdf_term = Arc::new(RwLock::new(SdfTerm::new(renderer.clone()))); - term_port.outer().add_observer(sdf_term.clone()); - - // color preview - let color_view = color_port.outer().get_view(); - let color_layer_id = renderer.lock().unwrap().new_layer_2d(); - renderer.lock().unwrap().update_camera_2d(color_layer_id, Camera2d{ - extent: Vec2::new(4.0, 4.0), - location: Vec2::new(-2.0, -2.0), - rotation: 0.0 - }); - renderer.lock().unwrap().set_layer_info(color_layer_id.into(), LayerInfo{ - extent: UVec2::new(600, 600), - location: IVec2::new(200,100) - }); - - event_loop.run(move |event, _target, control_flow|{ - //Set to polling for now, might be overwritten - //TODO: Maybe we want to use "WAIT" for the ui thread? However, the renderer.lock().unwrap()s don't work that hard - //if nothing changes. So should be okay for a alpha style programm. - *control_flow = winit::event_loop::ControlFlow::Poll; - - //now check if a rerender was requested, or if we worked on all - //events on that batch - match event{ - winit::event::Event::WindowEvent{window_id: _, event: winit::event::WindowEvent::Resized(newsize)} => { - - } - winit::event::Event::WindowEvent{window_id: _, event: winit::event::WindowEvent::KeyboardInput{ device_id, input, is_synthetic }} => { - if input.state == winit::event::ElementState::Pressed { - if let Some(kc) = input.virtual_keycode { - match kc { - winit::event::VirtualKeyCode::Space | - winit::event::VirtualKeyCode::Return => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char(' ')))); - } - winit::event::VirtualKeyCode::Key0 | - winit::event::VirtualKeyCode::Numpad0 => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('0')))); - } - winit::event::VirtualKeyCode::Key1 | - winit::event::VirtualKeyCode::Numpad1 => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('1')))); - } - winit::event::VirtualKeyCode::Key2 | - winit::event::VirtualKeyCode::Numpad2 => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('2')))); - } - winit::event::VirtualKeyCode::Key3 | - winit::event::VirtualKeyCode::Numpad3 => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('3')))); - } - winit::event::VirtualKeyCode::Key4 | - winit::event::VirtualKeyCode::Numpad4 => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('4')))); - } - winit::event::VirtualKeyCode::Key5 | - winit::event::VirtualKeyCode::Numpad5 => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('5')))); - } - winit::event::VirtualKeyCode::Key6 | - winit::event::VirtualKeyCode::Numpad6 => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('6')))); - } - winit::event::VirtualKeyCode::Key7 | - winit::event::VirtualKeyCode::Numpad7 => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('7')))); - } - winit::event::VirtualKeyCode::Key8 | - winit::event::VirtualKeyCode::Numpad8 => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('8')))); - } - winit::event::VirtualKeyCode::Key9 | - winit::event::VirtualKeyCode::Numpad9 => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('9')))); - } - winit::event::VirtualKeyCode::A => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('a')))); - } - winit::event::VirtualKeyCode::B => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('b')))); - } - winit::event::VirtualKeyCode::C => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('c')))); - } - winit::event::VirtualKeyCode::D => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('d')))); - } - winit::event::VirtualKeyCode::E => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('e')))); - } - winit::event::VirtualKeyCode::F => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('f')))); - } - winit::event::VirtualKeyCode::Tab => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Insert))); - } - winit::event::VirtualKeyCode::Delete => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Delete))); - } - winit::event::VirtualKeyCode::Back => { - color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Backspace))); - } - winit::event::VirtualKeyCode::Left => { - color_editor.pxev(); - } - winit::event::VirtualKeyCode::Right => { - color_editor.nexd(); - } - winit::event::VirtualKeyCode::Up => { - color_editor.up(); - } - winit::event::VirtualKeyCode::Down => { - color_editor.dn(); - color_editor.goto_home(); - } - winit::event::VirtualKeyCode::Home => { - color_editor.goto_home(); - } - winit::event::VirtualKeyCode::End => { - color_editor.goto_end(); - } - _ => { - } - } - } - } - } - winit::event::Event::MainEventsCleared => { - window.request_redraw(); - } - winit::event::Event::RedrawRequested(_) => { - color_port.update(); - term_port.update(); - - let c = color_view.get(); - let color_stream = PrimaryStream2d::new() - .push( - SecondaryStream2d::new( - Union, - Box2d { - extent: Vec2::new(0.5, 0.5) - } - ).push_mod( - Color( - Vec3::new( - (c.0 as f32 / 255.0).clamp(0.0, 1.0), - (c.1 as f32 / 255.0).clamp(0.0, 1.0), - (c.2 as f32 / 255.0).clamp(0.0, 1.0), - ) - ) - ).push_mod( - Round{radius: 0.2} - ).build() - ).build(); - - renderer.lock().unwrap().update_sdf_2d(color_layer_id, color_stream); - renderer.lock().unwrap().set_layer_order( - vec![ - vec![ color_layer_id.into() ].into_iter(), - sdf_term.read().unwrap().get_order().into_iter() - ] - .into_iter() - .flatten() - .collect::>() - .as_slice() - ); - - renderer.lock().unwrap().render(&window); - } - _ => {}, - } - - }) -} - diff --git a/shell/Cargo.toml b/shell/Cargo.toml deleted file mode 100644 index d086995..0000000 --- a/shell/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "shell" -version = "0.1.0" -edition = "2018" - -[dependencies] -nested = { path = "../nested" } -cgmath = "*" -termion = "*" -bincode = "*" -libc = "0.2.*" -portable-pty = "0.4.0" - -[dependencies.async-std] -version = "1.9.0" -features = ["unstable", "attributes"] diff --git a/shell/gram2 b/shell/gram2 deleted file mode 100644 index 7cae647..0000000 --- a/shell/gram2 +++ /dev/null @@ -1,93 +0,0 @@ - -‹ShellTerm› := - | Lit : "«String»" | "«Path»~«Sep Char '/'»~«Seq Char»~«TerminatedArray AsciiChar~Byte 0»" - | Var : $«ProcessArgument~ℕ~«PositionalInt 10 BigEndian»» - | Sub : $(«Process») - -$PATH:›Sequence Path‹ - :›SeparatedSequence Char '/' ‹ - :›Sequence ›Sequence Char‹‹ - :›‹ - :‹SeparatedSequence Char ':'‹ - :‹Sequence Char› - &‹OsString~› - ~‹List Char~Vec Byte› - -Seq -Vec -Sep -read :: Sep -> Seq -read (Sep xs) d -> -deco :: Style -> Seq -> - -ShellTerm::eval t:‹ShellTerm› -> ‹String› { - match t { - ShellTerm::Lit "s:«String»" -> { - - } - ShellTerm::Var var:$ - } -} - -$PATH : ‹Sequence Path› ~ ‹SeparatedSequence Char ':'› - -ShellTerm::eval := «» -> «» -«Path» :> «» - -‹Path› := [ PathSegment ] ~ ‹List › - -[Char] - :separator '/' - : - -‹ a: Int x b: Int › -( a b ) - - - -// Process is a Structure Type -‹Process› := { - env : ‹ Symbol -> ShellTerm › - exe : ‹ Path › - args : ‹ [ShellTerm] › - stdin : ‹ Pipe › -} - - - -// OsString is an Abstraction Type -[OsString] := [Sequence AsciiChar] ~ [Sequence Byte] ~ [TerminatedSequence Byte 0] ~ [Pointer Byte] ~ [MachineWord] - -execve := { - ‹ Process - ~ { env : Symbol, exe: Path~, } › - -> -} - -precedence of operators: '~' < ':' < '[ ]' < '{ }' - - := [ < ] - - - -‹Process exe=/bin/ls› : ‹Process› := { - args : ‹ [ProcessArgument] ~ [] -} - - :> «PosixShellScript ~ String» { ... } - :> «TerminalView» { ... } - - -»ProcessId«~»MachineInt«~»MachineWord«~»Register« -«ProcessId»~«MachineInt»~«MachineWord»~«Register» - -Pipe::read = { - fd: const ( FileDescriptor ~ MachineInt ~ Register ~ EAX ) - buf: ( Array Byte ~ ) -} -> - -stdout := «ProcessId» -> «FileDescriptor»~«MachineInt»~«Register»~«EAX» - - -poorly-written shell scripts often do not handle filenames with spaces. - diff --git a/shell/grammar b/shell/grammar deleted file mode 100644 index e47a070..0000000 --- a/shell/grammar +++ /dev/null @@ -1,10 +0,0 @@ - -ls :: [files]: - [options]: - -: (view ls) (template -(decorate files EnumSet) - -((λx.xx) a) = aa - --> (process files.to_seq.(map |x|{ }) ) diff --git a/shell/src/command.rs b/shell/src/command.rs deleted file mode 100644 index b2828a1..0000000 --- a/shell/src/command.rs +++ /dev/null @@ -1,330 +0,0 @@ -use { - std::{ - sync::{Arc, RwLock}, - collections::HashMap - }, - cgmath::{Vector2, Point2}, - termion::event::{Event, Key}, - nested::{ - vec::VecBuffer, - list::{ListEditor, PTYListEditor}, - sequence::{SequenceView, decorator::{Separate, Wrap, SeqDecorStyle}}, - core::{TypeTerm, Context}, - core::{OuterViewPort, ViewPort}, - index::{IndexArea, IndexView}, - char_editor::CharEditor, - terminal::{ - TerminalAtom, TerminalEditor, TerminalEditorResult, TerminalEvent, TerminalStyle, TerminalView, make_label - }, - tree::{TreeCursor, TreeNav, TreeNavResult}, - diagnostics::{Diagnostics}, - product::ProductEditor, - sum::SumEditor, - Nested - } -}; - -trait Action { - fn make_editor(&self, ctx: Arc>) -> Arc>; -} - -pub struct ActCd {} -impl Action for ActCd { - fn make_editor(&self, ctx: Arc>) -> Arc> { - let depth = 1; - Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone()) - .with_n(Point2::new(0, 0), vec![ ctx.read().unwrap().type_term_from_str("( Path )").unwrap() ] ) - )) as Arc> - } -} - -pub struct ActLs {} -impl Action for ActLs { - fn make_editor(&self, ctx: Arc>) -> Arc> { - let depth = 1; - Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone()) - .with_t(Point2::new(1, 0), " Files") - .with_n(Point2::new(0, 0), vec![ ctx.read().unwrap().type_term_from_str("( List Path )").unwrap() ] ) - .with_t(Point2::new(1, 1), " Options") - .with_n(Point2::new(0, 1), vec![ ctx.read().unwrap().type_term_from_str("( List String )").unwrap() ] ) - - )) as Arc> - } -} - -pub struct ActEcho {} -impl Action for ActEcho { - fn make_editor(&self, ctx: Arc>) -> Arc> { - let depth = 1; - - let a = Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone()) - .with_n(Point2::new(0, 0), vec![ ctx.read().unwrap().type_term_from_str("( String )").unwrap() ] ) - - )) as Arc>; - - let b = Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone()) - .with_n(Point2::new(0, 0), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] ) - - )) as Arc>; - - let mut x = Arc::new(RwLock::new( SumEditor::new( - vec![ - a, b - ] - ) )); - - x.write().unwrap().select(0); - x - } -} - -pub struct ActCp {} -impl Action for ActCp { - fn make_editor(&self, ctx: Arc>) -> Arc> { - let depth = 1; - Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone()) - .with_t(Point2::new(1, 1), " Source") - .with_n(Point2::new(0, 1), vec![ ctx.read().unwrap().type_term_from_str("( Path )").unwrap() ] ) - .with_t(Point2::new(1, 2), " Destination") - .with_n(Point2::new(0, 2), vec![ ctx.read().unwrap().type_term_from_str("( Path )").unwrap() ] ) - .with_t(Point2::new(1, 3), " Options") - .with_n(Point2::new(0, 3), vec![ ctx.read().unwrap().type_term_from_str("( List Symbol )").unwrap() ] ) - )) as Arc> - } -} - -pub struct ActNum {} -impl Action for ActNum { - fn make_editor(&self, ctx: Arc>) -> Arc> { - let depth = 1; - Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone()) - .with_t(Point2::new(1, 1), " Value") - .with_n(Point2::new(0, 1), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] ) - .with_t(Point2::new(1, 2), " Radix") - .with_n(Point2::new(0, 2), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 10 BigEndian )").unwrap() ] ) - - )) as Arc> - -// Arc::new(RwLock::new(nested::integer::PosIntEditor::new(10))) - } -} - -pub struct ActLet {} -impl Action for ActLet { - fn make_editor(&self, ctx: Arc>) -> Arc> { - let depth = 1; - Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone()) - .with_n(Point2::new(0, 0), vec![ ctx.read().unwrap().type_term_from_str("( Symbol )").unwrap() ] ) - .with_t(Point2::new(1, 0), " : ") - .with_n(Point2::new(2, 0), vec![ ctx.read().unwrap().type_term_from_str("( TypeTerm )").unwrap() ] ) - .with_t(Point2::new(3, 0), " := ") - .with_n(Point2::new(4, 0), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] ) - )) as Arc> - } -} - -pub struct Commander { - ctx: Arc>, - cmds: HashMap>, - - valid: Arc>, - confirmed: bool, - symbol_editor: PTYListEditor, - cmd_editor: Option>>, - - view_elements: VecBuffer>, - out_port: OuterViewPort, - - m_buf: VecBuffer>>, - msg_port: OuterViewPort> -} - -impl Commander { - pub fn new(ctx: Arc>) -> Self { - let port = ViewPort::new(); - let mut view_elements = VecBuffer::with_port(port.inner()); - - let symbol_editor = PTYListEditor::new( - || { - Arc::new(RwLock::new(CharEditor::new())) - }, - SeqDecorStyle::Plain, - '\n', - 0 - ); - - let valid = Arc::new(RwLock::new(false)); - view_elements.push(symbol_editor - .get_term_view() - .map_item({ - let valid = valid.clone(); - move - |pos, mut a| { - if *valid.read().unwrap() { - a.add_style_back(TerminalStyle::fg_color((0,255,0))) - } else { - a.add_style_back(TerminalStyle::fg_color((255,0,0))) - } - } - })); - - let mut cmds = HashMap::new(); - - cmds.insert("let".into(), Arc::new(ActLet{}) as Arc); - cmds.insert("cd".into(), Arc::new(ActCd{}) as Arc); - cmds.insert("echo".into(), Arc::new(ActEcho{}) as Arc); - cmds.insert("ls".into(), Arc::new(ActLs{}) as Arc); - cmds.insert("cp".into(), Arc::new(ActCp{}) as Arc); - cmds.insert("num".into(), Arc::new(ActNum{}) as Arc); - - let m_buf = VecBuffer::new(); - let mut c = Commander { - ctx, - cmds, - valid, - confirmed: false, - symbol_editor, - cmd_editor: None, - view_elements, - out_port: port.outer() - .to_sequence() - .separate(make_label(" ")) - .to_grid_horizontal() - .flatten(), - - msg_port: m_buf.get_port() - .to_sequence() - .flatten(), - m_buf - }; - - c - } -} - -impl TerminalEditor for Commander { - fn get_term_view(&self) -> OuterViewPort { - self.out_port.clone() - } - - fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { - if let (Some(cmd_editor), true) = (self.cmd_editor.as_ref(), self.confirmed) { - match event { - TerminalEvent::Input(Event::Key(Key::Char('\n'))) => { - let mut c = cmd_editor.write().unwrap(); - if c.nexd() == TreeNavResult::Exit { - // run - c.goto(TreeCursor::none()); - - TerminalEditorResult::Exit - } else { - TerminalEditorResult::Continue - } - } - event => { - cmd_editor.write().unwrap().handle_terminal_event(event) - } - } - } else { - match event { - TerminalEvent::Input(Event::Key(Key::Char(' '))) | - TerminalEvent::Input(Event::Key(Key::Char('\n'))) => { - if let Some(editor) = &self.cmd_editor { - self.confirmed = true; - self.symbol_editor.up(); - editor.write().unwrap().qpxev(); - - *self.view_elements.get_mut(1) = editor.read().unwrap().get_term_view(); - - self.m_buf.push(editor.read().unwrap().get_msg_port()); - - if *event == TerminalEvent::Input(Event::Key(Key::Char('\n'))) { - return self.handle_terminal_event(event); - } - } else { - // undefined command - let mut b = VecBuffer::new(); - b.push(nested::diagnostics::make_error(nested::terminal::make_label(&format!("invalid symbol {}", self.symbol_editor.get_string())))); - self.m_buf.clear(); - self.m_buf.push(b.get_port().to_sequence()); - } - - TerminalEditorResult::Continue - } - - event => { - self.m_buf.clear(); - let res = self.symbol_editor.handle_terminal_event(event); - let symbol = self.symbol_editor.get_string(); - - if let Some(action) = self.cmds.get(&symbol) { - let editor = action.make_editor(self.ctx.clone()); - - if self.view_elements.len() == 1 { - self.view_elements.push(editor.read().unwrap().get_term_view().map_item(|p,a| a.add_style_front(TerminalStyle::fg_color((80,80,80))))); - } else { - *self.view_elements.get_mut(1) = editor.read().unwrap().get_term_view().map_item(|p,a| a.add_style_front(TerminalStyle::fg_color((80,80,80)))); - } - - self.cmd_editor = Some(editor); - *self.valid.write().unwrap() = true; - } else { - /* - let mut b = VecBuffer::new(); - b.push(nested::diagnostics::make_error(nested::terminal::make_label(&format!("invalid symbol {}", self.symbol_editor.get_string())))); - self.m_buf.push(b.get_port().to_sequence()); -*/ - self.cmd_editor = None; - *self.valid.write().unwrap() = false; - - if self.view_elements.len() > 1 { - self.view_elements.remove(1); - } - } - - res - } - } - } - } -} - -impl Diagnostics for Commander { - fn get_msg_port(&self) -> OuterViewPort> { - self.msg_port.clone() - } -} - -impl TreeNav for Commander { - fn get_cursor(&self) -> TreeCursor { - if let (Some(cmd_editor), true) = (self.cmd_editor.as_ref(), self.confirmed) { - cmd_editor.write().unwrap().get_cursor() - } else { - self.symbol_editor.get_cursor() - } - } - fn get_cursor_warp(&self) -> TreeCursor { - if let (Some(cmd_editor), true) = (self.cmd_editor.as_ref(), self.confirmed) { - cmd_editor.write().unwrap().get_cursor_warp() - } else { - self.symbol_editor.get_cursor_warp() - } - } - fn goby(&mut self, dir: Vector2) -> TreeNavResult { - if let (Some(cmd_editor), true) = (self.cmd_editor.as_ref(), self.confirmed) { - cmd_editor.write().unwrap().goby(dir) - } else { - self.symbol_editor.goby(dir) - } - } - fn goto(&mut self, cur: TreeCursor) -> TreeNavResult { - if let (Some(cmd_editor), true) = (self.cmd_editor.as_ref(), self.confirmed) { - cmd_editor.write().unwrap().goto(cur) - } else { - self.symbol_editor.goto(cur) - } - } -} - -impl Nested for Commander {} - diff --git a/shell/src/incubator.rs b/shell/src/incubator.rs deleted file mode 100644 index 5143489..0000000 --- a/shell/src/incubator.rs +++ /dev/null @@ -1,18 +0,0 @@ - -use { - nested::commander::Commander, - nested::terminal::TerminalEvent -}; - -struct Incubator { - -} - -impl Commander for Incubator { - type Cmd = TerminalEvent; - - fn send_cmd(&mut self, cmd: &TerminalEvent) { - - } -} - diff --git a/shell/src/main.rs b/shell/src/main.rs deleted file mode 100644 index f8360fe..0000000 --- a/shell/src/main.rs +++ /dev/null @@ -1,302 +0,0 @@ -extern crate portable_pty; - -mod pty; -mod incubator; - -// TODO rewrite process & command with incubator rules -//mod process; -//mod command; - -use { - cgmath::{Point2, Vector2}, - nested::{ - core::{port::UpdateTask, Observer, AnyOuterViewPort, ViewPort}, - type_system::{Context, ReprTree}, - index::IndexArea, - singleton::{SingletonView, SingletonBuffer}, - list::{ListCursorMode, PTYListEditor}, - sequence::{decorator::{SeqDecorStyle, Separate}}, - terminal::{ - make_label, Terminal, TerminalAtom, TerminalCompositor, TerminalEditor, - TerminalEditorResult, TerminalEvent, TerminalStyle, - }, - tree::{TreeNav, TreeCursor, TreeNavResult}, - vec::VecBuffer, - diagnostics::{Diagnostics}, - index::{buffer::IndexBuffer}, - commander::Commander - }, - std::sync::{Arc, RwLock}, - termion::event::{Event, Key}, -}; - -#[async_std::main] -async fn main() { - let term_port = ViewPort::new(); - let compositor = TerminalCompositor::new(term_port.inner()); - - let mut term = Terminal::new(term_port.outer()); - let term_writer = term.get_writer(); - - let portmutex = Arc::new(RwLock::new(())); - - // Update Loop // - let tp = term_port.clone(); - async_std::task::spawn({ - let portmutex = portmutex.clone(); - async move { - loop { - { - let _l = portmutex.write().unwrap(); - tp.update(); - } - async_std::task::sleep(std::time::Duration::from_millis(10)).await; - } - } - }); - - // Type Context // - let ctx = Arc::new(RwLock::new(Context::new())); - let ctx = nested::type_system::init_mem_ctx(ctx); - let ctx = nested::type_system::init_editor_ctx(ctx); - let ctx = nested::type_system::init_math_ctx(ctx); - let ctx = nested::type_system::init_os_ctx(ctx); - - let vb = VecBuffer::::new(); - let rt_char = ReprTree::new_leaf( - ctx.read().unwrap().type_term_from_str("( Vec Char )").unwrap(), - AnyOuterViewPort::from(vb.get_port()) - ); - - let rt_digit = ReprTree::ascend(&rt_char, ctx.read().unwrap().type_term_from_str("( List ( Digit 10 ) )").unwrap()); - rt_digit.write().unwrap().insert_branch( - ReprTree::new_leaf( - ctx.read().unwrap().type_term_from_str("( Vec MachineInt )").unwrap(), - AnyOuterViewPort::from( - vb.get_port().to_sequence().map( - |c: &char| { - c.to_digit(10).unwrap() - } - ) - ) - ) - ); - -/* - ctx.write().unwrap().add_morphism( - MorphismType{ - mode: MorphismMode::Iso, - src_type: - }, - Box::new( - |repr| { - RadixProjection::new( - - ) - } - ) - ); - */ - - let c = ctx.clone(); - let mut process_list_editor = - PTYListEditor::new( - ctx.clone(), - c.read().unwrap().type_term_from_str("( List Path 1 )").unwrap(), - SeqDecorStyle::Plain, - Some('\n'), - 3 - ); - - async_std::task::spawn(async move { - let mut table = nested::index::buffer::IndexBuffer::new(); - - let magic = - make_label("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>") - .map_item(|pos, atom| { - atom.add_style_back(TerminalStyle::fg_color(( - 5, - ((80 + (pos.x * 30) % 100) as u8), - (55 + (pos.x * 15) % 180) as u8, - ))) - }); - - let mut cur_size = nested::singleton::SingletonBuffer::new(Vector2::new(10, 10)); - - table.insert_iter(vec![ - (Point2::new(0, 0), magic.clone()), - (Point2::new(0, 1), process_list_editor.editor.read().unwrap().get_cursor_widget()), - (Point2::new(0, 2), magic.clone()), - (Point2::new(0, 3), make_label(" ")), - (Point2::new(0, 4), - process_list_editor - .editor.read().unwrap() - .get_seg_seq_view() - .enumerate() - .map( - |(n, segment)| { - let mut buf = IndexBuffer::new(); - buf.insert_iter(vec![ - (Point2::new(0, 0), - make_label(match n+1 { - 1 => "I) ", - 2 => "II) ", - 3 => "III) ", - 4 => "IV) ", - 5 => "V) ", - 6 => "VI) ", - 7 => "VII) ", - 8 => "IIX) ", - 9 => "IX) ", - 10 => "X) ", - _ => "" - })), - (Point2::new(1, 0), segment.clone()) - ]); - - buf.get_port() - } - ) - .separate({ - let mut buf = IndexBuffer::new(); - buf.insert(Point2::new(1,0), make_label(" ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~").with_fg_color((40,40,40)) - ); - buf.get_port() - }) - .to_grid_vertical() - .flatten() - .flatten() - ), - - (Point2::new(0, 5), make_label(" ")), - (Point2::new(0, 6), magic.clone()), - - (Point2::new(0, 7), process_list_editor.diag.map( - |entry| { - let mut b = VecBuffer::new(); - b.push( - make_label("@").with_style( - TerminalStyle::bold(true) - .add(TerminalStyle::fg_color((120,120,0)))) - ); - - for x in entry.addr.iter() { - b.push( - make_label(&format!("{}", x)).with_fg_color((0, 100, 20)) - ); - b.push( - make_label(".") - .map_item(|_p,a| a - .add_style_back(TerminalStyle::bold(true)) - .add_style_back(TerminalStyle::fg_color((120,120,0)))) - ); - } - - b.push(entry.port.clone()); - b.get_port() - .to_sequence() - .to_grid_horizontal() - .flatten() - .map_item(move |_p,a| { - let select = false; - if select { - a.add_style_back(TerminalStyle::fg_color((60,60,60))) - } else { - *a - } - }) - } - ).to_grid_vertical().flatten()) - - ]); - - let (_w, _h) = termion::terminal_size().unwrap(); - - compositor - .write() - .unwrap() - .push(table.get_port().flatten().offset(Vector2::new(3, 0))); - - process_list_editor.editor.write().unwrap().goto(TreeCursor { - leaf_mode: ListCursorMode::Insert, - tree_addr: vec![0], - }); - - loop { - let ev = term.next_event().await; - let _l = portmutex.write().unwrap(); - - if let TerminalEvent::Resize(new_size) = ev { - cur_size.set(new_size); - term_port.inner().get_broadcast().notify(&IndexArea::Full); - continue; - } - -/* - if let Some(process_editor) = process_list_editor.get_item() { - let mut pe = process_editor.write().unwrap(); - /* - if pe.is_captured() { - if let TerminalEditorResult::Exit = pe.handle_terminal_event(&ev) { - drop(pe); - process_list_editor.up(); - process_list_editor.nexd(); - } - continue; - } - */ - } -*/ - match ev { - TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) => break, - TerminalEvent::Input(Event::Key(Key::Ctrl('l'))) => { - process_list_editor.editor.write().unwrap().goto(TreeCursor { - leaf_mode: ListCursorMode::Insert, - tree_addr: vec![0], - }); - //process_list_editor.clear(); - } - TerminalEvent::Input(Event::Key(Key::Left)) => { - process_list_editor.editor.write().unwrap().pxev(); - } - TerminalEvent::Input(Event::Key(Key::Right)) => { - process_list_editor.editor.write().unwrap().nexd(); - } - TerminalEvent::Input(Event::Key(Key::Up)) => { - if process_list_editor.editor.write().unwrap().up() == TreeNavResult::Exit { - process_list_editor.editor.write().unwrap().dn(); - } - } - TerminalEvent::Input(Event::Key(Key::Down)) => { - process_list_editor.editor.write().unwrap().dn(); - // == TreeNavResult::Continue { - //process_list_editor.goto_home(); - //} - } - TerminalEvent::Input(Event::Key(Key::Home)) => { - process_list_editor.editor.write().unwrap().qpxev(); - } - TerminalEvent::Input(Event::Key(Key::End)) => { - process_list_editor.editor.write().unwrap().qnexd(); - } - TerminalEvent::Input(Event::Key(Key::Char('\t'))) => { - let mut c = process_list_editor.editor.read().unwrap().get_cursor(); - c.leaf_mode = match c.leaf_mode { - ListCursorMode::Select => ListCursorMode::Insert, - ListCursorMode::Insert => ListCursorMode::Select - }; - process_list_editor.editor.write().unwrap().goto(c); - } - ev => { - process_list_editor.send_cmd(&ev); - } - } - } - - drop(term); - drop(term_port); - }); - - term_writer.show().await.expect("output error!"); -} - diff --git a/shell/src/process.rs b/shell/src/process.rs deleted file mode 100644 index a25f1fc..0000000 --- a/shell/src/process.rs +++ /dev/null @@ -1,277 +0,0 @@ -use { - crate::pty::{PTYStatus, PTY}, - nested::{ - core::{OuterViewPort, ViewPort}, - list::{ListCursorMode, PTYListEditor}, - sequence::{SequenceView, SequenceViewExt, decorator::{SeqDecorStyle, Separate, Wrap}}, - singleton::SingletonView, - char_editor::CharEditor, - terminal::{ - TerminalAtom, TerminalEditor, TerminalEditorResult, TerminalEvent, TerminalStyle, - TerminalView, - }, - tree::{TreeCursor, TreeNav, TreeNavResult}, - diagnostics::Diagnostics, - Nested - }, - std::sync::Arc, - std::sync::RwLock, - termion::event::{Event, Key}, - cgmath::Vector2 -}; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct ProcessArg { - editor: - PTYListEditor, -} - -impl ProcessArg { - pub fn get_data_port(&self) -> OuterViewPort> { - self.editor.get_data_port().map(|char_editor| { - char_editor - .read() - .unwrap() - .get_port() - .get_view() - .unwrap() - .get() - .unwrap() - }) - } -} - -impl TerminalEditor for ProcessArg { - fn get_term_view(&self) -> OuterViewPort { - self.editor.get_term_view() - } - - fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { - match event { - TerminalEvent::Input(Event::Key(Key::Char(' '))) - | TerminalEvent::Input(Event::Key(Key::Char('\n'))) => { - self.editor.up(); - TerminalEditorResult::Exit - } - - event => self.editor.handle_terminal_event(event), - } - } -} - -impl TreeNav for ProcessArg { - fn get_cursor(&self) -> TreeCursor { - self.editor.get_cursor() - } - fn get_cursor_warp(&self) -> TreeCursor { - self.editor.get_cursor_warp() - } - fn goto(&mut self, cur: TreeCursor) -> TreeNavResult { - self.editor.goto(cur) - } - fn goby(&mut self, dir: Vector2) -> TreeNavResult { - self.editor.goby(dir) - } -} - -impl Diagnostics for ProcessArg { -} - -impl Nested for ProcessArg {} - -pub struct ProcessLauncher { - cmd_editor: PTYListEditor, - pty: Option, - _ptybox: Arc>, - suspended: bool, - - pty_port: ViewPort, - status_port: ViewPort>, - - comp_port: ViewPort, - _compositor: Arc>, -} - -impl ProcessLauncher { - pub fn new() -> Self { - let pty_port = ViewPort::new(); - let status_port = ViewPort::new(); - let comp_port = ViewPort::new(); - let box_port = ViewPort::::new(); - let compositor = nested::terminal::TerminalCompositor::new(comp_port.inner()); - - let cmd_editor = PTYListEditor::new( - Box::new(|| { - Arc::new(RwLock::new(ProcessArg { - editor: PTYListEditor::new( - Box::new(|| Arc::new(RwLock::new(CharEditor::new()))), - SeqDecorStyle::Plain, - '\n', - 1 - ), - })) - }) as Box Arc> + Send + Sync>, - SeqDecorStyle::HorizontalSexpr, - ' ', - 0 - ); - - compositor.write().unwrap().push( - box_port - .outer() - .map_item(|_idx, x| x.add_style_back(TerminalStyle::fg_color((90, 120, 100)))), - ); - compositor.write().unwrap().push( - cmd_editor.get_term_view() - ); - - ProcessLauncher { - cmd_editor, - pty: None, - _ptybox: crate::ascii_box::AsciiBox::new( - cgmath::Vector2::new(0, 0), - pty_port.outer().map_item(|_, a: &TerminalAtom| { - a.add_style_back(TerminalStyle::fg_color((230, 230, 230))) - }), - box_port.inner(), - ), - suspended: false, - pty_port, - status_port, - comp_port, - _compositor: compositor, - } - } - - pub fn launch_pty(&mut self) { - let mut strings = Vec::new(); - - let v = self.cmd_editor.get_data_port().get_view().unwrap(); - for i in 0..v.len().unwrap_or(0) { - let arg_view = v - .get(&i) - .unwrap() - .read() - .unwrap() - .get_data_port() - .get_view() - .unwrap(); - strings.push(arg_view.iter().collect::()); - } - - if strings.len() > 0 { - // Spawn a shell into the pty - let mut cmd = crate::pty::CommandBuilder::new(strings[0].as_str()); - cmd.args(&strings[1..]); - cmd.cwd("."); - - self.cmd_editor.goto(TreeCursor { - leaf_mode: ListCursorMode::Insert, - tree_addr: vec![], - }); - - self.pty = PTY::new( - cmd, - cgmath::Vector2::new(120, 40), - self.pty_port.inner(), - self.status_port.inner(), - ); - } - } - - pub fn is_captured(&self) -> bool { - self.pty.is_some() && !self.suspended - } -} - -impl TerminalEditor for ProcessLauncher { - fn get_term_view(&self) -> OuterViewPort { - self.comp_port.outer() - } - - fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { - // todo: move to observer of status view - if let PTYStatus::Done { status: _ } = self.status_port.outer().get_view().get() { - self.pty = None; - self.suspended = false; - } - - match event { - TerminalEvent::Input(Event::Key(Key::Ctrl('c'))) => { - // todo: sigterm instead of kill? - if let Some(pty) = self.pty.as_mut() { - pty.kill(); - } - - self.pty = None; - self.suspended = false; - self.cmd_editor.goto(TreeCursor { - leaf_mode: ListCursorMode::Insert, - tree_addr: vec![], - }); - TerminalEditorResult::Exit - } - TerminalEvent::Input(Event::Key(Key::Ctrl('z'))) => { - self.suspended = true; - self.cmd_editor.goto(TreeCursor { - leaf_mode: ListCursorMode::Insert, - tree_addr: vec![], - }); - TerminalEditorResult::Exit - } - event => { - if let Some(pty) = self.pty.as_mut() { - pty.handle_terminal_event(event); - TerminalEditorResult::Continue - } else { - match event { - TerminalEvent::Input(Event::Key(Key::Char('\n'))) => { - // launch command - self.launch_pty(); - TerminalEditorResult::Continue - } - event => self.cmd_editor.handle_terminal_event(event), - } - } - } - } - } -} - -impl TreeNav for ProcessLauncher { - fn get_cursor(&self) -> TreeCursor { - self.cmd_editor.get_cursor() - } - fn get_cursor_warp(&self) -> TreeCursor { - self.cmd_editor.get_cursor_warp() - } - - fn goto(&mut self, cur: TreeCursor) -> TreeNavResult { - self.suspended = false; - if let PTYStatus::Done { status: _ } = self.status_port.outer().get_view().get() { - self.pty = None; - } - - if self.pty.is_none() { - self.cmd_editor.goto(cur) - } else { - self.cmd_editor.goto(TreeCursor { - leaf_mode: ListCursorMode::Select, - tree_addr: vec![], - }); - TreeNavResult::Continue - } - } - - fn goby(&mut self, dir: Vector2) -> TreeNavResult { - self.cmd_editor.goby(dir) - } - -} - -impl Diagnostics for ProcessLauncher { -} - -impl Nested for ProcessLauncher {} - diff --git a/shell/src/pty.rs b/shell/src/pty.rs deleted file mode 100644 index cc5fb6f..0000000 --- a/shell/src/pty.rs +++ /dev/null @@ -1,167 +0,0 @@ -use { - cgmath::Vector2, - nested::{ - core::InnerViewPort, - singleton::{SingletonBuffer, SingletonView}, - terminal::{TerminalEditorResult, TerminalEvent, TerminalView}, - }, - std::sync::{Arc, Mutex}, - termion::event::{Event, Key}, -}; - -pub use portable_pty::CommandBuilder; - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -#[derive(Clone)] -pub enum PTYStatus { - Running { pid: u32 }, - Done { status: portable_pty::ExitStatus }, -} - -impl Default for PTYStatus { - fn default() -> Self { - PTYStatus::Running { pid: 0 } - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - -pub struct PTY { - master: Mutex>, - child: Arc>>, -} - -impl PTY { - pub fn new( - cmd: portable_pty::CommandBuilder, - max_size: Vector2, - term_port: InnerViewPort, - status_port: InnerViewPort>, - ) -> Option { - // Create a new pty - let pair = portable_pty::native_pty_system() - .openpty(portable_pty::PtySize { - rows: max_size.y as u16, - cols: max_size.x as u16, - - // Not all systems support pixel_width, pixel_height, - // but it is good practice to set it to something - // that matches the size of the selected font. That - // is more complex than can be shown here in this - // brief example though! - pixel_width: 0, - pixel_height: 0, - }) - .unwrap(); - - if let Ok(child) = pair.slave.spawn_command(cmd) { - let mut reader = pair.master.try_clone_reader().unwrap(); - let mut status_buf = SingletonBuffer::with_port( - PTYStatus::Running { - pid: child.process_id().expect(""), - }, - status_port, - ); - - let child = Arc::new(Mutex::new(child)); - - async_std::task::spawn_blocking(move || { - nested::terminal::ansi_parser::read_ansi_from(&mut reader, max_size, term_port); - }); - - async_std::task::spawn_blocking({ - let child = child.clone(); - move || loop { - if let Ok(Some(status)) = child.lock().unwrap().try_wait() { - status_buf.set(PTYStatus::Done { status }); - break; - } - - std::thread::sleep(std::time::Duration::from_millis(10)); - } - }); - - Some(PTY { - master: Mutex::new(pair.master), - child, - }) - } else { - None - } - } - - pub fn kill(&mut self) { - self.child.lock().unwrap().kill().unwrap(); - } - - pub fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { - match event { - TerminalEvent::Input(Event::Key(Key::Char('\n'))) => { - self.master.lock().unwrap().write(&[13]).unwrap(); - TerminalEditorResult::Continue - } - TerminalEvent::Input(Event::Key(Key::Char(c))) => { - write!(self.master.lock().unwrap(), "{}", c).unwrap(); - TerminalEditorResult::Continue - } - TerminalEvent::Input(Event::Key(Key::Esc)) => { - self.master.lock().unwrap().write(&[0x1b]).unwrap(); - TerminalEditorResult::Continue - } - TerminalEvent::Input(Event::Key(Key::Backspace)) => { - self.master.lock().unwrap().write(&[0x8]).unwrap(); - TerminalEditorResult::Continue - } - TerminalEvent::Input(Event::Key(Key::F(n))) => { - self.master - .lock() - .unwrap() - .write(&[ - 0x1b, - 0x0a, - match n { - 11 => 133, - 12 => 134, - n => 58 + n, - }, - ]) - .unwrap(); - TerminalEditorResult::Continue - } - TerminalEvent::Input(Event::Key(Key::Up)) => { - self.master - .lock() - .unwrap() - .write(&[b'\x1B', b'[', b'A']) - .unwrap(); - TerminalEditorResult::Continue - } - TerminalEvent::Input(Event::Key(Key::Down)) => { - self.master - .lock() - .unwrap() - .write(&[b'\x1B', b'[', b'B']) - .unwrap(); - TerminalEditorResult::Continue - } - TerminalEvent::Input(Event::Key(Key::Right)) => { - self.master - .lock() - .unwrap() - .write(&[b'\x1B', b'[', b'C']) - .unwrap(); - TerminalEditorResult::Continue - } - TerminalEvent::Input(Event::Key(Key::Left)) => { - self.master - .lock() - .unwrap() - .write(&[b'\x1B', b'[', b'D']) - .unwrap(); - TerminalEditorResult::Continue - } - _ => TerminalEditorResult::Exit, - } - } -}