cyb/shell/src/now.rs

//! Now โ€” the particle the robot stands on.
//!
//! Not a world. Not a tab. The cursor. Space chroma will wear this;
//! spacetime shows particle meta or a file when we stand.

use bevy::prelude::*;
use file::{File, Particle};

use crate::worlds::content;

/// The particle underfoot, and whether spacetime is showing its meta,
/// its file, or the ordinary world.
#[derive(Resource, Debug, Default)]
pub struct Now {
    pub hash: Option<Particle>,
    pub idx: Option<usize>,
    pub kind: NowKind,
}

#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum NowKind {
    #[default]
    World,
    Meta,
    File,
}

impl Now {
    /// Stand on this particle's meta page. Never dump the file onto the
    /// UI thread โ€” a text spark of a lived-in particle is megabytes of
    /// Bevy `Text` and hangs the process. The file page is a later door.
    pub fn stand(&mut self, hash: [u8; 32], idx: Option<usize>) {
        self.hash = Some(Particle::from_bytes(hash));
        self.idx = idx;
        self.kind = NowKind::Meta;
    }

    pub fn dismiss(&mut self) {
        self.kind = NowKind::World;
        self.hash = None;
        self.idx = None;
    }
}

pub fn load_file(hash: [u8; 32]) -> Option<File> {
    let text = content::lookup(&hash)?;
    Some(File::bind(Particle::from_bytes(hash), text.into_bytes()))
}

pub struct NowPlugin;

impl Plugin for NowPlugin {
    fn build(&self, app: &mut App) {
        app.init_resource::<Now>()
            .add_plugins(crate::worlds::particle_page::ParticlePagePlugin)
            .add_plugins(crate::worlds::file::FilePagePlugin);
    }
}

Graph