command stage 1

This commit is contained in:
2024-11-22 05:59:14 +01:00
parent 533ec30597
commit 10c8f6d0ca
3 changed files with 95 additions and 30 deletions
+19 -4
View File
@@ -4,8 +4,16 @@
#include <pthread.h>
#include <time.h>
typedef struct {
void* element;
void* sender;
void* receiver;
boolean_t running;
} LArgs;
extern boolean_t render(void* element);
extern void *event_loop(void* element);
extern void *cmd_loop(void* element);
void sleep_ms(long milliseconds)
{
@@ -15,16 +23,23 @@ void sleep_ms(long milliseconds)
nanosleep(&ts, NULL);
}
boolean_t c_run(void* element)
boolean_t c_run(void* element, void* sender, void* receiver)
{
pthread_t thread;
pthread_t event_thread;
pthread_t cmd_thread;
LArgs args = { .element = element, .sender = sender, .receiver = receiver, .running = 1 };
if (pthread_create(&thread, NULL, event_loop, element) != 0)
if (pthread_create(&event_thread, NULL, event_loop, &args) != 0)
{
perror("Failed to create thread");
}
while (render(element))
if (pthread_create(&cmd_thread, NULL, cmd_loop, &args) != 0)
{
perror("Failed to create thread");
}
while (render(element) && args.running)
{
sleep_ms(20);
}
+63 -27
View File
@@ -3,14 +3,48 @@ use crossterm::{
terminal::{disable_raw_mode, enable_raw_mode},
};
use crate::{
utils::{clear, create_frame, flush, get_term_size, hide_cursor, render_to_frame, show_cursor},
Element,
use crate::prelude::*;
use crate::utils::{
clear, create_frame, flush, get_term_size, hide_cursor, render_to_frame, show_cursor,
};
use std::{ffi::c_void, ptr::null};
use std::{ffi::c_void, ptr::null, sync::mpsc};
pub struct LArgs {
pub element: *mut c_void,
pub sender: *const c_void,
pub receiver: *const c_void,
pub running: bool,
}
extern "C" {
fn c_run(element: *mut c_void) -> bool;
fn c_run(element: *mut c_void, sender: *const c_void, receiver: *const c_void) -> bool;
}
fn event(element: &mut Element, event: Event) {
if let crossterm::event::Event::Resize(width, height) = event {
element.update_data(width as usize, height as usize);
}
element.event(event);
}
pub fn run(element: &mut Element) -> bool {
hide_cursor();
enable_raw_mode().unwrap();
clear();
unsafe {
let (tx, rx) = mpsc::channel::<Command>();
let c = c_run(
element as *mut Element as *mut c_void,
&tx as *const mpsc::Sender<Command> as *const c_void,
&rx as *const mpsc::Receiver<Command> as *const c_void,
);
if !c {
show_cursor();
disable_raw_mode().unwrap();
clear();
}
return c;
}
}
#[no_mangle]
@@ -33,37 +67,39 @@ extern "C" fn event_loop(ptr: *mut c_void) -> *const c_void {
if ptr.is_null() {
return null() as *const c_void;
}
let element = unsafe { &mut *(ptr as *mut Element) };
let args = unsafe { &mut *(ptr as *mut LArgs) };
let element = unsafe { &mut *(args.element as *mut Element) };
let tx = unsafe { &*(args.sender as *const mpsc::Sender<Command>) };
let (width, height) = get_term_size();
element.update_data(width, height);
event(element, crossterm::event::Event::FocusGained);
loop {
while args.running {
if ptr.is_null() {
break;
}
event(element, crossterm::event::read().unwrap())
event(element, crossterm::event::read().unwrap());
tx.send(Command::Exit).unwrap();
}
null() as *const c_void
}
fn event(element: &mut Element, event: Event) {
if let crossterm::event::Event::Resize(width, height) = event {
element.update_data(width as usize, height as usize);
}
element.event(event);
}
pub fn run(element: &mut Element) -> bool {
hide_cursor();
enable_raw_mode().unwrap();
clear();
unsafe {
let c = c_run(element as *mut Element as *mut c_void);
if !c {
show_cursor();
disable_raw_mode().unwrap();
clear();
}
return c;
#[no_mangle]
extern "C" fn cmd_loop(ptr: *mut c_void) -> *const c_void {
if ptr.is_null() {
return null() as *const c_void;
}
let args = unsafe { &mut *(ptr as *mut LArgs) };
let _element = unsafe { &mut *(args.element as *mut Element) };
let rx = unsafe { &*(args.receiver as *const mpsc::Receiver<Command>) };
loop {
match rx.recv().unwrap() {
Command::Exit => {
args.running = false;
break;
}
}
}
null()
}
+15 -1
View File
@@ -43,7 +43,7 @@ pub use app::run;
pub mod prelude {
pub use crate::ui::Color::*;
pub use crate::{self as osui, css, rsx, rsx_elem, ui::*, Handler};
pub use crate::{style, Element, Value};
pub use crate::{style, Command, Element, Value, Document};
// useful for Element making
pub use crate::{run_handler, Children, ElementCore, ElementWidget};
pub use crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind};
@@ -195,3 +195,17 @@ impl Children {
pub fn convert<T>(widget: &mut Box<dyn ElementWidget>) -> &mut Box<T> {
unsafe { &mut *(widget as *mut _ as *mut Box<T>) }
}
pub enum Command {
Exit,
}
pub struct Document {
cmd_sender: std::sync::mpsc::Sender<Command>,
}
impl Document {
pub fn exit(&self) {
self.cmd_sender.send(Command::Exit).unwrap();
}
}