aboutsummaryrefslogtreecommitdiffhomepage
path: root/ui/src/usecase
diff options
context:
space:
mode:
Diffstat (limited to 'ui/src/usecase')
-rw-r--r--ui/src/usecase/mod.rs9
-rw-r--r--ui/src/usecase/presenter.rs59
-rw-r--r--ui/src/usecase/service.rs24
-rw-r--r--ui/src/usecase/view.rs22
-rw-r--r--ui/src/usecase/watcher.rs46
5 files changed, 160 insertions, 0 deletions
diff --git a/ui/src/usecase/mod.rs b/ui/src/usecase/mod.rs
new file mode 100644
index 0000000..7ca5fcb
--- /dev/null
+++ b/ui/src/usecase/mod.rs
@@ -0,0 +1,9 @@
+pub mod presenter;
+pub mod service;
+pub mod view;
+pub mod watcher;
+
+pub use presenter::*;
+pub use service::*;
+pub use view::*;
+pub use watcher::*;
diff --git a/ui/src/usecase/presenter.rs b/ui/src/usecase/presenter.rs
new file mode 100644
index 0000000..335d16d
--- /dev/null
+++ b/ui/src/usecase/presenter.rs
@@ -0,0 +1,59 @@
+use std::time::{Duration, Instant};
+
+use super::{service, DesktopServiceState, Event};
+use crate::BUFFER;
+use async_std::task::sleep;
+use crossbeam_channel::{Receiver, Sender};
+
+pub async fn create(sender: Sender<Event>, receiver: Receiver<Event>) {
+ let mut now = Instant::now();
+ let buffer = BUFFER.get().unwrap().to_owned();
+ let send = |event| sender.send(event).unwrap_or_default();
+ if let Some(mut service) = service::create() {
+ let mut service_state = DesktopServiceState::Unknown;
+ let mut file = "hbbs.out".to_owned();
+ send(Event::ViewRenderServiceState(service_state.to_owned()));
+ loop {
+ for _ in 1..buffer {
+ match receiver.recv_timeout(Duration::from_nanos(1)) {
+ Ok(event) => match event {
+ Event::BroswerInit => {
+ send(Event::BrowserUpdate(("file".to_owned(), file.to_owned())));
+ }
+ Event::BrowserAction(action) => match action.as_str() {
+ "restart" => service.restart(),
+ _ => (),
+ },
+ Event::FileChange(path) => {
+ if path == file {
+ send(Event::BrowserUpdate(("file".to_owned(), file.to_owned())));
+ }
+ }
+ Event::ViewAction(action) => match action.as_str() {
+ "start" => service.start(),
+ "stop" => service.stop(),
+ "restart" => service.restart(),
+ "pause" => service.pause(),
+ "exit" => send(Event::ViewRenderAppExit),
+ _ => {
+ file = action;
+ send(Event::BrowserUpdate(("file".to_owned(), file.to_owned())));
+ }
+ },
+ _ => (),
+ },
+ Err(_) => break,
+ }
+ }
+ sleep(Duration::from_micros(999)).await;
+ if now.elapsed().as_millis() > 999 {
+ let state = service.check();
+ if state != service_state {
+ service_state = state.to_owned();
+ send(Event::ViewRenderServiceState(state));
+ }
+ now = Instant::now();
+ }
+ }
+ }
+}
diff --git a/ui/src/usecase/service.rs b/ui/src/usecase/service.rs
new file mode 100644
index 0000000..4d992c1
--- /dev/null
+++ b/ui/src/usecase/service.rs
@@ -0,0 +1,24 @@
+use crate::adapter;
+
+pub fn create() -> Option<Box<dyn IDesktopService + Send>> {
+ if cfg!(target_os = "windows") {
+ return Some(Box::new(adapter::WindowsDesktopService::new()));
+ }
+ None
+}
+
+#[derive(Debug, Clone, PartialEq)]
+pub enum DesktopServiceState {
+ Paused,
+ Started,
+ Stopped,
+ Unknown,
+}
+
+pub trait IDesktopService {
+ fn start(&mut self);
+ fn stop(&mut self);
+ fn restart(&mut self);
+ fn pause(&mut self);
+ fn check(&mut self) -> DesktopServiceState;
+}
diff --git a/ui/src/usecase/view.rs b/ui/src/usecase/view.rs
new file mode 100644
index 0000000..882769b
--- /dev/null
+++ b/ui/src/usecase/view.rs
@@ -0,0 +1,22 @@
+use super::DesktopServiceState;
+use crate::adapter::desktop;
+use crossbeam_channel::{Receiver, Sender};
+
+pub async fn create(sender: Sender<Event>, receiver: Receiver<Event>) {
+ desktop::run(sender, receiver).await;
+}
+
+#[derive(Debug, Clone, PartialEq)]
+pub enum Event {
+ BrowserAction(String),
+ BroswerInit,
+ BrowserUpdate((String, String)),
+ BrowserRender(String),
+ FileChange(String),
+ ViewAction(String),
+ ViewInit,
+ ViewUpdate(String),
+ ViewRender(String),
+ ViewRenderAppExit,
+ ViewRenderServiceState(DesktopServiceState),
+}
diff --git a/ui/src/usecase/watcher.rs b/ui/src/usecase/watcher.rs
new file mode 100644
index 0000000..883ba68
--- /dev/null
+++ b/ui/src/usecase/watcher.rs
@@ -0,0 +1,46 @@
+use std::{path::Path, time::Duration};
+
+use super::Event;
+use crate::path;
+use async_std::task::{sleep, spawn_blocking};
+use crossbeam_channel::{bounded, Sender};
+use notify::{Config, RecommendedWatcher, RecursiveMode, Result, Watcher};
+
+pub async fn create(sender: Sender<Event>) {
+ loop {
+ let watch_sender = sender.clone();
+ match spawn_blocking(|| {
+ watch(
+ format!("{}/logs/", path().to_str().unwrap_or_default()),
+ watch_sender,
+ )
+ })
+ .await
+ {
+ Ok(_) => (),
+ Err(e) => println!("error: {e}"),
+ }
+ sleep(Duration::from_secs(1)).await;
+ }
+}
+
+fn watch<P: AsRef<Path>>(path: P, sender: Sender<Event>) -> Result<()> {
+ let (tx, rx) = bounded(10);
+ let mut watcher = RecommendedWatcher::new(tx, Config::default())?;
+ watcher.watch(path.as_ref(), RecursiveMode::Recursive)?;
+ for res in rx {
+ let event = res?;
+ for p in event.paths {
+ let path = p
+ .file_name()
+ .unwrap_or_default()
+ .to_str()
+ .unwrap_or_default()
+ .to_owned();
+ if path.len() > 0 {
+ sender.send(Event::FileChange(path)).unwrap_or_default();
+ }
+ }
+ }
+ Ok(())
+}