Skip to content

Commit

Permalink
Implemented Properties.GetAll support
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Haefner committed Jan 30, 2021
1 parent ff68b7a commit a8a8e44
Show file tree
Hide file tree
Showing 10 changed files with 460 additions and 121 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ add_library(simppl SHARED
src/clientside.cpp
src/serialization.cpp
src/bool.cpp
src/holders.cpp
)
# Provide a namespaced alias
add_library(Simppl::simppl ALIAS simppl)
Expand Down
4 changes: 1 addition & 3 deletions include/simppl/clientside.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,6 @@ struct ClientPropertyBase
StubBase* stub_;

eval_type eval_;

ClientPropertyBase* next_;
};


Expand Down Expand Up @@ -267,7 +265,7 @@ DataT ClientProperty<DataT, Flags>::get()
template<typename DataT, int Flags>
ClientProperty<DataT, Flags>& ClientProperty<DataT, Flags>::attach()
{
this->stub_->attach_property(*this);
this->stub_->attach_property(this);

dbus_pending_call_set_notify(this->stub_->get_property_async(this->name_).pending(),
&holder_type::pending_notify,
Expand Down
16 changes: 7 additions & 9 deletions include/simppl/serverside.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,14 +203,14 @@ struct ServerMethod : ServerMethodBase

struct ServerPropertyBase
{
typedef void (*eval_type)(ServerPropertyBase*, DBusMessage*);
typedef void (*eval_type)(ServerPropertyBase*, DBusMessageIter*);
typedef void (*eval_set_type)(ServerPropertyBase*, DBusMessageIter&);

ServerPropertyBase(const char* name, SkeletonBase* iface, int iface_id);

void eval(DBusMessage* msg)
void eval(DBusMessageIter* iter)
{
eval_(this, msg);
return eval_(this, iter);
}

void evalSet(DBusMessageIter& iter)
Expand Down Expand Up @@ -258,16 +258,14 @@ struct BaseProperty : ServerPropertyBase
}

static
void __eval(ServerPropertyBase* obj, DBusMessage* response)
void __eval(ServerPropertyBase* obj, DBusMessageIter* iter)
{
DBusMessageIter iter;
dbus_message_iter_init_append(response, &iter);

auto that = ((BaseProperty*)obj);

// missing initialization?
assert(!that->t_.empty());
detail::PropertyCodec<DataT>::encode(iter, that->t_.template get<cb_type>() ? (*that->t_.template get<cb_type>())() : *that->t_.template get<DataT>());

detail::PropertyCodec<DataT>::encode(*iter, that->t_.template get<cb_type>() ? (*that->t_.template get<cb_type>())() : *that->t_.template get<DataT>());
}

void notify(const DataT& data)
Expand Down
3 changes: 2 additions & 1 deletion include/simppl/skeletonbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,11 @@ struct SkeletonBase
DBusHandlerResult handle_property_set_request(DBusMessage* msg, ServerPropertyBase& property, DBusMessageIter& iter);
DBusHandlerResult handle_interface_request(DBusMessage* msg, ServerMethodBase& method);
DBusHandlerResult handle_error(DBusMessage* msg, const char* dbus_error);
DBusHandlerResult handle_property_getall_request(DBusMessage* msg, int iface_id);

#if SIMPPL_HAVE_INTROSPECTION
void introspect_interface(std::ostream& os, size_type index) const;
#endif
#endif
bool has_any_properties() const;
ServerPropertyBase* find_property(int iface_id, const char* name) const;
ServerMethodBase* find_method(int iface_id, const char* name) const;
Expand Down
61 changes: 57 additions & 4 deletions include/simppl/stubbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@

#include "simppl/callstate.h"
#include "simppl/pendingcall.h"
#include "simppl/variant.h"

#include "simppl/detail/constants.h"
#include "simppl/detail/holders.h"

#include "simppl/connectionstate.h"

Expand All @@ -29,13 +32,16 @@ struct ClientPropertyBase;

struct StubBase
{
typedef detail::InterimGetAllPropertiesCallbackHolder getall_properties_holder_type;

template<typename... T> friend struct ClientSignal;
template<typename... T> friend struct ClientMethod;
template<typename, int> friend struct ClientProperty;
template<typename, typename> friend struct ClientPropertyWritableMixin;

friend struct Dispatcher;
friend struct ClientPropertyBase;
friend struct detail::GetAllPropertiesHolder;

StubBase(const StubBase&) = delete;
StubBase& operator=(const StubBase&) = delete;
Expand Down Expand Up @@ -82,6 +88,30 @@ struct StubBase
return busname_;
}

/**
* Implementation of org.freedesktop.DBus.Properties.GetAll(). Blocking call.
*
* Before calling this method all Properties callbacks shall be installed.
* The properties callbacks will then be called before this function returns.
*
* Issues a call like this:
* dbus-send --print-reply --dest=test.Properties.s /test/Properties/s org.freedesktop.DBus.Properties.GetAll string:test.Properties
*
* @TODO complete async support
*/
void get_all_properties();

/**
* Implementation of org.freedesktop.DBus.Properties.GetAll(). Asynchronous call.
*
* Before calling this method all Properties callbacks shall be installed. You may install
* only some of the property callbacks. If a callback is not registered the property will
* just omitted.
*
* The asynchronous return will arrive as soon as call the property callbacks are evaluated.
*/
getall_properties_holder_type get_all_properties_async();


protected:

Expand All @@ -98,8 +128,8 @@ struct StubBase
void register_signal(ClientSignalBase& sigbase);
void unregister_signal(ClientSignalBase& sigbase);

void attach_property(ClientPropertyBase& prop);
void detach_property(ClientPropertyBase& prop);
void attach_property(ClientPropertyBase* prop);
void detach_property(ClientPropertyBase* prop);

/**
* Blocking call.
Expand All @@ -113,22 +143,45 @@ struct StubBase
*/
void set_property(const char* Name, std::function<void(DBusMessageIter&)>&& f);

/**
* Just register the property within the stub.
*/
void add_property(ClientPropertyBase* property);

PendingCall set_property_async(const char* Name, std::function<void(DBusMessageIter&)>&& f);

/**
* Second part of get_all_properties_async. Once the callback arrives
* the property callbacks have to be called.
*/
simppl::dbus::CallState get_all_properties_handle_response(DBusMessage& response);

std::vector<std::string> ifaces_;
char* objectpath_;
std::string busname_;
ConnectionState conn_state_;

Dispatcher* disp_;

ClientSignalBase* signals_; ///< attached signals
ClientPropertyBase* properties_; ///< attached properties
ClientSignalBase* signals_; ///< attached signals

std::vector<std::pair<ClientPropertyBase*, bool /*attached*/>> properties_; ///< all properties TODO maybe take another container...
int attached_properties_; ///< attach counter
};

} // namespace dbus

} // namespace simppl


