vox_geometry_rust 0.1.2

Geometry Tools for Rust
Documentation
/*
 * // Copyright (c) 2021 Feng Yang
 * //
 * // I am making my contributions/submissions to this project solely in my
 * // personal capacity and am not conveying any rights to any intellectual
 * // property of any third parties.
 */

use crate::particle_emitter2::*;
use crate::particle_system_data2::ParticleSystemData2Ptr;
use std::sync::{RwLock, Arc};

///
/// # Callback function type for update calls.
///
/// This type of callback function will take the emitter pointer, current
/// time, and time interval in seconds.
///
pub type OnBeginUpdateCallback = fn(&mut ParticleEmitterSet2, f64, f64);

///
/// # 2-D particle-based emitter set.
///
pub struct ParticleEmitterSet2 {
    _emitters: Vec<ParticleEmitter2Ptr>,

    _emitter_data: ParticleEmitter2Data,
    _on_begin_update_callback: Option<OnBeginUpdateCallback>,
}

impl ParticleEmitterSet2 {
    /// Constructs an emitter.
    pub fn new_default() -> ParticleEmitterSet2 {
        return ParticleEmitterSet2 {
            _emitters: vec![],
            _emitter_data: ParticleEmitter2Data::new(),
            _on_begin_update_callback: None,
        };
    }

    /// Constructs an emitter with sub-emitters.
    pub fn new(emitters: Vec<ParticleEmitter2Ptr>) -> ParticleEmitterSet2 {
        return ParticleEmitterSet2 {
            _emitters: emitters,
            _emitter_data: ParticleEmitter2Data::new(),
            _on_begin_update_callback: None,
        };
    }

    /// Adds sub-emitter.
    pub fn add_emitter(&mut self, emitter: ParticleEmitter2Ptr) {
        self._emitters.push(emitter);
    }

    ///
    /// \brief      Sets the callback function to be called when
    ///             ParticleEmitter2::update function is invoked.
    ///
    /// The callback function takes current simulation time in seconds unit. Use
    /// this callback to track any motion or state changes related to this
    /// emitter.
    ///
    /// - parameter:   callback The callback function.
    ///
    pub fn set_on_begin_update_callback(&mut self, callback: OnBeginUpdateCallback) {
        self._on_begin_update_callback = Some(callback);
    }
}

impl ParticleEmitter2 for ParticleEmitterSet2 {
    fn update(&mut self, current_time_in_seconds: f64, time_interval_in_seconds: f64) {
        match self._on_begin_update_callback {
            None => {}
            Some(callback) => {
                callback(self, current_time_in_seconds,
                         time_interval_in_seconds);
            }
        }

        self.on_update(current_time_in_seconds, time_interval_in_seconds);
    }

    fn on_set_target(&self, particles: ParticleSystemData2Ptr) {
        for emitter in &self._emitters {
            emitter.write().unwrap().set_target(particles.clone());
        }
    }

    fn on_update(&mut self, current_time_in_seconds: f64, time_interval_in_seconds: f64) {
        if !self.is_enabled() {
            return;
        }

        for emitter in &self._emitters {
            emitter.write().unwrap().update(current_time_in_seconds, time_interval_in_seconds);
        }
    }

    fn view(&self) -> &ParticleEmitter2Data {
        return &self._emitter_data;
    }

    fn view_mut(&mut self) -> &mut ParticleEmitter2Data {
        return &mut self._emitter_data;
    }
}

/// Shared pointer type for the ParticleEmitterSet2.
pub type ParticleEmitterSet2Ptr = Arc<RwLock<ParticleEmitterSet2>>;

///
/// # Front-end to create ParticleEmitterSet2 objects step by step.
///
pub struct Builder {
    _emitters: Vec<ParticleEmitter2Ptr>,
}

impl Builder {
    /// Returns builder with list of sub-emitters.
    pub fn with_emitters(&mut self, emitters: Vec<ParticleEmitter2Ptr>) -> &mut Self {
        self._emitters = emitters;
        return self;
    }

    /// Builds ParticleEmitterSet2.
    pub fn build(&mut self) -> ParticleEmitterSet2 {
        return ParticleEmitterSet2::new(self._emitters.clone());
    }

    /// Builds shared pointer of ParticleEmitterSet2 instance.
    pub fn make_shared(&mut self) -> ParticleEmitterSet2Ptr {
        return ParticleEmitterSet2Ptr::new(RwLock::new(self.build()));
    }

    /// constructor
    pub fn new() -> Builder {
        return Builder {
            _emitters: vec![]
        };
    }
}