docs/bevy/examples/remote/client.rs 5.5 K · 158 lines · raw · history

1 //! A simple command line client that allows issuing queries to a remote Bevy
2 //! app via the BRP.
3 //! This example requires the `bevy_remote` feature to be enabled.
4 //! You can run it with the following command:
5 //! ```text
6 //! cargo run --example client --features="bevy_remote"
7 //! ```
8 //! This example assumes that the `server` example is running on the same machine.
9
10 use std::any::type_name;
11
12 use anyhow::Result as AnyhowResult;
13 use bevy::{
14 ecs::hierarchy::ChildOf,
15 remote::{
16 builtin_methods::{
17 BrpQuery, BrpQueryFilter, BrpQueryParams, BrpWriteMessageParams, ComponentSelector,
18 BRP_QUERY_METHOD, BRP_WRITE_MESSAGE_METHOD,
19 },
20 http::{DEFAULT_ADDR, DEFAULT_PORT, DEFAULT_RENDER_PORT},
21 BrpRequest,
22 },
23 transform::components::Transform,
24 };
25
26 /// The application entry point.
27 fn main() -> AnyhowResult<()> {
28 // Create the URL. We're going to need it to issue the HTTP request.
29 let host_part = format!("{DEFAULT_ADDR}:{DEFAULT_PORT}");
30 let url = format!("http://{host_part}/");
31 // Creates a request to get all Transform components from the remote Bevy app.
32 // This request will return all entities that have a Transform component.
33 run_transform_only_query(&url)?;
34
35 // Create a query that only returns root entities - ie, entities that do not
36 // have a parent.
37 run_query_root_entities(&url)?;
38
39 // Create a query all request to send to the remote Bevy app.
40 // This request will return all entities in the app, their components, and their
41 // component values.
42 run_query_all_components_and_entities(&url)?;
43
44 // Run again against the render port
45 let host_part2 = format!("{DEFAULT_ADDR}:{DEFAULT_RENDER_PORT}");
46 let url2 = format!("http://{host_part2}/");
47
48 run_transform_only_query(&url2)?;
49 run_query_root_entities(&url2)?;
50 run_query_all_components_and_entities(&url2)?;
51
52 // Send an `AppExit::Success` message to the app to the remote Bevy app.
53 // This will make it quit.
54 send_app_exit(&url)?;
55
56 Ok(())
57 }
58
59 fn run_query_all_components_and_entities(url: &str) -> Result<(), anyhow::Error> {
60 let query_all_req = BrpRequest {
61 method: String::from(BRP_QUERY_METHOD),
62 id: Some(serde_json::to_value(1)?),
63 params: Some(
64 serde_json::to_value(BrpQueryParams {
65 data: BrpQuery {
66 components: Vec::default(),
67 option: ComponentSelector::All,
68 has: Vec::default(),
69 },
70 strict: false,
71 filter: BrpQueryFilter::default(),
72 })
73 .expect("Unable to convert query parameters to a valid JSON value"),
74 ),
75 };
76 println!("query_all req: {query_all_req:#?}");
77 let query_all_res = ureq::post(url)
78 .send_json(query_all_req)?
79 .body_mut()
80 .read_json::<serde_json::Value>()?;
81 println!("{query_all_res:#}");
82 Ok(())
83 }
84
85 fn run_transform_only_query(url: &str) -> Result<(), anyhow::Error> {
86 let get_transform_request = BrpRequest {
87 method: String::from(BRP_QUERY_METHOD),
88 id: Some(serde_json::to_value(1)?),
89 params: Some(
90 serde_json::to_value(BrpQueryParams {
91 data: BrpQuery {
92 components: vec![type_name::<Transform>().to_string()],
93 ..Default::default()
94 },
95 strict: false,
96 filter: BrpQueryFilter::default(),
97 })
98 .expect("Unable to convert query parameters to a valid JSON value"),
99 ),
100 };
101 println!("transform request: {get_transform_request:#?}");
102 let res = ureq::post(url)
103 .send_json(get_transform_request)?
104 .body_mut()
105 .read_json::<serde_json::Value>()?;
106 println!("{res:#}");
107 Ok(())
108 }
109
110 fn run_query_root_entities(url: &str) -> Result<(), anyhow::Error> {
111 let get_transform_request = BrpRequest {
112 method: String::from(BRP_QUERY_METHOD),
113 id: Some(serde_json::to_value(1)?),
114 params: Some(
115 serde_json::to_value(BrpQueryParams {
116 data: BrpQuery {
117 components: Vec::default(),
118 option: ComponentSelector::All,
119 has: Vec::default(),
120 },
121 strict: false,
122 filter: BrpQueryFilter {
123 without: vec![type_name::<ChildOf>().to_string()],
124 with: Vec::default(),
125 },
126 })
127 .expect("Unable to convert query parameters to a valid JSON value"),
128 ),
129 };
130 println!("transform request: {get_transform_request:#?}");
131 let res = ureq::post(url)
132 .send_json(get_transform_request)?
133 .body_mut()
134 .read_json::<serde_json::Value>()?;
135 println!("{res:#}");
136 Ok(())
137 }
138
139 fn send_app_exit(url: &str) -> Result<(), anyhow::Error> {
140 let write_message_request = BrpRequest {
141 method: String::from(BRP_WRITE_MESSAGE_METHOD),
142 id: Some(serde_json::to_value(1)?),
143 params: Some(
144 serde_json::to_value(BrpWriteMessageParams {
145 message: "bevy_app::app::AppExit".to_string(),
146 value: Some("Success".into()),
147 })
148 .expect("Unable to convert write message parameters to a valid JSON value"),
149 ),
150 };
151 println!("write message request: {write_message_request:#?}");
152 let res = ureq::post(url)
153 .send_json(write_message_request)?
154 .body_mut()
155 .read_json::<serde_json::Value>()?;
156 println!("{res:#}");
157 Ok(())
158 }