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(); }
66 class ObjectVTableMethodPrivate;
78 const std::string &signature,
const std::string &ret,
79 ObjectMethod handler);
83 const std::string &name()
const;
84 const std::string &signature()
const;
85 const std::string &ret()
const;
86 const ObjectMethod &handler()
const;
97 void setClosureFunction(ObjectMethodClosure closure);
100 std::unique_ptr<ObjectVTableMethodPrivate> d_ptr;
104 template <
typename T>
109 template <
typename U>
117 using type = std::tuple<>;
119 template <
typename U>
137 #define FCITX_OBJECT_VTABLE_METHOD(FUNCTION, FUNCTION_NAME, SIGNATURE, RET) \ 138 ::fcitx::dbus::ObjectVTableMethod FUNCTION##Method { \ 139 this, FUNCTION_NAME, SIGNATURE, RET, \ 140 ::fcitx::dbus::makeObjectVTablePropertyObjectMethodAdaptor< \ 141 FCITX_STRING_TO_DBUS_TYPE(RET), \ 142 FCITX_STRING_TO_DBUS_TUPLE(SIGNATURE)>( \ 143 this, [this](auto &&...args) { \ 144 return this->FUNCTION( \ 145 std::forward<decltype(args)>(args)...); \ 162 #define FCITX_OBJECT_VTABLE_SIGNAL(SIGNAL, SIGNAL_NAME, SIGNATURE) \ 163 ::fcitx::dbus::ObjectVTableSignal SIGNAL##Signal{this, SIGNAL_NAME, \ 165 using SIGNAL##ArgType = FCITX_STRING_TO_DBUS_TUPLE(SIGNATURE); \ 166 template <typename... Args> \ 167 void SIGNAL(Args &&...args) { \ 168 auto msg = SIGNAL##Signal.createSignal(); \ 169 SIGNAL##ArgType tupleArg{std::forward<Args>(args)...}; \ 173 template <typename... Args> \ 174 void SIGNAL##To(const std::string &dest, Args &&...args) { \ 175 auto msg = SIGNAL##Signal.createSignal(); \ 176 msg.setDestination(dest); \ 177 SIGNAL##ArgType tupleArg{std::forward<Args>(args)...}; \ 192 #define FCITX_OBJECT_VTABLE_PROPERTY(PROPERTY, NAME, SIGNATURE, GETMETHOD, \ 194 ::fcitx::dbus::ObjectVTableProperty PROPERTY##Property{ \ 195 this, NAME, SIGNATURE, \ 196 ::fcitx::dbus::makeObjectVTablePropertyGetMethodAdaptor< \ 197 FCITX_STRING_TO_DBUS_TUPLE(SIGNATURE)>(this, GETMETHOD), \ 198 ::fcitx::dbus::PropertyOptions{__VA_ARGS__}}; 211 #define FCITX_OBJECT_VTABLE_WRITABLE_PROPERTY(PROPERTY, NAME, SIGNATURE, \ 212 GETMETHOD, SETMETHOD, ...) \ 213 ::fcitx::dbus::ObjectVTableWritableProperty PROPERTY##Property{ \ 217 ::fcitx::dbus::makeObjectVTablePropertyGetMethodAdaptor< \ 218 FCITX_STRING_TO_DBUS_TUPLE(SIGNATURE)>(this, GETMETHOD), \ 219 ::fcitx::dbus::makeObjectVTablePropertySetMethodAdaptor< \ 220 FCITX_STRING_TO_DBUS_TUPLE(SIGNATURE)>(this, SETMETHOD), \ 221 ::fcitx::dbus::PropertyOptions{__VA_ARGS__}}; 223 class ObjectVTableSignalPrivate;
235 std::string signature);
239 const std::string &name()
const;
240 const std::string &signature()
const;
243 std::unique_ptr<ObjectVTableSignalPrivate> d_ptr;
247 enum class PropertyOption : uint32_t { Hidden = (1 << 0) };
251 class ObjectVTablePropertyPrivate;
263 std::string signature, PropertyGetMethod getMethod,
267 const std::string &name()
const;
268 const std::string &signature()
const;
269 bool writable()
const;
270 const PropertyGetMethod &getMethod()
const;
276 std::unique_ptr<ObjectVTablePropertyPrivate> d_ptr;
291 std::string signature,
292 PropertyGetMethod getMethod,
293 PropertySetMethod setMethod,
296 const PropertySetMethod &setMethod()
const;
305 friend class MessageSetter;
328 bool isRegistered()
const;
330 const std::string &path()
const;
332 const std::string &interface()
const;
341 Message *currentMessage()
const;
351 void setCurrentMessage(
Message *message);
357 virtual std::mutex &privateDataMutexForType() = 0;
359 static std::shared_ptr<ObjectVTablePrivate> newSharedPrivateData();
362 void setSlot(
Slot *slot);
364 std::unique_ptr<ObjectVTableBasePrivate> d_ptr;
380 template <
typename T>
383 std::mutex &privateDataMutexForType()
override {
384 return privateDataMutex();
387 static std::mutex &privateDataMutex() {
388 static std::mutex mutex;
392 static std::shared_ptr<ObjectVTablePrivate> d(newSharedPrivateData());
397 template <
typename Ret,
typename Args,
typename Callback>
402 : base_(base), callback_(std::move(callback)) {}
404 FCITX_INLINE_DEFINE_DEFAULT_DTOR_COPY_AND_MOVE(
408 base_->setCurrentMessage(&msg);
409 auto watcher = base_->watch();
413 using ReturnType = decltype(callWithTuple(callback_, args));
414 static_assert(std::is_same<Ret, ReturnType>::value,
415 "Return type does not match.");
418 [
this, &args]() {
return callWithTuple(callback_, args); });
422 }
catch (const ::fcitx::dbus::MethodCallError &error) {
423 auto reply = msg.
createError(error.name(), error.what());
426 if (watcher.isValid()) {
427 watcher.get()->setCurrentMessage(
nullptr);
437 template <
typename Ret,
typename Args,
typename Callback>
439 Callback &&callback) {
441 base, std::forward<Callback>(callback));
444 template <
typename Ret,
typename Callback>
449 : base_(base), callback_(std::move(callback)) {}
451 FCITX_INLINE_DEFINE_DEFAULT_DTOR_COPY_AND_MOVE(
454 void operator()(
Message &msg) {
455 Ret
property = callback_();
464 template <
typename Ret,
typename Callback>
466 Callback &&callback) {
468 base, std::forward<Callback>(callback));
471 template <
typename Ret,
typename Callback>
476 : base_(base), callback_(std::move(callback)) {}
478 FCITX_INLINE_DEFINE_DEFAULT_DTOR_COPY_AND_MOVE(
481 bool operator()(
Message &msg) {
482 base_->setCurrentMessage(&msg);
483 auto watcher = base_->watch();
486 callWithTuple(callback_, args);
489 if (watcher.isValid()) {
490 watcher.get()->setCurrentMessage(
nullptr);
500 template <
typename Ret,
typename Callback>
502 Callback &&callback) {
504 base, std::forward<Callback>(callback));
509 #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.
Register a DBus signal to current DBus VTable.