MrGVSV / bevy_proto

Create config files for entities in Bevy

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bevy 0.6

chrisburnor opened this issue · comments

Creating an issue for this because it's going to require some discussion rather than a simple fix.

Bevy 0.6 changes Component from:

pub trait Component: Send + Sync + 'static;

to

pub trait Component: Send + Sync + 'static {
       type Storage: ComponentStorage;
}

This breaks the implementation of ProtoComponent which must extend Component, which now has a trait type. This has all sorts of downstream implications in the code base.

I can see three possible (non-exclusive) paths forward:

  1. Simply move forward as-is and see if it is possible to update the types.
  2. Change ProtoComponent to not be bound to Component and create some sort of shim type to convert.
  3. Use Bevy Reflect (somehow) to work around the problem.

Yeah this is going to be a bit of an issue 🤔

I think I prefer option 2, since we already sorta allow that. Not every ProtoComponent needs to be a Component. It's allowed to insert whatever it wants into the given Commands.

So one solution would be to remove the trait bound as you suggest, but keep the derive macro the same (mostly). So even if Foo does not derive Component we still try to insert it by default. Thankfully with 0.6, this should throw an error right away (hopefully).

Then, for those that don't want to impl manually, we add a couple associated struct macros for the derive macro:

#[proto_comp(from = "ActualComponent")]

This would basically generate something like:

fn insert_self(&self, commands: &mut ProtoCommands, asset_server: &bevyRes<AssetServer>) {
  let component = ActualComponent::from(MyProtoComp);
  commands.insert(component);
}

#[proto_comp(with = "my_function")]

And this would just run my_function with the same arguments as insert_self:

fn insert_self(&self, commands: &mut ProtoCommands, asset_server: &bevyRes<AssetServer>) {
  let component = my_function(self, commands, asset_server);
  commands.insert(component);
}

Not sure if this would all actually work, but if it does, I think it's the simplest option. I'd maybe consider Reflect as a second choice, but I just don't have enough experience with it to really decide on that.