precedence 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +118 -0
- data/README +41 -9
- data/TODO +10 -5
- data/lib/precedence/activity.rb +429 -80
- data/lib/precedence/network.rb +223 -88
- data/lib/precedence/utilities.rb +44 -0
- data/lib/precedence.rb +1 -0
- data/tests/tc_activity.rb +287 -45
- data/tests/tc_network.rb +277 -39
- data/tests/ts_precedence.rb +2 -0
- metadata +3 -2
data/lib/precedence/activity.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require('yaml')
|
2
|
+
|
1
3
|
module Precedence
|
2
4
|
|
3
5
|
# A representation of an activity in a precedence network. Each activity
|
@@ -6,13 +8,30 @@ module Precedence
|
|
6
8
|
# other properties of the activity can be determined such as it's earliest
|
7
9
|
# finish time, float and so on.
|
8
10
|
#
|
9
|
-
|
10
|
-
class Activity
|
11
|
+
# The activity also has a probabilistic component.
|
12
|
+
class Activity
|
13
|
+
|
14
|
+
MEAN_DURATION = :mean_duration
|
15
|
+
EXPECTED_DURATION = :expected_duration
|
16
|
+
MINIMUM_DURATION = :minimum_duration
|
17
|
+
MAXIMUM_DURATION = :maximum_duration
|
11
18
|
|
19
|
+
@duration_type = EXPECTED_DURATION
|
20
|
+
|
21
|
+
EARLIEST_START = :earliest_start
|
22
|
+
LATEST_START = :latest_start
|
23
|
+
DROP_START = :drop_start
|
24
|
+
|
25
|
+
@start_type = EARLIEST_START
|
26
|
+
|
12
27
|
# A textual description of the activity.
|
13
28
|
attr_accessor :description
|
14
|
-
# The
|
15
|
-
attr_accessor :
|
29
|
+
# The expected duration of the activity
|
30
|
+
attr_accessor :expected_duration
|
31
|
+
# The minimum duration of the activity
|
32
|
+
attr_accessor :minimum_duration
|
33
|
+
# The maximum duration of the activity
|
34
|
+
attr_accessor :maximum_duration
|
16
35
|
# A unique reference for this activity.
|
17
36
|
attr_reader :reference
|
18
37
|
# The collection of activites that are dependent on the completion of
|
@@ -21,90 +40,147 @@ module Precedence
|
|
21
40
|
# The collection of activities that this activity depends on before it
|
22
41
|
# can begin executing.
|
23
42
|
attr_reader :pre_activities
|
24
|
-
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
43
|
+
# A collection of resources that are used by this activitity. Stating
|
44
|
+
# that
|
45
|
+
# activity.resources['concrete'] = 5
|
46
|
+
# indicates that the activity will use 5 units of concrete per time
|
47
|
+
# period.
|
48
|
+
attr_reader :resources
|
49
|
+
# Sets what the duration method should return. Can be set to one of:
|
50
|
+
# * EXPECTED_DURATION
|
51
|
+
# * MAXIMUM_DURATION
|
52
|
+
# * MINIMUM_DURATION
|
53
|
+
# * MEAN_DURATION
|
54
|
+
# Initially set to the expected duration
|
55
|
+
attr_accessor :duration_type
|
56
|
+
# Sets what the start attribute should return can be set to one of:
|
57
|
+
# * EARLIEST_START
|
58
|
+
# * LATEST_START
|
59
|
+
# * DROP_START
|
60
|
+
# Initially set to the earliest start
|
61
|
+
attr_accessor :start_type
|
62
|
+
|
63
|
+
# Creates a new activity. The only required field is the reference.
|
64
|
+
# The description, duration can be set in the block, which will have
|
65
|
+
# as a parameter the newly created activity. If they are not set in the
|
66
|
+
# block they will have as values "" and 0 respectively. Post- and
|
67
|
+
# pre-activities can also be set in the block by using the
|
68
|
+
# Activity.add_post_activities and Activity.add_pre_activities methods.
|
28
69
|
#
|
29
|
-
# *Note*: When assigning a reference for an activity
|
30
|
-
#
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
70
|
+
# *Note*: When assigning a reference for an activity
|
71
|
+
# StartActivity::REFERENCE and FinishActivity::REFERENCE are reserved
|
72
|
+
# for internal usage.
|
73
|
+
def initialize(reference, &block)
|
74
|
+
reference.respond_to?(:to_s) ? nil : raise("Parameter reference"+
|
75
|
+
"must respond to 'to_s'.")
|
76
|
+
reference = reference.to_s
|
77
|
+
if ((reference != Precedence::StartActivity::REFERENCE) &&
|
78
|
+
(reference != Precedence::FinishActivity::REFERENCE))
|
79
|
+
@reference = reference.to_s
|
80
|
+
else
|
81
|
+
raise "Activity reference '#{reference}' is reserved."
|
35
82
|
end
|
36
|
-
|
37
|
-
@description =
|
38
|
-
@
|
39
|
-
@
|
40
|
-
@
|
83
|
+
|
84
|
+
@description = ""
|
85
|
+
@post_activities = []
|
86
|
+
@pre_activities = []
|
87
|
+
@resources = Precedence::Utilities::ResourceHash.new
|
88
|
+
@expected_duration = 0
|
89
|
+
@minimum_duration = 0
|
90
|
+
@maximum_duration = 0
|
91
|
+
@duration_type = EXPECTED_DURATION
|
92
|
+
@start_type = EARLIEST_START
|
93
|
+
|
94
|
+
# Call the block if it is present
|
95
|
+
block ? block.call(self) : nil
|
96
|
+
|
97
|
+
# Type conversion
|
98
|
+
@expected_duration = @expected_duration.to_f
|
99
|
+
@minimum_duration = @minimum_duration.to_f
|
100
|
+
@maximum_duration = @maximum_duration.to_f
|
41
101
|
end
|
42
|
-
|
102
|
+
|
43
103
|
# Adds the activities in the parameter list to the post_activities
|
44
104
|
# collection of this activity and also adds this activity to the
|
45
105
|
# pre_activities collection of each of the activities.
|
46
|
-
|
47
|
-
|
106
|
+
#
|
107
|
+
# *Note*: When using the Network class it is better to use
|
108
|
+
# Network.connect than Activity.add_pre_activities or
|
109
|
+
# Activity.add_post_activities directly.
|
110
|
+
def add_post_activities(*post_acts) #:nodoc:
|
111
|
+
post_acts.flatten!
|
112
|
+
post_acts.each do |activity|
|
48
113
|
activity.register_pre_activity(self)
|
49
114
|
register_post_activity(activity)
|
50
115
|
end
|
116
|
+
return post_acts
|
51
117
|
end
|
52
118
|
|
53
119
|
# Adds the activities in the parameter list to the pre_activities
|
54
120
|
# collection of this activity and also adds this activity to the
|
55
121
|
# post_activities collection of each of the activities.
|
56
|
-
|
57
|
-
|
122
|
+
#
|
123
|
+
# *Note*: When using the Network class it is better to use
|
124
|
+
# Network.connect than Activity.add_pre_activities or
|
125
|
+
# Activity.add_post_activities directly.
|
126
|
+
def add_pre_activities(*pre_acts) #:nodoc:
|
127
|
+
pre_acts.flatten!
|
128
|
+
pre_acts.each do |activity|
|
58
129
|
activity.register_post_activity(self)
|
59
130
|
register_pre_activity(activity)
|
60
131
|
end
|
132
|
+
return pre_acts
|
61
133
|
end
|
62
134
|
|
63
135
|
# Removes the list of activities from the post_activities collection of
|
64
136
|
# the activity.
|
65
|
-
def remove_post_activities(*
|
66
|
-
|
137
|
+
def remove_post_activities(*post_acts) #:nodoc:
|
138
|
+
post_acts.flatten!
|
139
|
+
post_acts.each do |activity|
|
67
140
|
activity.deregister_pre_activity(self)
|
68
141
|
deregister_post_activity(activity)
|
69
|
-
end
|
142
|
+
end
|
143
|
+
return post_acts
|
70
144
|
end
|
71
145
|
|
72
146
|
# Removes the list of activities from the pre_activities collection of
|
73
147
|
# the activity.
|
74
|
-
def remove_pre_activities(*
|
75
|
-
|
148
|
+
def remove_pre_activities(*pre_acts) #:nodoc:
|
149
|
+
pre_acts.flatten!
|
150
|
+
pre_acts.each do |activity|
|
76
151
|
activity.deregister_post_activity(self)
|
77
152
|
deregister_pre_activity(activity)
|
78
153
|
end
|
154
|
+
return pre_acts
|
79
155
|
end
|
80
|
-
|
156
|
+
|
81
157
|
# The earliest possible time this activity can finish.
|
82
158
|
def earliest_finish
|
83
|
-
return
|
159
|
+
return earliest_start + duration
|
84
160
|
end
|
85
161
|
|
86
162
|
# The earliest possible time this activity can start.
|
87
163
|
def earliest_start
|
88
|
-
unless
|
89
|
-
(
|
164
|
+
unless self.pre_activities.empty?
|
165
|
+
return (pre_activities.max do |a,b|
|
90
166
|
a.earliest_finish <=> b.earliest_finish
|
91
167
|
end).earliest_finish
|
92
168
|
else
|
93
|
-
0.0
|
169
|
+
return 0.0
|
94
170
|
end
|
95
171
|
end
|
96
|
-
|
172
|
+
|
97
173
|
# The latest possible time this activity can start so as not to delay
|
98
174
|
# any dependent activities.
|
99
175
|
def latest_start
|
100
|
-
return latest_finish -
|
176
|
+
return latest_finish - duration
|
101
177
|
end
|
102
178
|
|
103
179
|
# The latest possible time this activity can finish so as not to delay
|
104
180
|
# any dependent activities.
|
105
181
|
def latest_finish
|
106
|
-
unless
|
107
|
-
(
|
182
|
+
unless post_activities.empty?
|
183
|
+
return (post_activities.min do |a,b|
|
108
184
|
a.latest_start <=> b.latest_start
|
109
185
|
end).latest_start
|
110
186
|
else
|
@@ -113,9 +189,9 @@ module Precedence
|
|
113
189
|
end
|
114
190
|
|
115
191
|
# The maximum earliest finish of this activities pre-activities.
|
116
|
-
def pre_activities_max_earliest_finish
|
117
|
-
unless
|
118
|
-
(
|
192
|
+
def pre_activities_max_earliest_finish #:nodoc:
|
193
|
+
unless pre_activities.empty?
|
194
|
+
return (pre_activities.max do |a,b|
|
119
195
|
a.earliest_finish <=> b.earliest_finish
|
120
196
|
end).earliest_finish
|
121
197
|
else
|
@@ -124,9 +200,9 @@ module Precedence
|
|
124
200
|
end
|
125
201
|
|
126
202
|
# The minimum earliest start of this activities post-activities.
|
127
|
-
def post_activities_min_earliest_start
|
128
|
-
unless
|
129
|
-
(
|
203
|
+
def post_activities_min_earliest_start #:nodoc:
|
204
|
+
unless post_activities.empty?
|
205
|
+
return (post_activities.min do |a,b|
|
130
206
|
a.earliest_start <=> b.earliest_start
|
131
207
|
end).earliest_start
|
132
208
|
else
|
@@ -154,46 +230,46 @@ module Precedence
|
|
154
230
|
# activities start as early as possible.
|
155
231
|
#
|
156
232
|
# *Note*: In almost all practical cases this is the same as if all
|
157
|
-
# preceding and
|
233
|
+
# preceding and successing activities start as lates as possible and so
|
158
234
|
# no late_float method is defined.
|
159
235
|
def early_float
|
160
236
|
return post_activities_min_earliest_start -
|
161
|
-
pre_activities_max_earliest_finish -
|
237
|
+
pre_activities_max_earliest_finish - duration
|
162
238
|
end
|
163
239
|
|
164
240
|
# Register this activity as a post-activity on the parameter.
|
165
241
|
def register_post_activity(activity) #:nodoc:
|
166
|
-
unless (
|
242
|
+
unless (post_activities.detect do |post_activity|
|
167
243
|
activity.reference == post_activity.reference
|
168
244
|
end)
|
169
|
-
|
245
|
+
post_activities << activity
|
170
246
|
end
|
171
247
|
end
|
172
248
|
|
173
249
|
# Register this activity as a pre-activity on the parameter.
|
174
250
|
def register_pre_activity(activity) #:nodoc:
|
175
|
-
unless (
|
251
|
+
unless (pre_activities.detect do |pre_activity|
|
176
252
|
activity.reference == pre_activity.reference
|
177
253
|
end)
|
178
|
-
|
254
|
+
pre_activities << activity
|
179
255
|
end
|
180
256
|
end
|
181
257
|
|
182
258
|
# Deregister this activity as a post-activity on the parameter.
|
183
259
|
def deregister_post_activity(activity) #:nodoc:
|
184
|
-
if (
|
260
|
+
if (post_activities.detect do |post_activity|
|
185
261
|
activity.reference == post_activity.reference
|
186
262
|
end)
|
187
|
-
|
263
|
+
post_activities.delete(activity)
|
188
264
|
end
|
189
265
|
end
|
190
266
|
|
191
267
|
# Deregister this activity as a pre-activity on the parameter.
|
192
268
|
def deregister_pre_activity(activity) #:nodoc:
|
193
|
-
if (
|
269
|
+
if (pre_activities.detect do |pre_activity|
|
194
270
|
activity.reference == pre_activity.reference
|
195
271
|
end)
|
196
|
-
|
272
|
+
pre_activities.delete(activity)
|
197
273
|
end
|
198
274
|
end
|
199
275
|
|
@@ -204,48 +280,321 @@ module Precedence
|
|
204
280
|
|
205
281
|
# Redefines the inspect method.
|
206
282
|
def inspect #:nodoc:
|
207
|
-
"#{
|
283
|
+
"#{reference}(#{duration})"
|
208
284
|
end
|
209
285
|
|
210
286
|
# Redefines the to_s method
|
211
287
|
def to_s #:nodoc:
|
212
|
-
return "Reference: #{
|
213
|
-
"Description: #{
|
214
|
-
"Duration: #{
|
288
|
+
return "Reference: #{reference}\n"+
|
289
|
+
"Description: #{description}\n"+
|
290
|
+
"Duration: #{duration}"+
|
215
291
|
("\nDepends on:\n " unless @pre_activities.empty?).to_s +
|
216
292
|
(@pre_activities.collect do |activity|
|
217
293
|
activity.reference
|
218
294
|
end).join(',')
|
219
295
|
end
|
220
296
|
|
221
|
-
#
|
222
|
-
|
223
|
-
|
297
|
+
# Returns a YAML document representing the activity object.
|
298
|
+
def to_yaml()
|
299
|
+
"---\n#{reference}:\n"+
|
300
|
+
(description == "" ? "" : " description: #{description}\n")+
|
301
|
+
(expected_duration == 0 ? "" : " expected duration: #{expected_duration}\n")+
|
302
|
+
(minimum_duration == 0 ? "" : " minimum duration: #{minimum_duration}\n")+
|
303
|
+
(maximum_duration == 0 ? "" : " maximum duration: #{maximum_duration}\n")+
|
304
|
+
(post_activities.empty? ? "" : " post activities:\n") +
|
305
|
+
(post_activities.collect do |activity|
|
306
|
+
" - #{activity.reference}"
|
307
|
+
end).join("\n")+"\n"+
|
308
|
+
(resources.empty? ? "" : " resources:\n")+
|
309
|
+
(resources.to_a.collect do |resource,value|
|
310
|
+
" #{resource}: #{value}"
|
311
|
+
end).join("\n")+"\n"
|
312
|
+
end
|
313
|
+
|
314
|
+
# Returns true if two activity objects have the same duration and
|
315
|
+
# reference, false otherwise.
|
316
|
+
def eql?(other)
|
317
|
+
if (self.reference == other.reference) and
|
318
|
+
(self.duration == other.duration)
|
319
|
+
return true
|
320
|
+
end
|
321
|
+
return false
|
322
|
+
end
|
323
|
+
|
324
|
+
alias == eql?
|
325
|
+
|
326
|
+
# Returns true if the activity is active during the time given.
|
327
|
+
#
|
328
|
+
# *Note*: If an activity has a start of x and a finish of y, then
|
329
|
+
# activity.active_on?(x)
|
330
|
+
# will return true, while
|
331
|
+
# activity.active_on?(y)
|
332
|
+
# will return false.
|
333
|
+
def active_on?(time)
|
334
|
+
return duration_range === time
|
335
|
+
end
|
336
|
+
|
337
|
+
# Returns true if the activity is active during the range given.
|
338
|
+
#
|
339
|
+
# *Note*: If a range given includes the last element
|
340
|
+
# (range.include_end? == true) it is treated as a range that does
|
341
|
+
# not include the last element
|
342
|
+
def active_during?(range)
|
343
|
+
unless range.exclude_end?
|
344
|
+
range = Range.new(range.begin,range.end,true)
|
345
|
+
end
|
224
346
|
|
225
|
-
|
226
|
-
|
347
|
+
return (range === start) ||
|
348
|
+
((finish > range.begin) && (finish < range.end)) ||
|
349
|
+
((start < range.begin) && (finish > range.begin))
|
350
|
+
|
351
|
+
end
|
352
|
+
|
353
|
+
# Returns a range object representing the duration of the activity. The
|
354
|
+
# range object return will have range.exclude_end? set to true.
|
355
|
+
#
|
356
|
+
# Example usage:
|
357
|
+
# activity.duration_range
|
358
|
+
def duration_range
|
359
|
+
return Range.new(start,finish,true)
|
360
|
+
end
|
361
|
+
|
362
|
+
# Sets what duration type the activity should use.
|
363
|
+
#
|
364
|
+
# Example usage:
|
365
|
+
# Activity.duration_type = Activity::MEAN_DURATION
|
366
|
+
# will change the duration type to the mean duration for all activities.
|
367
|
+
def duration_type=(type) #:nodoc:
|
368
|
+
case (type)
|
369
|
+
when MEAN_DURATION,EXPECTED_DURATION,
|
370
|
+
MINIMUM_DURATION, MAXIMUM_DURATION
|
371
|
+
@duration_type = type
|
372
|
+
else
|
373
|
+
raise "Duration type '#{type}' is unknown."
|
374
|
+
end
|
375
|
+
end
|
227
376
|
|
228
|
-
|
229
|
-
|
377
|
+
# Returns the duration of the activity dependent on what the
|
378
|
+
def duration
|
379
|
+
case(duration_type)
|
380
|
+
when MEAN_DURATION
|
381
|
+
return mean_duration
|
382
|
+
when EXPECTED_DURATION
|
383
|
+
return expected_duration
|
384
|
+
when MINIMUM_DURATION
|
385
|
+
return minimum_duration
|
386
|
+
when MAXIMUM_DURATION
|
387
|
+
return maximum_duration
|
388
|
+
else
|
389
|
+
raise "Duration type '#{type}' is unknown."
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
# Returns the mean duration which is defined as
|
394
|
+
# (4*expected_duration + minimum_duration + maximum_duration)/6
|
395
|
+
def mean_duration
|
396
|
+
return ((4*expected_duration)+minimum_duration+maximum_duration)/6.0
|
397
|
+
end
|
398
|
+
|
399
|
+
# The variance of the duration of the activity. Defined as
|
400
|
+
# (maximum_duration - minimum_duration)^2/36
|
401
|
+
def variance
|
402
|
+
return standard_deviation**2
|
403
|
+
end
|
404
|
+
|
405
|
+
# The standard deviation of the duration of the activity dfined as
|
406
|
+
# (maximum_duraion - minimum_duration) / 6
|
407
|
+
def standard_deviation
|
408
|
+
(maximum_duration - minimum_duration)/6.0
|
409
|
+
end
|
410
|
+
|
411
|
+
# Sets start type the activity should use.
|
412
|
+
#
|
413
|
+
# Example usage:
|
414
|
+
# Activity.start_type = Activity::LATEST_START
|
415
|
+
# will change the start type to the latest start for all activities.
|
416
|
+
def start_type=(type) #:nodoc:
|
417
|
+
case(type)
|
418
|
+
when EARLIEST_START,LATEST_START,DROP_START
|
419
|
+
@start_type = type
|
420
|
+
else
|
421
|
+
raise "Start type '#{type}' is unknown."
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
# Returns the start time of the activity dependent on what the
|
426
|
+
# start_type has been set to.
|
427
|
+
def start
|
428
|
+
case(start_type)
|
429
|
+
when EARLIEST_START
|
430
|
+
return self.earliest_start
|
431
|
+
when LATEST_START
|
432
|
+
return self.latest_start
|
433
|
+
when DROP_START
|
434
|
+
return self.drop_start
|
435
|
+
else
|
436
|
+
raise "Start type '#{type}' is unknown."
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
# Returns the finish time of the activity dependent on what the
|
441
|
+
# start_type and duration_type have been set to. This is equivalent
|
442
|
+
# to calling
|
443
|
+
# activity.start + activity.duration
|
444
|
+
def finish
|
445
|
+
start + duration
|
446
|
+
end
|
447
|
+
|
448
|
+
# Returns an Activity object that is represented by the YAML object.
|
449
|
+
# A YAML object is the object returned from a YAML::load or
|
450
|
+
# YAML::load_documents method. This method will automatically load
|
451
|
+
# a Start/FinishActivity if such a yamlObject is given.
|
452
|
+
#
|
453
|
+
# *Note*: This method will only restore the reference, varios durations,
|
454
|
+
# description and resource parameters. Post-/pre-activities are not
|
455
|
+
# restored (they are restored when using Precedence::Network.from_yaml).
|
456
|
+
def self.from_yaml_object(yamlObject) #:nodoc:
|
457
|
+
reference,activity = yamlObject.to_a[0]
|
458
|
+
if (reference.to_s == StartActivity::REFERENCE)
|
459
|
+
return StartActivity.from_yaml_object(yamlObject)
|
460
|
+
elsif (reference.to_s == FinishActivity::REFERENCE)
|
461
|
+
return FinishActivity.from_yaml_object(yamlObject)
|
462
|
+
else
|
463
|
+
return Precedence::Activity.new(reference.to_s) do |act|
|
464
|
+
act.expected_duration = activity['expected duration'].to_f
|
465
|
+
act.minimum_duration = activity['minimum duration'].to_f
|
466
|
+
act.maximum_duration = activity['maximum duration'].to_f
|
467
|
+
act.description = activity['description'].to_s
|
468
|
+
if activity['resources']
|
469
|
+
activity['resources'].each do |resource,value|
|
470
|
+
act.resources[resource] = value
|
471
|
+
end
|
472
|
+
end
|
473
|
+
end
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
# Returns an Activity object that is represented by a YAML document.
|
478
|
+
#
|
479
|
+
# *Note*: This method will only restore the reference, various durations,
|
480
|
+
# description and resource parameters. Post-/pre-activities are not
|
481
|
+
# restored (they are restored when using Precedence::Network.from_yaml).
|
482
|
+
def self.from_yaml(yaml)
|
483
|
+
return self.from_yaml_object(YAML::load(yaml))
|
484
|
+
end
|
485
|
+
|
486
|
+
# Priviliege settings
|
487
|
+
protected :register_post_activity, :register_pre_activity
|
488
|
+
protected :deregister_post_activity, :deregister_pre_activity
|
489
|
+
|
490
|
+
private :pre_activities_max_earliest_finish
|
491
|
+
private :post_activities_min_earliest_start
|
492
|
+
end
|
493
|
+
|
494
|
+
|
495
|
+
# A special activity which signifies the start of a precedence network.
|
496
|
+
# It has a duration of 0 and is not allowed to have any pre_activities.
|
497
|
+
# It's reference will always be 'start'.
|
498
|
+
class StartActivity < Precedence::Activity #:nodoc:
|
230
499
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
500
|
+
attr_reader :expected_duration, :maximum_duration, :minimum_duration
|
501
|
+
|
502
|
+
# Reference for the StartActivity
|
503
|
+
REFERENCE = 'start'
|
504
|
+
|
505
|
+
# Creates a new start activity.
|
506
|
+
def initialize(description=nil)
|
507
|
+
@reference = REFERENCE
|
508
|
+
if (description.nil?)
|
509
|
+
@description = @reference
|
510
|
+
else
|
511
|
+
@description = description.to_s
|
237
512
|
end
|
513
|
+
@expected_duration = 0
|
514
|
+
@minimum_duration = 0
|
515
|
+
@maximum_duration = 0
|
516
|
+
@post_activities = []
|
517
|
+
@pre_activities = []
|
518
|
+
@resources = {}
|
519
|
+
@duration_type = EXPECTED_DURATION
|
520
|
+
@start_type = EARLIEST_START
|
521
|
+
end
|
522
|
+
|
238
523
|
|
239
|
-
|
240
|
-
|
241
|
-
|
524
|
+
def self.from_yaml_object(yamlObj) #:nodoc:
|
525
|
+
reference,activity = yamlObj.to_a[0]
|
526
|
+
if (reference == REFERENCE)
|
527
|
+
if (!activity.nil?)
|
528
|
+
return Precedence::StartActivity.new(activity['description'])
|
529
|
+
else
|
530
|
+
return Precedence::StartActivity.new
|
531
|
+
end
|
242
532
|
else
|
243
|
-
|
533
|
+
raise("A StartActivity can only have a reference of '#{REFERENCE}'."+
|
534
|
+
" Given reference was '#{reference}'.")
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
def add_pre_activities(*pre_activities) #:nodoc:
|
539
|
+
self
|
540
|
+
end
|
541
|
+
|
542
|
+
def register_pre_activity(activity) #:nodoc:
|
543
|
+
raise "This activity can not be a post-activity of any other "+
|
544
|
+
"activity."
|
545
|
+
end
|
546
|
+
end
|
547
|
+
|
548
|
+
# A special activity which signifies the finish of a precedence network.
|
549
|
+
# It has a duration of 0 and is not allowed to have any post_activities.
|
550
|
+
# It's reference will always be 'finish'.
|
551
|
+
class FinishActivity < Precedence::Activity #:nodoc:
|
552
|
+
|
553
|
+
attr_reader :expected_duration, :maximum_duration, :minimum_duration
|
554
|
+
|
555
|
+
# Reference for the FinishActivity
|
556
|
+
REFERENCE = 'finish'
|
557
|
+
|
558
|
+
# Creates a new finish activity.
|
559
|
+
def initialize(description=nil)
|
560
|
+
|
561
|
+
@reference = REFERENCE
|
562
|
+
if (description.nil?)
|
563
|
+
@description = @reference
|
564
|
+
else
|
565
|
+
@description = description.to_s
|
244
566
|
end
|
245
|
-
@
|
246
|
-
@
|
247
|
-
@
|
567
|
+
@expected_duration = 0
|
568
|
+
@minimum_duration = 0
|
569
|
+
@maximum_duration = 0
|
570
|
+
@post_activities = []
|
571
|
+
@pre_activities = []
|
572
|
+
@resources = {}
|
573
|
+
@duration_type = EXPECTED_DURATION
|
574
|
+
@start_type = EARLIEST_START
|
575
|
+
end
|
576
|
+
|
577
|
+
def self.from_yaml_object(yamlObj) #:nodoc:
|
578
|
+
reference,activity = yamlObj.to_a[0]
|
579
|
+
if (reference == REFERENCE)
|
580
|
+
if (!activity.nil?)
|
581
|
+
return Precedence::FinishActivity.new(activity['description'])
|
582
|
+
else
|
583
|
+
return Precedence::FinishActivity.new
|
584
|
+
end
|
585
|
+
else
|
586
|
+
raise "A FinishActivity can only have a reference of '#{REFERENCE}'."+
|
587
|
+
" Given reference was '#{reference}'."
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
def add_post_activities(*post_activities) #:nodoc:
|
592
|
+
self
|
593
|
+
end
|
594
|
+
|
595
|
+
def register_post_activity(activity) #:nodoc:
|
596
|
+
raise "This activity can not be a pre-activity of any other "+
|
597
|
+
"activity."
|
248
598
|
end
|
249
599
|
end
|
250
|
-
end
|
251
|
-
|
600
|
+
end
|