Class: Bonito::SerialTimeline
- Defined in:
- lib/bonito/serial_timeline.rb
Overview
A SerialTimeline is a data structure with a duration (measured in seconds) that contains timelines. A timeline is any instance of a class that inherits from the Timeline base class.
A SerialTimeline serves to define an interval in which it may be simulated that one or more Moment objects are evaluated in series_.
A SerialTimeline exposes methods that can either be used to define these Moment objects directly or to create additional child data structures (i.e ParallelTimeline objects or further, child SerialTimeline objects) which can in turn be provide more fine grained control over precisely when any given Moment objects may be evaluated.
Example
Bonito.over(2.weeks) do
please { puts Time.now }
end
The above defines a SerialTimeline (using the Bonito#over module method) that specifies a 2 week time period. A single Moment is included in this serial (via the #please factory method). When the top level SerialTimeline is evaluated (using a Runner object) the block
puts Time.now
is evaluated exactly once. Furthermore, the simulated time at which the block is evaluated will be contained at some point within the 2 week interval beginning on some start date provided when instantiating the Runner object.
As mentioned, it is also possible to include other data structures within SerialTimeline objects, including other SerialTimeline objects.
Example
We could use the #over method to add an empty SerialTimeline to the previous example in order to force the already included Moment to be evaluated during the last day of the 2 week period.
Bonito.over(2.weeks) do
over(2.weeks - 1.day) # This defines an empty serial
please { puts Time.now }
end
The empty SerialTimeline returned by the #over factory method consumes 13 days of the parent SerialTimeline object’s total duration of 2 weeks. This means that when this parent SerialTimeline is evaluated, the Moment will be as if it occurred during the final day of the 2 week period.
Finally, we may also define ParallelTimeline objects within serials using the #simultaneously method. These allow for multiple SerialTimeline objects to be defined over the same time period and for any Moment objects contained within to be interleaved when the parent SerialTimeline is ultimately evaluated.
The #simultaneously method instantiates a ParallelTimeline object, whilst accepting a block. The block is evaluated within the context of the new ParallelTimeline. Timelines defined within this block will be evaluated in parallel.
Note that ParallelTimeline implements many of the same methods as SerialTimeline
Example
Bonito.over(2.weeks) do
simultaneously do
over 1.week do
puts "SerialTimeline 1 #{Time.now}"
end
over 6.days, after: 1.day do
puts "SerialTimeline 2 #{Time.now}"
end
end
over 1.week {} # This defines an empty serial
end
Now, when evaluating this SerialTimeline both the blocks
puts "SerialTimeline 1 #{Time.now}"
and
puts "SerialTimeline 2 #{Time.now}"
will be evaluated once during the first week. The precise instant is chosen randomly within this interval with the only constraint being that the second block cannot be evaluated during the first day (This offset is controlled by the after parameter of the #simultaneously method).
Note that the moment from the second SerialTimeline could still be evaluated at a simulated time before that at which the moment from the first SerialTimeline is evaluated.
Instance Attribute Summary
Attributes inherited from Timeline
Instance Method Summary collapse
-
#*(other) ⇒ Object
Repeatedly apply the #+ method of the current SerialTimeline to itself.
-
#**(other) ⇒ Object
Scale up a serial by parallelising it according to some factor.
-
#+(other) ⇒ Object
Combine two Windows into a single, larger SerialTimeline object.
-
#initialize(duration, parent = nil, &block) ⇒ SerialTimeline
constructor
Instantiate a new SerialTimeline object.
-
#over(duration, &block) ⇒ Object
Define a new SerialTimeline and add it as a child to the current SerialTimeline.
-
#please(&block) ⇒ Object
Define a new Moment and add it as a child to the current SerialTimeline.
-
#repeat(times:, over:, &block) ⇒ Object
Define a new serial and append it multiple times as a child of the current SerialTimeline object.
-
#simultaneously(&block) ⇒ Object
Define a new ParallelTimeline object append it as a child to the current SerialTimeline.
-
#unused_duration ⇒ Object
The the amount of #duration remaining taking into account the duration of any Timeline objects included as children of the SerialTimeline.
-
#use(*timelines) ⇒ Object
Append an existing Timeline as a child of the current SerialTimeline.
Methods inherited from Timeline
#each, schedule_with, #scheduler, #size
Constructor Details
#initialize(duration, parent = nil, &block) ⇒ SerialTimeline
Instantiate a new SerialTimeline object
- duration
-
The total time period (in seconds) that the SerialTimeline encompasses
- parent
-
If the SerialTimeline is a child of another Timeline, parent is this Timeline
- block
-
A block that will be evaluated within the context of the newly created SerialTimeline. Note that the following two statements are equivalent
a_serial = Bonito::SerialTimeline.new(1.week) do
please { p Time.now }end
another_serial = Bonito::SerialTimeline.new 1.week serial.please { p Time.now }
The ability to include a block in this way is in order to allow the code used to define a given SerialTimeline will reflect its hierarchy.
143 144 145 146 147 148 |
# File 'lib/bonito/serial_timeline.rb', line 143 def initialize(duration, parent = nil, &block) @parent = parent @total_child_duration = 0 super duration instance_eval(&block) if block_given? end |
Instance Method Details
#*(other) ⇒ Object
Repeatedly apply the #+ method of the current SerialTimeline to itself
- other
-
Denotes the number of times the current serial should be added to itself.
Returns a new SerialTimeline object
Note that the following statements are equivalent for some serial serial:
serial * 3
serial + serial + serial
254 255 256 257 258 |
# File 'lib/bonito/serial_timeline.rb', line 254 def *(other) SerialTimeline.new(duration * other) do use(*Array.new(other) { entries }.reduce(:+)) end end |
#**(other) ⇒ Object
Scale up a serial by parallelising it according to some factor
- other
-
An Integer denoting the degree of parallelism with which to scale the serial.
Returns a new ParallelTimeline whose child timelines are precisely the current serial repeated other times.
268 269 270 271 272 273 |
# File 'lib/bonito/serial_timeline.rb', line 268 def **(other) this = self SerialTimeline.new(duration) do simultaneously { use(*Array.new(other) { this }) } end end |
#+(other) ⇒ Object
Combine two Windows into a single, larger SerialTimeline object.
- other
-
Some other SerialTimeline object
Returns a SerialTimeline object consisting of the ordered child Timeline objects of the current SerialTimeline with the ordered child Timeline objects of other appended to the end.
234 235 236 237 238 |
# File 'lib/bonito/serial_timeline.rb', line 234 def +(other) SerialTimeline.new duration + other.duration do use(*(to_a + other.to_a)) end end |
#over(duration, &block) ⇒ Object
Define a new SerialTimeline and add it as a child to the current SerialTimeline
- duration
-
The duration (in seconds) of the newly created child SerialTimeline
- block
-
A block passed to the #new method on the child SerialTimeline object
Returns the newly created SerialTimeline object
166 167 168 |
# File 'lib/bonito/serial_timeline.rb', line 166 def over(duration, &block) self.class.new(duration, self, &block).tap(&method(:use)) end |
#please(&block) ⇒ Object
Define a new Moment and add it as a child to the current SerialTimeline
- block
-
A block passed to the #new method on the child Moment object
Returns the newly created Moment object
176 177 178 |
# File 'lib/bonito/serial_timeline.rb', line 176 def please(&block) Moment.new(&block).tap(&method(:use)) end |
#repeat(times:, over:, &block) ⇒ Object
Define a new serial and append it multiple times as a child of the current SerialTimeline object.
- times
-
The number of times that the new SerialTimeline object to be appended to the current SerialTimeline
- over
-
The total duration (in senconds) of the new repeated SerialTimeline objects.
- block
-
A block passed to the #new method on the child SerialTimeline object
Returns the current SerialTimeline
196 197 198 199 |
# File 'lib/bonito/serial_timeline.rb', line 196 def repeat(times:, over:, &block) repeated_block = proc { times.times { instance_eval(&block) } } over(over, &repeated_block) end |
#simultaneously(&block) ⇒ Object
Define a new ParallelTimeline object append it as a child to the current SerialTimeline. Also permit the evaluation of methods within the context of the new ParallelTimeline.
- block
-
A block to be passed to the #new method on the child ParallelTimeline method.
Returns the current SerialTimeline object
210 211 212 |
# File 'lib/bonito/serial_timeline.rb', line 210 def simultaneously(&block) use ParallelTimeline.new(&block) end |
#unused_duration ⇒ Object
The the amount of #duration remaining taking into account the duration of any Timeline objects included as children of the SerialTimeline.
152 153 154 |
# File 'lib/bonito/serial_timeline.rb', line 152 def unused_duration duration - @total_child_duration end |
#use(*timelines) ⇒ Object
Append an existing Timeline as a child of the current SerialTimeline
- timelines
-
An array of Timeline objects that will be appended, in order to the current SerialTimeline
Returns the current SerialTimeline object
221 222 223 224 |
# File 'lib/bonito/serial_timeline.rb', line 221 def use(*timelines) timelines.each { |timeline| send :<<, timeline } self end |