Remove the steven_id system

This commit is contained in:
Thinkofname 2016-04-20 21:51:49 +01:00
parent 23e779c0d7
commit bb5032fd30
1 changed files with 106 additions and 76 deletions

View File

@ -96,67 +96,8 @@ macro_rules! define_blocks {
mod internal_ids { mod internal_ids {
create_ids!(usize, $($name),+); create_ids!(usize, $($name),+);
} }
mod internal_sizes {
$(
#[allow(non_upper_case_globals)]
pub const $name : usize = $(($(1 + consume_token!($val) + )+ 0) * )* 1;
)+
}
mod internal_offsets {
use super::internal_sizes;
offsets!($($name),+);
}
mod internal_offset_max {
use super::internal_sizes;
use super::internal_offsets;
$(
#[allow(non_upper_case_globals)]
pub const $name: usize = internal_offsets::$name + internal_sizes::$name - 1;
)+
}
impl Block { impl Block {
#[allow(unused_variables, unused_mut, unused_assignments)]
pub fn get_steven_id(&self) -> usize {
match *self {
$(
Block::$name {
$($fname,)*
} => {
let mut offset = internal_offsets::$name;
let mut mul = 1;
$(
offset += [$($val),+].into_iter().position(|v| *v == $fname).unwrap() * mul;
mul *= $(1 + consume_token!($val) + )+ 0;
)*
offset
},
)+
}
}
#[allow(unused_variables, unused_assignments)]
pub fn by_steven_id(id: usize) -> Block {
match id {
$(
mut data @ internal_offsets::$name ... internal_offset_max::$name=> {
data -= internal_offsets::$name;
$(
let vals = [$($val),+];
let $fname = vals[data % vals.len()];
data /= vals.len();
)*
Block::$name {
$(
$fname: $fname,
)*
}
},
)*
_ => Block::Missing {}
}
}
#[allow(unused_variables, unreachable_code)] #[allow(unused_variables, unreachable_code)]
pub fn get_vanilla_id(&self) -> Option<usize> { pub fn get_vanilla_id(&self) -> Option<usize> {
match *self { match *self {
@ -293,25 +234,114 @@ macro_rules! define_blocks {
lazy_static! { lazy_static! {
static ref VANILLA_ID_MAP: Vec<Option<Block>> = { static ref VANILLA_ID_MAP: Vec<Option<Block>> = {
let mut blocks = vec![]; let mut blocks = vec![];
for i in 0 .. internal_offsets::Missing { $({
let block = Block::by_steven_id(i); #[allow(non_camel_case_types, dead_code)]
if let Some(id) = block.get_vanilla_id() { struct CombinationIter<$($fname),*> {
if blocks.len() <= id { first: bool,
blocks.resize(id + 1, None); finished: bool,
} state: CombinationIterState<$($fname),*>,
if blocks[id].is_none() { orig: CombinationIterOrig<$($fname),*>,
blocks[id] = Some(block); current: CombinationIterCurrent,
} else { }
panic!( #[allow(non_camel_case_types)]
"Tried to register {:#?} to {}:{} but {:#?} was already registered", struct CombinationIterState<$($fname),*> {
block, $($fname: $fname,)*
id >> 4, }
id & 0xF, #[allow(non_camel_case_types)]
blocks[id] struct CombinationIterOrig<$($fname),*> {
); $($fname: $fname,)*
}
#[allow(non_camel_case_types)]
struct CombinationIterCurrent {
$($fname: $ftype,)*
}
#[allow(non_camel_case_types)]
impl <$($fname : Iterator<Item=$ftype> + Clone),*> Iterator for CombinationIter<$($fname),*> {
type Item = Block;
#[allow(unused_mut, unused_variables, unreachable_code, unused_assignments)]
fn next(&mut self) -> Option<Self::Item> {
if self.finished {
return None;
}
if self.first {
self.first = false;
return Some(Block::$name {
$(
$fname: self.current.$fname,
)*
});
}
let mut has_value = false;
loop {
$(
if let Some(val) = self.state.$fname.next() {
self.current.$fname = val;
has_value = true;
break;
}
self.state.$fname = self.orig.$fname.clone();
self.current.$fname = self.state.$fname.next().unwrap();
)*
self.finished = true;
return None;
}
if has_value {
Some(Block::$name {
$(
$fname: self.current.$fname,
)*
})
} else {
None
}
} }
} }
} #[allow(non_camel_case_types)]
impl <$($fname : Iterator<Item=$ftype> + Clone),*> CombinationIter<$($fname),*> {
fn new($(mut $fname:$fname),*) -> CombinationIter<$($fname),*> {
CombinationIter {
finished: false,
first: true,
orig: CombinationIterOrig {
$($fname: $fname.clone(),)*
},
current: CombinationIterCurrent {
$($fname: $fname.next().unwrap(),)*
},
state: CombinationIterState {
$($fname: $fname,)*
}
}
}
}
let iter = CombinationIter::new(
$({
let vals = vec![$($val),+];
vals.into_iter()
}),*
);
for block in iter {
if let Some(id) = block.get_vanilla_id() {
if blocks.len() <= id {
blocks.resize(id + 1, None);
}
if blocks[id].is_none() {
blocks[id] = Some(block);
} else {
panic!(
"Tried to register {:#?} to {}:{} but {:#?} was already registered",
block,
id >> 4,
id & 0xF,
blocks[id]
);
}
}
}
})+
blocks blocks
}; };
} }