Module: Roby::Interface::V2::Protocol

Defined in:
lib/roby/interface/v2/protocol.rb

Overview

Protocol definition for communications in the Interface protocol

Nothing else than this and basic types is allowed

See Also:

Defined Under Namespace

Classes: Action, ActionArgument, ActionModel, DelayedArgumentFromState, Error, ExecutionException, StructObject, Task, TaskEvent, TaskEventGenerator, VoidClass

Constant Summary collapse

Void =
VoidClass.new.freeze
BUILTIN_ALLOWED_CLASSES =

List of classes allowed to be transmitted as-is by the protocol

[
    Action,
    ActionArgument,
    Error,
    CommandLibrary::InterfaceCommands,
    Command,
    ExecutionException,
    Time,
    Regexp
].freeze
BUILTIN_MARSHALLERS =

List of classes and methods that should be used to marshal them

[
    [Actions::Models::Action, :marshal_action_model],
    [Actions::Action, :marshal_action],
    [Roby::Task, :marshal_task],
    [Roby::TaskEventGenerator, :marshal_task_event_generator],
    [Roby::TaskEvent, :marshal_task_event],
    [::Exception, :marshal_exception],
    [Roby::ExecutionException, :marshal_execution_exception],
    [Roby::DelayedArgumentFromState, :marshal_delayed_argument_from_state]
].freeze

Class Method Summary collapse

Class Method Details

.add_marshaller(*classes, &block) ⇒ Object



190
191
192
# File 'lib/roby/interface/v2/protocol.rb', line 190

def self.add_marshaller(*classes, &block)
    classes.each { @marshallers[_1] = block }
end

.allow_classes(*classes) ⇒ Object



182
183
184
# File 'lib/roby/interface/v2/protocol.rb', line 182

def self.allow_classes(*classes)
    add_marshaller(*classes) { _2 }
end

.allow_objects(*objects) ⇒ Object



186
187
188
# File 'lib/roby/interface/v2/protocol.rb', line 186

def self.allow_objects(*objects)
    @allowed_objects.merge(objects)
end

.each_marshaller(&block) ⇒ Object



194
195
196
# File 'lib/roby/interface/v2/protocol.rb', line 194

def self.each_marshaller(&block)
    @marshallers.each(&block)
end

.marshal_action(channel, action) ⇒ Action

Convert a Actions::Action

Parameters:

Returns:



259
260
261
262
263
264
# File 'lib/roby/interface/v2/protocol.rb', line 259

def self.marshal_action(channel, action)
    Action.new(
        model: marshal_action_model(channel, action.model),
        arguments: channel.marshal_filter_object(action)
    )
end

.marshal_action_argument_model(channel, action_argument) ⇒ ActionArgument

Parameters:

Returns:



248
249
250
251
252
# File 'lib/roby/interface/v2/protocol.rb', line 248

def self.marshal_action_argument_model(channel, action_argument)
    Protocol::ActionArgument.new(
        **channel.marshal_filter_object(action_argument.to_h)
    )
end

.marshal_action_model(channel, action, planner_model: nil) ⇒ ActionModel

Parameters:

Returns:



271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/roby/interface/v2/protocol.rb', line 271

def self.marshal_action_model(channel, action, planner_model: nil)
    arguments = action.arguments.map do
        marshal_action_argument_model(channel, _1)
    end
    ActionModel.new(
        planner_name: planner_model&.name,
        name: action.name,
        doc: action.doc,
        arguments: arguments,
        advanced: action.advanced?
    )
end

.marshal_delayed_argument_from_state(_channel, delayed_arg) ⇒ Object



368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
# File 'lib/roby/interface/v2/protocol.rb', line 368

def self.marshal_delayed_argument_from_state(_channel, delayed_arg)
    object =
        case delayed_arg.__object__
        when Conf
            :Conf
        when State
            :State
        else
            delayed_arg.__object__.to_s
        end

    DelayedArgumentFromState.new(
        object: object, path: delayed_arg.__methods__
    )
end

.marshal_exception(_channel, exception) ⇒ Error

Convert a Exception

Parameters:

Returns:



341
342
343
344
345
346
347
# File 'lib/roby/interface/v2/protocol.rb', line 341

def self.marshal_exception(_channel, exception)
    message = PP.pp(exception, +"").chomp
    Error.new(
        class_name: exception.class.name, message: message,
        backtrace: exception.backtrace || []
    )
end

.marshal_execution_exception(channel, execution_exception) ⇒ Object

Convert a ExecutionException



350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
# File 'lib/roby/interface/v2/protocol.rb', line 350

