pub struct Packet { /* private fields */ }Expand description
One message between players: a kind (what it is about) and a list of values.
use audio_code::prelude::*;
let packet = Packet::new("move").with(vec3(3.0, 4.0, 0.0)).with(90.0).with("running");
assert_eq!(packet.kind(), "move");
assert_eq!(packet.vec3(0), vec3(3.0, 4.0, 0.0));
assert_eq!(packet.float(1), 90.0);
assert_eq!(packet.text(2), "running");
// Missing or other values give a neutral result instead of a crash:
assert_eq!(packet.int(7), 0);Text converts into a packet without values, so ctx.net.send_all("ready") works.
Implementations§
Source§impl Packet
impl Packet
Sourcepub fn new(kind: impl Into<String>) -> Self
pub fn new(kind: impl Into<String>) -> Self
A packet of the given kind without values.
Examples found in repository?
147 fn host_events(&mut self, event: &NetEvent, ctx: &mut Context) {
148 match event {
149 NetEvent::Connected(id) => {
150 let name = ctx.net.name(*id).to_string();
151 ctx.speak(format!("{name} joined"));
152 // Tell the newcomer about everybody, and everybody about the newcomer.
153 ctx.net.send(*id, Packet::new("player").with(PeerId::SERVER).with(ctx.net.name(PeerId::SERVER)).with(self.position));
154 for (other, o) in &self.others {
155 ctx.net.send(*id, Packet::new("player").with(*other).with(&o.name).with(o.position));
156 }
157 ctx.net.send_all_except(*id, Packet::new("player").with(*id).with(&name).with(Vec3::ZERO));
158 self.add(ctx, *id, &name, Vec3::ZERO);
159 }
160 NetEvent::Message(from, packet) => match packet.kind() {
161 "move" => {
162 self.moved(*from, packet.vec3(0));
163 ctx.net.send_all_except(*from, Packet::new("pos").with(*from).with(packet.vec3(0)));
164 }
165 "chat" => {
166 let text = packet.text(0);
167 ctx.play("chat");
168 ctx.speak(format!("{}: {text}", self.name(ctx, *from)));
169 ctx.net.send_all_except(*from, Packet::new("chat").with(*from).with(text));
170 }
171 _ => {}
172 },
173 NetEvent::Disconnected(id, _) => {
174 self.remove(ctx, *id);
175 ctx.net.send_all(Packet::new("gone").with(*id));
176 }
177 }
178 }
179
180 /// The client's side of the protocol.
181 fn client_events(&mut self, event: &NetEvent, ctx: &mut Context) {
182 match event {
183 NetEvent::Message(_, packet) => match packet.kind() {
184 "player" => self.add(ctx, packet.peer(0), packet.text(1), packet.vec3(2)),
185 "pos" => self.moved(packet.peer(0), packet.vec3(1)),
186 "gone" => self.remove(ctx, packet.peer(0)),
187 "chat" => {
188 ctx.play("chat");
189 ctx.speak(format!("{}: {}", self.name(ctx, packet.peer(0)), packet.text(1)));
190 }
191 _ => {}
192 },
193 NetEvent::Disconnected(_, reason) => {
194 ctx.speak(ctx.lang.describe_reason(reason));
195 ctx.audio.stop_all();
196 let scene = Lobby::new(ctx);
197 ctx.switch_scene(scene);
198 }
199 NetEvent::Connected(_) => {}
200 }
201 }
202}
203
204impl Scene for Field {
205 fn start(&mut self, ctx: &mut Context) {
206 ctx.speech.speak_queued("Arrows walk, Enter chats, Space finds the others, Escape leaves.");
207 }
208
209 fn on_net(&mut self, event: &NetEvent, ctx: &mut Context) {
210 if ctx.net.is_host() {
211 self.host_events(event, ctx);
212 } else {
213 self.client_events(event, ctx);
214 }
215 }
216
217 fn on_ui(&mut self, event: &UiEvent, ctx: &mut Context) {
218 if let UiEvent::TextSubmitted { id, text } = event
219 && id == "chat"
220 {
221 // The host sends to everybody, a client sends to the host, who passes it on.
222 if ctx.net.is_host() {
223 ctx.net.send_all(Packet::new("chat").with(PeerId::SERVER).with(text));
224 } else {
225 ctx.net.send_all(Packet::new("chat").with(text));
226 }
227 ctx.play("chat");
228 }
229 }
230
231 fn update(&mut self, ctx: &mut Context) {
232 let step = vec3(
233 ctx.input.repeating(Key::Right, 0.25, 0.25) as i32 as f32 - ctx.input.repeating(Key::Left, 0.25, 0.25) as i32 as f32,
234 ctx.input.repeating(Key::Up, 0.25, 0.25) as i32 as f32 - ctx.input.repeating(Key::Down, 0.25, 0.25) as i32 as f32,
235 0.0,
236 );
237 if step != Vec3::ZERO {
238 self.position = (self.position + step).clamp(Vec3::splat(-20.0), Vec3::splat(20.0));
239 ctx.play("step");
240 if ctx.net.is_host() {
241 ctx.net.send_all(Packet::new("pos").with(PeerId::SERVER).with(self.position));
242 } else {
243 ctx.net.send_all(Packet::new("move").with(self.position));
244 }
245 }
246 ctx.audio.set_listener(self.position, 0.0);
247
248 if ctx.pressed(Key::Enter) {
249 ctx.ui.input("chat", "Message");
250 }
251 if ctx.pressed(Key::Space) {
252 let text = if self.others.is_empty() {
253 "Nobody else is here".to_string()
254 } else {
255 let places: Vec<String> = self
256 .others
257 .values()
258 .map(|o| format!("{}: {}", o.name, ctx.lang.describe_position(self.position, 0.0, o.position)))
259 .collect();
260 places.join(". ")
261 };
262 ctx.speak(text);
263 }
264 if ctx.pressed(Key::P) {
265 if ctx.net.is_host() {
266 ctx.speak(format!("You are the host, {} players connected", ctx.net.player_count()));
267 } else {
268 let ms = (ctx.net.ping(PeerId::SERVER) * 1000.0).round();
269 ctx.speak(format!("Ping {ms} milliseconds"));
270 }
271 }
272 if ctx.pressed(Key::Escape) {
273 ctx.net.close();
274 ctx.audio.stop_all();
275 ctx.speak("You left");
276 let scene = Lobby::new(ctx);
277 ctx.switch_scene(scene);
278 }
279 }Sourcepub fn with(self, value: impl Into<Arg>) -> Self
pub fn with(self, value: impl Into<Arg>) -> Self
Adds a value (builder style).
Examples found in repository?
147 fn host_events(&mut self, event: &NetEvent, ctx: &mut Context) {
148 match event {
149 NetEvent::Connected(id) => {
150 let name = ctx.net.name(*id).to_string();
151 ctx.speak(format!("{name} joined"));
152 // Tell the newcomer about everybody, and everybody about the newcomer.
153 ctx.net.send(*id, Packet::new("player").with(PeerId::SERVER).with(ctx.net.name(PeerId::SERVER)).with(self.position));
154 for (other, o) in &self.others {
155 ctx.net.send(*id, Packet::new("player").with(*other).with(&o.name).with(o.position));
156 }
157 ctx.net.send_all_except(*id, Packet::new("player").with(*id).with(&name).with(Vec3::ZERO));
158 self.add(ctx, *id, &name, Vec3::ZERO);
159 }
160 NetEvent::Message(from, packet) => match packet.kind() {
161 "move" => {
162 self.moved(*from, packet.vec3(0));
163 ctx.net.send_all_except(*from, Packet::new("pos").with(*from).with(packet.vec3(0)));
164 }
165 "chat" => {
166 let text = packet.text(0);
167 ctx.play("chat");
168 ctx.speak(format!("{}: {text}", self.name(ctx, *from)));
169 ctx.net.send_all_except(*from, Packet::new("chat").with(*from).with(text));
170 }
171 _ => {}
172 },
173 NetEvent::Disconnected(id, _) => {
174 self.remove(ctx, *id);
175 ctx.net.send_all(Packet::new("gone").with(*id));
176 }
177 }
178 }
179
180 /// The client's side of the protocol.
181 fn client_events(&mut self, event: &NetEvent, ctx: &mut Context) {
182 match event {
183 NetEvent::Message(_, packet) => match packet.kind() {
184 "player" => self.add(ctx, packet.peer(0), packet.text(1), packet.vec3(2)),
185 "pos" => self.moved(packet.peer(0), packet.vec3(1)),
186 "gone" => self.remove(ctx, packet.peer(0)),
187 "chat" => {
188 ctx.play("chat");
189 ctx.speak(format!("{}: {}", self.name(ctx, packet.peer(0)), packet.text(1)));
190 }
191 _ => {}
192 },
193 NetEvent::Disconnected(_, reason) => {
194 ctx.speak(ctx.lang.describe_reason(reason));
195 ctx.audio.stop_all();
196 let scene = Lobby::new(ctx);
197 ctx.switch_scene(scene);
198 }
199 NetEvent::Connected(_) => {}
200 }
201 }
202}
203
204impl Scene for Field {
205 fn start(&mut self, ctx: &mut Context) {
206 ctx.speech.speak_queued("Arrows walk, Enter chats, Space finds the others, Escape leaves.");
207 }
208
209 fn on_net(&mut self, event: &NetEvent, ctx: &mut Context) {
210 if ctx.net.is_host() {
211 self.host_events(event, ctx);
212 } else {
213 self.client_events(event, ctx);
214 }
215 }
216
217 fn on_ui(&mut self, event: &UiEvent, ctx: &mut Context) {
218 if let UiEvent::TextSubmitted { id, text } = event
219 && id == "chat"
220 {
221 // The host sends to everybody, a client sends to the host, who passes it on.
222 if ctx.net.is_host() {
223 ctx.net.send_all(Packet::new("chat").with(PeerId::SERVER).with(text));
224 } else {
225 ctx.net.send_all(Packet::new("chat").with(text));
226 }
227 ctx.play("chat");
228 }
229 }
230
231 fn update(&mut self, ctx: &mut Context) {
232 let step = vec3(
233 ctx.input.repeating(Key::Right, 0.25, 0.25) as i32 as f32 - ctx.input.repeating(Key::Left, 0.25, 0.25) as i32 as f32,
234 ctx.input.repeating(Key::Up, 0.25, 0.25) as i32 as f32 - ctx.input.repeating(Key::Down, 0.25, 0.25) as i32 as f32,
235 0.0,
236 );
237 if step != Vec3::ZERO {
238 self.position = (self.position + step).clamp(Vec3::splat(-20.0), Vec3::splat(20.0));
239 ctx.play("step");
240 if ctx.net.is_host() {
241 ctx.net.send_all(Packet::new("pos").with(PeerId::SERVER).with(self.position));
242 } else {
243 ctx.net.send_all(Packet::new("move").with(self.position));
244 }
245 }
246 ctx.audio.set_listener(self.position, 0.0);
247
248 if ctx.pressed(Key::Enter) {
249 ctx.ui.input("chat", "Message");
250 }
251 if ctx.pressed(Key::Space) {
252 let text = if self.others.is_empty() {
253 "Nobody else is here".to_string()
254 } else {
255 let places: Vec<String> = self
256 .others
257 .values()
258 .map(|o| format!("{}: {}", o.name, ctx.lang.describe_position(self.position, 0.0, o.position)))
259 .collect();
260 places.join(". ")
261 };
262 ctx.speak(text);
263 }
264 if ctx.pressed(Key::P) {
265 if ctx.net.is_host() {
266 ctx.speak(format!("You are the host, {} players connected", ctx.net.player_count()));
267 } else {
268 let ms = (ctx.net.ping(PeerId::SERVER) * 1000.0).round();
269 ctx.speak(format!("Ping {ms} milliseconds"));
270 }
271 }
272 if ctx.pressed(Key::Escape) {
273 ctx.net.close();
274 ctx.audio.stop_all();
275 ctx.speak("You left");
276 let scene = Lobby::new(ctx);
277 ctx.switch_scene(scene);
278 }
279 }Sourcepub fn kind(&self) -> &str
pub fn kind(&self) -> &str
What the packet is about, e.g. "move" or "chat".
Examples found in repository?
147 fn host_events(&mut self, event: &NetEvent, ctx: &mut Context) {
148 match event {
149 NetEvent::Connected(id) => {
150 let name = ctx.net.name(*id).to_string();
151 ctx.speak(format!("{name} joined"));
152 // Tell the newcomer about everybody, and everybody about the newcomer.
153 ctx.net.send(*id, Packet::new("player").with(PeerId::SERVER).with(ctx.net.name(PeerId::SERVER)).with(self.position));
154 for (other, o) in &self.others {
155 ctx.net.send(*id, Packet::new("player").with(*other).with(&o.name).with(o.position));
156 }
157 ctx.net.send_all_except(*id, Packet::new("player").with(*id).with(&name).with(Vec3::ZERO));
158 self.add(ctx, *id, &name, Vec3::ZERO);
159 }
160 NetEvent::Message(from, packet) => match packet.kind() {
161 "move" => {
162 self.moved(*from, packet.vec3(0));
163 ctx.net.send_all_except(*from, Packet::new("pos").with(*from).with(packet.vec3(0)));
164 }
165 "chat" => {
166 let text = packet.text(0);
167 ctx.play("chat");
168 ctx.speak(format!("{}: {text}", self.name(ctx, *from)));
169 ctx.net.send_all_except(*from, Packet::new("chat").with(*from).with(text));
170 }
171 _ => {}
172 },
173 NetEvent::Disconnected(id, _) => {
174 self.remove(ctx, *id);
175 ctx.net.send_all(Packet::new("gone").with(*id));
176 }
177 }
178 }
179
180 /// The client's side of the protocol.
181 fn client_events(&mut self, event: &NetEvent, ctx: &mut Context) {
182 match event {
183 NetEvent::Message(_, packet) => match packet.kind() {
184 "player" => self.add(ctx, packet.peer(0), packet.text(1), packet.vec3(2)),
185 "pos" => self.moved(packet.peer(0), packet.vec3(1)),
186 "gone" => self.remove(ctx, packet.peer(0)),
187 "chat" => {
188 ctx.play("chat");
189 ctx.speak(format!("{}: {}", self.name(ctx, packet.peer(0)), packet.text(1)));
190 }
191 _ => {}
192 },
193 NetEvent::Disconnected(_, reason) => {
194 ctx.speak(ctx.lang.describe_reason(reason));
195 ctx.audio.stop_all();
196 let scene = Lobby::new(ctx);
197 ctx.switch_scene(scene);
198 }
199 NetEvent::Connected(_) => {}
200 }
201 }Sourcepub fn int(&self, index: usize) -> i64
pub fn int(&self, index: usize) -> i64
The value at index as a whole number. Decimals are cut off, bool gives 0 or 1,
text is parsed. Anything else gives 0.
Sourcepub fn float(&self, index: usize) -> f32
pub fn float(&self, index: usize) -> f32
The value at index as a decimal number. Whole numbers and bool convert, text is
parsed. Anything else gives 0.0.
Sourcepub fn bool(&self, index: usize) -> bool
pub fn bool(&self, index: usize) -> bool
The value at index as bool. Numbers are true when not zero, text when it is
"true". Anything else gives false.
Sourcepub fn text(&self, index: usize) -> &str
pub fn text(&self, index: usize) -> &str
The value at index as text, or "" if it is not text.
Examples found in repository?
147 fn host_events(&mut self, event: &NetEvent, ctx: &mut Context) {
148 match event {
149 NetEvent::Connected(id) => {
150 let name = ctx.net.name(*id).to_string();
151 ctx.speak(format!("{name} joined"));
152 // Tell the newcomer about everybody, and everybody about the newcomer.
153 ctx.net.send(*id, Packet::new("player").with(PeerId::SERVER).with(ctx.net.name(PeerId::SERVER)).with(self.position));
154 for (other, o) in &self.others {
155 ctx.net.send(*id, Packet::new("player").with(*other).with(&o.name).with(o.position));
156 }
157 ctx.net.send_all_except(*id, Packet::new("player").with(*id).with(&name).with(Vec3::ZERO));
158 self.add(ctx, *id, &name, Vec3::ZERO);
159 }
160 NetEvent::Message(from, packet) => match packet.kind() {
161 "move" => {
162 self.moved(*from, packet.vec3(0));
163 ctx.net.send_all_except(*from, Packet::new("pos").with(*from).with(packet.vec3(0)));
164 }
165 "chat" => {
166 let text = packet.text(0);
167 ctx.play("chat");
168 ctx.speak(format!("{}: {text}", self.name(ctx, *from)));
169 ctx.net.send_all_except(*from, Packet::new("chat").with(*from).with(text));
170 }
171 _ => {}
172 },
173 NetEvent::Disconnected(id, _) => {
174 self.remove(ctx, *id);
175 ctx.net.send_all(Packet::new("gone").with(*id));
176 }
177 }
178 }
179
180 /// The client's side of the protocol.
181 fn client_events(&mut self, event: &NetEvent, ctx: &mut Context) {
182 match event {
183 NetEvent::Message(_, packet) => match packet.kind() {
184 "player" => self.add(ctx, packet.peer(0), packet.text(1), packet.vec3(2)),
185 "pos" => self.moved(packet.peer(0), packet.vec3(1)),
186 "gone" => self.remove(ctx, packet.peer(0)),
187 "chat" => {
188 ctx.play("chat");
189 ctx.speak(format!("{}: {}", self.name(ctx, packet.peer(0)), packet.text(1)));
190 }
191 _ => {}
192 },
193 NetEvent::Disconnected(_, reason) => {
194 ctx.speak(ctx.lang.describe_reason(reason));
195 ctx.audio.stop_all();
196 let scene = Lobby::new(ctx);
197 ctx.switch_scene(scene);
198 }
199 NetEvent::Connected(_) => {}
200 }
201 }Sourcepub fn vec2(&self, index: usize) -> Vec2
pub fn vec2(&self, index: usize) -> Vec2
The value at index as a 2D vector. A 3D vector loses its z. Anything else gives
Vec2::ZERO.
Sourcepub fn vec3(&self, index: usize) -> Vec3
pub fn vec3(&self, index: usize) -> Vec3
The value at index as a 3D vector. A 2D vector gets z = 0. Anything else gives
Vec3::ZERO.
Examples found in repository?
147 fn host_events(&mut self, event: &NetEvent, ctx: &mut Context) {
148 match event {
149 NetEvent::Connected(id) => {
150 let name = ctx.net.name(*id).to_string();
151 ctx.speak(format!("{name} joined"));
152 // Tell the newcomer about everybody, and everybody about the newcomer.
153 ctx.net.send(*id, Packet::new("player").with(PeerId::SERVER).with(ctx.net.name(PeerId::SERVER)).with(self.position));
154 for (other, o) in &self.others {
155 ctx.net.send(*id, Packet::new("player").with(*other).with(&o.name).with(o.position));
156 }
157 ctx.net.send_all_except(*id, Packet::new("player").with(*id).with(&name).with(Vec3::ZERO));
158 self.add(ctx, *id, &name, Vec3::ZERO);
159 }
160 NetEvent::Message(from, packet) => match packet.kind() {
161 "move" => {
162 self.moved(*from, packet.vec3(0));
163 ctx.net.send_all_except(*from, Packet::new("pos").with(*from).with(packet.vec3(0)));
164 }
165 "chat" => {
166 let text = packet.text(0);
167 ctx.play("chat");
168 ctx.speak(format!("{}: {text}", self.name(ctx, *from)));
169 ctx.net.send_all_except(*from, Packet::new("chat").with(*from).with(text));
170 }
171 _ => {}
172 },
173 NetEvent::Disconnected(id, _) => {
174 self.remove(ctx, *id);
175 ctx.net.send_all(Packet::new("gone").with(*id));
176 }
177 }
178 }
179
180 /// The client's side of the protocol.
181 fn client_events(&mut self, event: &NetEvent, ctx: &mut Context) {
182 match event {
183 NetEvent::Message(_, packet) => match packet.kind() {
184 "player" => self.add(ctx, packet.peer(0), packet.text(1), packet.vec3(2)),
185 "pos" => self.moved(packet.peer(0), packet.vec3(1)),
186 "gone" => self.remove(ctx, packet.peer(0)),
187 "chat" => {
188 ctx.play("chat");
189 ctx.speak(format!("{}: {}", self.name(ctx, packet.peer(0)), packet.text(1)));
190 }
191 _ => {}
192 },
193 NetEvent::Disconnected(_, reason) => {
194 ctx.speak(ctx.lang.describe_reason(reason));
195 ctx.audio.stop_all();
196 let scene = Lobby::new(ctx);
197 ctx.switch_scene(scene);
198 }
199 NetEvent::Connected(_) => {}
200 }
201 }Sourcepub fn peer(&self, index: usize) -> PeerId
pub fn peer(&self, index: usize) -> PeerId
The value at index as a player id (stored with .with(peer)). Anything that is not
a valid number gives PeerId::SERVER.
Examples found in repository?
181 fn client_events(&mut self, event: &NetEvent, ctx: &mut Context) {
182 match event {
183 NetEvent::Message(_, packet) => match packet.kind() {
184 "player" => self.add(ctx, packet.peer(0), packet.text(1), packet.vec3(2)),
185 "pos" => self.moved(packet.peer(0), packet.vec3(1)),
186 "gone" => self.remove(ctx, packet.peer(0)),
187 "chat" => {
188 ctx.play("chat");
189 ctx.speak(format!("{}: {}", self.name(ctx, packet.peer(0)), packet.text(1)));
190 }
191 _ => {}
192 },
193 NetEvent::Disconnected(_, reason) => {
194 ctx.speak(ctx.lang.describe_reason(reason));
195 ctx.audio.stop_all();
196 let scene = Lobby::new(ctx);
197 ctx.switch_scene(scene);
198 }
199 NetEvent::Connected(_) => {}
200 }
201 }Trait Implementations§
impl StructuralPartialEq for Packet
Auto Trait Implementations§
impl Freeze for Packet
impl RefUnwindSafe for Packet
impl Send for Packet
impl Sync for Packet
impl Unpin for Packet
impl UnsafeUnpin for Packet
impl UnwindSafe for Packet
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.