class Bonito::SerialTimeline
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.
Public Class Methods
Instantiate a new SerialTimeline object
- duration
-
The total time period (in seconds) that the
SerialTimelineencompasses - parent
-
If the
SerialTimelineis 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 equivalenta_serial =
Bonito::SerialTimeline.new(1.week)doplease { p Time.now }
end
another_serial =
Bonito::SerialTimeline.new1.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.
# 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
Public Instance Methods
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
# File lib/bonito/serial_timeline.rb, line 254 def *(other) SerialTimeline.new(duration * other) do use(*Array.new(other) { entries }.reduce(:+)) end end
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.
# File lib/bonito/serial_timeline.rb, line 268 def **(other) this = self SerialTimeline.new(duration) do simultaneously { use(*Array.new(other) { this }) } end end
Combine two Windows into a single, larger SerialTimeline object.
- other
-
Some other
SerialTimelineobject
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.
# File lib/bonito/serial_timeline.rb, line 234 def +(other) SerialTimeline.new duration + other.duration do use(*(to_a + other.to_a)) end end
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
SerialTimelineobject
Returns the newly created SerialTimeline object
# File lib/bonito/serial_timeline.rb, line 166 def over(duration, &block) self.class.new(duration, self, &block).tap(&method(:use)) end
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
Momentobject
Returns the newly created Moment object
# File lib/bonito/serial_timeline.rb, line 176 def please(&block) Moment.new(&block).tap(&method(:use)) end
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
SerialTimelineobject to be appended to the currentSerialTimeline - over
-
The total duration (in senconds) of the new repeated
SerialTimelineobjects. - block
-
A block passed to the new method on the child
SerialTimelineobject
Returns the current SerialTimeline
# 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
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
# File lib/bonito/serial_timeline.rb, line 210 def simultaneously(&block) use ParallelTimeline.new(&block) end
The the amount of duration remaining taking into account the duration of any Timeline objects included as children of the SerialTimeline.
# File lib/bonito/serial_timeline.rb, line 152 def unused_duration duration - @total_child_duration end
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
# File lib/bonito/serial_timeline.rb, line 221 def use(*timelines) timelines.each { |timeline| send :<<, timeline } self end