blob: d11ea3a1ce9178a7bf6d7a28b944c6ec53247e02 (
plain) (
tree)
|
|
use super::units::*;
use super::orbital::*;
use std::vec::Vec;
use std::rc::Rc;
use std::cell::RefCell;
pub struct System
{
pub orbitals : Rc<RefCell<Vec<Orbital>>>,
}
pub struct SystemBuilder
{
orbitals : Rc<RefCell<Vec<Orbital>>>,
}
impl System
{
fn orbital_set(&self, orbitals : &mut [Orbital], i : usize)
-> (&mut Orbital, Option<&mut Orbital>)
{
//The orbital vector must first be converted to a mutable span, so that I can access the raw data.
assert!(i < orbitals.len());
unsafe {
//From the orbital span, take a raw pointer from the given index,
//cast to a pointer to a mutable Orbital, and dereference.
let orbital = &mut *(orbitals.get_unchecked_mut(i) as *mut Orbital);
//Assuming the orbital is a valid object, check for the parent orbital.
match orbital.origin() {
Some(origin_i) => {
//Make sure the origin index does not break rules.
assert!(origin_i != i, "Object cannot orbit itself");
assert!(origin_i < orbitals.len());
let origin = &mut *(orbitals.get_unchecked_mut(origin_i) as *mut Orbital);
(orbital, Some(origin))
},
None => (orbital, None)
}
}
}
pub fn tick(&self, t : Second)
{
let orbitals = &mut self.orbitals.borrow_mut()[..];
for i in 0..orbitals.len() {
let orbital_set = self.orbital_set(orbitals, i);
match orbital_set.1 {
Some(origin) => { orbital_set.0.tick(origin, t); },
None => {}
}
}
}
}
impl SystemBuilder
{
pub fn new() -> SystemBuilder
{
SystemBuilder {
orbitals : Rc::new(RefCell::new(vec![]))
}
}
pub fn add_body(&self, orbital : Orbital) -> usize
{
let mut orbitals = self.orbitals.borrow_mut();
let new_ind = orbitals.len();
orbitals.push(orbital);
new_ind
}
pub fn build(self) -> System
{
System {
orbitals : self.orbitals
}
}
}
|