WIP
This commit is contained in:
parent
8928401233
commit
ccaf8c1f0b
11 changed files with 611 additions and 39 deletions
53
src/algorithm/binaryHeap.rs
Normal file
53
src/algorithm/binaryHeap.rs
Normal file
|
@ -0,0 +1,53 @@
|
|||
|
||||
use crate::drawableVec::DrawableVec;
|
||||
|
||||
use std::collections::{HashMap, BinaryHeap};
|
||||
|
||||
use color_eyre::Result;
|
||||
|
||||
pub async fn sort(list: &mut DrawableVec) -> Result<()>{
|
||||
|
||||
let mut indexMap:HashMap<u32, usize> = HashMap::new();
|
||||
let mut binHeap:BinaryHeap<u32> = BinaryHeap::new();
|
||||
|
||||
let mut ind = 0;
|
||||
for bar in list.elements(){
|
||||
binHeap.push(*bar);
|
||||
indexMap.insert(*bar, ind);
|
||||
ind += 1;
|
||||
}
|
||||
for i in (0..list.len()).rev(){
|
||||
let bar = binHeap.pop().unwrap();
|
||||
let barIndex = *indexMap.get(&bar).unwrap();
|
||||
list.swap(i, barIndex).await?;
|
||||
let temp = list.get(barIndex);
|
||||
indexMap.insert(temp, barIndex);
|
||||
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(non_snake_case)]
|
||||
mod tests {
|
||||
use crate::GuiHookVec::NonGuiVec;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
||||
macro_rules! aw {
|
||||
($e:expr) => {
|
||||
tokio_test::block_on($e)
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn binartHeap_correct() {
|
||||
let mut list:NonGuiVec = aw!(SortingList::new(1000,0.0));
|
||||
aw!(binaryHeap(&mut list));
|
||||
assert_eq!( list.isSorted(), true);
|
||||
}
|
||||
}
|
||||
*/
|
40
src/algorithm/bogoSort.rs
Normal file
40
src/algorithm/bogoSort.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
use crate::drawableVec::DrawableVec;
|
||||
|
||||
use color_eyre::Result;
|
||||
pub async fn sort(list: &mut DrawableVec) -> Result<()>{
|
||||
|
||||
loop{
|
||||
list.swap(0,0).await?;
|
||||
if list.isSorted() {
|
||||
break;
|
||||
}
|
||||
list.randomize();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
/*
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(non_snake_case)]
|
||||
mod tests {
|
||||
use crate::GuiHookVec::NonGuiVec;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
||||
macro_rules! aw {
|
||||
($e:expr) => {
|
||||
tokio_test::block_on($e)
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bogoSort_correct_this_is_a_meme() {
|
||||
let mut list:NonGuiVec = aw!(SortingList::new(5,0.0));
|
||||
aw!(bogoSort(&mut list));
|
||||
assert_eq!( list.isSorted(), true);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
41
src/algorithm/bubbleSort.rs
Normal file
41
src/algorithm/bubbleSort.rs
Normal file
|
@ -0,0 +1,41 @@
|
|||
use crate::drawableVec::DrawableVec;
|
||||
|
||||
use color_eyre::Result;
|
||||
|
||||
pub async fn sort(list:&mut DrawableVec) -> Result<()>{
|
||||
let n = list.len();
|
||||
for i in 0..n {
|
||||
for j in 0..(n - i - 1) {
|
||||
if list.lessThan(j + 1, j) {
|
||||
list.swap(j, j + 1).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
}
|
||||
/*
|
||||
#[cfg(test)]
|
||||
#[allow(non_snake_case)]
|
||||
mod tests {
|
||||
use crate::GuiHookVec::NonGuiVec;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
||||
macro_rules! aw {
|
||||
($e:expr) => {
|
||||
tokio_test::block_on($e)
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bubblesort_correct() {
|
||||
let mut list:NonGuiVec = aw!(SortingList::new(1000,0.0));
|
||||
aw!(bubbleSort(&mut list));
|
||||
assert_eq!( list.isSorted(), true);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
58
src/algorithm/coctailShaker.rs
Normal file
58
src/algorithm/coctailShaker.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
use crate::drawableVec::DrawableVec;
|
||||
|
||||
use color_eyre::Result;
|
||||
|
||||
pub async fn sort(list:&mut DrawableVec) -> Result<()>{
|
||||
let mut lowerBound = 0;
|
||||
let mut upperBound = list.len()-1;
|
||||
let mut swapped = true;
|
||||
while swapped{
|
||||
swapped = false;
|
||||
for i in lowerBound..upperBound {
|
||||
if list.lessThan(i+1, i) {
|
||||
list.swap(i, i+1).await?;
|
||||
swapped = true;
|
||||
}
|
||||
}
|
||||
if !swapped{
|
||||
break;
|
||||
}
|
||||
swapped = false;
|
||||
upperBound = upperBound-1;
|
||||
for i in ((lowerBound)..(upperBound)).rev() {
|
||||
if list.lessThan(i+1, i) {
|
||||
list.swap(i+1, i).await?;
|
||||
swapped = true;
|
||||
}
|
||||
}
|
||||
|
||||
lowerBound = lowerBound+1;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
}
|
||||
/*
|
||||
#[cfg(test)]
|
||||
#[allow(non_snake_case)]
|
||||
mod tests {
|
||||
use crate::GuiHookVec::NonGuiVec;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
||||
macro_rules! aw {
|
||||
($e:expr) => {
|
||||
tokio_test::block_on($e)
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn coctailshakersort_correct() {
|
||||
let mut list:NonGuiVec = aw!(SortingList::new(1000,0.0));
|
||||
aw!(cocktailShaker(&mut list));
|
||||
assert_eq!( list.isSorted(), true);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
|
@ -1,3 +1,29 @@
|
|||
use crate::drawableVec::DrawableVec;
|
||||
|
||||
pub mod insertSort;
|
||||
mod radixSort;
|
||||
mod insertSort;
|
||||
mod bubbleSort;
|
||||
mod binaryHeap;
|
||||
mod coctailShaker;
|
||||
mod quickSort;
|
||||
mod bogoSort;
|
||||
mod radixSortLSD;
|
||||
use color_eyre::{eyre::Ok, Result};
|
||||
|
||||
|
||||
|
||||
|
||||
pub async fn sort(algo: String, list: &mut DrawableVec) -> Result<()> {
|
||||
match algo.as_str() {
|
||||
"insertSort" => insertSort::sort(list).await?,
|
||||
"bubbleSort" => bubbleSort::sort(list).await?,
|
||||
"bogoSort" => bogoSort::sort(list).await?,
|
||||
"cocktailShaker" => coctailShaker::sort(list).await?,
|
||||
"binaryHeap" => binaryHeap::sort(list).await?,
|
||||
"quickSort" => quickSort::sort(list).await?,
|
||||
"radixSortMSD" => radixSort::sort(list).await?,
|
||||
"radixSortLSD" => radixSortLSD::sort(list).await?,
|
||||
_ => panic!("No algorithm with that name implemented!")
|
||||
}
|
||||
Ok(())
|
||||
}
|
74
src/algorithm/quickSort.rs
Normal file
74
src/algorithm/quickSort.rs
Normal file
|
@ -0,0 +1,74 @@
|
|||
use crate::drawableVec::DrawableVec;
|
||||
|
||||
use color_eyre::Result;
|
||||
|
||||
|
||||
|
||||
pub async fn sort(list:&mut DrawableVec) -> Result<()> {
|
||||
let mut stack:Vec<(usize,usize)> = Vec::new();
|
||||
|
||||
let start = 0;
|
||||
let end = list.len()-1;
|
||||
|
||||
stack.push((start,end));
|
||||
|
||||
while stack.len() > 0{
|
||||
let (start,end) = stack.pop().unwrap();
|
||||
|
||||
let p = list.get(end);
|
||||
let temp = partition(list, start, end, p).await?;
|
||||
let pivot = if temp >= 0 {temp} else {break;};
|
||||
|
||||
if pivot != 0 && pivot as usize -1 > start{
|
||||
|
||||
stack.push((start,pivot as usize-1));
|
||||
}
|
||||
|
||||
if pivot as usize + 1 < end{
|
||||
stack.push((pivot as usize +1, end))
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
async fn partition(list:&mut DrawableVec, low:usize, high:usize, p:u32) -> Result<i32>{
|
||||
let mut pIndex = low;
|
||||
|
||||
for i in low..high{
|
||||
if list.lessThanEqual(i, p){
|
||||
list.swap(i, pIndex).await?;
|
||||
pIndex += 1;
|
||||
}
|
||||
}
|
||||
list.swap(pIndex, high).await?;
|
||||
|
||||
return Ok(pIndex as i32)
|
||||
}
|
||||
/*
|
||||
#[cfg(test)]
|
||||
#[allow(non_snake_case)]
|
||||
mod tests {
|
||||
use crate::GuiHookVec::NonGuiVec;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
||||
macro_rules! aw {
|
||||
($e:expr) => {
|
||||
tokio_test::block_on($e)
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn quicksort_correct() {
|
||||
let mut list:NonGuiVec = aw!(SortingList::new(1000,0.0));
|
||||
aw!(quickSort(&mut list));
|
||||
assert_eq!( list.isSorted(), true);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
124
src/algorithm/radixSort.rs
Normal file
124
src/algorithm/radixSort.rs
Normal file
|
@ -0,0 +1,124 @@
|
|||
use crate::drawableVec::DrawableVec;
|
||||
|
||||
use color_eyre::{eyre::Ok, Result};
|
||||
|
||||
|
||||
|
||||
pub async fn sort(list:&mut DrawableVec) -> Result<()> {
|
||||
|
||||
let mut max = usize::MIN;
|
||||
for i in list.getListClone().into_iter().map(|x| format!("{:b}",x)){
|
||||
|
||||
if max < i.len(){
|
||||
max = i.len();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
let mut stack:Vec<(usize, usize)> = Vec::new();
|
||||
let mut stack2:Vec<(usize,usize)> = Vec::new();
|
||||
stack.push((0, list.len()));
|
||||
for i in (0..(max)).rev(){
|
||||
|
||||
while stack.len() > 0{
|
||||
let cur = stack.pop().unwrap();
|
||||
|
||||
match radix(list, i, cur.0, cur.1).await?{
|
||||
Some((initial, switch, max)) => {
|
||||
|
||||
if initial < switch{
|
||||
stack2.push((initial, switch));
|
||||
}
|
||||
if switch < max{
|
||||
|
||||
stack2.push((switch, max));
|
||||
}
|
||||
|
||||
},
|
||||
None => return Ok(())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
stack = stack2.clone();
|
||||
stack2.clear();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn radix(list:&mut DrawableVec, radix:usize, mut minBoundry:usize, mut maxBoundry:usize) -> Result<Option<(usize,usize,usize)>>{
|
||||
let initialMin = minBoundry.clone();
|
||||
let initialMax = maxBoundry.clone();
|
||||
|
||||
|
||||
|
||||
loop{
|
||||
if maxBoundry == minBoundry{
|
||||
break
|
||||
}
|
||||
let currentBit = get_bit_at(list.get(minBoundry), radix);
|
||||
|
||||
if currentBit{
|
||||
list.swap(minBoundry, maxBoundry-1).await?;
|
||||
maxBoundry -= 1;
|
||||
}else{
|
||||
list.swap(minBoundry, minBoundry).await?;
|
||||
|
||||
minBoundry += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Ok(Some((initialMin, minBoundry, initialMax)))
|
||||
}
|
||||
fn get_bit_at(input: u32, n: usize) -> bool {
|
||||
|
||||
if format!("{:b}", input).len() <= n{
|
||||
false
|
||||
}else{
|
||||
input & (1 << n) != 0
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
#[cfg(test)]
|
||||
#[allow(non_snake_case)]
|
||||
mod tests {
|
||||
use crate::GuiHookVec::NonGuiVec;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
||||
macro_rules! aw {
|
||||
($e:expr) => {
|
||||
tokio_test::block_on($e)
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn radixsort_correct() {
|
||||
let mut list:NonGuiVec = aw!(SortingList::new(1000,0.0));
|
||||
aw!(radixSort(&mut list));
|
||||
assert_eq!( list.isSorted(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_bit_at_test(){
|
||||
let num = 0b0001;
|
||||
let othernum = 2;
|
||||
assert_eq!(get_bit_at(num, 0), true);
|
||||
assert_eq!(get_bit_at(num, 1), false);
|
||||
assert_eq!(get_bit_at(othernum, 1), true);
|
||||
assert_eq!(get_bit_at(othernum, 2), false);
|
||||
assert_eq!(get_bit_at(othernum, 3), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
*/
|
100
src/algorithm/radixSortLSD.rs
Normal file
100
src/algorithm/radixSortLSD.rs
Normal file
|
@ -0,0 +1,100 @@
|
|||
use crate::drawableVec::DrawableVec;
|
||||
|
||||
use color_eyre::Result;
|
||||
|
||||
pub async fn sort(list:&mut DrawableVec) -> Result<()> {
|
||||
|
||||
let mut max = usize::MIN;
|
||||
for i in list.getListClone().into_iter().map(|x| format!("{:b}",x)){
|
||||
|
||||
if max < i.len(){
|
||||
max = i.len();
|
||||
}
|
||||
|
||||
}
|
||||
for i in 0..(max){
|
||||
radix(list, i).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn radix(list:&mut DrawableVec, radix:usize) -> Result<()>{
|
||||
let mut bucket = vec![vec![];2];
|
||||
|
||||
for (i, bar) in list.elements().enumerate(){
|
||||
|
||||
let cur = if get_bit_at(*bar, radix) {1} else {0};
|
||||
|
||||
bucket[cur].push(i);
|
||||
|
||||
}
|
||||
|
||||
|
||||
let mut sortedIndexes = Vec::new();
|
||||
for elements in bucket.into_iter(){
|
||||
for i in elements{
|
||||
sortedIndexes.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
let mut listClone = list.getListClone();
|
||||
let mut count = 0;
|
||||
for i in sortedIndexes.clone(){
|
||||
list.set(count, listClone[i]).await?;
|
||||
count += 1;
|
||||
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_bit_at(input: u32, n: usize) -> bool {
|
||||
|
||||
if format!("{:b}", input).len() <= n{
|
||||
false
|
||||
}else{
|
||||
input & (1 << n) != 0
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(non_snake_case)]
|
||||
mod tests {
|
||||
use crate::GuiHookVec::NonGuiVec;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
||||
macro_rules! aw {
|
||||
($e:expr) => {
|
||||
tokio_test::block_on($e)
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn radixsort_correct() {
|
||||
let mut list:NonGuiVec = aw!(SortingList::new(1000,0.0));
|
||||
aw!(radixSort(&mut list));
|
||||
assert_eq!( list.isSorted(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_bit_at_test(){
|
||||
let num = 0b0001;
|
||||
let othernum = 2;
|
||||
assert_eq!(get_bit_at(num, 0), true);
|
||||
assert_eq!(get_bit_at(num, 1), false);
|
||||
assert_eq!(get_bit_at(othernum, 1), true);
|
||||
assert_eq!(get_bit_at(othernum, 2), false);
|
||||
assert_eq!(get_bit_at(othernum, 3), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
*/
|
|
@ -1,6 +1,7 @@
|
|||
use std::time::Duration;
|
||||
|
||||
use color_eyre::{eyre::Ok, Result};
|
||||
use rand::seq::SliceRandom;
|
||||
use ratatui::{
|
||||
DefaultTerminal, Frame,
|
||||
crossterm::event::{self, Event, KeyCode, KeyEventKind},
|
||||
|
@ -12,8 +13,8 @@ use ratatui::{
|
|||
use tokio::{sync::mpsc::{UnboundedReceiver, UnboundedSender}, time::sleep};
|
||||
|
||||
use crate::{
|
||||
algorithm::{self, insertSort::{self, sort}},
|
||||
graphics::{self, vertical_barchart}, tui::{self, Message},
|
||||
algorithm::{self},
|
||||
tui::Message,
|
||||
};
|
||||
|
||||
pub enum SortingMessage{
|
||||
|
@ -23,7 +24,8 @@ pub enum SortingMessage{
|
|||
pub struct DrawableVec {
|
||||
vec: Vec<u32>,
|
||||
event_rx: UnboundedReceiver<SortingMessage>,
|
||||
event_tx: UnboundedSender<Message>
|
||||
event_tx: UnboundedSender<Message>,
|
||||
algo: String
|
||||
}
|
||||
|
||||
impl DrawableVec {
|
||||
|
@ -31,12 +33,13 @@ impl DrawableVec {
|
|||
return DrawableVec {
|
||||
vec,
|
||||
event_rx,
|
||||
event_tx: event_tx.clone()
|
||||
event_tx: event_tx.clone(),
|
||||
algo: "radixSortMSD".to_string(),
|
||||
};
|
||||
}
|
||||
|
||||
pub async fn run(mut self) -> Result<()> {
|
||||
insertSort::sort(&mut self).await?;
|
||||
algorithm::sort(self.algo.clone(), &mut self).await?;
|
||||
sleep(Duration::from_secs(100000)).await;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -53,7 +56,47 @@ impl DrawableVec {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn set(&mut self, i:usize, elem:u32) -> Result<()>{
|
||||
self.vec[i] = elem;
|
||||
self.event_tx.send(Message::SetEvent(i, elem))?;
|
||||
|
||||
self.event_rx.recv().await;
|
||||
Ok(())
|
||||
|
||||
}
|
||||
|
||||
pub fn lessThan(&self, a: usize, b: usize) -> bool {
|
||||
self.vec[a] < self.vec[b]
|
||||
}
|
||||
|
||||
pub fn elements(&mut self) -> std::slice::Iter<'_, u32> {
|
||||
self.vec.iter()
|
||||
}
|
||||
|
||||
pub fn get(&mut self, i:usize)-> u32{
|
||||
*self.vec.get(i).unwrap()
|
||||
}
|
||||
|
||||
pub fn randomize(&mut self){
|
||||
self.vec.shuffle(&mut rand::rng());
|
||||
}
|
||||
pub fn isSorted(&mut self) -> bool{
|
||||
let mut prev:u32 = 0;
|
||||
for bar in self.elements() {
|
||||
if *bar < prev{
|
||||
return false;
|
||||
}else{
|
||||
prev = *bar;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
pub fn lessThanEqual(&mut self, a:usize, b:u32) -> bool{
|
||||
return self.get(a) <= b
|
||||
}
|
||||
|
||||
pub fn getListClone(&self) -> Vec<u32>{
|
||||
self.vec.clone()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,11 +13,9 @@ pub fn vertical_barchart(temperatures: &[u32]) -> BarChart {
|
|||
.enumerate()
|
||||
.map(|(hour, value)| vertical_bar(hour, value))
|
||||
.collect();
|
||||
let title = Line::from("Weather (Vertical)").centered();
|
||||
BarChart::default()
|
||||
.data(BarGroup::default().bars(&bars))
|
||||
.block(Block::new().title(title))
|
||||
.bar_width(5)
|
||||
.bar_width(1)
|
||||
}
|
||||
|
||||
pub fn vertical_bar(hour: usize, temperature: &u32) -> Bar {
|
||||
|
|
63
src/tui.rs
63
src/tui.rs
|
@ -1,19 +1,29 @@
|
|||
use std::{time::Duration};
|
||||
use std::time::Duration;
|
||||
|
||||
use color_eyre::{Result, eyre::Ok};
|
||||
use crossterm::event::{Event, KeyCode, KeyEventKind, MouseEventKind};
|
||||
use rand::seq::SliceRandom;
|
||||
use ratatui::{layout::{Constraint, Layout}, prelude::CrosstermBackend, style::Stylize, Terminal};
|
||||
use tokio::{sync::mpsc::{self, UnboundedReceiver, UnboundedSender}, task::JoinHandle, time};
|
||||
use color_eyre::{eyre::Ok, Result};
|
||||
use ratatui::{
|
||||
Terminal,
|
||||
layout::{Constraint, Layout},
|
||||
prelude::CrosstermBackend,
|
||||
style::Stylize,
|
||||
};
|
||||
use tokio::{
|
||||
sync::mpsc::{self, UnboundedReceiver, UnboundedSender},
|
||||
task::JoinHandle,
|
||||
time,
|
||||
};
|
||||
pub enum Message {
|
||||
Quit,
|
||||
Tick,
|
||||
Render,
|
||||
StartSimulation,
|
||||
SwapEvent(usize, usize)
|
||||
SwapEvent(usize, usize),
|
||||
SetEvent(usize, u32),
|
||||
}
|
||||
|
||||
pub struct Tui{
|
||||
pub struct Tui {
|
||||
terminal: Terminal<CrosstermBackend<std::io::Stdout>>,
|
||||
tick_rate: f64,
|
||||
frame_rate: f64,
|
||||
|
@ -23,8 +33,10 @@ pub struct Tui{
|
|||
should_exit: bool,
|
||||
vec: Vec<u32>,
|
||||
}
|
||||
use crate::{drawableVec::{self, DrawableVec, SortingMessage}, graphics::vertical_barchart};
|
||||
|
||||
use crate::{
|
||||
drawableVec::{self, DrawableVec, SortingMessage},
|
||||
graphics::vertical_barchart,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum UpdateCommand {
|
||||
|
@ -32,22 +44,22 @@ pub enum UpdateCommand {
|
|||
Quit,
|
||||
}
|
||||
|
||||
impl Tui{
|
||||
pub fn new() -> Result<Self>{
|
||||
impl Tui {
|
||||
pub fn new() -> Result<Self> {
|
||||
let terminal = ratatui::init();
|
||||
let (event_tx, event_rx):(UnboundedSender<Message>,UnboundedReceiver<Message>) = mpsc::unbounded_channel();
|
||||
let (event_tx, event_rx): (UnboundedSender<Message>, UnboundedReceiver<Message>) =
|
||||
mpsc::unbounded_channel();
|
||||
let (sorting_tx, sorting_rx) = mpsc::unbounded_channel();
|
||||
let mut vec = (Vec::from_iter(1..100));
|
||||
vec.shuffle(&mut rand::rng());
|
||||
let drawableVec = DrawableVec::new(event_tx.clone(),sorting_rx, vec.clone());
|
||||
let drawableVec = DrawableVec::new(event_tx.clone(), sorting_rx, vec.clone());
|
||||
|
||||
let sorter = tokio::spawn(drawableVec.run());
|
||||
|
||||
|
||||
Ok(Self{
|
||||
Ok(Self {
|
||||
terminal,
|
||||
tick_rate: 10.,
|
||||
frame_rate: 60.,
|
||||
tick_rate: 20.,
|
||||
frame_rate: 120.,
|
||||
event_rx,
|
||||
event_tx,
|
||||
sorting_tx,
|
||||
|
@ -56,7 +68,7 @@ impl Tui{
|
|||
})
|
||||
}
|
||||
|
||||
pub async fn run(&mut self) -> Result<()>{
|
||||
pub async fn run(&mut self) -> Result<()> {
|
||||
let tick_rate = Duration::from_secs_f64(1.0 / self.tick_rate);
|
||||
let frame_rate = Duration::from_secs_f64(1.0 / self.frame_rate);
|
||||
let mut tick_interval = time::interval(tick_rate);
|
||||
|
@ -96,18 +108,22 @@ impl Tui{
|
|||
async fn update(&mut self, message: Message) -> Result<UpdateCommand> {
|
||||
match message {
|
||||
Message::Quit => Ok(UpdateCommand::Quit),
|
||||
Message::Tick => {
|
||||
Ok(UpdateCommand::None)
|
||||
}
|
||||
Message::Tick => Ok(UpdateCommand::None),
|
||||
Message::Render => {
|
||||
self.view()?;
|
||||
Ok(UpdateCommand::None)
|
||||
}
|
||||
Message::StartSimulation => todo!(),
|
||||
Message::SwapEvent(a,b) => {self.vec.swap(a, b); Ok(UpdateCommand::None)},
|
||||
Message::SwapEvent(a, b) => {
|
||||
self.vec.swap(a, b);
|
||||
Ok(UpdateCommand::None)
|
||||
}
|
||||
Message::SetEvent(i, e) => {
|
||||
self.vec.insert(i, e);
|
||||
Ok(UpdateCommand::None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn view(&mut self) -> Result<()> {
|
||||
self.terminal.draw(|frame| {
|
||||
|
@ -130,7 +146,7 @@ impl Tui{
|
|||
Event::Key(key) => {
|
||||
if key.kind == KeyEventKind::Press && key.code == KeyCode::Esc {
|
||||
self.event_tx.send(Message::Quit)?;
|
||||
}else if key.kind == KeyEventKind::Press && key.code == KeyCode:: Enter {
|
||||
} else if key.kind == KeyEventKind::Press && key.code == KeyCode::Enter {
|
||||
self.event_tx.send(Message::StartSimulation)?;
|
||||
}
|
||||
}
|
||||
|
@ -138,5 +154,4 @@ impl Tui{
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue