Added ExtensionContext #26
This commit is contained in:
@@ -1,20 +1,19 @@
|
|||||||
use crate::extensions::Extension;
|
use crate::extensions::{Extension, ExtensionContext};
|
||||||
|
|
||||||
pub struct InputExtension;
|
pub struct InputExtension;
|
||||||
|
|
||||||
impl Extension for InputExtension {
|
impl Extension for InputExtension {
|
||||||
fn init(&mut self, screen: std::sync::Arc<crate::Screen>) {
|
fn init(&mut self, ctx: &ExtensionContext) {
|
||||||
|
let ctx = ctx.clone();
|
||||||
crossterm::terminal::enable_raw_mode().unwrap();
|
crossterm::terminal::enable_raw_mode().unwrap();
|
||||||
std::thread::spawn(move || loop {
|
std::thread::spawn(move || loop {
|
||||||
if let Ok(e) = crossterm::event::read() {
|
if let Ok(e) = crossterm::event::read() {
|
||||||
for widget in screen.widgets.lock().unwrap().iter() {
|
ctx.event(&e);
|
||||||
widget.event(&e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_close(&mut self, _screen: std::sync::Arc<crate::Screen>) {
|
fn on_close(&mut self) {
|
||||||
crossterm::terminal::disable_raw_mode().unwrap();
|
crossterm::terminal::disable_raw_mode().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+49
-4
@@ -11,7 +11,7 @@ pub use velocity::*;
|
|||||||
use std::{
|
use std::{
|
||||||
any::{type_name, Any},
|
any::{type_name, Any},
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex, MutexGuard},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -21,15 +21,25 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub trait Extension {
|
pub trait Extension {
|
||||||
fn init(&mut self, _screen: Arc<Screen>) {}
|
fn init(&mut self, _ctx: &ExtensionContext) {}
|
||||||
fn on_close(&mut self, _screen: Arc<Screen>) {}
|
fn on_close(&mut self) {}
|
||||||
fn render_widget(&mut self, _scope: &mut RenderScope, _widget: &Arc<Widget>) {}
|
fn render_widget(
|
||||||
|
&mut self,
|
||||||
|
_scope: &mut RenderScope,
|
||||||
|
_widget: &Arc<Widget>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Event: Send + Sync {
|
pub trait Event: Send + Sync {
|
||||||
fn as_any(&self) -> &dyn Any;
|
fn as_any(&self) -> &dyn Any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ExtensionContext {
|
||||||
|
screen: Arc<Screen>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Handler<E: Event>(Arc<Mutex<dyn FnMut(&Arc<Widget>, &E) + Send + Sync>>);
|
pub struct Handler<E: Event>(Arc<Mutex<dyn FnMut(&Arc<Widget>, &E) + Send + Sync>>);
|
||||||
|
|
||||||
@@ -64,3 +74,38 @@ impl<'a> dyn Event + 'a {
|
|||||||
self.as_any().downcast_ref()
|
self.as_any().downcast_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ExtensionContext {
|
||||||
|
pub fn new(screen: Arc<Screen>) -> Self {
|
||||||
|
Self { screen }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn event<E: Event + Clone + 'static>(&self, e: &E) {
|
||||||
|
for widget in self.screen.widgets.lock().unwrap().iter() {
|
||||||
|
widget.event(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_widgets(&self) -> MutexGuard<Vec<Arc<Widget>>> {
|
||||||
|
self.screen.widgets.lock().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter_components<C: Component + 'static + Clone, F: FnMut(&Arc<Widget>, Option<C>)>(
|
||||||
|
&self,
|
||||||
|
mut iterator: F,
|
||||||
|
) {
|
||||||
|
for widget in self.screen.widgets.lock().unwrap().iter() {
|
||||||
|
iterator(widget, widget.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_components<C: Component + 'static + Clone>(&self) -> Vec<C> {
|
||||||
|
let mut components = Vec::new();
|
||||||
|
for widget in self.screen.widgets.lock().unwrap().iter() {
|
||||||
|
if let Some(c) = widget.get() {
|
||||||
|
components.push(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
components
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,22 +1,21 @@
|
|||||||
use std::{fmt::Debug, sync::Arc};
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use crate::extensions::Extension;
|
use crate::event;
|
||||||
use crate::{event, Screen};
|
use crate::extensions::{Extension, ExtensionContext};
|
||||||
|
|
||||||
pub struct TickExtension(pub u16);
|
pub struct TickExtension(pub u16);
|
||||||
|
|
||||||
event!(TickEvent(pub u32));
|
event!(TickEvent(pub u32));
|
||||||
|
|
||||||
impl Extension for TickExtension {
|
impl Extension for TickExtension {
|
||||||
fn init(&mut self, screen: Arc<Screen>) {
|
fn init(&mut self, ctx: &ExtensionContext) {
|
||||||
|
let ctx = ctx.clone();
|
||||||
let rate_dur = 1000 / self.0 as u64;
|
let rate_dur = 1000 / self.0 as u64;
|
||||||
std::thread::spawn({
|
std::thread::spawn({
|
||||||
move || {
|
move || {
|
||||||
let mut tick = 0;
|
let mut tick = 0;
|
||||||
loop {
|
loop {
|
||||||
for w in screen.widgets.lock().unwrap().iter() {
|
ctx.event(&TickEvent(tick));
|
||||||
w.event(&TickEvent(tick));
|
|
||||||
}
|
|
||||||
tick += 1;
|
tick += 1;
|
||||||
std::thread::sleep(std::time::Duration::from_millis(rate_dur));
|
std::thread::sleep(std::time::Duration::from_millis(rate_dur));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ use crate::{
|
|||||||
extensions::Extension,
|
extensions::Extension,
|
||||||
style::{Position, Transform},
|
style::{Position, Transform},
|
||||||
widget::Widget,
|
widget::Widget,
|
||||||
Screen,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct VelocityExtension;
|
pub struct VelocityExtension;
|
||||||
@@ -43,12 +42,13 @@ impl VelocityExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Extension for VelocityExtension {
|
impl Extension for VelocityExtension {
|
||||||
fn init(&mut self, screen: Arc<Screen>) {
|
fn init(&mut self, ctx: &super::ExtensionContext) {
|
||||||
|
let ctx = ctx.clone();
|
||||||
std::thread::spawn({
|
std::thread::spawn({
|
||||||
move || {
|
move || {
|
||||||
let mut tick = 0;
|
let mut tick = 0;
|
||||||
loop {
|
loop {
|
||||||
for widget in screen.widgets.lock().unwrap().iter() {
|
for widget in ctx.get_widgets().iter() {
|
||||||
Self::apply_velocity_xy(tick, widget);
|
Self::apply_velocity_xy(tick, widget);
|
||||||
}
|
}
|
||||||
if tick > 1000 {
|
if tick > 1000 {
|
||||||
|
|||||||
+5
-2
@@ -33,6 +33,7 @@ use std::sync::{Arc, Mutex};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
extensions::{Extension, Handler},
|
extensions::{Extension, Handler},
|
||||||
|
prelude::ExtensionContext,
|
||||||
render_scope::RenderScope,
|
render_scope::RenderScope,
|
||||||
widget::{BoxedElement, DynWidget, Element, StaticWidget, Widget, WidgetLoad},
|
widget::{BoxedElement, DynWidget, Element, StaticWidget, Widget, WidgetLoad},
|
||||||
};
|
};
|
||||||
@@ -158,8 +159,10 @@ impl Screen {
|
|||||||
///
|
///
|
||||||
/// This method blocks and repeatedly renders the screen at a fixed interval.
|
/// This method blocks and repeatedly renders the screen at a fixed interval.
|
||||||
pub fn run(self: &Arc<Self>) -> std::io::Result<()> {
|
pub fn run(self: &Arc<Self>) -> std::io::Result<()> {
|
||||||
|
let ctx = ExtensionContext::new(self.clone());
|
||||||
|
|
||||||
for ext in self.extensions.lock().unwrap().iter() {
|
for ext in self.extensions.lock().unwrap().iter() {
|
||||||
ext.lock().unwrap().init(self.clone());
|
ext.lock().unwrap().init(&ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::hide_cursor()?;
|
utils::hide_cursor()?;
|
||||||
@@ -230,7 +233,7 @@ impl Screen {
|
|||||||
utils::clear().unwrap();
|
utils::clear().unwrap();
|
||||||
|
|
||||||
for ext in self.extensions.lock().unwrap().iter() {
|
for ext in self.extensions.lock().unwrap().iter() {
|
||||||
ext.lock().unwrap().on_close(self.clone());
|
ext.lock().unwrap().on_close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user