All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.pubnub.api.presence.eventengine.state.PresenceState.kt Maven / Gradle / Ivy

Go to download

PubNub is a cross-platform client-to-client (1:1 and 1:many) push service in the cloud, capable of broadcasting real-time messages to millions of web and mobile clients simultaneously, in less than a quarter second!

There is a newer version: 10.2.0
Show newest version
package com.pubnub.api.presence.eventengine.state

import com.pubnub.api.PubNubException
import com.pubnub.api.eventengine.State
import com.pubnub.api.eventengine.noTransition
import com.pubnub.api.eventengine.transitionTo
import com.pubnub.api.presence.eventengine.effect.PresenceEffectInvocation
import com.pubnub.api.presence.eventengine.event.PresenceEvent

internal sealed class PresenceState : State {
    object HeartbeatInactive : PresenceState() {
        override fun transition(event: PresenceEvent): Pair> {
            return when (event) {
                is PresenceEvent.Joined -> {
                    transitionTo(Heartbeating(event.channels, event.channelGroups))
                }
                else -> {
                    noTransition()
                }
            }
        }
    }

    data class Heartbeating(
        val channels: Set,
        val channelGroups: Set
    ) : PresenceState() {
        override fun onEntry(): Set = setOf(PresenceEffectInvocation.Heartbeat(channels, channelGroups))

        override fun transition(event: PresenceEvent): Pair> {
            return when (event) {
                is PresenceEvent.LeftAll -> {
                    transitionTo(HeartbeatInactive, PresenceEffectInvocation.Leave(channels, channelGroups))
                }
                is PresenceEvent.Disconnect -> {
                    transitionTo(HeartbeatStopped(channels, channelGroups), PresenceEffectInvocation.Leave(channels, channelGroups))
                }
                is PresenceEvent.Joined -> {
                    transitionTo(Heartbeating(channels + event.channels, channelGroups + event.channelGroups))
                }
                is PresenceEvent.Left -> {
                    transitionTo(Heartbeating(channels - event.channels, channelGroups - event.channelGroups), PresenceEffectInvocation.Leave(event.channels, event.channelGroups))
                }
                is PresenceEvent.StateSet -> {
                    transitionTo(Heartbeating(event.channels, event.channelGroups))
                }
                is PresenceEvent.HeartbeatSuccess -> {
                    transitionTo(HeartbeatCooldown(channels, channelGroups))
                }
                is PresenceEvent.HeartbeatFailure -> {
                    transitionTo(HeartbeatReconnecting(channels, channelGroups, 0, event.reason))
                }
                else -> {
                    noTransition()
                }
            }
        }
    }

    data class HeartbeatReconnecting(
        val channels: Set,
        val channelGroups: Set,
        val attempts: Int,
        val reason: PubNubException?
    ) : PresenceState() {
        override fun onEntry(): Set = setOf(PresenceEffectInvocation.DelayedHeartbeat(channels, channelGroups, attempts, reason))
        override fun onExit(): Set = setOf(PresenceEffectInvocation.CancelDelayedHeartbeat)

        override fun transition(event: PresenceEvent): Pair> {
            return when (event) {
                is PresenceEvent.Joined -> {
                    transitionTo(Heartbeating(channels + event.channels, channelGroups + event.channelGroups))
                }
                is PresenceEvent.Left -> {
                    transitionTo(Heartbeating(channels - event.channels, channelGroups - event.channelGroups), PresenceEffectInvocation.Leave(event.channels, event.channelGroups))
                }
                is PresenceEvent.StateSet -> {
                    transitionTo(Heartbeating(event.channels, event.channelGroups))
                }
                is PresenceEvent.HeartbeatSuccess -> {
                    transitionTo(HeartbeatCooldown(channels, channelGroups))
                }
                is PresenceEvent.HeartbeatFailure -> {
                    transitionTo(HeartbeatReconnecting(channels, channelGroups, attempts + 1, event.reason))
                }
                is PresenceEvent.HeartbeatGiveup -> {
                    transitionTo(HeartbeatFailed(channels, channelGroups, event.reason))
                }
                is PresenceEvent.Disconnect -> {
                    transitionTo(HeartbeatStopped(channels, channelGroups), PresenceEffectInvocation.Leave(channels, channelGroups))
                }
                is PresenceEvent.LeftAll -> {
                    transitionTo(HeartbeatInactive, PresenceEffectInvocation.Leave(channels, channelGroups))
                }
                else -> {
                    noTransition()
                }
            }
        }
    }

