I'm implementing a game using Rust, just to learn the language and some game patterns, and basically I have a concept where I have a Creature
type, which can be a Character
(a player) or Enemy
(the monsters of my game). The way that I'm doing this right now is just declaring Creature
as an enum and having two options, Character
and Enemy
, like this:
pub enum Creature {
Character(Character),
Enemy(Enemy),
}
The problem is that in my systems, I always need to add a match to know if it's a character or an enemy, and in most cases I don't care about that, since both have fields in common. So improving this with OOP would be easy, just declare Creature
as a class and make Character
and Enemy
inherit from Creature
. But of course this doesn't work in Rust.
So, what I'm trying is to declare Creature
as a Trait
, and that works for some extent, until I have to type fields as Creature
. Basically, I'm sending data over a TCP socket from the server to the client, and serializing the data, and for that, the server message struct must have 'static
and implement Send
.
So right now I'm getting this error when I try to type a field inside my server message struct as Creature
:
the size for values of type `(dyn Creature + 'static)` cannot be known at compilation time
the trait `Sized` is not implemented for `(dyn Creature + 'static)`
no field of an enum variant may have a dynamically sized type
change the field's type to have a statically known size
And my server message looks like:
pub enum ServerMessage {
...
SpawnCreature {
creature: dyn Creature,
position: Position,
},
...
}
And in my struct that has the code to send data over the socket, I'm getting this:
`(dyn Creature + 'static)` cannot be sent between threads safely
within `ServerMessage`, the trait `Send` is not implemented for `(dyn Creature + 'static)`
required for `ServerMessage` to implement `PostMsg`
Also, I'm using threads to send and listen for messages in the socket.
So, searching on google I didn't find any good explanation on how I can do this, or if this is even possible, I see some very simple examples using Box
, but I don't know if that's going to work for my case.
I know that in Rust I should use composition instead of inheritance, but for this specific case, something like inheritance would improve my code so much.
If there is not really a good way of doing this, it's all good, I'm just curious to know if this is possible in some way.