Class: DBus::ObjectTree

Inherits:
DBusCallable show all
Defined in:
lib/dbus.rb

Overview

An object tree allows you to register a handler for a tree of object paths. This means that literal Ruby objects do not need to be created for each object over the bus, but you can have a virtual tree of objects handled by a single Ruby object. There are two ways to handle method calls on virtual objects:

  1. Pass a list of dbus_methods in to initialize. This works just like DBus::Object, except an object_path is passed as the first argument to each method, denoting which virtual object the call was made on. If all the objects in the tree support the same methods, this is the best approach.

  2. Override object_method_called. This allows you to define the valid methods dynamically on an object by object basis. For example, if providing an object tree that represented a filesystem heirarchy, you'd only want an ls method on directory objects, not file objects.

Instance Method Summary collapse

Methods inherited from DBusCallable

#dispatch, #dispatch_message, #new_error_reply, #on_unregister

Constructor Details

#initialize(base_path, service, dbus_methods = []) ⇒ ObjectTree

Returns a new instance of ObjectTree.


307
308
309
310
311
312
313
314
315
# File 'lib/dbus.rb', line 307

def initialize(base_path, service, dbus_methods=[])
  @connection = service.get_bus.get_connection
  super(@connection, dbus_methods)
  @base_path = base_path
  @service = service
  @methods = dbus_methods
  @service.get_bus.get_connection.register_fallback(base_path, method(:on_unregister),
                                                    method(:on_message))
end

Instance Method Details

#broadcast_signal(interface, signal_name, relative_path) ⇒ Object

Broadcast the signal signal_name for interface interface for the object identified by relative_path


324
325
326
327
328
# File 'lib/dbus.rb', line 324

def broadcast_signal(interface, signal_name, relative_path)
  object_path = relative_path_to_object_path(relative_path)
  message = DBus::Binding::DBusMessage.new_signal(object_path, interface, signal_name)
  @connection.send(message)
end

#object_method_calledObject

Raises:

  • (NotImplementedError)

330
331
332
# File 'lib/dbus.rb', line 330

def object_method_called
  raise NotImplementedError, "Not implemented"
end

#on_message(connection, message) ⇒ Object


334
335
336
337
338
339
340
341
342
343
344
345
346
347
# File 'lib/dbus.rb', line 334

def on_message(connection, message)
  target_object_full_path = message.get_path
  n = @base_path.length
  unless @base_path == target_object_full_path[0,n]
    @connection.send(new_error_reply(message, "Invalid target path: #{target_object_full_path}"))
    return HANDLER_RESULT_HANDLED
  end
  target_object_path = target_object_full_path[n..-1]
  target_method = message.get_member
  target_args = message.to_a
  args = [target_object_path, *target_args]
  @connection.send(dispatch(target_method, args, message))
  HANDLER_RESULT_HANDLED
end

#relative_path_to_object_path(path) ⇒ Object

Create a new absolute ObjectPath for the given relative path


318
319
320
# File 'lib/dbus.rb', line 318

def relative_path_to_object_path(path)
  ObjectPath.new(@base_path + path)
end