organicomplex 0.7.0

Interactive complex-valued cellular automaton on 2D and 3D grids in search of that stuff - emergence, open-endedness, organicity etc.
use crate::{
	base::PrependErrorString,
	sys::System,
	fontset::Fontset,
	lingua::Lingua,
	precalc::Precalc,
	state::State
};

mod ether;
pub use ether::Ether;

mod meta;
pub use meta::MMeta;
mod sync;
pub use sync::MSync;
mod telemetry;
pub use telemetry::MTelemetry;

pub const ERR_ALREADY_SET: &str = "master already set";
pub const ERR_NOT_SET_CANNOT_RUN: &str = "master not set, cannot run";
pub const ERR_NOT_SET_CANNOT_FINISH: &str = "master not set, cannot finish";

pub struct Context<'a> {
	pub sys: &'a mut System,
	pub precalc: &'a Precalc,
	pub fontset: &'a Fontset<'a>,
	pub lingua: &'a mut Lingua,
	pub state: &'a mut State,
	pub ether: &'a mut Ether
}

pub trait Master {
	fn id(&self) -> String {
		String::from("")
	}

	fn start(&mut self, _ctx: &mut Context) -> Result<(), String> {
		Ok(())
	}

	fn run(&mut self, _ctx: &mut Context) -> Result<(), String> {
		Ok(())
	}

	fn finish(&mut self, _ctx: &mut Context) -> Result<(), String> {
		Ok(())
	}

}

pub struct Mastermind {
	masters: Vec<Box<dyn Master>>,
	meta: Box<dyn Master>
}

impl Mastermind {
	pub fn new() -> Mastermind {
		let masters: Vec<Box<dyn Master>> = Vec::new();
		let meta = MMeta::new();
		Mastermind{masters, meta}
	}

	pub fn add(&mut self, mut ms: Vec<Box<dyn Master>>) {
		self.masters.append(&mut ms); // move
	}

	pub fn start(&mut self, ctx: &mut Context) -> Result<(), String> {
		for m in &mut self.masters {
			m.start(ctx).pre_err(format!("cannot start {} master", m.id()))?;
		}
		self.meta.start(ctx).pre_err(format!("cannot start {} master", self.meta.id()))?;
		Ok(())
	}

	pub fn run(&mut self, ctx: &mut Context) -> Result<(), String> {
		match ctx.ether.meta {
			false => {
				for m in &mut self.masters {
					m.run(ctx).pre_err(format!("cannot run {} master", m.id()))?;
				}
			},
			true => self.meta.run(ctx).pre_err(format!("cannot run {} master", self.meta.id()))?
		}
		Ok(())
	}

	pub fn finish(&mut self, ctx: &mut Context) -> Result<(), String> {
		for m in &mut self.masters {
			m.finish(ctx).pre_err(format!("cannot finish {} master", m.id()))?;
		}
		self.meta.finish(ctx).pre_err(format!("cannot finish {} master", self.meta.id()))?;
		Ok(())
	}

}