Something went wrong. Try again.
a tiny pet with an even tinier brain, living in your browser
Something went wrong. Try again.
2.7 kB · 83 lines
Rust
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384//! A hosted pet: the shared engine (tokenling-core, the same rules the//! browser runs locally) plus this host's ownership and error fields.use anyhow::{Result, ensure};use serde::{Deserialize, Serialize};use std::ops::{Deref, DerefMut};use tokenling_core::types::PetState;pub use tokenling_core::{ body::{DAY, HOUR, MIN, simulate_body, weather_at}, engine::{Command, Effect, Engine, Game, Task},};
pub fn now() -> f64 { chrono::Utc::now().timestamp_millis() as f64}/// The host draws from the thread's random generator.pub fn dice() -> impl FnMut() -> f64 { rand::random::<f64>}
#[derive(Clone, Debug, Deserialize, Serialize)]#[serde(rename_all = "camelCase")]pub struct HostedPet { /// Stored flattened, so rows keep the layout they had before the engine moved to core. #[serde(flatten)] pub engine: Engine, pub epoch: u64, pub authority: String, pub local_device: Option<String>, pub last_seen: f64, pub last_error: Option<String>,}impl Deref for HostedPet { type Target = Engine; fn deref(&self) -> &Engine { &self.engine }}impl DerefMut for HostedPet { fn deref_mut(&mut self) -> &mut Engine { &mut self.engine }}
impl HostedPet { pub fn new(state: PetState, t: f64) -> Self { Self { engine: Engine::new(state, t), epoch: 0, authority: "local".into(), local_device: None, last_seen: t, last_error: None, } } /// Runs the body while this host owns the pet. pub fn advance(&mut self, t: f64, seed: &str) { if self.authority == "remote" { self.engine.advance(t, seed, false, &mut dice()); } } pub fn command(&mut self, command: Command, t: f64, seed: &str) -> Result<()> { ensure!(self.authority == "remote", "this pet is running locally"); self.last_seen = t; self.engine.command(command, t, seed, &mut dice())?; Ok(()) } pub fn apply_line(&mut self, body: &str, t: f64, seed: &str) { self.engine.apply_line(body, t, seed, &mut dice()); } pub fn answer_offer(&mut self, yes: bool, t: f64, seed: &str) { self.engine.answer_offer(yes, t, seed, &mut dice()); } pub fn schedule_idle(&mut self, t: f64) { self.engine.schedule_idle(t, &mut dice()); } /// The next task, after a failed turn's back-off unless the owner asked for one. pub fn choose_task(&self, t: f64) -> Option<Task> { if self.pending.is_none() && self.last_error.is_some() && t < self.next_idle { return None; } self.engine.choose_task(t, true) }}