aboutsummaryrefslogtreecommitdiff
path: root/src/test/scala/sims/test/gui/SceneManager.scala
blob: 39da30884f341c906bc8f0f2f5dc8fff9b3bc1c5 (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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package sims.test.gui

import processing.core.PApplet
import scala.collection.mutable.ArrayBuffer
import sims.math._
import sims.test.gui.scenes._
import sims.test.gui.RichShape._
import sims.test.gui.RichJoint._

class SceneManager(implicit top: PApplet) {
	
	/* Contains objects that will be rendered on `draw()`. */
	private var _graphicals = new ArrayBuffer[Graphical[_]]
	def graphicals: Seq[Graphical[_]] = _graphicals
	
	/* Current scene. */
	private var _currentScene: Scene = EmptyScene
	
	/* Get current scene. */
	def currentScene = _currentScene
	
	/* Set current scene. */
	def currentScene_=(newScene: Scene) = {
		
		// remove reactions
		currentScene.deafTo(currentScene.world)
		currentScene.reactions.clear()
		
		// empty world
		currentScene.world.clear()
		
		// clear graphical objects
		_graphicals.clear()
		
		// custom exit behavior
		currentScene.exit()
		
		// add new reactions to create / remove graphical objects
		newScene.listenTo(newScene.world)
		newScene.reactions += {
			case BodyAdded(newScene.world, body) => for (s <- body.shapes) _graphicals += s.toGraphical
			case BodyRemoved(newScene.world, body) => for (s <- body.shapes) {
				val index = _graphicals.findIndexOf((g: Graphical[_]) => g match {
					case gs: GraphicalShape => gs.physical == s
					case _ => false
				})
				_graphicals.remove(index)
			}
			
			case JointAdded(newScene.world, joint) => _graphicals += joint.toGraphical
			case JointRemoved(newScene.world, joint) => {
				val index = _graphicals.findIndexOf((g: Graphical[_]) => g match {
					case gj: GraphicalJoint => gj.physical == joint
					case _ => false
				})
				_graphicals.remove(index)
			}
			
		}
		
		// custom initialization
		newScene.init()
		
		// set current scene
		_currentScene = newScene
		
		println("set scene to '" + currentScene.name + "'")
	}
	
	private var currentSceneIndex = 0
	val scenes = List(
			BasicScene,
			CollisionScene,
			LongCollisionScene,
			CloudScene,
			PyramidScene,
			ShiftedStackScene,
			JointScene
		)
		
	def nextScene() = {
		currentSceneIndex += 1
		currentScene = scenes(mod(currentSceneIndex, scenes.length))
	}
	
	def previousScene() = {
		currentSceneIndex -= 1
		currentScene = scenes(mod(currentSceneIndex, scenes.length))
	}
	
	def restartScene() = {
		currentScene = currentScene
	}
	
}