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

commonMain.it.unibo.tuprolog.solve.channel.impl.AbstractInputChannel.kt Maven / Gradle / Ivy

There is a newer version: 1.0.4
Show newest version
package it.unibo.tuprolog.solve.channel.impl

import it.unibo.tuprolog.core.Struct
import it.unibo.tuprolog.solve.channel.InputChannel
import it.unibo.tuprolog.utils.dequeOf
import it.unibo.tuprolog.utils.synchronizedOnSelf
import it.unibo.tuprolog.utils.takeFirst

abstract class AbstractInputChannel : AbstractChannel(), InputChannel {
    private val queue: MutableList = dequeOf()

    override val available: Boolean
        get() = synchronizedOnSelf { if (isClosed) throw IllegalStateException("Input channel is closed") else true }

    protected abstract fun readActually(): T?

    final override fun read(): T? =
        synchronizedOnSelf {
            if (isClosed) throw IllegalStateException("Input channel is closed")
            refillQueueIfNecessary()
            val read = queue.takeFirst()
            notify(read)
            read
        }

    final override fun peek(): T? =
        synchronizedOnSelf {
            if (isClosed) throw IllegalStateException("Input channel is closed")
            refillQueueIfNecessary()
            queue[0]
        }

    private fun refillQueue() {
        queue.add(readActually())
    }

    private fun refillQueueIfNecessary() {
        if (queue.isEmpty()) {
            refillQueue()
        }
    }

    override val isOver: Boolean
        get() =
            synchronizedOnSelf {
                if (isClosed) throw IllegalStateException("Input channel is closed")
                refillQueueIfNecessary()
                queue.first() == null
            }

    override fun toString(): String = "${this::class.simpleName}(id=$id, available=$available, closed=$isClosed)"

    override val streamTerm: Struct by lazy { InputChannel.streamTerm(id) }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy