-
Notifications
You must be signed in to change notification settings - Fork 26
Huge Update #2 #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 37 commits
4484398
13e25f7
7f20c12
8751315
855596d
863054b
d9d9e36
d87eaac
cd8b9c8
a708198
bb88b65
bcae5cf
5f6dcf8
09c2811
e330de1
f20b568
8e24687
7d561be
4e4b19b
dc531b3
82c8168
62e346a
d49a232
e21bd2c
ef071c8
577d7bd
e9324cf
3080364
4b25ddc
4efa37f
d21b063
01fe79d
da58586
f77df67
5aad870
e765e0f
b448b18
62eb1d8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,64 +1,115 @@ | ||
| #![allow(non_upper_case_globals)] | ||
| use enet_sys::{ | ||
| ENetEvent, _ENetEventType_ENET_EVENT_TYPE_CONNECT, _ENetEventType_ENET_EVENT_TYPE_DISCONNECT, | ||
| _ENetEventType_ENET_EVENT_TYPE_NONE, _ENetEventType_ENET_EVENT_TYPE_RECEIVE, | ||
| }; | ||
|
|
||
| use crate::{Packet, Peer}; | ||
| use crate::{Host, Packet, Peer, PeerID}; | ||
|
|
||
| /// This enum represents an event that can occur when servicing an `EnetHost`. | ||
| /// | ||
| /// Also see the official ENet documentation for more information. | ||
| /// This struct represents an event that can occur when servicing an `Host`. | ||
LeonMatthes marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| #[derive(Debug)] | ||
| pub enum Event<'a, T> { | ||
| /// This variant represents the connection of a peer, contained in the only | ||
| /// field. | ||
| Connect(Peer<'a, T>), | ||
| /// This variant represents the disconnection of a peer, either because it | ||
| /// was requested or due to a timeout. | ||
| /// | ||
| /// The disconnected peer is contained in the first field, while the second | ||
| /// field contains the user-specified data for this disconnection. | ||
| Disconnect(Peer<'a, T>, u32), | ||
| /// This variants repersents a packet that was received. | ||
| pub struct Event<'a, T> { | ||
| peer: &'a mut Peer<T>, | ||
| peer_id: PeerID, | ||
| kind: EventKind, | ||
| } | ||
|
|
||
| /// The type of an event. | ||
| #[derive(Debug)] | ||
| pub enum EventKind { | ||
| /// Peer has connected. | ||
| Connect, | ||
| /// Peer has disconnected. | ||
| // | ||
| /// The data of the peer will be dropped when the received `Event` is dropped. | ||
LeonMatthes marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Disconnect { | ||
| /// The data associated with this event. Usually a reason for disconnection. | ||
| data: u32, | ||
| }, | ||
| /// Peer has received a packet. | ||
| Receive { | ||
| /// The `Peer` that sent the packet. | ||
| sender: Peer<'a, T>, | ||
| /// The channel on which the packet was received. | ||
| /// ID of the channel that the packet was received on. | ||
| channel_id: u8, | ||
| /// The `Packet` that was received. | ||
| packet: Packet, | ||
| }, | ||
| } | ||
|
|
||
| impl<'a, T> Event<'a, T> { | ||
| pub(crate) fn from_sys_event<'b>(event_sys: &'b ENetEvent) -> Option<Event<'a, T>> { | ||
| #[allow(non_upper_case_globals)] | ||
| match event_sys.type_ { | ||
| _ENetEventType_ENET_EVENT_TYPE_NONE => None, | ||
| _ENetEventType_ENET_EVENT_TYPE_CONNECT => { | ||
| Some(Event::Connect(Peer::new(event_sys.peer))) | ||
| } | ||
| _ENetEventType_ENET_EVENT_TYPE_DISCONNECT => { | ||
| Some(Event::Disconnect(Peer::new(event_sys.peer), event_sys.data)) | ||
| } | ||
| _ENetEventType_ENET_EVENT_TYPE_RECEIVE => Some(Event::Receive { | ||
| sender: Peer::new(event_sys.peer), | ||
| pub(crate) fn from_sys_event(event_sys: ENetEvent, host: &'a Host<T>) -> Option<Event<'a, T>> { | ||
| if event_sys.type_ == _ENetEventType_ENET_EVENT_TYPE_NONE { | ||
| return None; | ||
| } | ||
|
|
||
| let peer = unsafe { Peer::new_mut(&mut *event_sys.peer) }; | ||
| let peer_id = unsafe { host.peer_id(event_sys.peer) }; | ||
| let kind = match event_sys.type_ { | ||
| _ENetEventType_ENET_EVENT_TYPE_CONNECT => EventKind::Connect, | ||
| _ENetEventType_ENET_EVENT_TYPE_DISCONNECT => EventKind::Disconnect { | ||
| data: event_sys.data, | ||
| }, | ||
| _ENetEventType_ENET_EVENT_TYPE_RECEIVE => EventKind::Receive { | ||
| channel_id: event_sys.channelID, | ||
| packet: Packet::from_sys_packet(event_sys.packet), | ||
| }), | ||
| }, | ||
| _ => panic!("unrecognized event type: {}", event_sys.type_), | ||
| }; | ||
|
|
||
| Some(Event { | ||
| peer, | ||
| peer_id, | ||
| kind, | ||
| }) | ||
| } | ||
|
|
||
| /// The peer that this event happened on. | ||
| pub fn peer(&'_ self) -> &'_ Peer<T> { | ||
| &*self.peer | ||
| } | ||
|
|
||
| /// The peer that this event happened on. | ||
| pub fn peer_mut(&'_ mut self) -> &'_ mut Peer<T> { | ||
| self.peer | ||
| } | ||
|
|
||
| /// The `PeerID` of the peer that this event happened on. | ||
| pub fn peer_id(&self) -> PeerID { | ||
| self.peer_id | ||
| } | ||
|
|
||
| /// The type of this event. | ||
| pub fn kind(&self) -> &EventKind { | ||
| &self.kind | ||
| } | ||
|
|
||
| /// Take the EventKind out of this event. | ||
| /// If this peer is a Disconnect event, it will clean up the Peer. | ||
| /// See the `Drop` implementation | ||
| pub fn take_kind(mut self) -> EventKind { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is your use case for requiring this method? I would guess you want to take out the packet from a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that was my use case. I'm sending all received event kinds for each peer through crossbeam channels, such that my Peers just boil down to a single crossbeam receiver. Which is very multi-threading friendly. That's why I need to be able to take ownership of the EventKind. |
||
| // Unfortunately we can't simply take the `kind` out of the Event, as otherwise the `Drop` | ||
| // implementation would no longer work. | ||
| // We can however, swap the actual EventKind with an empty EventKind (in this case | ||
| // Connect). | ||
| // As the `Drop` implementation will then do nothing, we need to call cleanup_after_disconnect before we do the swap. | ||
| self.cleanup_after_disconnect(); | ||
|
|
||
| let mut kind = EventKind::Connect; | ||
| std::mem::swap(&mut kind, &mut self.kind); | ||
LeonMatthes marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| kind | ||
| } | ||
|
|
||
| fn cleanup_after_disconnect(&mut self) { | ||
| match self.kind { | ||
| EventKind::Disconnect { .. } => self.peer.cleanup_after_disconnect(), | ||
| EventKind::Connect | EventKind::Receive { .. } => {} | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Dropping an `Event` with `EventKind::Disconnect` will clean up the Peer, by dropping | ||
| /// the data associated with the `Peer`, as well as invalidating the `PeerID`. | ||
| impl<'a, T> Drop for Event<'a, T> { | ||
| fn drop(&mut self) { | ||
| // Seemingly, the lifetime of an ENetPeer ends with the end of the Disconnect | ||
| // event. However, this is *not really clear* in the ENet docs! | ||
| // It looks like the Peer *might* live longer, but not shorter, so it should be | ||
| // safe to destroy the associated data (if any) here. | ||
| if let Event::Disconnect(peer, _) = self { | ||
| peer.set_data(None) | ||
| } | ||
| self.cleanup_after_disconnect(); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.