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_emitter3::*;
use crate::particle_system_data3::ParticleSystemData3Ptr;
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 ParticleEmitterSet3, f64, f64);

///
/// # 3-D particle-based emitter set.
///
pub struct ParticleEmitterSet3 {
    _emitters: Vec<ParticleEmitter3Ptr>,

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

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

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

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

    ///
    /// \brief      Sets the callback function to be called when
    ///             ParticleEmitter3::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 ParticleEmitter3 for ParticleEmitterSet3 {
    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: ParticleSystemData3Ptr) {
        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) -> &ParticleEmitter3Data {
        return &self._emitter_data;
    }

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

/// Shared pointer type for the ParticleEmitterSet3.
pub type ParticleEmitterSet3Ptr = Arc<RwLock<ParticleEmitterSet3>>;

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

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

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

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

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