Introduce support for asynchronous D-Bus method calls on the client side (#42)

Fixes #32
This commit is contained in:
Stanislav Angelovič
2019-03-25 14:45:48 +01:00
committed by GitHub
parent 004f158817
commit 663df31398
18 changed files with 481 additions and 54 deletions
+45 -23
View File
@@ -94,10 +94,18 @@ std::string ProxyGenerator::processInterface(Node& interface) const
body << tab << "{" << endl
<< registration
<< tab << "}" << endl << endl
<< declaration << endl;
<< tab << "}" << endl << endl;
if (!declaration.empty())
body << declaration << endl;
std::string methodDefinitions, asyncDeclarations;
std::tie(methodDefinitions, asyncDeclarations) = processMethods(methods);
if (!asyncDeclarations.empty())
{
body << asyncDeclarations << endl;
}
std::string methodDefinitions = processMethods(methods);
if (!methodDefinitions.empty())
{
body << "public:" << endl << methodDefinitions;
@@ -117,9 +125,10 @@ std::string ProxyGenerator::processInterface(Node& interface) const
return body.str();
}
std::string ProxyGenerator::processMethods(const Nodes& methods) const
std::tuple<std::string, std::string> ProxyGenerator::processMethods(const Nodes& methods) const
{
std::ostringstream methodSS;
std::ostringstream definitionSS, asyncDeclarationSS;
for (const auto& method : methods)
{
auto name = method->get("name");
@@ -128,15 +137,15 @@ std::string ProxyGenerator::processMethods(const Nodes& methods) const
Nodes outArgs = args.select("direction" , "out");
bool dontExpectReply{false};
bool async{false};
Nodes annotations = (*method)["annotation"];
for (const auto& annotation : annotations)
{
if (annotation->get("name") == "org.freedesktop.DBus.Method.NoReply"
&& annotation->get("value") == "true")
{
if (annotation->get("name") == "org.freedesktop.DBus.Method.NoReply" && annotation->get("value") == "true")
dontExpectReply = true;
break;
}
else if (annotation->get("name") == "org.freedesktop.DBus.Method.Async"
&& (annotation->get("value") == "client" || annotation->get("value") == "clientserver"))
async = true;
}
if (dontExpectReply && outArgs.size() > 0)
{
@@ -146,39 +155,52 @@ std::string ProxyGenerator::processMethods(const Nodes& methods) const
}
auto retType = outArgsToType(outArgs);
std::string argStr, argTypeStr;
std::tie(argStr, argTypeStr, std::ignore) = argsToNamesAndTypes(inArgs);
std::string inArgStr, inArgTypeStr;
std::tie(inArgStr, inArgTypeStr, std::ignore) = argsToNamesAndTypes(inArgs);
std::string outArgStr, outArgTypeStr;
std::tie(outArgStr, outArgTypeStr, std::ignore) = argsToNamesAndTypes(outArgs);
methodSS << tab << retType << " " << name << "(" << argTypeStr << ")" << endl
definitionSS << tab << (async ? "void" : retType) << " " << name << "(" << inArgTypeStr << ")" << endl
<< tab << "{" << endl;
if (outArgs.size() > 0)
if (outArgs.size() > 0 && !async)
{
methodSS << tab << tab << retType << " result;" << endl;
definitionSS << tab << tab << retType << " result;" << endl;
}
methodSS << tab << tab << "object_.callMethod(\"" << name << "\")"
definitionSS << tab << tab << "object_.callMethod" << (async ? "Async" : "") << "(\"" << name << "\")"
".onInterface(interfaceName)";
if (inArgs.size() > 0)
{
methodSS << ".withArguments(" << argStr << ")";
definitionSS << ".withArguments(" << inArgStr << ")";
}
if (outArgs.size() > 0)
if (async && !dontExpectReply)
{
methodSS << ".storeResultsTo(result);" << endl
<< tab << tab << "return result";
auto nameBigFirst = name;
nameBigFirst[0] = islower(nameBigFirst[0]) ? nameBigFirst[0] + 'A' - 'a' : nameBigFirst[0];
definitionSS << ".uponReplyInvoke([this](const sdbus::Error* error" << (outArgTypeStr.empty() ? "" : ", ") << outArgTypeStr << ")"
"{ this->on" << nameBigFirst << "Reply(" << outArgStr << (outArgStr.empty() ? "" : ", ") << "error); })";
asyncDeclarationSS << tab << "virtual void on" << nameBigFirst << "Reply("
<< outArgTypeStr << (outArgTypeStr.empty() ? "" : ", ") << "const sdbus::Error* error) = 0;" << endl;
}
else if (outArgs.size() > 0)
{
definitionSS << ".storeResultsTo(result);" << endl
<< tab << tab << "return result";
}
else if (dontExpectReply)
{
methodSS << ".dontExpectReply()";
definitionSS << ".dontExpectReply()";
}
methodSS << ";" << endl << tab << "}" << endl << endl;
definitionSS << ";" << endl << tab << "}" << endl << endl;
}
return methodSS.str();
return std::make_tuple(definitionSS.str(), asyncDeclarationSS.str());
}
std::tuple<std::string, std::string> ProxyGenerator::processSignals(const Nodes& signals) const