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

net.pechorina.kairos.automat.SyncAutomat.kt Maven / Gradle / Ivy

The newest version!
package net.pechorina.kairos.automat

import mu.KotlinLogging
import net.pechorina.kairos.automat.listeners.AutomatListener
import java.util.UUID
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference

class SyncAutomat(
        val states: Set>,
        val id: String = UUID.randomUUID().toString(),
        val name: String? = null
) : Automat {

    private val current: AtomicReference> = AtomicReference()
    private val extendedState: ExtendedState
    private val running: AtomicBoolean = AtomicBoolean(false)
    private val listeners: MutableList> = arrayListOf()
    private val initial: State
    private val endStates: Set>

    init {
        this.running.set(false)
        this.initial = states.first { it.initialState }
        this.endStates = states.filter { it.finalState }.toSet()
        this.current.set(initial)
        this.extendedState = ExtendedState(this)
    }

    override fun id(): String {
        return this.id
    }

    override fun name(): String? {
        return this.name
    }

    override fun start() {
        this.running.set(true)
        listeners.forEach { it.stateMachineStarted(this) }
    }

    override fun stop() {
        this.running.set(false)
        listeners.forEach { it.stateMachineStopped(this) }
    }

    override fun reset() {
        this.current.set(initial)
    }

    override fun isRunning(): Boolean {
        return this.running.get()
    }

    override fun currentState(): S {
        return this.current.get().value
    }

    override fun finalStates(): Set {
        return this.endStates.map { it.value }.toSet()
    }

    override fun initialState(): S {
        return this.initial.value
    }

    override fun extendedState(): ExtendedState {
        return this.extendedState
    }

    @Synchronized
    override fun sendEvent(event: E) {
        val payloadEvent = PayloadEvent(event)
        listeners().forEach { it.newEvent(payloadEvent) }

        if (!running.get()) {
            log.trace { "Machine is not running" }
            return
        }

        if (current.get().finalState) {
            log.trace { "Machine is in final state: ${currentState()}" }
            return
        }

        val transition = current.get().findTransition(payloadEvent)
        if (transition == null) {
            listeners.forEach { it.eventNotAccepted(payloadEvent) }
            return
        }

        listeners.forEach { it.transitionStarted(transition) }

        this.current.set(
                transition.transit(this)
        )

        listeners.forEach { it.transitionEnded(transition) }

        if (this.current.get().finalState) {
            log.trace { "Machine reached the final state: ${this.current.get()}}" }
            stop()
        }
    }

    override fun listeners(): List> {
        return listeners
    }

    override fun addListener(listener: AutomatListener) {
        this.listeners.add(listener)
    }

    companion object {
        val log = KotlinLogging.logger {}
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy