Skip to content

Commit

Permalink
Native DBus objectmanager support on server side (switchable)
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Haefner committed Jul 18, 2024
1 parent 0d21e85 commit caa3f07
Show file tree
Hide file tree
Showing 12 changed files with 529 additions and 7 deletions.
11 changes: 11 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ endif()
option(HAVE_INTROSPECTION "Have introspection" ON)
include(CMakeDependentOption)

option(SIMPPL_HAVE_OBJECTMANAGER "Have native objectmanager support in server objects" ON)

cmake_dependent_option(SIMPPL_BUILD_TESTS "Build tests"
ON "SIMPPL_NOT_SUBPROJECT" OFF
)
Expand Down Expand Up @@ -65,16 +67,25 @@ add_library(simppl SHARED
src/bool.cpp
src/holders.cpp
src/properties.cpp
src/objectmanagermixin.cpp
)
# Provide a namespaced alias
add_library(Simppl::simppl ALIAS simppl)

# DBus introspection support
if(HAVE_INTROSPECTION)
target_compile_definitions(simppl PUBLIC SIMPPL_HAVE_INTROSPECTION=1)
else()
target_compile_definitions(simppl PUBLIC SIMPPL_HAVE_INTROSPECTION=0)
endif()

# Native objectmanager support on server side. Add or remove objects to/from
# a skeleton implementing the standard DBus ObjectManager interface. The
# standard API is automatically activated just like with properties.
if(SIMPPL_HAVE_OBJECTMANAGER)
target_compile_definitions(simppl PUBLIC SIMPPL_HAVE_OBJECTMANAGER=1)
endif()

target_include_directories(simppl
PUBLIC
$<INSTALL_INTERFACE:include>
Expand Down
49 changes: 49 additions & 0 deletions include/simppl/api/objectmanager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#ifndef __SIMPPL_ORG_FREEDESKTOP_DBUS_OBJECTMANAGER_H__
#define __SIMPPL_ORG_FREEDESKTOP_DBUS_OBJECTMANAGER_H__


#include "simppl/interface.h"
#include "simppl/map.h"
#include "simppl/vector.h"
#include "simppl/objectpath.h"
#include "simppl/any.h"


namespace org
{
namespace freedesktop
{
namespace DBus
{
using simppl::dbus::out;


typedef
std::map<simppl::dbus::ObjectPath, ///< object registration path
std::map<std::string, ///< interface name
std::map<std::string, simppl::dbus::Any> ///< properties
>
> managed_objects_t;


INTERFACE(ObjectManager)
{
Method<out<managed_objects_t>> GetManagedObjects;

Signal<simppl::dbus::ObjectPath, std::map<std::string, std::map<std::string, simppl::dbus::Any>>> InterfacesAdded;
Signal<simppl::dbus::ObjectPath, std::vector<std::string>> InterfacesRemoved;

ObjectManager()
: INIT(GetManagedObjects)
, INIT(InterfacesAdded)
, INIT(InterfacesRemoved)
{
// NOOP
}
};
}
}
}


#endif // __SIMPPL_ORG_FREEDESKTOP_DBUS_OBJECTMANAGER_H__
6 changes: 4 additions & 2 deletions include/simppl/detail/interposer.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,21 @@ namespace detail

template<int Id,
typename AncestorT,
typename Ancestor0T,
template<typename...> class Method,
template<typename...> class Signal,
template<typename, int> class Property,
template<int, typename, template<typename...> class, template<typename...> class, template<typename, int> class, typename> class I,
template<int, typename, template<typename...> class, template<typename...> class, template<typename, int> class, typename> class... Is>
struct Interposer : I<Id, AncestorT, Method, Signal, Property, Interposer<Id-1, AncestorT, Method, Signal, Property, Is...>> {};
struct Interposer : I<Id, AncestorT, Method, Signal, Property, Interposer<Id-1, AncestorT, Ancestor0T, Method, Signal, Property, Is...>> {};

template<typename AncestorT,
typename Ancestor0T,
template<typename...> class Method,
template<typename...> class Signal,
template<typename, int> class Property,
template<int, typename, template<typename...> class, template<typename...> class, template<typename, int> class, typename> class I>
struct Interposer<0, AncestorT, Method, Signal, Property, I> : I<0, AncestorT, Method, Signal, Property, AncestorT> {};
struct Interposer<0, AncestorT, Ancestor0T, Method, Signal, Property, I> : I<0, Ancestor0T, Method, Signal, Property, Ancestor0T> {};


} // detail
Expand Down
77 changes: 77 additions & 0 deletions include/simppl/detail/objectmanagerinterposer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#ifndef __SIMPPL_DBUS_OBJECTMANAGERINTERPOSER_H__
#define __SIMPPL_DBUS_OBJECTMANAGERINTERPOSER_H__

#if SIMPPL_HAVE_OBJECTMANAGER
# include "simppl/api/objectmanager.h"
# include "simppl/objectmanagermixin.h"

# include "simppl/serverside.h" // FIXME remove this?


