7 #ifndef _FCITX_UTILS_DBUS_OBJECTVTABLE_H_ 8 #define _FCITX_UTILS_DBUS_OBJECTVTABLE_H_ 17 #include <type_traits> 19 #include <fcitx-utils/fcitxutils_export.h> 21 #include <fcitx-utils/macros.h> 31 class ObjectVTableBase;
34 class ObjectVTablePrivate;
36 using ObjectMethod = std::function<bool(Message)>;
37 using ObjectMethodClosure = std::function<bool(Message, const ObjectMethod &)>;
38 using PropertyGetMethod = std::function<void(Message &)>;
39 using PropertySetMethod = std::function<bool(Message &)>;
55 : name_(name), error_(error) {}
57 const char *what()
const noexcept
override {
return error_.c_str(); }
59 const char *name()
const {
return name_.c_str(); }
76 const char *what()
const noexcept
override {
return "MethodCallNoReply"; }
79 class ObjectVTableMethodPrivate;
91 const std::string &signature,
const std::string &ret,
92 ObjectMethod handler);
96 const std::string &name()
const;
97 const std::string &signature()
const;
98 const std::string &ret()
const;
99 const ObjectMethod &handler()
const;
110 void setClosureFunction(ObjectMethodClosure closure);
113 std::unique_ptr<ObjectVTableMethodPrivate> d_ptr;
117 template <
typename T>
122 template <
typename U>
130 using type = std::tuple<>;
132 template <
typename U>
150 #define FCITX_OBJECT_VTABLE_METHOD(FUNCTION, FUNCTION_NAME, SIGNATURE, RET) \ 151 ::fcitx::dbus::ObjectVTableMethod FUNCTION##Method { \ 152 this, FUNCTION_NAME, SIGNATURE, RET, \ 153 ::fcitx::dbus::makeObjectVTablePropertyObjectMethodAdaptor< \ 154 FCITX_STRING_TO_DBUS_TYPE(RET), \ 155 FCITX_STRING_TO_DBUS_TUPLE(SIGNATURE)>( \ 156 this, [this](auto &&...args) { \ 157 return this->FUNCTION( \ 158 std::forward<decltype(args)>(args)...); \ 175 #define FCITX_OBJECT_VTABLE_SIGNAL(SIGNAL, SIGNAL_NAME, SIGNATURE) \ 176 ::fcitx::dbus::ObjectVTableSignal SIGNAL##Signal{this, SIGNAL_NAME, \ 178 using SIGNAL##ArgType = FCITX_STRING_TO_DBUS_TUPLE(SIGNATURE); \ 179 template <typename... Args> \ 180 void SIGNAL(Args &&...args) { \ 181 auto msg = SIGNAL##Signal.createSignal(); \ 182 SIGNAL##ArgType tupleArg{std::forward<Args>(args)...}; \ 186 template <typename... Args> \ 187 void SIGNAL##To(const std::string &dest, Args &&...args) { \ 188 auto msg = SIGNAL##Signal.createSignal(); \ 189 msg.setDestination(dest); \ 190 SIGNAL##ArgType tupleArg{std::forward<Args>(args)...}; \ 205 #define FCITX_OBJECT_VTABLE_PROPERTY(PROPERTY, NAME, SIGNATURE, GETMETHOD, \ 207 ::fcitx::dbus::ObjectVTableProperty PROPERTY##Property{ \ 208 this, NAME, SIGNATURE, \ 209 ::fcitx::dbus::makeObjectVTablePropertyGetMethodAdaptor< \ 210 FCITX_STRING_TO_DBUS_TUPLE(SIGNATURE)>(this, GETMETHOD), \ 211 ::fcitx::dbus::PropertyOptions{__VA_ARGS__}}; 224 #define FCITX_OBJECT_VTABLE_WRITABLE_PROPERTY(PROPERTY, NAME, SIGNATURE, \ 225 GETMETHOD, SETMETHOD, ...) \ 226 ::fcitx::dbus::ObjectVTableWritableProperty PROPERTY##Property{ \ 230 ::fcitx::dbus::makeObjectVTablePropertyGetMethodAdaptor< \ 231 FCITX_STRING_TO_DBUS_TUPLE(SIGNATURE)>(this, GETMETHOD), \ 232 ::fcitx::dbus::makeObjectVTablePropertySetMethodAdaptor< \ 233 FCITX_STRING_TO_DBUS_TUPLE(SIGNATURE)>(this, SETMETHOD), \ 234 ::fcitx::dbus::PropertyOptions{__VA_ARGS__}}; 236 class ObjectVTableSignalPrivate;
248 std::string signature);
252 const std::string &name()
const;
253 const std::string &signature()
const;
256 std::unique_ptr<ObjectVTableSignalPrivate> d_ptr;
260 enum class PropertyOption : uint32_t { Hidden = (1 << 0) };
264 class ObjectVTablePropertyPrivate;
276 std::string signature, PropertyGetMethod getMethod,
280 const std::string &name()
const;
281 const std::string &signature()
const;
282 bool writable()
const;
283 const PropertyGetMethod &getMethod()
const;
289 std::unique_ptr<ObjectVTablePropertyPrivate> d_ptr;
304 std::string signature,
305 PropertyGetMethod getMethod,
306 PropertySetMethod setMethod,
309 const PropertySetMethod &setMethod()
const;
318 friend class MessageSetter;
341 bool isRegistered()
const;
343 const std::string &path()
const;
345 const std::string &interface()
const;
354 Message *currentMessage()
const;
364 void setCurrentMessage(
Message *message);
370 virtual std::mutex &privateDataMutexForType() = 0;
372 static std::shared_ptr<ObjectVTablePrivate> newSharedPrivateData();
375 void setSlot(
Slot *slot);
377 std::unique_ptr<ObjectVTableBasePrivate> d_ptr;
393 template <
typename T>
396 std::mutex &privateDataMutexForType()
override {
397 return privateDataMutex();
400 static std::mutex &privateDataMutex() {
401 static std::mutex mutex;
405 static std::shared_ptr<ObjectVTablePrivate> d(newSharedPrivateData());
410 template <
typename Ret,
typename Args,
typename Callback>
415 : base_(base), callback_(std::move(callback)) {}
417 FCITX_INLINE_DEFINE_DEFAULT_DTOR_COPY_AND_MOVE(
421 base_->setCurrentMessage(&msg);
422 auto watcher = base_->watch();
426 using ReturnType = decltype(callWithTuple(callback_, args));
427 static_assert(std::is_same<Ret, ReturnType>::value,
428 "Return type does not match.");
431 [
this, &args]() {
return callWithTuple(callback_, args); });
436 auto reply = msg.
createError(error.name(), error.what());
441 if (watcher.isValid()) {
442 watcher.get()->setCurrentMessage(
nullptr);
452 template <
typename Ret,
typename Args,
typename Callback>
454 Callback &&callback) {
456 base, std::forward<Callback>(callback));
459 template <
typename Ret,
typename Callback>
464 : base_(base), callback_(std::move(callback)) {}
466 FCITX_INLINE_DEFINE_DEFAULT_DTOR_COPY_AND_MOVE(
469 void operator()(
Message &msg) {
470 Ret
property = callback_();
479 template <
typename Ret,
typename Callback>
481 Callback &&callback) {
483 base, std::forward<Callback>(callback));
486 template <
typename Ret,
typename Callback>
491 : base_(base), callback_(std::move(callback)) {}
493 FCITX_INLINE_DEFINE_DEFAULT_DTOR_COPY_AND_MOVE(
496 bool operator()(
Message &msg) {
497 base_->setCurrentMessage(&msg);
498 auto watcher = base_->watch();
501 callWithTuple(callback_, args);
504 if (watcher.isValid()) {
505 watcher.get()->setCurrentMessage(
nullptr);
515 template <
typename Ret,
typename Callback>
517 Callback &&callback) {
519 base, std::forward<Callback>(callback));
524 #endif // _FCITX_UTILS_DBUS_OBJECTVTABLE_H_ bool send()
Send this message.
Basic DBus type of a DBus message.
Base class of any DBus object.
Register a DBus read-only property to current DBus VTable.
Message createError(const char *name, const char *message) const
Create a error reply to this message.
Virtual base class represent some internal registration of the bus.
Utitliy classes for statically tracking the life of a object.
A class that represents a connection to the Bus.
Message createReply() const
Create a reply to this message.
Register a DBus property to current DBus VTable.
An exception if you want message to return a DBus error.
Helper class to be used with TrackableObjectReference.
Register a DBus method to current DBus VTable.
Class provides bit flag support for Enum.
Helper template class to make easier to use type safe enum flags.
An exception to not reply a the D-Bus method call.
Register a DBus signal to current DBus VTable.