#include <simpledbus/advanced/Interface.h>
#include <simpledbus/advanced/Proxy.h>
#include <simpledbus/base/Exceptions.h>
#include <simpledbus/interfaces/Properties.h>
using namespace SimpleDBus;
Interface::Interface(std::shared_ptr<Connection> conn, std::shared_ptr<Proxy> proxy, const std::string& interface_name)
: _conn(conn),
_proxy(proxy),
_bus_name(proxy->bus_name()),
_path(proxy->path()),
_interface_name(interface_name),
_loaded(true) {}
std::shared_ptr<Proxy> Interface::proxy() const { return _proxy.lock(); }
void Interface::load(Holder options) {
_property_update_mutex.lock();
auto changed_options = options.get_dict_string();
for (auto& [name, value] : changed_options) {
_properties[name] = value;
_property_valid_map[name] = true;
}
_property_update_mutex.unlock();
for (auto& [name, value] : changed_options) {
property_changed(name);
}
_loaded = true;
}
void Interface::unload() { _loaded = false; }
bool Interface::is_loaded() const { return _loaded; }
Message Interface::create_method_call(const std::string& method_name) {
return Message::create_method_call(_bus_name, _path, _interface_name, method_name);
}
void Interface::property_refresh(const std::string& property_name) {
if (!_loaded || !_property_valid_map[property_name]) {
return;
}
bool cb_property_changed_required = false;
try {
auto properties_interface = std::dynamic_pointer_cast<SimpleDBus::Interfaces::Properties>(proxy()->interface_get("org.freedesktop.DBus.Properties"));
Holder property_latest = properties_interface->Get(_interface_name, property_name);
_property_update_mutex.lock();
_property_valid_map[property_name] = true;
if (_properties[property_name] != property_latest) {
_properties[property_name] = property_latest;
cb_property_changed_required = true;
}
_property_update_mutex.unlock();
} catch (const Exception::SendFailed& e) {
_property_update_mutex.lock();
_property_valid_map[property_name] = true;
_property_update_mutex.unlock();
}
if (cb_property_changed_required) {
property_changed(property_name);
}
}
void Interface::property_changed(std::string option_name) {}
void Interface::signal_property_changed(Holder changed_properties, Holder invalidated_properties) {
_property_update_mutex.lock();
auto changed_options = changed_properties.get_dict_string();
for (auto& [name, value] : changed_options) {
_properties[name] = value;
_property_valid_map[name] = true;
}
auto removed_options = invalidated_properties.get_array();
for (auto& removed_option : removed_options) {
_property_valid_map[removed_option.get_string()] = false;
}
_property_update_mutex.unlock();
for (auto& [name, value] : changed_options) {
property_changed(name);
}
}
void Interface::message_handle(Message& msg) {}