    data class HeartbeatStopped(
        val channels: Set,
        val channelGroups: Set
    ) : PresenceState() {
        override fun transition(event: PresenceEvent): Pair> {
            return when (event) {
                is PresenceEvent.LeftAll -> {
                    transitionTo(HeartbeatInactive)
                }
                is PresenceEvent.Joined -> {
                    transitionTo(HeartbeatStopped(channels + event.channels, channelGroups + event.channelGroups))
                }
                is PresenceEvent.Left -> {
                    transitionTo(HeartbeatStopped(channels - event.channels, channelGroups - event.channelGroups))
                }
                is PresenceEvent.StateSet -> {
                    transitionTo(HeartbeatStopped(event.channels, event.channelGroups))
                }
                is PresenceEvent.Reconnect -> {
                    transitionTo(Heartbeating(channels, channelGroups))
                }
                else -> {
                    noTransition()
                }
            }
        }
    }

    data class HeartbeatFailed(
        val channels: Set,
        val channelGroups: Set,
        val reason: PubNubException?
    ) : PresenceState() {
        override fun transition(event: PresenceEvent): Pair> {
            return when (event) {
                is PresenceEvent.LeftAll -> {
                    transitionTo(HeartbeatInactive, PresenceEffectInvocation.Leave(channels, channelGroups))
                }
                is PresenceEvent.Joined -> {
                    transitionTo(Heartbeating(channels + event.channels, channelGroups + event.channelGroups))
                }
                is PresenceEvent.Left -> {
                    transitionTo(Heartbeating(channels - event.channels, channelGroups - event.channelGroups), PresenceEffectInvocation.Leave(event.channels, event.channelGroups))
                }
                is PresenceEvent.StateSet -> {
                    transitionTo(Heartbeating(event.channels, event.channelGroups))
                }
                is PresenceEvent.Reconnect -> {
                    transitionTo(Heartbeating(channels, channelGroups))
                }
                is PresenceEvent.Disconnect -> {
                    transitionTo(HeartbeatStopped(channels, channelGroups), PresenceEffectInvocation.Leave(channels, channelGroups))
                }
                else -> {
                    noTransition()
                }
            }
        }
    }

    data class HeartbeatCooldown(
        val channels: Set,
        val channelGroups: Set
    ) : PresenceState() {
        override fun onEntry(): Set = setOf(PresenceEffectInvocation.Wait())
        override fun onExit(): Set = setOf(PresenceEffectInvocation.CancelWait)

        override fun transition(event: PresenceEvent): Pair> {
            return when (event) {
                is PresenceEvent.Joined -> {
                    transitionTo(Heartbeating(channels + event.channels, channelGroups + event.channelGroups))
                }
                is PresenceEvent.Left -> {
                    transitionTo(Heartbeating(channels - event.channels, channelGroups - event.channelGroups), PresenceEffectInvocation.Leave(event.channels, event.channelGroups))
                }
                is PresenceEvent.StateSet -> {
                    transitionTo(Heartbeating(event.channels, event.channelGroups))
                }
                is PresenceEvent.TimesUp -> {
                    transitionTo(Heartbeating(channels, channelGroups))
                }
                is PresenceEvent.Disconnect -> {
                    transitionTo(HeartbeatStopped(channels, channelGroups), PresenceEffectInvocation.Leave(channels, channelGroups))
                }
                is PresenceEvent.LeftAll -> {
                    transitionTo(HeartbeatInactive, PresenceEffectInvocation.Leave(channels, channelGroups))
                }
                else -> {
                    noTransition()
                }
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy