Would there be demand for a feature like this - or an existing way to do it:
imagine macros for declaring classes in a system, (e.g. one class per soucefile) then something to gather!(other_macro)
their invocations in one location (e.g. to roll code to list them in a UI, iterate them coherently at runtime , whatever you need). You could seamlessly switch from 'sort by type' to 'sort by function' approaches.
example :-
// many of these scattered between source-files
// 'declare_class!{} in this example is empty
// foo.rs
declare_class!{
Foo { /* foo fields*/ },
render{println!("i am a foo")},
update{},
...
}
// bar.rs
declare_class!{
Bar { /* bar fields */ } ,
render{println!("i am a bar")},
update{},
...
}
// baz.rs
declare_class!{ Baz ... }
// then in one source file:-
// classes.rs
generate_class_list!{ gather!(declare_class) } <<<<< PROPOSED FEATURE
//gather! instantiates itself as follows:-
generate_class_list!{
{ Foo {/*fields go here*/}
Render{println!("i am a foo")} Update{}
}
{ Bar { }
Render{println!("i am a bar")}
Update{}
}
}
// uber-macro 'generate_class_list'
// actually rolls everything.. a list of all the classes in a big enum for 'matching' against,
// plain structs for all their data, a list of each type stored coherently in a homogenous vector,
// result might be as below,
// but you could easily switch between 'struct of arrays per type', 'array of trait-objets', 'one big enum'
struct Foo {
/* foo fields */
}
impl Foo {
fn render(&self) { println!("i am a foo") }
fn update(&self) { .. }
...
}
struct Bar {
/* bar fields */
}
impl Bar {
fn render(&self) { println!("i am a bar") }
fn update(&self) { }
...
}
...
struct World {
foo:vector<Foo>
bar:vector<Bar>
baz:vector<Baz>
}
impl World {
fn update() {
for x in self.foo.iter() { x.update() }
for x in self.bar.iter() { x.update() }
for x in self.baz.iter() { x.update() }
}
fn render() {
for x in self.foo.iter() { x.render() }
for x in self.bar.iter() { x.render() }
for x in self.baz.iter() { x.render() }
}
}
// but you could easily also have rolled it..
enum UberEntity {
Foo { /* foo fields */
Bar { /* bar fields */
}
impl UberEntity {
fn render(&self) {
match self {
Foo{..}=> {
println! ( "i am a foo!" );
}
Foo{..}=> {
println! ( "i am a bar!" );
}
}
}
}
// or rolled trait objects for a more OOP-like approach ..
Of course they could be nested, e.g. 'declare event types', 'roll an event dispatcher per entity'