Class: SimpleKit::EventScheduler

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

Overview

Class EventScheduler provides the computation engine for a discrete event simulation model. It uses an array-based priority queue implementation for the pending events list.

Users must create a model class which:

  • implements an init method;

  • Instantiates a model and invokes the run method to start execution.

Defined Under Namespace

Classes: EventNotice

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(the_model) ⇒ EventScheduler

Initialize the EventScheduler by remembering the specified model and setting up an empty event list.



42
43
44
45
46
# File 'lib/simplekit.rb', line 42

def initialize(the_model)
  @user_model = the_model
  @event_list = PriorityQueue.new
  @cancel_set = {}
end

Instance Attribute Details

#model_timeObject (readonly)

Returns the value of attribute model_time.



38
39
40
# File 'lib/simplekit.rb', line 38

def model_time
  @model_time
end

#user_modelObject (readonly)

Returns the value of attribute user_model.



38
39
40
# File 'lib/simplekit.rb', line 38

def user_model
  @user_model
end

Instance Method Details

#cancel(event, args = {}) ⇒ Object

Cancel an individual occurrence of event type event. If no args are provided, the next scheduled occurrence of event is targeted. If a subset of the event’s args is provided, they must all be a match with the corresponding args of the scheduled event in order for the cancellation to apply, but args which are not specified do not affect the target event matching.



68
69
70
71
72
# File 'lib/simplekit.rb', line 68

def cancel(event, args = {})
  @cancel_set[event] ||= Set.new
  # @cancel_set[event].add(args.empty? ? nil : args)
  @cancel_set[event].add(args)
end

#cancel_all(event) ⇒ Object

Cancel all currently scheduled events of type event.



75
76
77
78
79
80
81
82
83
84
# File 'lib/simplekit.rb', line 75

def cancel_all(event)
  if event
    PriorityQueue.new.tap do |pq|
      while (event_notice = @event_list.pop)
        pq.push event_notice unless event_notice.event == event
      end
      @event_list = pq
    end
  end
end

#haltObject

Clear the event list, which causes termination of the simulation. Never schedule any new events after invoking halt.



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

def halt
  @event_list.clear
end

#runObject

Start execution of a model. The simulation model_time is initialized to zero and the model is initialized via the mandatory init method. Then loop while events are pending on the event_list. The event with the smallest time is popped, model_time is updated to the event time, and the event method is invoked with the args, if any, set by schedule.



91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/simplekit.rb', line 91

def run
  @model_time = 0.0
  @user_model.init
  while (current_event = @event_list.pop)
    next if should_cancel?(current_event)
    @model_time = current_event.time
    if current_event.args.empty?
      @user_model.send(current_event.event)
    else
      @user_model.send(current_event.event, **current_event.args)
    end
  end
end

#schedule(event, delay, args = {}) ⇒ Object

Add an event to the pending events list.

Arguments
  • event -> the event to be scheduled.

  • delay -> the amount of time which should elapse before the event executes.

  • args -> zero or more named arguments to pass to the event at invocation time. These should be specified with labels, and consequently they can be placed in any order.



57
58
59
60
# File 'lib/simplekit.rb', line 57

def schedule(event, delay, args = {})
  raise 'Model scheduled event with negative delay.' if delay < 0
  @event_list.push EventNotice.new(event, @model_time, delay, args)
end