Coeur-Morny-Cono/src/main/scala/cc/sukazyo/cono/morny/bot/api/EventEnv.scala
Eyre_S c5c6683459
for event, fix wrong OK stats, add CANCELED tag
- Now the status of EventEnv is a State array that infers the state history
  - State can be OK or CANCELED, and can be set multiple times
  - state method can get the last state set, and status method can get the state history
  - Default EventListener.executeFilter implementation is changed to true if stats is null
- add consume[T](T=>Unit) for EventEnv, to simplifying the old consume[T](Class[T])(T=>Unit)
- changed execution sort of EventListener in EventListenerManager. Now atEventPost method will be run after all events' normal listeners complete.
- cha OnMedicationNotifyApply will only tag event as OK when the refresh function works (fixed part of the wrong OK state)
- cha MornyOnUpdateTimestampOffsetLock tag event CANCELED but not OK to fix part of the wrong OK state
2023-11-20 11:18:32 +08:00

66 lines
1.8 KiB
Scala

package cc.sukazyo.cono.morny.bot.api
import cc.sukazyo.cono.morny.util.EpochDateTime.EpochMillis
import cc.sukazyo.messiva.utils.StackUtils
import com.pengrad.telegrambot.model.Update
import scala.collection.mutable
import scala.reflect.{classTag, ClassTag}
class EventEnv (
val update: Update
) {
trait StateSource (val from: StackTraceElement)
enum State:
case OK (_from: StackTraceElement) extends State with StateSource(_from)
case CANCELED (_from: StackTraceElement) extends State with StateSource(_from)
private val _status: mutable.ListBuffer[State] = mutable.ListBuffer.empty
private val variables: mutable.HashMap[Class[?], Any] = mutable.HashMap.empty
val timeStartup: EpochMillis = System.currentTimeMillis
def isEventOk: Boolean = _status.lastOption match
case Some(x) if x == State.OK => true
case _ => false
//noinspection UnitMethodIsParameterless
def setEventOk: Unit =
_status += State.OK(StackUtils.getStackTrace(1)(1))
//noinspection UnitMethodIsParameterless
def setEventCanceled: Unit =
_status += State.CANCELED(StackUtils.getStackTrace(1)(1))
def state: State|Null =
_status.lastOption match
case Some(x) => x
case None => null
def status: List[State] =
_status.toList
def provide (i: Any): Unit =
variables += (i.getClass -> i)
def consume [T] (t: Class[T]) (consumer: T => Unit): ConsumeResult = {
variables get t match
case Some(i) => consumer(i.asInstanceOf[T]); ConsumeResult(true)
case None => ConsumeResult(false)
}
def consume [T: ClassTag] (consumer: T => Unit): ConsumeResult =
variables get classTag[T].runtimeClass match
case Some(i) => consumer(i.asInstanceOf[T]); ConsumeResult(true)
case None => ConsumeResult(false)
class ConsumeResult (success: Boolean) {
def onfail (processor: => Unit): Unit = {
if !success then processor
}
}
}