Class: TaskJuggler::Scoreboard

Inherits:
Object
  • Object
show all
Defined in:
lib/taskjuggler/Scoreboard.rb

Overview

Scoreboard objects are instrumental during the scheduling process. The project time span is divided into discrete time slots by the scheduling resolution. This class models the resulting time slots with an array that spans from project start o project end. Each slot has an index start with 0 at the project start.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(startDate, endDate, resolution, initVal = nil) ⇒ Scoreboard

Create the scoreboard based on the the given startDate, endDate and timing resolution. The resolution must be specified in seconds. Optionally you can provide an initial value for the scoreboard cells.



30
31
32
33
34
35
36
# File 'lib/taskjuggler/Scoreboard.rb', line 30

def initialize(startDate, endDate, resolution, initVal = nil)
  @startDate = startDate
  @endDate = endDate
  @resolution = resolution
  @size = ((endDate - startDate) / resolution).ceil + 1
  clear(initVal)
end

Instance Attribute Details

#endDateObject (readonly)

Returns the value of attribute endDate.



25
26
27
# File 'lib/taskjuggler/Scoreboard.rb', line 25

def endDate
  @endDate
end

#resolutionObject (readonly)

Returns the value of attribute resolution.



25
26
27
# File 'lib/taskjuggler/Scoreboard.rb', line 25

def resolution
  @resolution
end

#sizeObject (readonly)

Returns the value of attribute size.



25
26
27
# File 'lib/taskjuggler/Scoreboard.rb', line 25

def size
  @size
end

#startDateObject (readonly)

Returns the value of attribute startDate.



25
26
27
# File 'lib/taskjuggler/Scoreboard.rb', line 25

def startDate
  @startDate
end

Instance Method Details

#[](idx) ⇒ Object

Get the value at index idx.



97
98
99
# File 'lib/taskjuggler/Scoreboard.rb', line 97

def [](idx)
  @sb[idx]
end

#[]=(idx, value) ⇒ Object

Set the value at index idx.



102
103
104
# File 'lib/taskjuggler/Scoreboard.rb', line 102

def []=(idx, value)
  @sb[idx] = value
end

#clear(initVal = nil) ⇒ Object

Erase all values and set them to nil or a new initial value.



39
40
41
# File 'lib/taskjuggler/Scoreboard.rb', line 39

def clear(initVal = nil)
  @sb = Array.new(@size, initVal)
end

#collect!Object

Assign result of block to each element.



92
93
94
# File 'lib/taskjuggler/Scoreboard.rb', line 92

def collect!
  @sb.collect! { |x| yield x }
end

#collectIntervals(iv, minDuration) ⇒ Object

Return a list of intervals that describe a contiguous part of the scoreboard that contains only the values that yield true for the passed block. The intervals must be within the interval described by iv and must be at least minDuration long. The return value is an IntervalList.



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/taskjuggler/Scoreboard.rb', line 121

def collectIntervals(iv, minDuration)
  # Determine the start and stop index for the scoreboard search. We save
  # the original values for later use as well.
  startIdx = sIdx = dateToIdx(iv.start)
  endIdx = eIdx = dateToIdx(iv.end)

  # Convert the minDuration into number of slots.
  minDuration /= @resolution
  minDuration = 1 if minDuration <= 0

  # Expand the interval with the minDuration to both sides. This will
  # reduce the failure to detect intervals at the iv boundary. However,
  # this will not prevent undetected intervals at the project time frame
  # boundaries.
  startIdx -= minDuration
  startIdx = 0 if startIdx < 0
  endIdx += minDuration
  endIdx = @size - 1 if endIdx > @size - 1

  # This is collects the resulting intervals.
  intervals = IntervalList.new

  # The duration counter for the currently analyzed interval and the start
  # index.
  duration = start = 0

  idx = startIdx
  loop do
    # Check whether the scoreboard slot matches any of the target values
    # and we have not yet reached the last slot.
    if yield(@sb[idx]) && idx < endIdx
      # If so, save the start position if this is the first slot and start
      # counting the matching slots.
      start = idx if start == 0
      duration += 1
    else
      # If we don't have a match or are at the end of the interval, check
      # if we've just finished a matching interval.
      if duration > 0
        if duration >= minDuration
          # Make sure that all intervals are within the originally
          # requested Interval.
          start = sIdx if start < sIdx
          idx = eIdx if idx > eIdx

          intervals << TimeInterval.new(idxToDate(start), idxToDate(idx))
        end
        duration = start = 0
      end
    end
    break if (idx += 1) > endIdx
  end

  intervals
end

#dateToIdx(date, forceIntoProject = true) ⇒ Object

Converts a date to the corresponding scoreboard index. You can optionally sanitize the date by forcing it into the project time span.



57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/taskjuggler/Scoreboard.rb', line 57

def dateToIdx(date, forceIntoProject = true)
  idx = ((date - @startDate) / @resolution).to_i

  if forceIntoProject
    return 0 if idx < 0
    return @size - 1 if idx >= @size
  elsif (idx < 0 || idx >= @size)
    raise "Date #{date} is out of project time range " +
          "(#{@startDate} - #{@endDate})"
  end

  idx
end

#each(startIdx = 0, endIdx = @size) ⇒ Object

Iterate over all scoreboard entries.



72
73
74
75
76
77
78
79
80
81
82
# File 'lib/taskjuggler/Scoreboard.rb', line 72

def each(startIdx = 0, endIdx = @size)
  if startIdx != 0 || endIdx != @size
    startIdx.upto(endIdx - 1) do |i|
      yield @sb[i]
    end
  else
    @sb.each do |entry|
      yield entry
    end
  end
end

#each_indexObject

Iterate over all scoreboard entries by index.



85
86
87
88
89
# File 'lib/taskjuggler/Scoreboard.rb', line 85

def each_index
  @sb.each_index do |index|
    yield index
  end
end

#get(date) ⇒ Object

Get the value corresponding to date.



107
108
109
# File 'lib/taskjuggler/Scoreboard.rb', line 107

def get(date)
  @sb[dateToIdx(date)]
end

#idxToDate(idx, forceIntoProject = false) ⇒ Object

Converts a scroreboard index to the corresponding date. You can optionally sanitize the idx value by forcing it into the project range.



45
46
47
48
49
50
51
52
53
# File 'lib/taskjuggler/Scoreboard.rb', line 45

def idxToDate(idx, forceIntoProject = false)
  if forceIntoProject
    return @startDate if kdx < 0
    return @endDate if @size - 1 if idx >= @size
  elsif idx < 0 || idx >= @size
    raise "Index #{idx} is out of scoreboard range (#{size - 1})"
  end
  @startDate + idx * @resolution
end

#inspectObject



177
178
179
180
181
182
183
184
# File 'lib/taskjuggler/Scoreboard.rb', line 177

def inspect
  s = ''
  0.upto(@sb.length - 1) do |i|
    s << "#{idxToDate(i)}: #{@sb[i]}"
  end

  s
end

#set(date, value) ⇒ Object

Set the value corresponding to date.



112
113
114
# File 'lib/taskjuggler/Scoreboard.rb', line 112

def set(date, value)
  @sb[dateToIdx(date)] = value
end