def self.marshal_execution_exception(channel, execution_exception)
    exception = execution_exception.exception
    if exception.respond_to?(:failed_task) &&
       (failed_task = exception.failed_task)
        marshalled_failed_task =
            channel.marshal_filter_object(failed_task)
    end

    ExecutionException.new(
        exception: marshal_exception(channel, exception),
        failed_task: marshalled_failed_task,
        involved_tasks: channel.marshal_filter_object(
            execution_exception.each_involved_task.to_a
        )
    )
end

.marshal_struct_generic(channel, object) ⇒ Object

Generic path to marshal a struct



387
388
389
390
391
392
# File 'lib/roby/interface/v2/protocol.rb', line 387

def self.marshal_struct_generic(channel, object)
    contents = object.to_h.transform_values do |v|
        channel.marshal_filter_object(v)
    end
    StructObject.new(klass: object.class.name, contents: contents)
end

.marshal_task(channel, task) ⇒ Task

Convert a Task

Parameters:

Returns:



289
290
291
292
293
294
295
296
297
# File 'lib/roby/interface/v2/protocol.rb', line 289

def self.marshal_task(channel, task)
    Task.new(
        id: task.droby_id.id,
        model: task.model.name,
        state: task.current_roby_task_state,
        started_since: task.start_event.last&.time,
        arguments: marshal_task_arguments(channel, task.arguments)
    )
end

.marshal_task_arguments(channel, arguments) ⇒ Hash

Convert a TaskArguments

Parameters:

Returns:

  • (Hash)


304
305
306
307
308
# File 'lib/roby/interface/v2/protocol.rb', line 304

def self.marshal_task_arguments(channel, arguments)
    arguments.assigned_arguments.transform_values do
        channel.marshal_filter_object(_1)
    end
end

.marshal_task_event(channel, event) ⇒ TaskEvent

Convert a TaskEventGenerator

Parameters:

Returns:



327
328
329
330
331
332
333
334
# File 'lib/roby/interface/v2/protocol.rb', line 327

def self.marshal_task_event(channel, event)
    TaskEvent.new(
        time: event.time,
        generator: marshal_task_event_generator(channel, event.generator),
        context: channel.marshal_filter_object(event.context),
        propagation_id: event.propagation_id
    )
end

.marshal_task_event_generator(channel, generator) ⇒ TaskEventGenerator

Convert a TaskEventGenerator

Parameters:

Returns:



315
316
317
318
319
320
# File 'lib/roby/interface/v2/protocol.rb', line 315

def self.marshal_task_event_generator(channel, generator)
    TaskEventGenerator.new(
        task: marshal_task(channel, generator.task),
        symbol: generator.symbol
    )
end

.register_marshallers(protocol) ⇒ Object



222
223
224
225
226
227
228
229
# File 'lib/roby/interface/v2/protocol.rb', line 222

def self.register_marshallers(protocol)
    protocol.allow_classes(*BUILTIN_ALLOWED_CLASSES)
    protocol.add_marshaller(Roby::VoidClass) { Void }

    BUILTIN_MARSHALLERS.each do |klass, method|
        protocol.add_marshaller(klass, &method(method))
    end
end

.setup_channel(channel) ⇒ Object

Configure channel marshalling to convert Roby classes into their protocol equivalent

Parameters:



235
236
237
238
239
240
241
# File 'lib/roby/interface/v2/protocol.rb', line 235

def self.setup_channel(channel)
    each_marshaller do |klass, block|
        channel.add_marshaller(klass, &block)
    end

    channel.allow_objects(*@allowed_objects)
end

.unmarshal_object(channel, object) ⇒ Object



394
395
396
397
398
399
400
401
402
403
404
405
# File 'lib/roby/interface/v2/protocol.rb', line 394

def self.unmarshal_object(channel, object)
    case object
    when Array
        object.map { unmarshal_object(channel, _1) }
    when Hash
        object.transform_values { unmarshal_object(channel, _1) }
    when StructObject
        unmarshal_struct_generic(channel, object)
    else
        object
    end
end

.unmarshal_struct_generic(channel, object) ⇒ Object



407
408
409
410
411
412
413
# File 'lib/roby/interface/v2/protocol.rb', line 407

def self.unmarshal_struct_generic(channel, object)
    o = channel.resolve_struct(object).new
    object.contents.each do |k, v|
        o[k] = unmarshal_object(channel, v)
    end
    o
end

.void?(value) ⇒ Boolean

Returns:

  • (Boolean)


175
176
177
# File 'lib/roby/interface/v2/protocol.rb', line 175

def self.void?(value)
    value.kind_of?(VoidClass)
end