class Fit4Ruby::GlobalFitMessage

The GlobalFitMessage stores an abstract description of a particular FitMessage. It holds information like the name, the global ID number and the data fields of the message.

Attributes

field_values_by_name[R]
fields_by_name[R]
fields_by_number[R]
name[R]
number[R]

Public Class Methods

new(name, number, field_values_by_name = {}) click to toggle source

Create a new GlobalFitMessage definition. @param name [String] name of the FIT message @param number [Fixnum] global message number

# File lib/fit4ruby/GlobalFitMessage.rb, line 223
def initialize(name, number, field_values_by_name = {})
  @name = name
  @number = number
  # Field names must be unique. A name always matches a single Field.
  @fields_by_name = {}
  # Field numbers are not unique. A group of alternative fields shares the
  # same number and is stored as an AltField. Otherwise as Field.
  @fields_by_number = {}
  # To generate the proper definition message we need to know the length
  # of String and Array fields. This is only needed when writing FIT
  # files.
  @field_values_by_name = field_values_by_name
end

Public Instance Methods

==(m) click to toggle source

Two GlobalFitMessage objects are considered equal if they have the same number, name and list of named fields. In case they have String or Array values, they must have identical size.

# File lib/fit4ruby/GlobalFitMessage.rb, line 240
def ==(m)
  unless @number == m.number && @name == m.name &&
      @fields_by_name.keys.sort == m.fields_by_name.keys.sort
    return false
  end

  unless @field_values_by_name.size == m.field_values_by_name.size
    return false
  end

  unless @field_values_by_name.empty?
    @field_values_by_name.keys.each do |name|
      a = @field_values_by_name[name]
      b = m.field_values_by_name[name]
      if a.class != b.class
        return false
      end
      if a.is_a?(String)
        if a.bytes.length != b.bytes.length
          return false
        end
      elsif a.is_a?(Array)
        if a.length != b.length
          return false
        end
      end
    end
  end

  true
end
alt_field(number, ref_field, &block) click to toggle source

Define a new set of Field alternatives for this message definition.

# File lib/fit4ruby/GlobalFitMessage.rb, line 297
def alt_field(number, ref_field, &block)
  unless @fields_by_name.include?(ref_field)
    raise "Unknown ref_field: #{ref_field}"
  end

  field = AltField.new(self, ref_field, &block)
  register_field_by_number(field, number)
end
construct(field_values_by_name) click to toggle source
# File lib/fit4ruby/GlobalFitMessage.rb, line 322
def construct(field_values_by_name)
  gfm = GlobalFitMessage.new(@name, @number, field_values_by_name)

  @fields_by_number.each do |number, field|
    if field.is_a?(AltField)
      # For alternative fields, we need to look at the value of the
      # selector field and pick the corresponding Field.
      field = field.select(field_values_by_name)
    end
    gfm.field(number, field.type, field.name, field.opts)
  end

  gfm
end
each_field(field_values) { |number, field| ... } click to toggle source
# File lib/fit4ruby/GlobalFitMessage.rb, line 272
def each_field(field_values)
  @fields_by_number.each do |number, field|
    if field.is_a?(AltField)
      # For alternative fields, we need to look at the value of the
      # selector field and pick the corresponding Field.
      field = field.select(field_values)
    end

    yield(number, field)
  end
end
field(number, type, name, opts = {}) click to toggle source

Define a new Field for this message definition.

# File lib/fit4ruby/GlobalFitMessage.rb, line 285
def field(number, type, name, opts = {})
  field = Field.new(type, name, opts)
  register_field_by_name(field, name)
  register_field_by_number(field, number)
end
has_field?(name) click to toggle source

Check if a field with the given name already exists?

# File lib/fit4ruby/GlobalFitMessage.rb, line 292
def has_field?(name)
  return @fields_by_name.include?(name)
end
register_field_by_name(field, name) click to toggle source
# File lib/fit4ruby/GlobalFitMessage.rb, line 306
def register_field_by_name(field, name)
  if @fields_by_name.include?(name)
    raise "Field '#{name}' has already been defined"
  end

  @fields_by_name[name] = field
end
register_field_by_number(field, number) click to toggle source
# File lib/fit4ruby/GlobalFitMessage.rb, line 314
def register_field_by_number(field, number)
  if @fields_by_name.include?(number)
    raise "Field #{number} has already been defined"
  end

  @fields_by_number[number] = field
end
write(io, local_message_type) click to toggle source
# File lib/fit4ruby/GlobalFitMessage.rb, line 337
def write(io, local_message_type)
  header = FitRecordHeader.new
  header.normal = 0
  header.message_type = 1
  header.local_message_type = local_message_type
  header.write(io)

  definition = FitDefinition.new
  definition.global_message_number = @number
  definition.setup(self, @field_values_by_name)
  definition.write(io)
end