command stage 1
This commit is contained in:
@@ -4,8 +4,16 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void* element;
|
||||||
|
void* sender;
|
||||||
|
void* receiver;
|
||||||
|
boolean_t running;
|
||||||
|
} LArgs;
|
||||||
|
|
||||||
extern boolean_t render(void* element);
|
extern boolean_t render(void* element);
|
||||||
extern void *event_loop(void* element);
|
extern void *event_loop(void* element);
|
||||||
|
extern void *cmd_loop(void* element);
|
||||||
|
|
||||||
void sleep_ms(long milliseconds)
|
void sleep_ms(long milliseconds)
|
||||||
{
|
{
|
||||||
@@ -15,16 +23,23 @@ void sleep_ms(long milliseconds)
|
|||||||
nanosleep(&ts, NULL);
|
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");
|
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);
|
sleep_ms(20);
|
||||||
}
|
}
|
||||||
|
|||||||
+61
-25
@@ -3,14 +3,48 @@ use crossterm::{
|
|||||||
terminal::{disable_raw_mode, enable_raw_mode},
|
terminal::{disable_raw_mode, enable_raw_mode},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::prelude::*;
|
||||||
utils::{clear, create_frame, flush, get_term_size, hide_cursor, render_to_frame, show_cursor},
|
use crate::utils::{
|
||||||
Element,
|
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" {
|
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]
|
#[no_mangle]
|
||||||
@@ -33,37 +67,39 @@ extern "C" fn event_loop(ptr: *mut c_void) -> *const c_void {
|
|||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
return null() as *const c_void;
|
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();
|
let (width, height) = get_term_size();
|
||||||
element.update_data(width, height);
|
element.update_data(width, height);
|
||||||
event(element, crossterm::event::Event::FocusGained);
|
event(element, crossterm::event::Event::FocusGained);
|
||||||
loop {
|
|
||||||
|
while args.running {
|
||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
event(element, crossterm::event::read().unwrap())
|
event(element, crossterm::event::read().unwrap());
|
||||||
|
tx.send(Command::Exit).unwrap();
|
||||||
}
|
}
|
||||||
null() as *const c_void
|
null() as *const c_void
|
||||||
}
|
}
|
||||||
|
|
||||||
fn event(element: &mut Element, event: Event) {
|
#[no_mangle]
|
||||||
if let crossterm::event::Event::Resize(width, height) = event {
|
extern "C" fn cmd_loop(ptr: *mut c_void) -> *const c_void {
|
||||||
element.update_data(width as usize, height as usize);
|
if ptr.is_null() {
|
||||||
|
return null() as *const c_void;
|
||||||
}
|
}
|
||||||
element.event(event);
|
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>) };
|
||||||
pub fn run(element: &mut Element) -> bool {
|
loop {
|
||||||
hide_cursor();
|
match rx.recv().unwrap() {
|
||||||
enable_raw_mode().unwrap();
|
Command::Exit => {
|
||||||
clear();
|
args.running = false;
|
||||||
unsafe {
|
break;
|
||||||
let c = c_run(element as *mut Element as *mut c_void);
|
}
|
||||||
if !c {
|
|
||||||
show_cursor();
|
|
||||||
disable_raw_mode().unwrap();
|
|
||||||
clear();
|
|
||||||
}
|
}
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
null()
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-1
@@ -43,7 +43,7 @@ pub use app::run;
|
|||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::ui::Color::*;
|
pub use crate::ui::Color::*;
|
||||||
pub use crate::{self as osui, css, rsx, rsx_elem, ui::*, Handler};
|
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
|
// useful for Element making
|
||||||
pub use crate::{run_handler, Children, ElementCore, ElementWidget};
|
pub use crate::{run_handler, Children, ElementCore, ElementWidget};
|
||||||
pub use crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind};
|
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> {
|
pub fn convert<T>(widget: &mut Box<dyn ElementWidget>) -> &mut Box<T> {
|
||||||
unsafe { &mut *(widget as *mut _ as *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();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user