Class: RGame::Engine::Scene::SceneStack

Inherits:
Component
  • Object
show all
Defined in:
lib/rgame/engine/scene/scene_stack.rb

Instance Attribute Summary

Attributes inherited from Component

#node

Instance Method Summary collapse

Methods inherited from Component

#context, #on_detach

Methods included from RGame::Engine::Signal::DSL

#signal

Constructor Details

#initializeSceneStack

Returns a new instance of SceneStack.



7
8
9
10
11
# File 'lib/rgame/engine/scene/scene_stack.rb', line 7

def initialize
  super
  @stack = []
  @players = nil
end

Instance Method Details

#control(actions) ⇒ Object

Scenes live off the host's child list, so the traversal does not reach them on its own — and what has to reach them is the input source, not the snapshot this component was handed.

A component receives one player's resolved Actions, which is right for a component: it belongs to exactly one node. A scene is a whole subtree and may contain nodes owned by different players, so handing it a single snapshot would flatten all of them onto whoever owns the host. The registry is pulled from the tree instead, the same way any system is, and passed down so each node in the scene resolves its own.

Without a registry — a spec driving a stack with a bare snapshot — the snapshot is passed on, which is exactly what it means: one answer for everyone.



58
59
60
61
62
# File 'lib/rgame/engine/scene/scene_stack.rb', line 58

def control(actions)
  return unless (current_scene = current)

  current_scene.control(@players || actions)
end

#currentObject



40
41
42
# File 'lib/rgame/engine/scene/scene_stack.rb', line 40

def current
  @stack.last
end

#draw(renderer, view) ⇒ Object

Every scene in the stack, not just the current one — that asymmetry with control/update is what lets a menu pushed on top keep the world visible underneath while freezing it.



73
74
75
76
77
# File 'lib/rgame/engine/scene/scene_stack.rb', line 73

def draw(renderer, view)
  @stack.each do |scene|
    scene.draw(renderer, view)
  end
end

#on_attachObject

See #control: the scenes this holds need the input source, and a component is only handed one player's snapshot.



15
# File 'lib/rgame/engine/scene/scene_stack.rb', line 15

def on_attach = @players = node.system(Engine::Players)

#popObject



25
26
27
28
29
30
31
32
33
# File 'lib/rgame/engine/scene/scene_stack.rb', line 25

def pop
  scene = @stack.pop
  return self unless scene

  scene.exit_tree              # cascades on_remove/on_detach, releasing systems
  scene.scene = nil
  scene.parent = nil
  self
end

#push(scene) ⇒ Object



17
18
19
20
21
22
23
# File 'lib/rgame/engine/scene/scene_stack.rb', line 17

def push(scene)
  @stack.push(scene)
  scene.parent = node          # so scene.root resolves up to the host
  scene.scene = scene          # mark the scene as its subtree's scene boundary
  scene.enter_tree             # cascades on_attach/on_add through the scene
  self
end

#replace(scene) ⇒ Object



35
36
37
38
# File 'lib/rgame/engine/scene/scene_stack.rb', line 35

def replace(scene)
  pop
  push(scene)
end

#sweep_freedObject

Scenes live in @stack, off the host's child list, so the host's #sweep_freed can't reach them — forward the sweep into the active scene's subtree.



81
82
83
# File 'lib/rgame/engine/scene/scene_stack.rb', line 81

def sweep_freed
  current&.sweep_freed
end

#update(dt) ⇒ Object



64
65
66
67
68
# File 'lib/rgame/engine/scene/scene_stack.rb', line 64

def update(dt)
  return unless (current_scene = current)

  current_scene.update(dt)
end