Class: DBus::Object

Inherits:
Object
  • Object
show all
Defined in:
lib/dbus/object.rb

Overview

Exported object type

Exportable D-Bus object class

Objects that are going to be exported by a D-Bus service should inherit from this class. At the client side, use ProxyObject.

Defined Under Namespace

Classes: UndefinedInterface

Constant Summary collapse

@@cur_intf =

Interface

nil
@@intfs_mutex =
Mutex.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ Object

Create a new object with a given path. Use Service#export to export it.



33
34
35
36
# File 'lib/dbus/object.rb', line 33

def initialize(path)
  @path = path
  @service = nil
end

Instance Attribute Details

#pathObject (readonly)

The path of the object.



20
21
22
# File 'lib/dbus/object.rb', line 20

def path
  @path
end

#service=(value) ⇒ Object (writeonly)

The service that the object is exported by.



26
27
28
# File 'lib/dbus/object.rb', line 26

def service=(value)
  @service = value
end

Class Method Details

.dbus_interface(s) ⇒ Object

Select (and create) the interface that the following defined methods belong to.



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/dbus/object.rb', line 71

def self.dbus_interface(s)
  @@intfs_mutex.synchronize do
    @@cur_intf = intfs[s]
    if !@@cur_intf
      @@cur_intf = Interface.new(s)
      # As this is a mutable class_attr, we cannot use
      #   self.intfs[s] = @@cur_intf                      # Hash#[]=
      # as that would modify parent class attr in place.
      # Using the setter lets a subclass have the new value
      # while the superclass keeps the old one.
      self.intfs = intfs.merge(s => @@cur_intf)
    end
    yield
    @@cur_intf = nil
  end
end

.dbus_method(sym, protoype = "", &block) ⇒ Object

Defines an exportable method on the object with the given name sym, prototype and the code in a block.

Raises:



97
98
99
100
101
# File 'lib/dbus/object.rb', line 97

def self.dbus_method(sym, protoype = "", &block)
  raise UndefinedInterface, sym if @@cur_intf.nil?
  @@cur_intf.define(Method.new(sym.to_s).from_prototype(protoype))
  define_method(Object.make_method_name(@@cur_intf.name, sym.to_s), &block)
end

.dbus_signal(sym, protoype = "") ⇒ Object

Defines a signal for the object with a given name sym and prototype.

Raises:



110
111
112
113
114
115
116
117
118
# File 'lib/dbus/object.rb', line 110

def self.dbus_signal(sym, protoype = "")
  raise UndefinedInterface, sym if @@cur_intf.nil?
  cur_intf = @@cur_intf
  signal = Signal.new(sym.to_s).from_prototype(protoype)
  cur_intf.define(Signal.new(sym.to_s).from_prototype(protoype))
  define_method(sym.to_s) do |*args|
    emit(cur_intf, signal, *args)
  end
end

.make_method_name(intfname, methname) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Helper method that returns a method name generated from the interface name intfname and method name methname.



125
126
127
# File 'lib/dbus/object.rb', line 125

def self.make_method_name(intfname, methname)
  "#{intfname}%%#{methname}"
end

Instance Method Details

#dispatch(msg) ⇒ Object

Dispatch a message msg to call exported methods



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/dbus/object.rb', line 39

def dispatch(msg)
  case msg.message_type
  when Message::METHOD_CALL
    reply = nil
    begin
      if !intfs[msg.interface]
        raise DBus.error("org.freedesktop.DBus.Error.UnknownMethod"),
              "Interface \"#{msg.interface}\" of object \"#{msg.path}\" doesn't exist"
      end
      meth = intfs[msg.interface].methods[msg.member.to_sym]
      if !meth
        raise DBus.error("org.freedesktop.DBus.Error.UnknownMethod"),
              "Method \"#{msg.member}\" on interface \"#{msg.interface}\" of object \"#{msg.path}\" doesn't exist"
      end
      methname = Object.make_method_name(msg.interface, msg.member)
      retdata = method(methname).call(*msg.params)
      retdata = [*retdata]

      reply = Message.method_return(msg)
      meth.rets.zip(retdata).each do |rsig, rdata|
        reply.add_param(rsig.type, rdata)
      end
    rescue => ex
      dbus_msg_exc = msg.annotate_exception(ex)
      reply = ErrorMessage.from_exception(dbus_msg_exc).reply_to(msg)
    end
    @service.bus.message_queue.push(reply)
  end
end

#emit(intf, sig, *args) ⇒ Object

Emits a signal from the object with the given interface, signal sig and arguments args.



105
106
107
# File 'lib/dbus/object.rb', line 105

def emit(intf, sig, *args)
  @service.bus.emit(@service, self, intf, sig, *args)
end