calculator_server.cpp
calculator_client.cpp
calculator_watcher.cpp
This particular piece is the watcher that uses the generated ObjectProxy derived class to observe calculation signals from the server.
The client and watcher both use the same proxy generated from the XML document (see the calculator server example for the modified document).
The proxy is generated with this command:
dbus-cxx-xml2cpp --xml calculator.xml --proxy -f
Here is the generated proxy file:
#ifndef __DBUS_PROXY_DBUS_EXAMPLE_CALCULATOR_H #define __DBUS_PROXY_DBUS_EXAMPLE_CALCULATOR_H #include <dbus-cxx.h> #include "calculator.h" namespace DBus { namespace Example { class CalculatorProxy : public ::DBus::ObjectProxy { protected: CalculatorProxy( ::DBus::Connection::pointer conn, const std::string& dest="dbuscxx.example.calculator.server", const std::string& path="/dbuscxx/example/Calculator"): ::DBus::ObjectProxy(conn, dest, path) { ::DBus::Path child_path; m_method_add_ddd = this->create_method< double,double,double >( "Calculator.Basic", "add" ); m_method_sub_ddd = this->create_method< double,double,double >( "Calculator.Basic", "sub" ); m_method_mul_ddd = this->create_method< double,double,double >( "Calculator.Basic", "mul" ); m_method_div_ddd = this->create_method< double,double,double >( "Calculator.Basic", "div" ); m_method_pi_d = this->create_method< double >( "Calculator.Basic", "pi" ); m_method_print_pi_v = this->create_method< void >( "Calculator.Basic", "print_pi" ); m_signal_calculation = this->create_signal<void,std::string,std::string,double,double,double>( "Calculator.Basic", "calculation" ); m_method_factorial_ty = this->create_method< uint64_t,uint8_t >( "Calculator.Computed", "factorial" ); m_method_fibonacci_ty = this->create_method< uint64_t,uint8_t >( "Calculator.Computed", "fibonacci" ); m_method_thue_morse_ty = this->create_method< uint64_t,uint8_t >( "Calculator.Computed", "thue_morse" ); m_signal_computation = this->create_signal<void,std::string,uint64_t,uint8_t>( "Calculator.Computed", "computation" ); } public: typedef DBusCxxPointer<CalculatorProxy> pointer; static pointer create( ::DBus::Connection::pointer conn, const std::string& dest="dbuscxx.example.calculator.server", const std::string& path="/dbuscxx/example/Calculator" ) { return pointer( new CalculatorProxy(conn, dest, path)); } double add( double a, double b ) { return (*m_method_add_ddd)( a, b); } double subtract( double a, double b ) { return (*m_method_sub_ddd)( a, b); } double multiply( double a, double b ) { return (*m_method_mul_ddd)( a, b); } double divide( double a, double b ) { return (*m_method_div_ddd)( a, b); } double pi( ) { return (*m_method_pi_d)(); } void print_pi( ) { return (*m_method_print_pi_v)(); } ::DBus::signal_proxy<void,std::string,std::string,double,double,double >& signal_calculation() { return *m_signal_calculation; } uint64_t factorial( uint8_t n ) { return (*m_method_factorial_ty)( n); } uint64_t fibonacci( uint8_t n ) { return (*m_method_fibonacci_ty)( n); } uint64_t thue_morse( uint8_t n ) { return (*m_method_thue_morse_ty)( n); } ::DBus::signal_proxy<void,std::string,uint64_t,uint8_t >& signal_computation() { return *m_signal_computation; } protected: ::DBus::MethodProxy<double,double,double>::pointer m_method_add_ddd; ::DBus::MethodProxy<double,double,double>::pointer m_method_sub_ddd; ::DBus::MethodProxy<double,double,double>::pointer m_method_mul_ddd; ::DBus::MethodProxy<double,double,double>::pointer m_method_div_ddd; ::DBus::MethodProxy<double>::pointer m_method_pi_d; ::DBus::MethodProxy<void>::pointer m_method_print_pi_v; ::DBus::signal_proxy<void,std::string,std::string,double,double,double>::pointer m_signal_calculation; ::DBus::MethodProxy<uint64_t,uint8_t>::pointer m_method_factorial_ty; ::DBus::MethodProxy<uint64_t,uint8_t>::pointer m_method_fibonacci_ty; ::DBus::MethodProxy<uint64_t,uint8_t>::pointer m_method_thue_morse_ty; ::DBus::signal_proxy<void,std::string,uint64_t,uint8_t>::pointer m_signal_computation; }; } } #endif
And here is the watcher application:
/*************************************************************************** * Copyright (C) 2009 by Rick L. Vinyard, Jr. * * rvinyard@cs.nmsu.edu * * * * This file is part of the dbus-cxx library. * * * * The dbus-cxx library is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * version 3 as published by the Free Software Foundation. * * * * The dbus-cxx library is distributed in the hope that it will be * * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this software. If not see <http://www.gnu.org/licenses/>. * ***************************************************************************/ #include "calculator_proxy.h" class Watcher { public: Watcher() { } ~Watcher() { } void watch( Examples::CalculatorInterface::pointer calc ) { calc->signal_calculation().connect( sigc::bind( sigc::mem_fun(*this,&Watcher::print_calculation), calc ) ); calc->signal_computation().connect( sigc::bind( sigc::mem_fun(*this,&Watcher::print_computation), calc ) ); } void print_calculation(std::string op, std::string opsym, double result, double param1, double param2, Examples::CalculatorInterface::pointer ci) { std::cout << ci->name() << ": " << param1 << " " << opsym << " " << param2 << " = " << result << std::endl; } void print_computation(std::string op, uint64_t result, uint8_t n, Examples::CalculatorInterface::pointer ci) { std::cout << ci->name() << ": " << op << "(" << (int)n << ") = " << result << std::endl; } }; class Recalculator: public Examples::Calculator { public: typedef DBusCxxPointer<CalculatorInterface> pointer; Recalculator(Examples::CalculatorInterface::pointer base) { if ( base ) base->signal_calculation().connect( sigc::mem_fun(*this, &Recalculator::on_calculation) ); } static pointer create( Examples::CalculatorInterface::pointer base ) { return pointer( new Recalculator(base) ); } ~Recalculator() { } virtual double add( double a, double b ) const { double result = a+b+2.0; m_signal_calculation.emit( "add", "+", result, a, b ); return result; } protected: void on_calculation( const std::string& op, const std::string& opsym, double result, double a, double b ) { if ( opsym.empty() ) return; switch (opsym[0]) { case '+': this->add(a,b); break; case '-': this->subtract(a,b); break; case '*': this->multiply(a,b); break; case '/': this->divide(a,b); break; } } }; int main() { DBus::init(); DBus::Dispatcher dispatcher; DBus::Connection::pointer connection = dispatcher.create_connection( DBus::BUS_SESSION ); DBus::Example::CalculatorProxy::pointer proxy = DBus::Example::CalculatorProxy::create(connection); proxy->set_name( "calculator" ); Watcher watcher; watcher.watch( proxy ); Recalculator::pointer recalculator = Recalculator::create(proxy); recalculator->set_name( "re-calculator" ); watcher.watch( recalculator ); std::cout << "Running" << std::flush; for (int i=0; i < 30; i++) { std::cout << "." << std::flush; sleep(1); } std::cout << std::endl; return 0; }