You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
What problem does this solve or what need does it fill?
Querying the world directly always the creation of QueryState, rather than returning a Query that can be worked with directly.
let query_state = world.query::<(&Foo,&mutBar),With<A>>();for(foo, bar)in query_state.iter(&world){assert!(foo > bar);}
This is directly relevant to:
Exclusive systems. We could cache this state in a Local, but this is rarely done in practice.
Commands. Under the current commands model, there is nowhere to cache this state.
Integration tests. There is effectively no point caching this state, both because the queries are often not repeated, and because we are not in a performance-constrained setting.
The existing approach is confusing to beginners, heavy on boilerplate and directly exposes end users to QueryState, which should largely be engine-internal.
What solution would you like?
Create two core methods on World, replacing the current World::query and World::query_filtered:
World::query: returns a stateless Query directly from the world. This is used in commands and integration tests.
World::query_state: returns a QueryState. This is used in engine internals, and exclusive systems.
In order to get this to work we need to:
Allow Query to store a &QueryState or a new InternalQueryState value, rather than just a QueryState.
Tweak the initialization methods.
Warn when Added or Changed are used with a InternalQueryState.
The example above becomes the much more direct and familiar:
Write helper methods (in the engine, or in end user test code) that wrap this boilerplate. This doesn't save much work, and seriously reduces clarity and directness, especially as the methods proliferate. This was the approach taken in Utility functions for integration testing #3839.
What problem does this solve or what need does it fill?
Querying the world directly always the creation of
QueryState, rather than returning aQuerythat can be worked with directly.This is directly relevant to:
Local, but this is rarely done in practice.The existing approach is confusing to beginners, heavy on boilerplate and directly exposes end users to
QueryState, which should largely be engine-internal.What solution would you like?
Create two core methods on
World, replacing the currentWorld::queryandWorld::query_filtered:World::query: returns a stateless Query directly from the world. This is used in commands and integration tests.World::query_state: returns aQueryState. This is used in engine internals, and exclusive systems.In order to get this to work we need to:
Queryto store a&QueryStateor a newInternalQueryStatevalue, rather than just aQueryState.AddedorChangedare used with aInternalQueryState.The example above becomes the much more direct and familiar:
What alternative(s) have you considered?
QueryStatewhen writing integration tests and custom commands. Very boilerplate heavy and confusing to new users.Additional context
Closely related to #3774.