class Roby::StateField
Representation of a level in the current state
Public Class Methods
Roby::OpenStruct::new
# File lib/roby/state/state_model.rb, line 144 def initialize(model = nil, attach_to = nil, attach_name = nil) if !attach_to # We are root, initialize last_known and data_sources @last_known = StateLastValueField.new @data_sources = StateDataSourceField.new end super(model, attach_to, attach_name) if model # If we do have a model, verify that the assigned values match # the model's type global_filter do |name, value| if (field_model = model.get(name)) && (field_type = field_model.type) if !(field_type === value) raise ArgumentError, "field #{name} is expected to have values of type #{field_type.name}, #{value} is of type #{value.class}" end end value end end end
Public Instance Methods
Reimplemented from OpenStruct
It disables automatic substruct creation for state variables for which a data source exists
# File lib/roby/state/state_model.rb, line 195 def __get(name, create_substruct = true) if (source = data_sources.get(name)) && !source.kind_of?(StateDataSourceField) # Don't create a substruct, we know that this subfield should be # populated by the data source create_substruct = false end return super(name, create_substruct) end
Roby::OpenStruct#attach
# File lib/roby/state/state_model.rb, line 175 def attach super @last_known.attach @data_sources.attach end
# File lib/roby/state/state_model.rb, line 216 def create_model StateModel.new end
Returns a structure that gives access to the data sources for the members of this struct. I.e.
state.pose.data_sources.position
will give the data source for state.pose.position if there is one.
Due to the use of open structures, one should always check for the presence of the field first with
if state.pose.data_sources.position? # do something with state.pose.data_sources.position end
Note that the models are accessible from any level, i.e. state.model.pose.position is an equivalent of the above example.
# File lib/roby/state/state_model.rb, line 140 def data_sources @data_sources end
Returns a structure that gives access to the last known values for the members of this struct. I.e.
state.pose.last_known.position
is the last value known for state.pose.position
Note that the last known values are accessible from any level, i.e. state.last_known.pose.position is an equivalent of the above example.
# File lib/roby/state/state_model.rb, line 119 def last_known @last_known end
Roby::OpenStruct#link_to
# File lib/roby/state/state_model.rb, line 167 def link_to(parent, name) super @last_known = parent.last_known.get(name) || StateLastValueField.new(nil, parent.last_known, name) @data_sources = parent.data_sources.get(name) || StateDataSourceField.new(nil, parent.data_sources, name) end
Reimplemented from OpenStruct
# File lib/roby/state/state_model.rb, line 182 def method_missing(name, *args) if name =~ /(.*)=$/ if data_source = data_sources.get($1) raise ArgumentError, "cannot explicitely set a field for which a data source exists" end end super end
Returns a structure that gives access to the models of the members of this struct. I.e.
state.pose.model.position
is the model for state.pose.position
Due to the use of open structures, one should always check for the presence of the field first with
if state.pose.model.position? # do something with state.pose.model.position end
Note that the models are accessible from any level, i.e. state.model.pose.position is an equivalent of the above example.
# File lib/roby/state/state_model.rb, line 106 def model @model end
Read each subfield that have a source, and update both their last_known
and current value.
# File lib/roby/state/state_model.rb, line 206 def read data_sources.each_member do |field_name, field_source| new_value = field_source.read set(field_name, new_value) if new_value last_known.set(field_name, new_value) end end end
# File lib/roby/state/state_model.rb, line 86 def to_s "#<StateField:#{object_id} path=#{path.join("/")} fields=#{@members.keys.sort.join(",")}>" end