Skip to content

Instantly share code, notes, and snippets.

@Cifram
Created December 28, 2014 02:12
Show Gist options
  • Select an option

  • Save Cifram/7991a3581cc0d37a7095 to your computer and use it in GitHub Desktop.

Select an option

Save Cifram/7991a3581cc0d37a7095 to your computer and use it in GitHub Desktop.
extern crate cgmath;
use self::cgmath::Matrix4;
use scene::MeshComponent;
macro_rules! scene(
($($comp_name:ident($comp_adder:ident, $comp_getter:ident, $comp_remover:ident, $comp_foreach:ident): $comp:ident),*) => (
pub struct Scene {
transforms: Vec<Option<Matrix4<f32>>>,
$(
$comp_name: Vec<Option<Box<$comp>>>,
)*
}
impl Scene {
pub fn new() -> Scene {
return Scene {
transforms: Vec::new(),
$(
$comp_name: Vec::new(),
)*
};
}
pub fn add_actor(&mut self, transform: Matrix4<f32>) -> Actor {
self.transforms.push(Some(transform));
return Actor { id: self.transforms.len()-1 };
}
pub fn remove_actor(&mut self, actor: Actor) {
self.transforms[actor.id] = None;
loop {
match self.transforms[self.transforms.len()-1] {
Some(_) => break,
None => { let _ = self.transforms.pop(); }
}
}
}
pub fn set_transform(&mut self, actor: Actor, transform: Matrix4<f32>) {
if !self.actor_exists(actor) {
fail!("Attempt to set transform on actor {}, which doesn't exist", actor.id);
}
self.transforms[actor.id] = Some(transform);
}
pub fn get_transform(&self, actor: Actor) -> Matrix4<f32> {
if !self.actor_exists(actor) {
fail!("Attempt to get transform from actor {}, which doesn't exist", actor.id);
}
return self.transforms[actor.id].unwrap();
}
$(
pub fn $comp_adder(&mut self, actor: Actor) {
if !self.actor_exists(actor) {
fail!("Attempt to add {} on actor {}, which doesn't exist", stringify!($comp), actor.id);
}
if actor.id >= self.$comp_name.len() {
self.$comp_name.grow(actor.id+1, None);
}
match self.$comp_name[actor.id] {
Some(_) => {
fail!("Attempt to add {0} on actor {1}, which already has a {0}", stringify!($comp), actor.id);
}
None => { self.$comp_name[actor.id] = Some($comp::new()); }
}
}
pub fn $comp_getter(&mut self, actor: Actor) -> Option<&mut $comp> {
if !self.actor_exists(actor) {
fail!("Attempt to get {} on actor {}, which doesn't exist", stringify!($comp), actor.id);
}
if actor.id >= self.$comp_name.len() {
return None;
}
match &mut self.$comp_name[actor.id] {
&Some(ref mut component) => { return Some(&mut **component); }
&None => { return None; }
}
}
pub fn $comp_remover(&mut self, actor: Actor) {
if !self.actor_exists(actor) {
fail!("Attempt to remove {} from actor {}, which doesn't exist", stringify!($comp), actor.id);
}
if actor.id < self.$comp_name.len() {
fail!("Attempt to remove {0} from actor {1}, which doesn't have a {0}", stringify!($comp), actor.id);
}
match self.$comp_name[actor.id] {
None => { fail!("Attempt to remove {0} from actor {1}, which doesn't have a {0}", stringify!($comp), actor.id); }
Some(_) => { self.$comp_name[actor.id] = None; }
}
}
pub fn $comp_foreach(&mut self, func: |&mut $comp|) {
for maybe_component in self.$comp_name.iter_mut() {
match maybe_component {
&Some(ref mut component) => func(&mut **component),
&None => {}
}
}
}
)*
pub fn actor_exists(&self, actor: Actor) -> bool {
return actor.id < self.transforms.len() && self.transforms[actor.id] != None;
}
}
);
)
pub struct Actor {
id: uint,
}
scene!(
mesh_component(add_mesh_component, get_mesh_component, remove_mesh_component, foreach_mesh_component): MeshComponent
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment