src/Pure/System/event_bus.scala
author wenzelm
Wed, 15 Jun 2011 21:30:15 +0200
changeset 43406 40c67d894be4
parent 38849 2f198d107aef
child 45635 d9cf3520083c
permissions -rw-r--r--
avoid compiler warning -- this is unchecked anyway;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
38428
c13c95c97e89 event_bus.scala rather belongs to system plumbing;
wenzelm
parents: 36676
diff changeset
     1
/*  Title:      Pure/System/event_bus.scala
29190
89217ccfd130 Generic event bus.
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
89217ccfd130 Generic event bus.
wenzelm
parents:
diff changeset
     3
32539
668052c4220e modernized Event_Bus -- based on actors;
wenzelm
parents: 29200
diff changeset
     4
Generic event bus with multiple receiving actors.
29190
89217ccfd130 Generic event bus.
wenzelm
parents:
diff changeset
     5
*/
89217ccfd130 Generic event bus.
wenzelm
parents:
diff changeset
     6
89217ccfd130 Generic event bus.
wenzelm
parents:
diff changeset
     7
package isabelle
89217ccfd130 Generic event bus.
wenzelm
parents:
diff changeset
     8
32539
668052c4220e modernized Event_Bus -- based on actors;
wenzelm
parents: 29200
diff changeset
     9
import scala.actors.Actor, Actor._
29191
de56edf88514 added methods "+" and "-";
wenzelm
parents: 29190
diff changeset
    10
import scala.collection.mutable.ListBuffer
29190
89217ccfd130 Generic event bus.
wenzelm
parents:
diff changeset
    11
89217ccfd130 Generic event bus.
wenzelm
parents:
diff changeset
    12
32539
668052c4220e modernized Event_Bus -- based on actors;
wenzelm
parents: 29200
diff changeset
    13
class Event_Bus[Event]
29200
787ba47201c7 optional exception logging;
wenzelm
parents: 29191
diff changeset
    14
{
32539
668052c4220e modernized Event_Bus -- based on actors;
wenzelm
parents: 29200
diff changeset
    15
  /* receivers */
668052c4220e modernized Event_Bus -- based on actors;
wenzelm
parents: 29200
diff changeset
    16
668052c4220e modernized Event_Bus -- based on actors;
wenzelm
parents: 29200
diff changeset
    17
  private val receivers = new ListBuffer[Actor]
668052c4220e modernized Event_Bus -- based on actors;
wenzelm
parents: 29200
diff changeset
    18
668052c4220e modernized Event_Bus -- based on actors;
wenzelm
parents: 29200
diff changeset
    19
  def += (r: Actor) { synchronized { receivers += r } }
668052c4220e modernized Event_Bus -- based on actors;
wenzelm
parents: 29200
diff changeset
    20
  def + (r: Actor): Event_Bus[Event] = { this += r; this }
29200
787ba47201c7 optional exception logging;
wenzelm
parents: 29191
diff changeset
    21
32539
668052c4220e modernized Event_Bus -- based on actors;
wenzelm
parents: 29200
diff changeset
    22
  def += (f: Event => Unit) {
43406
40c67d894be4 avoid compiler warning -- this is unchecked anyway;
wenzelm
parents: 38849
diff changeset
    23
    this += actor { loop { react { case x => f(x.asInstanceOf[Event]) } } }
32539
668052c4220e modernized Event_Bus -- based on actors;
wenzelm
parents: 29200
diff changeset
    24
  }
29190
89217ccfd130 Generic event bus.
wenzelm
parents:
diff changeset
    25
32539
668052c4220e modernized Event_Bus -- based on actors;
wenzelm
parents: 29200
diff changeset
    26
  def + (f: Event => Unit): Event_Bus[Event] = { this += f; this }
29191
de56edf88514 added methods "+" and "-";
wenzelm
parents: 29190
diff changeset
    27
32539
668052c4220e modernized Event_Bus -- based on actors;
wenzelm
parents: 29200
diff changeset
    28
  def -= (r: Actor) { synchronized { receivers -= r } }
668052c4220e modernized Event_Bus -- based on actors;
wenzelm
parents: 29200
diff changeset
    29
  def - (r: Actor) = { this -= r; this }
29190
89217ccfd130 Generic event bus.
wenzelm
parents:
diff changeset
    30
29200
787ba47201c7 optional exception logging;
wenzelm
parents: 29191
diff changeset
    31
787ba47201c7 optional exception logging;
wenzelm
parents: 29191
diff changeset
    32
  /* event invocation */
787ba47201c7 optional exception logging;
wenzelm
parents: 29191
diff changeset
    33
32539
668052c4220e modernized Event_Bus -- based on actors;
wenzelm
parents: 29200
diff changeset
    34
  def event(x: Event) { synchronized { receivers.foreach(_ ! x) } }
38849
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    35
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    36
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    37
  /* await global condition -- triggered via bus events */
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    38
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    39
  def await(cond: => Boolean)
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    40
  {
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    41
    case object Wait
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    42
    val a = new Actor {
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    43
      def act {
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    44
        if (cond) react { case Wait => reply(()); exit(Wait) }
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    45
        else {
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    46
          loop {
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    47
            react {
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    48
              case trigger if trigger != Wait =>
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    49
                if (cond) { react { case Wait => reply(()); exit(Wait) } }
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    50
            }
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    51
          }
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    52
        }
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    53
      }
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    54
    }
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    55
    this += a
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    56
    a.start
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    57
    a !? Wait
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    58
    this -= a
2f198d107aef session_actor: await state assigment of previous change before signalling current change, and avoid crash in overrun situations;
wenzelm
parents: 38428
diff changeset
    59
  }
29190
89217ccfd130 Generic event bus.
wenzelm
parents:
diff changeset
    60
}