mirror of
https://github.com/Kistler-Group/sdbus-cpp.git
synced 2026-01-26 15:42:19 +01:00
feat: add support for async property get/set on client-side (#354)
* feat: add async property get/set convenience support classes * feat: add no-reply and async overloads to Properties_proxy * feat: add convenience functions for GetAll functionality * test: add tests for new functionality * add codegen IDL support and documentation
This commit is contained in:
committed by
GitHub
parent
0eda855745
commit
290078d6af
@@ -108,12 +108,18 @@ std::string ProxyGenerator::processInterface(Node& interface) const
|
||||
if (!declaration.empty())
|
||||
body << declaration << endl;
|
||||
|
||||
std::string methodDefinitions, asyncDeclarations;
|
||||
std::tie(methodDefinitions, asyncDeclarations) = processMethods(methods);
|
||||
std::string methodDefinitions, asyncDeclarationsMethods;
|
||||
std::tie(methodDefinitions, asyncDeclarationsMethods) = processMethods(methods);
|
||||
std::string propertyDefinitions, asyncDeclarationsProperties;
|
||||
std::tie(propertyDefinitions, asyncDeclarationsProperties) = processProperties(properties);
|
||||
|
||||
if (!asyncDeclarations.empty())
|
||||
if (!asyncDeclarationsMethods.empty())
|
||||
{
|
||||
body << asyncDeclarations << endl;
|
||||
body << asyncDeclarationsMethods << endl;
|
||||
}
|
||||
if (!asyncDeclarationsProperties.empty())
|
||||
{
|
||||
body << asyncDeclarationsProperties << endl;
|
||||
}
|
||||
|
||||
if (!methodDefinitions.empty())
|
||||
@@ -121,7 +127,6 @@ std::string ProxyGenerator::processInterface(Node& interface) const
|
||||
body << "public:" << endl << methodDefinitions;
|
||||
}
|
||||
|
||||
std::string propertyDefinitions = processProperties(properties);
|
||||
if (!propertyDefinitions.empty())
|
||||
{
|
||||
body << "public:" << endl << propertyDefinitions;
|
||||
@@ -293,9 +298,9 @@ std::tuple<std::string, std::string> ProxyGenerator::processSignals(const Nodes&
|
||||
return std::make_tuple(registrationSS.str(), declarationSS.str());
|
||||
}
|
||||
|
||||
std::string ProxyGenerator::processProperties(const Nodes& properties) const
|
||||
std::tuple<std::string, std::string> ProxyGenerator::processProperties(const Nodes& properties) const
|
||||
{
|
||||
std::ostringstream propertySS;
|
||||
std::ostringstream propertySS, asyncDeclarationSS;
|
||||
for (const auto& property : properties)
|
||||
{
|
||||
auto propertyName = property->get("name");
|
||||
@@ -307,25 +312,93 @@ std::string ProxyGenerator::processProperties(const Nodes& properties) const
|
||||
auto propertyArg = std::string("value");
|
||||
auto propertyTypeArg = std::string("const ") + propertyType + "& " + propertyArg;
|
||||
|
||||
bool asyncGet{false};
|
||||
bool futureGet{false}; // Async property getter implemented by means of either std::future or callbacks
|
||||
bool asyncSet{false};
|
||||
bool futureSet{false}; // Async property setter implemented by means of either std::future or callbacks
|
||||
|
||||
Nodes annotations = (*property)["annotation"];
|
||||
for (const auto& annotation : annotations)
|
||||
{
|
||||
const auto annotationName = annotation->get("name");
|
||||
const auto annotationValue = annotation->get("value");
|
||||
|
||||
if (annotationName == "org.freedesktop.DBus.Property.Get.Async" && annotationValue == "client") // Server-side not supported (may be in the future)
|
||||
asyncGet = true;
|
||||
else if (annotationName == "org.freedesktop.DBus.Property.Get.Async.ClientImpl" && annotationValue == "callback")
|
||||
futureGet = false;
|
||||
else if (annotationName == "org.freedesktop.DBus.Property.Get.Async.ClientImpl" && (annotationValue == "future" || annotationValue == "std::future"))
|
||||
futureGet = true;
|
||||
else if (annotationName == "org.freedesktop.DBus.Property.Set.Async" && annotationValue == "client") // Server-side not supported (may be in the future)
|
||||
asyncSet = true;
|
||||
else if (annotationName == "org.freedesktop.DBus.Property.Set.Async.ClientImpl" && annotationValue == "callback")
|
||||
futureSet = false;
|
||||
else if (annotationName == "org.freedesktop.DBus.Property.Set.Async.ClientImpl" && (annotationValue == "future" || annotationValue == "std::future"))
|
||||
futureSet = true;
|
||||
}
|
||||
|
||||
if (propertyAccess == "read" || propertyAccess == "readwrite")
|
||||
{
|
||||
propertySS << tab << propertyType << " " << propertyNameSafe << "()" << endl
|
||||
const std::string realRetType = (asyncGet ? (futureGet ? "std::future<sdbus::Variant>" : "sdbus::PendingAsyncCall") : propertyType);
|
||||
|
||||
propertySS << tab << realRetType << " " << propertyNameSafe << "()" << endl
|
||||
<< tab << "{" << endl;
|
||||
propertySS << tab << tab << "return proxy_->getProperty(\"" << propertyName << "\")"
|
||||
propertySS << tab << tab << "return proxy_->getProperty" << (asyncGet ? "Async" : "") << "(\"" << propertyName << "\")"
|
||||
".onInterface(INTERFACE_NAME)";
|
||||
if (asyncGet)
|
||||
{
|
||||
auto nameBigFirst = propertyName;
|
||||
nameBigFirst[0] = islower(nameBigFirst[0]) ? nameBigFirst[0] + 'A' - 'a' : nameBigFirst[0];
|
||||
|
||||
if (futureGet) // Async methods implemented through future
|
||||
{
|
||||
propertySS << ".getResultAsFuture()";
|
||||
}
|
||||
else // Async methods implemented through callbacks
|
||||
{
|
||||
propertySS << ".uponReplyInvoke([this](const sdbus::Error* error, const sdbus::Variant& value)"
|
||||
"{ this->on" << nameBigFirst << "PropertyGetReply(value.get<" << propertyType << ">(), error); })";
|
||||
|
||||
asyncDeclarationSS << tab << "virtual void on" << nameBigFirst << "PropertyGetReply("
|
||||
<< "const " << propertyType << "& value, const sdbus::Error* error) = 0;" << endl;
|
||||
}
|
||||
}
|
||||
propertySS << ";" << endl << tab << "}" << endl << endl;
|
||||
}
|
||||
|
||||
if (propertyAccess == "readwrite" || propertyAccess == "write")
|
||||
{
|
||||
propertySS << tab << "void " << propertyNameSafe << "(" << propertyTypeArg << ")" << endl
|
||||
<< tab << "{" << endl;
|
||||
propertySS << tab << tab << "proxy_->setProperty(\"" << propertyName << "\")"
|
||||
const std::string realRetType = (asyncSet ? (futureSet ? "std::future<void>" : "sdbus::PendingAsyncCall") : "void");
|
||||
|
||||
propertySS << tab << realRetType << " " << propertyNameSafe << "(" << propertyTypeArg << ")" << endl
|
||||
<< tab << "{" << endl;
|
||||
propertySS << tab << tab << (asyncSet ? "return " : "") << "proxy_->setProperty" << (asyncSet ? "Async" : "")
|
||||
<< "(\"" << propertyName << "\")"
|
||||
".onInterface(INTERFACE_NAME)"
|
||||
".toValue(" << propertyArg << ")";
|
||||
|
||||
if (asyncSet)
|
||||
{
|
||||
auto nameBigFirst = propertyName;
|
||||
nameBigFirst[0] = islower(nameBigFirst[0]) ? nameBigFirst[0] + 'A' - 'a' : nameBigFirst[0];
|
||||
|
||||
if (futureSet) // Async methods implemented through future
|
||||
{
|
||||
propertySS << ".getResultAsFuture()";
|
||||
}
|
||||
else // Async methods implemented through callbacks
|
||||
{
|
||||
propertySS << ".uponReplyInvoke([this](const sdbus::Error* error)"
|
||||
"{ this->on" << nameBigFirst << "PropertySetReply(error); })";
|
||||
|
||||
asyncDeclarationSS << tab << "virtual void on" << nameBigFirst << "PropertySetReply("
|
||||
<< "const sdbus::Error* error) = 0;" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
propertySS << ";" << endl << tab << "}" << endl << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return propertySS.str();
|
||||
return std::make_tuple(propertySS.str(), asyncDeclarationSS.str());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user