14 #include <unordered_set> 17 #include "../../log.h" 18 #include "../../macros.h" 19 #include "../objectvtable.h" 21 #include "message_p.h" 22 #include "objectvtable_p_sdbus.h" 23 #include "objectvtablewrapper_p.h" 24 #include "sd-bus-wrap.h" 28 class ObjectVTablePrivate {
30 const std::string &vtableString(
const std::string &str) {
31 auto iter = stringPool_.find(str);
32 if (iter == stringPool_.end()) {
33 iter = stringPool_.insert(str).first;
38 bool hasVTable_ =
false;
39 std::vector<sd_bus_vtable> vtable_;
40 std::unordered_set<std::string> stringPool_;
43 int SDMethodCallback(sd_bus_message *m,
void *userdata,
45 auto *vtable =
static_cast<ObjectVTableBase *
>(userdata);
49 auto *method = vtable->findMethod(sd_bus_message_get_member(m));
54 method->handler()(MessagePrivate::fromSDBusMessage(m));
56 }
catch (
const std::exception &e) {
58 FCITX_ERROR() << e.what();
64 int SDPropertyGetCallback(sd_bus * ,
const char * ,
65 const char * ,
const char *property,
66 sd_bus_message *reply,
void *userdata,
68 auto *vtable =
static_cast<ObjectVTableBase *
>(userdata);
72 auto *prop = vtable->findProperty(property);
77 auto msg = MessagePrivate::fromSDBusMessage(reply);
78 prop->getMethod()(msg);
80 }
catch (
const std::exception &e) {
82 FCITX_ERROR() << e.what();
88 int SDPropertySetCallback(sd_bus * ,
const char * ,
89 const char * ,
const char *property,
90 sd_bus_message *value,
void *userdata,
92 auto *vtable =
static_cast<ObjectVTableBase *
>(userdata);
96 auto *prop = vtable->findProperty(property);
97 if (!prop || !prop->writable()) {
101 auto msg = MessagePrivate::fromSDBusMessage(value);
102 static_cast<ObjectVTableWritableProperty *
>(prop)->setMethod()(msg);
104 }
catch (
const std::exception &e) {
106 FCITX_ERROR() << e.what();
112 ObjectVTableBasePrivate::~ObjectVTableBasePrivate() {}
114 uint32_t PropertyOptionsToSDBusFlags(PropertyOptions options) {
116 if (options.test(PropertyOption::Hidden)) {
117 result |= SD_BUS_VTABLE_HIDDEN;
122 const sd_bus_vtable *
123 ObjectVTableBasePrivate::toSDBusVTable(ObjectVTableBase *q) {
124 std::lock_guard<std::mutex> lock(q->privateDataMutexForType());
125 auto *p = q->privateDataForType();
126 if (!p->hasVTable_) {
127 std::vector<sd_bus_vtable> &result = p->vtable_;
128 result.push_back(vtable_start());
130 for (
const auto &m : methods_) {
131 auto *method = m.second;
132 result.push_back(vtable_method(
133 p->vtableString(method->name()).c_str(),
134 p->vtableString(method->signature()).c_str(),
135 p->vtableString(method->ret()).c_str(), 0, SDMethodCallback));
138 for (
const auto &s : sigs_) {
139 auto *sig = s.second;
141 vtable_signal(p->vtableString(sig->name()).c_str(),
142 p->vtableString(sig->signature()).c_str()));
145 for (
const auto &pr : properties_) {
146 auto *prop = pr.second;
147 if (prop->writable()) {
148 result.push_back(vtable_writable_property(
149 p->vtableString(prop->name()).c_str(),
150 p->vtableString(prop->signature()).c_str(),
151 SDPropertyGetCallback, SDPropertySetCallback,
152 PropertyOptionsToSDBusFlags(prop->options())));
154 result.push_back(vtable_property(
155 p->vtableString(prop->name()).c_str(),
156 p->vtableString(prop->signature()).c_str(),
157 SDPropertyGetCallback,
158 PropertyOptionsToSDBusFlags(prop->options())));
162 result.push_back(vtable_end());
163 p->hasVTable_ =
true;
166 return p->vtable_.data();
169 ObjectVTableBase::ObjectVTableBase()
170 : d_ptr(
std::make_unique<ObjectVTableBasePrivate>()) {}
172 ObjectVTableBase::~ObjectVTableBase() {}
174 void ObjectVTableBase::addMethod(ObjectVTableMethod *method) {
176 d->methods_[method->name()] = method;
179 void ObjectVTableBase::addProperty(ObjectVTableProperty *property) {
181 d->properties_[
property->name()] = property;
184 void ObjectVTableBase::addSignal(ObjectVTableSignal *signal) {
186 d->sigs_[signal->name()] = signal;
189 ObjectVTableMethod *ObjectVTableBase::findMethod(
const std::string &name) {
191 auto iter = d->methods_.find(name);
192 if (iter == d->methods_.end()) {
198 ObjectVTableProperty *ObjectVTableBase::findProperty(
const std::string &name) {
200 auto iter = d->properties_.find(name);
201 if (iter == d->properties_.end()) {
213 return d->slot_ ? d->slot_->bus_ :
nullptr;
223 return d->slot_->path_;
228 return d->slot_->interface_;
241 std::shared_ptr<ObjectVTablePrivate> ObjectVTableBase::newSharedPrivateData() {
242 return std::make_shared<ObjectVTablePrivate>();
245 void ObjectVTableBase::setSlot(Slot *slot) {
247 d->slot_.reset(static_cast<SDVTableSlot *>(slot));
bool isRegistered() const
Return whether this object is registered to a bus.
Bus * bus()
Return the bus that the object is registered to.
void setCurrentMessage(Message *message)
Set the current dbus message.
void releaseSlot()
Unregister the dbus object from the bus.
const std::string & interface() const
Return the registered dbus interface of the object.
Message * currentMessage() const
Return the current dbus message for current method.
const std::string & path() const
Return the registered dbus object path of the object.