use crate::{errors::SdkError, events::SessionStatus};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum LifecycleEvent {
Connected,
NetworkLost,
Backgrounded,
Foregrounded,
RemoteExit,
Cancelled,
Failed,
Closed,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Lifecycle {
status: SessionStatus,
input_generation: u64,
transport_open: bool,
}
impl Default for Lifecycle {
fn default() -> Self {
Self::new()
}
}
impl Lifecycle {
pub const fn new() -> Self {
Self {
status: SessionStatus::Connecting,
input_generation: 0,
transport_open: false,
}
}
pub const fn status(self) -> SessionStatus {
self.status
}
pub const fn input_generation(self) -> u64 {
self.input_generation
}
pub const fn transport_open(self) -> bool {
self.transport_open
}
pub fn transition(&mut self, event: LifecycleEvent) -> Result<SessionStatus, SdkError> {
let next = match (self.status, event) {
(SessionStatus::Connecting, LifecycleEvent::Connected) => {
self.transport_open = true;
SessionStatus::Live
}
(SessionStatus::Live, LifecycleEvent::NetworkLost)
| (SessionStatus::Suspended, LifecycleEvent::Foregrounded) => {
self.transport_open = false;
SessionStatus::Recovering
}
(SessionStatus::Live, LifecycleEvent::Backgrounded) => {
self.invalidate_input();
self.transport_open = false;
SessionStatus::Suspended
}
(SessionStatus::Recovering, LifecycleEvent::Connected) => {
self.transport_open = true;
SessionStatus::Live
}
(_, LifecycleEvent::RemoteExit | LifecycleEvent::Closed) => {
self.transport_open = false;
SessionStatus::Closed
}
(_, LifecycleEvent::Cancelled | LifecycleEvent::Failed) => {
self.transport_open = false;
SessionStatus::Failed
}
(SessionStatus::Recovering, LifecycleEvent::Backgrounded) => {
self.invalidate_input();
self.transport_open = false;
SessionStatus::Suspended
}
(status, _) => {
return Err(if status == SessionStatus::Closed {
SdkError::SessionClosed
} else {
SdkError::TransportUnavailable
});
}
};
self.status = next;
Ok(next)
}
fn invalidate_input(&mut self) {
self.input_generation = self.input_generation.saturating_add(1);
}
}