mod acts;
mod balls;
pub mod cadence;
mod deletes;
mod derive;
mod dirty;
mod drift;
mod echo;
mod focus;
mod grace;
mod knobs;
mod line;
mod live;
mod memo;
mod ops;
mod panels;
mod raise;
mod refresh;
mod roots;
mod search;
mod seat;
mod snapshot;
mod view;
use crate::binding::Workspace;
use crate::fs_watcher::RootKind;
use crate::keymap::InspectorTab;
use crate::projects::runner::BlRunner;
use crate::state::{DirtySet, SearchCell, SnapshotCell, latest_snapshot, new_snapshot_cell};
use crate::ui_state::{Clock, UiState};
use crate::watch::Mark;
use clap::Parser;
use std::path::PathBuf;
use std::sync::Arc;
pub use self::cadence::Cadence;
pub use self::derive::Deriver;
pub use self::derive::worker::Worker;
pub use self::drift::stale_label;
pub use self::grace::WoundGrace;
pub(crate) use self::memo::SnapMemo;
pub use self::roots::Roots;
pub(crate) use self::snapshot::addressable;
pub use self::snapshot::growth_label;
pub use self::snapshot::{Growth, Snapshot};
#[derive(Parser, Debug, Clone, PartialEq, Eq)]
#[command(version, about = "yog: egui frontend for lernie loops")]
pub struct Args {
#[arg(long)]
pub workspace: Option<PathBuf>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Focus {
pub ws: Option<String>,
pub agent: Option<String>,
pub tab: InspectorTab,
}
pub struct AppModel {
roots: Roots,
ui: UiState,
focus: Focus,
pub(crate) snap: Arc<Snapshot>,
derived: Arc<Snapshot>,
folded: Option<echo::Echo>,
cell: SnapshotCell,
dirty: DirtySet,
clock: Arc<dyn Clock>,
identity_user: Option<String>,
search: SearchCell,
started: Option<echo::Echo>,
raised: Option<PathBuf>,
folded_raise: Option<PathBuf>,
lane: crate::wire::lane::Tail,
wire: crate::wire::link::Link,
wire_refusal: Option<String>,
acts: acts::Acts,
}
impl AppModel {
pub fn boot(
roots: Roots,
initial_focus: Option<PathBuf>,
clock: Arc<dyn Clock>,
balls: Box<dyn BlRunner>,
user: Option<String>,
) -> (Self, Deriver) {
let ui = UiState::open(roots.ui_json());
let dirty = DirtySet::default();
let cell = new_snapshot_cell(Arc::new(Snapshot::empty(clock.unix())));
let mut deriver = Deriver::new(
roots.clone(),
Arc::clone(&clock),
balls,
dirty.clone(),
Arc::clone(&cell),
);
deriver.boot();
let derived = latest_snapshot(&cell);
let mut model = Self {
snap: Arc::clone(&derived),
derived,
folded: None,
roots,
ui,
focus: Focus::default(),
cell,
dirty,
clock,
identity_user: user,
search: SearchCell::default(),
started: None,
raised: None,
folded_raise: None,
lane: crate::wire::lane::Tail::default(),
wire: crate::wire::link::Link::default(),
wire_refusal: None,
acts: acts::Acts::default(),
};
model.focus = model.startup_focus(initial_focus, &Arc::clone(&model.snap).workspaces);
(model, deriver)
}
pub(crate) fn mark_dirty<I: IntoIterator<Item = PathBuf>>(&self, roots: I) {
self.dirty
.mark_all(roots.into_iter().map(|r| (r, Mark::Watch)));
}
}
fn desired_watches(roots: &Roots, workspaces: &[Workspace]) -> Vec<(PathBuf, RootKind)> {
let mut desired = vec![
(roots.names(), RootKind::NamesRoot),
(roots.workspaces(), RootKind::WorkspacesRoot),
(roots.replays(), RootKind::WorkspacesRoot),
(roots.yog_state.clone(), RootKind::YogState),
(roots.balls_clones.clone(), RootKind::BallsClones),
];
desired.extend(
workspaces
.iter()
.map(|w| (w.path.clone(), RootKind::Workspace)),
);
desired
}
#[cfg(test)]
mod tests;