use std::sync::Arc;
use std::time::Duration;
use crate::ga::TerminationCause;
use crate::observer::{AllObserver, ExtensionEvent, GaObserver, IslandGaObserver, Nsga2Observer};
use crate::stats::GenerationStats;
use crate::traits::ChromosomeT;
pub struct CompositeObserver<U: ChromosomeT> {
observers: Vec<Arc<dyn AllObserver<U> + Send + Sync>>,
}
impl<U: ChromosomeT> CompositeObserver<U> {
pub fn new() -> Self {
CompositeObserver {
observers: Vec::new(),
}
}
#[allow(clippy::should_implement_trait)]
pub fn add(mut self, obs: Arc<dyn AllObserver<U> + Send + Sync>) -> Self {
self.observers.push(obs);
self
}
pub fn observer_count(&self) -> usize {
self.observers.len()
}
}
impl<U: ChromosomeT> Default for CompositeObserver<U> {
fn default() -> Self {
Self::new()
}
}
impl<U: ChromosomeT> Clone for CompositeObserver<U> {
fn clone(&self) -> Self {
CompositeObserver {
observers: self.observers.clone(),
}
}
}
impl<U: ChromosomeT> GaObserver<U> for CompositeObserver<U> {
fn on_run_start(&self) {
for obs in &self.observers {
obs.on_run_start();
}
}
fn on_generation_start(&self, generation: usize) {
for obs in &self.observers {
obs.on_generation_start(generation);
}
}
fn on_selection_complete(&self, generation: usize, duration: Duration, population_size: usize) {
for obs in &self.observers {
obs.on_selection_complete(generation, duration, population_size);
}
}
fn on_crossover_complete(&self, generation: usize, duration: Duration, offspring_count: usize) {
for obs in &self.observers {
obs.on_crossover_complete(generation, duration, offspring_count);
}
}
fn on_mutation_complete(&self, generation: usize, duration: Duration, population_size: usize) {
for obs in &self.observers {
obs.on_mutation_complete(generation, duration, population_size);
}
}
fn on_fitness_evaluation_complete(&self, generation: usize, duration: Duration, population_size: usize) {
for obs in &self.observers {
obs.on_fitness_evaluation_complete(generation, duration, population_size);
}
}
fn on_survivor_selection_complete(&self, generation: usize, duration: Duration, population_size: usize) {
for obs in &self.observers {
obs.on_survivor_selection_complete(generation, duration, population_size);
}
}
fn on_new_best(&self, generation: usize, best: U) {
for obs in &self.observers {
obs.on_new_best(generation, best.clone());
}
}
fn on_stagnation(&self, generation: usize, stagnation_count: usize) {
for obs in &self.observers {
obs.on_stagnation(generation, stagnation_count);
}
}
fn on_extension_triggered(&self, event: ExtensionEvent) {
for obs in &self.observers {
obs.on_extension_triggered(event);
}
}
fn on_generation_end(&self, stats: &GenerationStats) {
for obs in &self.observers {
obs.on_generation_end(stats);
}
}
fn on_run_end(&self, cause: TerminationCause, all_stats: &[GenerationStats]) {
for obs in &self.observers {
obs.on_run_end(cause, all_stats);
}
}
}
impl<U: ChromosomeT> IslandGaObserver<U> for CompositeObserver<U> {
fn on_island_run_start(&self, island_id: usize) {
for obs in &self.observers {
obs.on_island_run_start(island_id);
}
}
fn on_island_run_end(&self, island_id: usize) {
for obs in &self.observers {
obs.on_island_run_end(island_id);
}
}
fn on_island_generation_end(&self, island_id: usize, generation: usize, stats: &GenerationStats) {
for obs in &self.observers {
obs.on_island_generation_end(island_id, generation, stats);
}
}
fn on_migration_triggered(&self, generation: usize, migration_count: usize) {
for obs in &self.observers {
obs.on_migration_triggered(generation, migration_count);
}
}
}
impl<U: ChromosomeT> Nsga2Observer<U> for CompositeObserver<U> {
fn on_pareto_front_assigned(&self, generation: usize, front_count: usize, population_size: usize) {
for obs in &self.observers {
obs.on_pareto_front_assigned(generation, front_count, population_size);
}
}
fn on_non_dominated_sort_complete(&self, generation: usize, duration_ms: f64) {
for obs in &self.observers {
obs.on_non_dominated_sort_complete(generation, duration_ms);
}
}
fn on_crowding_distance_calculated(&self, generation: usize, duration_ms: f64) {
for obs in &self.observers {
obs.on_crowding_distance_calculated(generation, duration_ms);
}
}
}