Add support for returning all Component
and values to query method in the Bevy Remote Protocol (#19857)
# Objective
We should have an API with filtering to allow BRP clients to retrieve
all relevant data from the world state. Currently working on adding
examples - but reviews are appreciated! Still semi-WIP while I get my
head around bevy’s reflection and implementation :)
## Solution
This change adds support to query all entities in the world, and returns
all of their Reflected Components with corresponding values. For custom
`Components` it's important to still implement `Reflect` so that this
endpoint returns these. This will be useful for the
`bevy_entity_inspector` so that we can easily get the current world
state. We have modified the existing query API
so that clients can now pass in an empty `components[]` on the JSON
request.
## Testing
Updated example to showcase how to use the new endpoint to get all data:
```rust
/// Create a query_all request to send to the remote Bevy app.
/// This request will return all entities in the app, their components, and their
/// component values.
fn run_query_all_components_and_entities(url: String) -> Result<(), anyhow::Error> {
let query_all_req = BrpRequest {
jsonrpc: String::from("2.0"),
method: String::from(BRP_QUERY_METHOD),
id: Some(serde_json::to_value(1)?),
params: None,
};
println!("query_all req: {:#?}", query_all_req);
let query_all_res = ureq::post(&url)
.send_json(query_all_req)?
.body_mut()
.read_json::<serde_json::Value>()?;
println!("{query_all_res:#}");
Ok(())
}
```
---
## Showcase
In the `client.rs` example, we can clearly see (assuming the `server.rs`
is running) a query hit for all entities and components:
```text
query_all req: BrpRequest {
jsonrpc: "2.0",
method: "bevy/query",
id: Some(
Number(1),
),
params: Some(
Object {
"data": Object {
"components": Array [],
"has": Array [],
"option": Array [],
},
"filter": Object {
"with": Array [],
"without": Array [],
},
"strict": Bool(false),
},
),
}
```
And in the massive response:
```text
.....
{
"components": {
"bevy_window::monitor::Monitor": {
"name": "\\\\.\\DISPLAY1",
"physical_height": 1080,
"physical_position": [
-1920,
0
],
"physical_width": 1920,
"refresh_rate_millihertz": 240000,
"scale_factor": 1.25,
"video_modes": [
{
"bit_depth": 32,
"physical_size": [
1920,
1080
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
1680,
1050
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
1600,
900
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
1440,
900
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
1400,
1050
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
1366,
768
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
1360,
768
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
1280,
1024
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
1280,
960
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
1280,
800
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
1280,
768
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
1280,
720
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
1280,
600
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
1152,
864
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
1024,
768
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
800,
600
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
640,
480
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
640,
400
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
512,
384
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
400,
300
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
320,
240
],
"refresh_rate_millihertz": 240000
},
{
"bit_depth": 32,
"physical_size": [
320,
200
],
"refresh_rate_millihertz": 240000
}
]
}
},
"entity": 4294967267
},
....
```
What's also really cool about this and `bevy_reflect` is that we also
get custom components returned as well (see below for `"server::Cube":
1.0` as the custom reflected struct specified in `server.rs`:
```text
{
"components": {
"bevy_render::primitives::Aabb": {
"center": [
0.0,
0.0,
0.0
],
"half_extents": [
0.5,
0.5,
0.5
]
},
"bevy_render::view::visibility::InheritedVisibility": true,
"bevy_render::view::visibility::ViewVisibility": true,
"bevy_render::view::visibility::Visibility": "Inherited",
"bevy_transform::components::global_transform::GlobalTransform": [
1.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
1.0,
0.0,
2.4572744369506836,
0.0
],
"bevy_transform::components::transform::Transform": {
"rotation": [
0.0,
0.0,
0.0,
1.0
],
"scale": [
1.0,
1.0,
1.0
],
"translation": [
0.0,
2.4572744369506836,
0.0
]
},
"bevy_transform::components::transform::TransformTreeChanged": null,
"server::Cube": 1.0
},
```
---------
Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>