class TimeSpan::TimeLine
class TimeLine # # TimeLine is how RelativeTime objects are related to each other, they have to have the same # frame of reference. # # instance methods: # # to_s -- convenience method to see which object we have # position_of(obj) -- its location on the TimeLine # increase_after(position, amount) -- make room in the index for an insertion # append (obj) -- add obj to end of the TimeLine # append_to_next(relative_object, object, relative) at relative offset to relative_object, put obj # insert_before_next(relative_object, object, relative) inserts into new time slot relative to relative_object insert_at(position, object) -- places object at position, appending if equal time exists # remove(obj) -- remove object from the TimeLine # compress! -- compresses the TimeLine, removing [] and adjusting the index accordingly # #
@author Craig A. .Cook
Attributes
Public Class Methods
# File lib/time_span.rb, line 246 def initialize(name="") @name = name @line = [] @indices_of = {} @spans = [] end
Public Instance Methods
test for value equality. Checking span trait is redundant – can't have spans without times' @param [TimeSpan::TimeLine] TimeLine
being compared to @return [Boolean] true if name is equal and all other attributes are empty.
# File lib/time_span.rb, line 261 def == (other_timeline) (object_id == other_timeline.object_id) || (@name == other_timeline.name) && (@line.empty? && @indices_of.empty? && @spans.empty?) && (other_timeline.line.empty? && other_timeline.indices_of.empty? && other_timeline.spans.empty?) end
all statuses on the TimeLine
@return [Array] statuses for all attached RelativeTime
s on the TimeLine
# File lib/time_span.rb, line 293 def all_relative_time_statuses relative_times.inject([]) {|acc, v| acc << v.reference_to } end
inserts to the end of the relative object's time, becoming equal with it @param relative_obj object after which to insert obj @param obj object inserted after relative_object @return (see insert_at
)
# File lib/time_span.rb, line 326 def append_to_next(relative_obj, obj, relative=1) insert_at(position_of(relative_obj)+relative, obj) end
@raise [NotImplementedError] Cannot use base Ruby clone which can create illegal objects by gem rules.
# File lib/time_span.rb, line 254 def clone raise NotImplementedError, "Cannot use base Ruby clone which can create illegal objects by gem rules." end
removes all [] elements, and decrements accordingly the @indices_of ideally this should be transactional
@return [nil] cleanup method
# File lib/time_span.rb, line 373 def compress! mod_level = 0 offsets = [] 0.upto(line.size-1) do |i| mod_level -= 1 if @line[i].empty? offsets << mod_level end ## poor man's transaction. Don't do directly on indices_of so less chance of interruption indices = indices_of indices.each_key do |key| indices[key] = indices[key] + offsets[indices[key]] end indices_of = indices @line.delete([]) end
bump up indices after a point, so that a RelativeTime
may be inserted @return nil no return value, helper method to keep data structures up to date.
# File lib/time_span.rb, line 307 def increase_after(pos, by=1) @indices_of.each_key do |key| @indices_of[key] += by if (@indices_of[key] >= pos) end end
place obj at the numbered position
@param pos where to insert obj in the TimeLIne @param obj obj inserted into the TimeLIne @return [Fixnum] ]the (relative) position where the object was inserted
# File lib/time_span.rb, line 346 def insert_at(pos, obj) raise ArgumentError, "can only add a time to its own time_line" unless obj.time_line.equal? self if @line[pos].nil? @line[pos] = [obj] else op = @line[pos].kind_of?(Array) ? '<<' : '=' @line[pos].send(op.to_sym, obj).uniq! # no duplicates in same position # dup in diff position overwrites below end @indices_of[obj] = pos end
inserts into a new space before the relative object (first parameter)
inserts obj before relative_obj by offset @param relative_obj object for computing position where obj is inserted @param the inserted object @return (see insert_at
)
# File lib/time_span.rb, line 335 def insert_before_next(relative_obj, obj, relative_offset=1) relative_position = position_of(relative_obj) increase_after(relative_position + relative_offset, relative_offset) @line[relative_position + relative_offset,0] = nil insert_at(relative_position+relative_offset, obj) end
find the position of a RelativeTime on the TimeLine
@return [Fixnum] RelativeTime's position on the TimeLine
(self)
# File lib/time_span.rb, line 301 def position_of(obj) @indices_of[obj] end
attached times only (internal API)
@return [Array] indices of keys
# File lib/time_span.rb, line 287 def relative_times indices_of.keys end
cannot remove [] or the @indices_of will be wrong call compress to remove the extra []s @param obj object to be removed from the TimeLIne @return []nil|Fixnum] position of deleted object
# File lib/time_span.rb, line 362 def remove(obj) pos = position_of(obj) if pos # do nothing if it isn't there' @line[pos].delete(obj) # remove from list @indices_of.delete(obj) # remove from index end end
returns the TimeLine's name @return [String] TimeLine's name'
# File lib/time_span.rb, line 270 def to_s name.to_s end