Skip to content

Commit

Permalink
Changes systems to behave more simillarly to Bevy, started preparatio…
Browse files Browse the repository at this point in the history
…ns for a scheduling system.
  • Loading branch information
TheEmeraldBee committed Mar 14, 2024
1 parent 30363be commit c423a84
Show file tree
Hide file tree
Showing 21 changed files with 729 additions and 335 deletions.
14 changes: 6 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,9 @@ use ratatui::widgets::Paragraph;

use widgetui::*;

use std::{cell::RefMut, error::Error};

fn widget(frame: &mut WidgetFrame, mut events: RefMut<Events>) -> WidgetResult {
frame.render_widget(Paragraph::new("Hello, world!"), frame.size());
fn widget(mut frame: ResMut<WidgetFrame>, mut events: ResMut<Events>) -> WidgetResult {
let size = frame.size()
frame.render_widget(Paragraph::new("Hello, world!"), size);

if events.key(crossterm::event::KeyCode::Char('q')) {
events.register_exit();
Expand Down Expand Up @@ -94,10 +93,9 @@ use ratatui::widgets::Paragraph;

use widgetui::*;

use std::{cell::RefMut, error::Error};

fn widget(frame: &mut WidgetFrame, mut events: RefMut<Events>) -> WidgetResult {
frame.render_widget(Paragraph::new("Hello, world!"), frame.size());
fn widget(mut frame: ResMut<WidgetFrame>, mut events: ResMut<Events>) -> WidgetResult {
let size = frame.size()
frame.render_widget(Paragraph::new("Hello, world!"), size);

if events.key(crossterm::event::KeyCode::Char('q')) {
events.register_exit();
Expand Down
10 changes: 5 additions & 5 deletions examples/custom_chunk.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{cell::RefMut, error::Error};
use std::error::Error;

use ratatui::{
prelude::{Constraint, Direction, Layout},
Expand All @@ -8,7 +8,7 @@ use widgetui::*;

struct TestChunk;

pub fn chunk_generator(frame: &mut WidgetFrame, mut chunks: RefMut<Chunks>) -> WidgetResult {
pub fn chunk_generator(frame: Res<WidgetFrame>, mut chunks: ResMut<Chunks>) -> WidgetResult {
// A Custom macro to simplify creating your chunks!
let chunk = layout! {
frame.size(),
Expand All @@ -23,9 +23,9 @@ pub fn chunk_generator(frame: &mut WidgetFrame, mut chunks: RefMut<Chunks>) -> W
}

pub fn render(
frame: &mut WidgetFrame,
chunks: RefMut<Chunks>,
mut events: RefMut<Events>,
mut frame: ResMut<WidgetFrame>,
chunks: Res<Chunks>,
mut events: ResMut<Events>,
) -> WidgetResult {
let chunk = chunks.get_chunk::<TestChunk>()?;

Expand Down
14 changes: 8 additions & 6 deletions examples/custom_set.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::{cell::RefMut, error::Error};
use std::error::Error;

use ratatui::widgets::Paragraph;
use widgetui::*;

// This creates a state! No derive macro required
#[derive(State)]
pub struct CoolState {
pub q_count: i32,
}
Expand All @@ -15,9 +15,9 @@ impl Default for CoolState {
}

pub fn widget(
frame: &mut WidgetFrame,
mut events: RefMut<Events>,
mut state: RefMut<CoolState>,
mut frame: ResMut<WidgetFrame>,
mut events: ResMut<Events>,
mut state: ResMut<CoolState>,
) -> WidgetResult {
if events.key(crossterm::event::KeyCode::Char('q')) {
state.q_count -= 1;
Expand All @@ -27,9 +27,11 @@ pub fn widget(
}
}

let size = frame.size();

frame.render_widget(
Paragraph::new(format!("Press `q` {} more times", state.q_count)),
frame.size(),
size,
);

Ok(())
Expand Down
11 changes: 6 additions & 5 deletions examples/custom_state.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
use std::{cell::RefMut, error::Error};
use std::error::Error;

use ratatui::widgets::Paragraph;
use widgetui::*;

#[derive(State)]
pub struct CustomState {
state: i32,
}

pub struct CustomChunk;

pub fn handle_state(
frame: &mut WidgetFrame,
mut custom_state: RefMut<CustomState>,
mut events: RefMut<Events>,
mut chunks: RefMut<Chunks>,
mut frame: ResMut<WidgetFrame>,
mut custom_state: ResMut<CustomState>,
mut events: ResMut<Events>,
mut chunks: ResMut<Chunks>,
) -> WidgetResult {
// Register A Test Chunk
chunks.register_chunk::<CustomChunk>(frame.size());
Expand Down
10 changes: 3 additions & 7 deletions examples/message.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::{cell::RefMut, error::Error, time::Duration};
use std::{error::Error, time::Duration};

use ratatui::prelude::{Constraint, Direction, Layout};
use widgetui::{
widgets::message::{Message, MessageChunk, MessageState},
*,
};

fn chunk_builder(frame: &mut WidgetFrame, mut chunks: RefMut<Chunks>) -> WidgetResult {
fn chunk_builder(frame: Res<'_, WidgetFrame>, mut chunks: ResMut<'_, Chunks>) -> WidgetResult {
let popup = layout![
frame.size(),
(%50),
Expand All @@ -23,11 +23,7 @@ fn chunk_builder(frame: &mut WidgetFrame, mut chunks: RefMut<Chunks>) -> WidgetR
Ok(())
}

fn my_widget(
_frame: &mut WidgetFrame,
mut events: RefMut<Events>,
mut message: RefMut<MessageState>,
) -> WidgetResult {
fn my_widget(mut events: ResMut<Events>, mut message: ResMut<MessageState>) -> WidgetResult {
if events.key(crossterm::event::KeyCode::Char('m')) {
message.render_message("Custom Message", Duration::from_millis(500));
}
Expand Down
7 changes: 4 additions & 3 deletions examples/minimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ use crossterm::event::KeyCode;
use ratatui::widgets::Paragraph;
use widgetui::*;

use std::{cell::RefMut, error::Error};
use std::error::Error;

fn widget(frame: &mut WidgetFrame, mut events: RefMut<Events>) -> WidgetResult {
frame.render_widget(Paragraph::new("Hello, world!"), frame.size());
fn widget(mut frame: ResMut<WidgetFrame>, mut events: ResMut<Events>) -> WidgetResult {
let size = frame.size();
frame.render_widget(Paragraph::new("Hello, world!"), size);

if events.key(KeyCode::Char('q')) {
events.register_exit();
Expand Down
64 changes: 47 additions & 17 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
use std::{
any::Any,
any::{Any, TypeId},
cell::RefCell,
collections::HashMap,
error::Error,
ops::Deref,
time::{Duration, SystemTime},
};

use ratatui::prelude::Backend;
use ratatui::{buffer::Buffer, prelude::Backend};

use crate::{
chunks::Chunks,
events::Events,
set::{Set, Sets},
setup::{reset_terminal, restore_terminal, setup_terminal, WidgetFrame, WidgetTerminal},
states::{States, Time},
widget::{IntoWidgetSet, MultiFromStates, Widget},
states::{MultiFromStates, States, Time},
widget::{into_widget::IntoWidget, into_widget_set::IntoWidgetSet, Widget},
widgets::message::MessageState,
Res, ResMut, WidgetParam,
};

/// The powerhouse of widgetui, runs all defined widgets for you
Expand All @@ -28,12 +32,15 @@ impl App {
/// Create a new app with the given clock time (in ms)
pub fn new(clock: u64) -> Result<Self, Box<dyn Error>> {
let terminal = setup_terminal()?;

Ok(Self {
terminal,
widgets: vec![],
states: States::default(),
states: HashMap::new(),
clock: Duration::from_millis(clock),
})
}
.handle_panics()
.states((Chunks::default(), Time::default(), Events::default())))
}

/// Running this will ensure that any panic that happens, this will catch
Expand All @@ -51,13 +58,18 @@ impl App {

/// Adds the following Widgets to the system.
/// This will take in a tuple of widgets, or a single widget.
pub fn widgets<I>(mut self, widget: impl IntoWidgetSet<I>) -> Self {
pub fn widgets<I, T>(mut self, widget: impl IntoWidgetSet<I, T>) -> Self {
for widget in widget.into_widget_set() {
self.widgets.push(widget);
}
self
}

pub fn widget<W: Widget + 'static>(mut self, widget: W) -> Self {
self.widgets.push(Box::new(widget));
self
}

/// Add the following states to the system
/// This will take in a state or a tuple of states.
pub fn states<S: MultiFromStates>(self, state: S) -> Self {
Expand Down Expand Up @@ -85,17 +97,26 @@ impl App {
self.terminal.autoresize()?;
let mut frame = self.terminal.get_frame();

let widget_frame = WidgetFrame {
cursor_position: None,
buffer: frame.buffer_mut().clone(),
viewport_area: frame.size(),
count: frame.count(),
};

self.states.insert(
TypeId::of::<WidgetFrame>(),
RefCell::new(Box::new(widget_frame)),
);

{
let mut chunks = self.states.get::<Chunks>()?;
let mut chunks = chunks.get();
let mut chunks = ResMut::<Chunks>::retrieve(&self.states);

chunks.clear();

let mut events = self.states.get::<Events>()?;
let mut events = events.get();
let mut events = ResMut::<Events>::retrieve(&self.states);

let mut time = self.states.get::<Time>()?;
let mut time = time.get();
let mut time = ResMut::<Time>::retrieve(&self.states);

events.event = None;

Expand All @@ -110,10 +131,19 @@ impl App {
time.set_duration(total_time);
}

self.states.get::<Chunks>()?.get();

for widget in &mut self.widgets {
widget.call(&mut frame, &mut self.states)?;
widget.call(&mut self.states)?;
}

// Update the window.
{
let widget_frame = Res::<WidgetFrame>::retrieve(&self.states);

if let Some((x, y)) = widget_frame.cursor_position {
frame.set_cursor(x, y);
}

*frame.buffer_mut() = widget_frame.buffer.clone();
}

// Render Frame
Expand All @@ -124,7 +154,7 @@ impl App {
self.terminal.backend_mut().flush()?;

// Handle App Events
if self.states.get::<Events>()?.get().exit {
if ResMut::<Events>::retrieve(&self.states).exit {
return Ok(());
}
}
Expand Down
11 changes: 4 additions & 7 deletions src/chunks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@ use std::{

use ratatui::prelude::Rect;

use crate::{setup::WidgetFrame, States, WidgetResult};

use crate::states::State;
use crate::FromStates;
use crate::*;

/// The default system of storage for the system.
#[derive(Default)]
#[derive(Default, State)]
pub struct Chunks {
chunks: HashMap<TypeId, Rect>,
}
Expand All @@ -32,9 +29,9 @@ impl Chunks {
/// Returns a rect if the type id is within the chunk,
/// an error is thrown if it isn't registered.
pub fn get_chunk<T: Any>(&self) -> Result<Rect, Box<dyn Error>> {
return match self.chunks.get(&TypeId::of::<T>()).cloned() {
match self.chunks.get(&TypeId::of::<T>()).cloned() {
Some(chunk) => Ok(chunk),
None => Err(anyhow!("Chunk doesn't exist").into()),
};
}
}
}
4 changes: 1 addition & 3 deletions src/events.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
use crossterm::event::{Event, KeyCode, KeyEvent};

use crate::FromStates;
use crate::State;
use crate::States;

/// A state that wraps over the events from crossterm
#[derive(Default, Clone)]
#[derive(Default, Clone, State)]
pub struct Events {
pub event: Option<Event>,
pub(crate) exit: bool,
Expand Down
8 changes: 5 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ pub use chunks::Chunks;
pub use events::Events;
pub use set::Set;
pub use setup::{WidgetBackend, WidgetFrame, WidgetTerminal};
pub use states::{State, States};
pub use widget::{FromStates, WidgetResult};
pub use states::{MultiFromStates, State};
pub use widget::{into_widget_set::IntoWidgetSet, WidgetResult};

pub use tui_helper_proc_macro::set;
pub use tui_helper_proc_macro::FromState;
pub use tui_helper_proc_macro::State;

pub use widget::param::*;

// Re-Exports
pub use crossterm;
Expand Down
Loading

0 comments on commit c423a84

Please sign in to comment.