namespace simppl
{

namespace dbus
{

namespace detail
{

/**
* Check if object manager interface is part of the implemented interfaces.
*/
template<template<int,
typename,
template<typename...> class,
template<typename...> class,
template<typename,int> class,
typename> class... Is>
struct ObjectManagerInterposer
{
enum { avail = Find<org::freedesktop::DBus::ObjectManager<0, SkeletonBase, ServerMethod, ServerSignal, ServerProperty, SkeletonBase>,
typename make_typelist<Is<0, SkeletonBase, ServerMethod, ServerSignal, ServerProperty, SkeletonBase>...>::type>::value != -1 };

typedef typename std::conditional<avail, SizedObjectManagerMixin<sizeof...(Is)>, SizedSkeletonBase<sizeof...(Is)>>::type type;
};

} // detail

} // dbus

} // simppl

#else

namespace simppl
{

namespace dbus
{

namespace detail
{

/**
* No objectmanager interposing. You may implement the API for yourself.
*/
template<template<int,
typename,
template<typename...> class,
template<typename...> class,
template<typename,int> class,
typename> class... Is>
struct ObjectManagerInterposer
{
typedef SizedSkeletonBase<sizeof...(Is)> type;
};

} // detail

} // dbus

} // simppl

#endif // SIMPPL_HAVE_OBJECTMANAGER

#endif // __SIMPPL_DBUS_OBJECTMANAGERINTERPOSER_H__

4 changes: 3 additions & 1 deletion include/simppl/dispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace dbus
// forward decls
struct StubBase;
struct SkeletonBase;
struct ObjectManagerMixin;
struct ClientSignalBase;
struct ObjectPath;

Expand All @@ -38,6 +39,7 @@ struct Dispatcher
{
friend struct StubBase;
friend struct SkeletonBase;
friend struct ObjectManagerMixin;

friend void dispatcher_add_stub(Dispatcher&, StubBase&);
friend void dispatcher_add_skeleton(Dispatcher&, SkeletonBase&);
Expand Down Expand Up @@ -149,7 +151,7 @@ struct Dispatcher

/// Do a single iteration on the self-hosted mainloop.
int step_ms(int millis);

/// Stub want's to be called due the callback registration
void notify_connected(StubBase& stub);

Expand Down
61 changes: 61 additions & 0 deletions include/simppl/objectmanagermixin.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#ifndef __SIMPPL_DBUS_OBJECTMANAGERMIXIN_H__
#define __SIMPPL_DBUS_OBJECTMANAGERMIXIN_H__

#include <set>

#include "simppl/skeletonbase.h"


namespace simppl
{

namespace dbus
{

class SkeletonBase;

/**
* If native objectmanager support is enabled, this class
* extends the API of the Skeletons in case the
* org.freedesktop.DBus.ObjectManager API is included.
*/
struct ObjectManagerMixin : public SkeletonBase
{
public:

ObjectManagerMixin(size_t size)
: SkeletonBase(size)
{
// NOOP
}

void add_managed_object(SkeletonBase* obj);
void remove_managed_object(SkeletonBase* obj);

private:

void serialize_object(DBusMessageIter& iter, const simppl::dbus::SkeletonBase& obj);

DBusHandlerResult handle_objectmanager_request(DBusMessage* msg);

std::set<SkeletonBase*> objects_;
};


template<size_t N>
struct SizedObjectManagerMixin : public ObjectManagerMixin
{
SizedObjectManagerMixin()
: ObjectManagerMixin(N)
{
// NOOP
}
};

} // dbus

} // simppl


#endif // __SIMPPL_DBUS_OBJECTMANAGERMIXIN_H__

5 changes: 4 additions & 1 deletion include/simppl/skeleton.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "simppl/serverside.h"
#include "simppl/typelist.h"
#include "simppl/detail/interposer.h"
#include "simppl/detail/objectmanagerinterposer.h"


namespace simppl
Expand All @@ -27,7 +28,9 @@ template<template<int,
template<typename...> class,
template<typename,int> class,
typename> class... Is>
struct Skeleton : detail::Interposer<sizeof...(Is)-1, detail::SizedSkeletonBase<sizeof...(Is)>, ServerMethod, ServerSignal, ServerProperty, Is...>
struct Skeleton : public detail::Interposer<sizeof...(Is)-1, detail::SizedSkeletonBase<sizeof...(Is)>,
typename detail::ObjectManagerInterposer<Is...>::type,
ServerMethod, ServerSignal, ServerProperty, Is...>
{
friend struct Dispatcher;

Expand Down
3 changes: 3 additions & 0 deletions include/simppl/skeletonbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ struct SkeletonBase
friend struct ServerMethodBase;
friend struct ServerPropertyBase;
friend struct ServerSignalBase;
friend struct ObjectManagerMixin;

static DBusHandlerResult method_handler(DBusConnection *connection, DBusMessage *message, void *user_data);

Expand Down Expand Up @@ -104,6 +105,8 @@ struct SkeletonBase
DBusHandlerResult handle_error(DBusMessage* msg, const char* dbus_error);
DBusHandlerResult handle_property_getall_request(DBusMessage* msg, int iface_id);

virtual DBusHandlerResult handle_objectmanager_request(DBusMessage* msg);

#if SIMPPL_HAVE_INTROSPECTION
void introspect_interface(std::ostream& os, size_type index) const;
#endif
Expand Down
Loading

0 comments on commit caa3f07

Please sign in to comment.