bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
35.24k stars 3.47k forks source link

multiple queries / SystemParam from `DeferredWorld` #14869

Open DasLixou opened 1 month ago

DasLixou commented 1 month ago

What problem does this solve or what need does it fill?

There is currently no easy way of getting multiple queries from a DeferredWorld.

What solution would you like?

Add DeferredWorld::queries over a generic amount of queries and return if they have no violations.

SkiFire13 commented 1 month ago

This should be made to work in a generic way with any SystemParam/with SystemState. Then multiple queries would be supported as (Query<A>, Query<B>) or SystemState<(Query<A>, Query<B>)

DasLixou commented 1 week ago

Ok so: Unsure if this should be allowed in DeferredWorld because I think there could be system params that break its promises. Also, seems like SystemState is that what I was searching for. I think we should remove World::query and either link more agressively to or add a helper method for system states. DeferredWorld on the other side, unsure if we can do anything more than multi-query, really.. Thoughts?

SkiFire13 commented 1 week ago

unsure if we can do anything more than multi-query

AFAIK no SystemParam yet modifies the World structurally, also because I don't think the access mechanism allows to safely express that. So currently any SystemParam should be ok to allow. If this ever change there are at least these SystemParams that don't perform structural changes:

DasLixou commented 1 week ago

But System param has &mut World, right? So a third party system param might do that.

SkiFire13 commented 1 week ago

Ah I see my mistake: I was assuming this is just about fetching the system parameter (which takes a UnsafeWorldCell and need to respect the access API), however there's also the problem of initializing the SystemParam, and that takes &mut World and can do pretty much anything.

It could however work if the SystemState was already initialized though. I wonder if guaranteeing that is possible.

DasLixou commented 1 week ago

So having SystemState still take an &mut World but then have system_params (bikeshed) functions on both World and DeferredWorld? That would also make finding it easier.

SkiFire13 commented 1 week ago

So having SystemState still take an &mut World but then have system_params (bikeshed) functions on both World and DeferredWorld?

The issue is that currently SystemState is lazily initialized the first time get is called. This cannot happen with DeferredWorld, so something else needs to initialize it before that point.

I just noticed however that component hooks are simple fns, so they can't hold on to an initialized system param.

DasLixou commented 1 week ago

Sorry, what do component hooks have to do with that? And I thought SystemState::new initializes the parameters? It at least calls Param::init_state..

SkiFire13 commented 1 week ago

Sorry, what do component hooks have to do with that?

They are the main users of DeferredWorld, so that's probably where you want to get system states/parameters.

And I thought SystemState::new initializes the parameters?

You're right, I think have confused them with systems (which initialize their SystemState on either an explicit call to initialize or lazily when run is called).

That doesn't really solve the problem since you have to create them somewhere though.