pub mod file;
pub mod slog_logger;
#[cfg(feature = "visualizer")]
pub mod visualizer;
use crate::core::{ArgminKV, ArgminOp, Error, IterState};
use serde::{Deserialize, Serialize};
use std::default::Default;
use std::sync::{Arc, Mutex};
pub use file::*;
pub use slog_logger::*;
#[cfg(feature = "visualizer")]
pub use visualizer::*;
pub trait Observe<O: ArgminOp> {
fn observe_init(&self, _name: &str, _kv: &ArgminKV) -> Result<(), Error> {
Ok(())
}
fn observe_iter(&mut self, _state: &IterState<O>, _kv: &ArgminKV) -> Result<(), Error> {
Ok(())
}
}
#[derive(Clone, Default)]
pub struct Observer<O> {
observers: Vec<(Arc<Mutex<dyn Observe<O>>>, ObserverMode)>,
}
impl<O: ArgminOp> Observer<O> {
pub fn new() -> Self {
Observer { observers: vec![] }
}
pub fn push<OBS: Observe<O> + 'static>(
&mut self,
observer: OBS,
mode: ObserverMode,
) -> &mut Self {
self.observers.push((Arc::new(Mutex::new(observer)), mode));
self
}
}
impl<O: ArgminOp> Observe<O> for Observer<O> {
fn observe_init(&self, msg: &str, kv: &ArgminKV) -> Result<(), Error> {
for l in self.observers.iter() {
l.0.lock().unwrap().observe_init(msg, kv)?
}
Ok(())
}
fn observe_iter(&mut self, state: &IterState<O>, kv: &ArgminKV) -> Result<(), Error> {
use ObserverMode::*;
for l in self.observers.iter_mut() {
let iter = state.get_iter();
let observer = &mut l.0.lock().unwrap();
match l.1 {
Always => observer.observe_iter(state, kv),
Every(i) if iter % i == 0 => observer.observe_iter(state, kv),
NewBest if state.is_best() => observer.observe_iter(state, kv),
Never | Every(_) | NewBest => Ok(()),
}?
}
Ok(())
}
}
#[derive(Copy, Clone, Serialize, Deserialize, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum ObserverMode {
Never,
Always,
Every(u64),
NewBest,
}
impl Default for ObserverMode {
fn default() -> ObserverMode {
ObserverMode::Always
}
}