I would like to get rid of this drawmode field and 'monomorphize' this draw_rect_to function.
Thus avoiding the 'match' statement.
I could write a Bmp<D> struct
I could also write a draw_rect_to<D>() function separating drawmode entirely.
But both would "uglify" calling code.
Any ideas for nice implementations? (maybe PhantomData? transmute?)
I would like creation of Bmp to be without generics. But that is doable by a default alias I think, which is then "opaque".
I do not like the 'look' of these :: for calling generic functions.
Currently I have to make all my bitmaps in-game mutable when drawing because I have to change to drawmode. Looking for a good way too avoid that.
You'll get used to it. You don't need the turbofish most of the time anyway, due to type inference.
If you want generic code, then just write generic code. The syntax of any particular language feature shouldn't be the primary reason for how you structure your code. You should organize your code around domain concepts, not surface syntax.
transmute is extremely dangerous, since it tells the compiler to treat the thing you're transmuting as a bit pattern, and interpret it as-if it was something else. Unless you know for sure that this is OK, you should avoid it.
Virtually everything that you can do with transmute can be done without unsafe using the standard library's functionality. The few things that you can't do this way depend crucially on details of how a given system works, and tend to be wildly unportable.
if you want an alternative to type parameters, you can check out the impl Trait syntax, as well as type objects and the Any trait. trait objects have a runtime overhead, but they do have their uses, such as reducing code size and handling cases where you don't know the type until runtime. i wouldn't mess with transmute unless you already have experience in an unsafe language like C, since unsafe rust can actually be a fair bit trickier than C, due to factors like unspecified memory layouts.
also, unless i'm mistaken, i think you might've mixed up monomorphic and polymorphic?
Ok I will not mention transmute anymore. It is not needed anyway.
At least I deleted the field from Bmp and added a parameter to the draw functions, like:
pub fn draw_to(&self, dst: &mut Self, dst_x: i32, dst_y: i32, mode: DrawMode)
{
// match statement on <mode> and do your thing.
}
And I meant monomorph, not polymorph. @drmason13: yes, thanks. True, but this only works if drawmode is constant, isnt it?
I think if the drawmode is variable, monomorphization is impossible anyway?
But I do not know enough of the compiling process.
In my chessprogram I managed to heavily monomorphize stuff with trait constants (with very good speed result), but here the drawmode is variable and not constant.
let src = Bmp::new(100, 100);
let mut dst = Bmp::new(200, 200);
let mode = some_sprite.drawmode; // variable
bmp.draw_to(&mut dst, 10, 10, mode);
I see what you mean, and you're right, at some point somewhere you'll need to have a compile-time known DrawMode to avoid handling each possible DrawMode at runtime.
It could be that the sprites are Sprite<DrawMode> to always have a fixed DrawMode. And... I guess sprites are fed in as assets - grouped by DrawMode - and there are separate functions that load a Sprite with a certain DrawMode. And now all the code handling a sprite has to be generic... That doesn't sound fun!
I think the enum is what you actually want. If you don't know what a sprite's DrawMode will be until runtime, but you know at compile time that it has to be one of a fixed set of possible values. Well, that's what enums are for!