Class: Presently::PresentationController

Inherits:
Object
  • Object
show all
Defined in:
lib/presently/presentation_controller.rb

Overview

Manages the mutable state of a presentation: current slide, clock, and listeners.

Wraps an immutable Presentation and provides navigation, timing, and listener notification. Multiple views (display, presenter) can register as listeners to receive updates.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(presentation, state: nil) ⇒ PresentationController

Initialize a new controller for the given presentation.



19
20
21
22
23
24
25
26
27
# File 'lib/presently/presentation_controller.rb', line 19

def initialize(presentation, state: nil)
	@presentation = presentation
	@current_index = 0
	@clock = Clock.new
	@listeners = []
	@state = state
	
	@state&.restore(self)
end

Instance Attribute Details

#clockObject (readonly)

Returns the value of attribute clock.



36
37
38
# File 'lib/presently/presentation_controller.rb', line 36

def clock
  @clock
end

#current_indexObject (readonly)

Returns the value of attribute current_index.



33
34
35
# File 'lib/presently/presentation_controller.rb', line 33

def current_index
  @current_index
end

#presentationObject (readonly)

Returns the value of attribute presentation.



30
31
32
# File 'lib/presently/presentation_controller.rb', line 30

def presentation
  @presentation
end

#The index of the current slide.(indexofthecurrentslide.) ⇒ Object (readonly)



33
# File 'lib/presently/presentation_controller.rb', line 33

attr :current_index

#The underlying presentation data.(underlyingpresentationdata.) ⇒ Object (readonly)



30
# File 'lib/presently/presentation_controller.rb', line 30

attr :presentation

Instance Method Details

#add_listener(listener) ⇒ Object

Register a listener to be notified when the slide changes. The listener must respond to ‘#slide_changed!`.



149
150
151
# File 'lib/presently/presentation_controller.rb', line 149

def add_listener(listener)
	@listeners << listener
end

#advance!Object

Advance to the next slide.



137
138
139
# File 'lib/presently/presentation_controller.rb', line 137

def advance!
	go_to(@current_index + 1)
end

#current_slideObject

The currently displayed slide.



52
53
54
# File 'lib/presently/presentation_controller.rb', line 52

def current_slide
	@presentation.slides[@current_index]
end

#go_to(index) ⇒ Object

Navigate to a specific slide by index. Ignores out-of-bounds indices. Notifies listeners on change.



129
130
131
132
133
134
# File 'lib/presently/presentation_controller.rb', line 129

def go_to(index)
	return if index < 0 || index >= slide_count
	
	@current_index = index
	notify_listeners!
end

#next_slideObject

The slide following the current one.



58
59
60
# File 'lib/presently/presentation_controller.rb', line 58

def next_slide
	@presentation.slides[@current_index + 1]
end

#pacingObject

The current pacing status relative to the slide timing.



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/presently/presentation_controller.rb', line 100

def pacing
	return :on_time unless @clock.started?
	
	elapsed = @clock.elapsed
	slide_start = @presentation.expected_time_at(@current_index)
	slide_end = @presentation.expected_time_at(@current_index + 1)
	
	if elapsed > slide_end
		:behind
	elsif elapsed < slide_start
		:ahead
	else
		:on_time
	end
end

#previous_slideObject

The slide preceding the current one.



64
65
66
# File 'lib/presently/presentation_controller.rb', line 64

def previous_slide
	@presentation.slides[@current_index - 1] if @current_index > 0
end

#reload!Object

Reload slides from disk and notify listeners.



160
161
162
163
# File 'lib/presently/presentation_controller.rb', line 160

def reload!
	@presentation = @presentation.reload
	notify_listeners!
end

#remove_listener(listener) ⇒ Object

Remove a previously registered listener.



155
156
157
# File 'lib/presently/presentation_controller.rb', line 155

def remove_listener(listener)
	@listeners.delete(listener)
end

#reset_timer!Object

Reset the timer so that elapsed time matches the expected time for the current slide.



93
94
95
96
# File 'lib/presently/presentation_controller.rb', line 93

def reset_timer!
	@clock.reset!(@presentation.expected_time_at(@current_index))
	notify_listeners!
end

#retreat!Object

Go back to the previous slide.



142
143
144
# File 'lib/presently/presentation_controller.rb', line 142

def retreat!
	go_to(@current_index - 1)
end

#save_state!Object

Persist the current state to disk.



166
167
168
# File 'lib/presently/presentation_controller.rb', line 166

def save_state!
	@state&.save(self)
end

#slide_countObject

The total number of slides.



70
71
72
# File 'lib/presently/presentation_controller.rb', line 70

def slide_count
	@presentation.slide_count
end

#slide_progressObject

The progress through the current slide’s allocated time.



82
83
84
85
86
87
88
89
90
# File 'lib/presently/presentation_controller.rb', line 82

def slide_progress
	return 0.0 unless @clock.started?
	
	slide = current_slide
	return 0.0 unless slide
	
	time_into_slide = @clock.elapsed - @presentation.expected_time_at(@current_index)
	(time_into_slide / slide.duration).clamp(0.0, 1.0)
end

#slidesObject

The ordered list of slides, delegated to the presentation.



46
47
48
# File 'lib/presently/presentation_controller.rb', line 46

def slides
	@presentation.slides
end

#templatesObject

The template resolver, delegated to the presentation.



40
41
42
# File 'lib/presently/presentation_controller.rb', line 40

def templates
	@presentation.templates
end

#The presentation timer.=(presentationtimer. = (value)) ⇒ Object



36
# File 'lib/presently/presentation_controller.rb', line 36

attr :clock

#time_remainingObject

The estimated time remaining in the presentation.



118
119
120
121
122
123
124
# File 'lib/presently/presentation_controller.rb', line 118

def time_remaining
	return total_duration unless @clock.started?
	
	expected_remaining = @presentation.expected_time_at(slide_count) - @clock.elapsed
	
	[expected_remaining, 0].max
end

#total_durationObject

The total expected duration of the presentation.



76
77
78
# File 'lib/presently/presentation_controller.rb', line 76

def total_duration
	@presentation.total_duration
end