Skip to content

Observing models

Romain Franceschini edited this page Apr 27, 2020 · 2 revisions

Quartz provides a simple publish/subscribe mechanism to observe both the state of a model and its ports based on the Observer pattern. While being simulated, a model and its ports can inform a set of third-party objects either when a state transition occur, or when a message is sent over ports.

Such design can be used to develop specific pieces of software that can react to models dynamics. For example, one can develop a graphical user interface for its model to help him better visualize the state of a model, which can be laid out when necessary. Based on the same idea, observing a port of a given model may be useful for a piece of software responsible for plotting its values. This feature establish a simple way to react to the evolution of models. It can be used by the modeler for model-specific code, but could also be used by a larger M&S environment relying on Quartz as a simulation kernel.

Define an observer

An observer object must conforms to the Observer protocol. It subscribes to updates using Observable#add_observer. Observable classes include AtomicModel, OutputPort and MultiComponent::Component.

Example 1: Observing model state changes

class MyObserver
  include Quartz::Observer
  
  def update(observable, info)
    if observable.is_a?(MyModel)
      model = observable.as(MyModel)
      puts "#{model.name} changed its state to #{model.phase}"
    end
  end
end
  
model = MyModel.new("mymodel")
model.add_observer(MyObserver.new)
Quartz::Simulation.new(model).simulate

Example 2: Observing outputs on a port

class MyObserver
  include Quartz::Observer

  def update(observable, info)
    if observable.is_a?(Port)
      puts "port '#{port.name}' sent value '#{info[:payload]}'"
    end
  end
end

model = MyModel.new("mymodel")
model.output_port(:out).add_observer(MyObserver.new)
Quartz::Simulation.new(model).simulate

Next: Simulation hooks

Clone this wiki locally