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.



287
288
289
290
291
292
293
294
295
# File 'lib/dbus.rb', line 287

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



304
305
306
307
308
# File 'lib/dbus.rb', line 304

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)


310
311
312
# File 'lib/dbus.rb', line 310

def object_method_called
  raise NotImplementedError, "Not implemented"
end

#on_message(connection, message) ⇒ Object



314
315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/dbus.rb', line 314

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



298
299
300
# File 'lib/dbus.rb', line 298

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