aboutsummaryrefslogtreecommitdiff
path: root/src/test/scala/sims/test/gui/events.scala
blob: 22015ceaeaefe5857f1ad8a38650f14cdd46f3fb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package sims.test.gui

import scala.collection.mutable.ListBuffer
import sims.dynamics._

trait Event
case class BodyAdded(world: World, body: Body) extends Event
case class BodyRemoved(world: World, body: Body) extends Event
case class Stepped(wordl: World) extends Event
case class JointAdded(world: World, joint: Joint) extends Event
case class JointRemoved(world: World, joint: Joint) extends Event

object Reactions {
	class Impl extends Reactions {
		private val parts = new ListBuffer[Reaction]
		def isDefinedAt(e: Event) = parts exists (_ isDefinedAt e)
		def +=(r: Reaction) = parts += r
		def -=(r: Reaction) = parts -= r
		def clear() = parts.clear()
		def apply(e: Event) {
			for (p <- parts; if p isDefinedAt e) p(e)
		}
	}
	type Reaction = PartialFunction[Event, Unit]
}

abstract class Reactions extends Reactions.Reaction {
	def +=(r: Reactions.Reaction): Unit
	def -=(r: Reactions.Reaction): Unit
	def clear(): Unit
}

trait Reactor {
	val reactions: Reactions = new Reactions.Impl 
	
	def listenTo(ps: Publisher*) = for (p <- ps) p.subscribe(reactions)
	def deafTo(ps: Publisher*) = for (p <- ps) p.unsubscribe(reactions)
}

trait Publisher {
	import Reactions._
	
	private val listeners = new ListBuffer[Reaction]
	
	def subscribe(listener: Reaction) = listeners += listener
	def unsubscribe(listener: Reaction) = listeners -= listener
	
	def publish(e: Event) { for (l <- listeners) l(e) }
}