inline
void operator>>(simppl::dbus::detail::InterimGetAllPropertiesCallbackHolder&& r, const std::function<void(simppl::dbus::CallState)>& f)
{
dbus_pending_call_set_notify(r.pc_.pending(),
&simppl::dbus::detail::GetAllPropertiesHolder::pending_notify,
new simppl::dbus::detail::GetAllPropertiesHolder(f, r.stub_),
&simppl::dbus::detail::GetAllPropertiesHolder::_delete);
}


#endif // SIMPPL_STUBBASE_H
10 changes: 4 additions & 6 deletions src/clientside.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@

namespace simppl
{

namespace dbus
{


ClientSignalBase::ClientSignalBase(const char* name, StubBase* stub, int)
: stub_(stub)
, name_(name)
, next_(nullptr)
{
// NOOP
}
Expand All @@ -20,16 +19,15 @@ ClientSignalBase::ClientSignalBase(const char* name, StubBase* stub, int)
ClientPropertyBase::ClientPropertyBase(const char* name, StubBase* stub, int)
: name_(name)
, stub_(stub)
, next_(nullptr)
{
// NOOP
stub_->add_property(this);
}


/// only call this after the server is connected.
void ClientPropertyBase::detach()
{
stub_->detach_property(*this);
stub_->detach_property(this);
}


Expand Down
34 changes: 34 additions & 0 deletions src/holders.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "simppl/pendingcall.h"
#include "simppl/variant.h"
#include "simppl/stub.h"

#include "simppl/detail/holders.h"


simppl::dbus::detail::GetAllPropertiesHolder::GetAllPropertiesHolder(std::function<void(CallState)> f, StubBase& stub)
: f_(f)
, stub_(stub)
{
// NOOP
}


/*static*/
void simppl::dbus::detail::GetAllPropertiesHolder::_delete(void* p)
{
auto that = (GetAllPropertiesHolder*)p;
delete that;
}


/*static*/
void simppl::dbus::detail::GetAllPropertiesHolder::pending_notify(DBusPendingCall* pc, void* data)
{
auto msg = simppl::dbus::make_message(dbus_pending_call_steal_reply(pc));

auto that = (GetAllPropertiesHolder*)data;
assert(that->f_);

auto cs = that->stub_.get_all_properties_handle_response(*msg);
that->f_(cs);
}
Loading

0 comments on commit a8a8e44

Please sign in to comment.