Skip to content

Commit

Permalink
Standardize facelift argument exchange
Browse files Browse the repository at this point in the history
Change-Id: Ifd09ce0e4b16a6a060d2a2634adc614f56b3a139
  • Loading branch information
😎 Mostafa Emami committed Sep 5, 2020
1 parent 6245cee commit a344cd6
Show file tree
Hide file tree
Showing 55 changed files with 751 additions and 1,861 deletions.
35 changes: 35 additions & 0 deletions codegen/facelift/templates/IPCAdapter.template.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,29 @@
#include "InterfaceManager.h"

#ifdef DBUS_IPC_ENABLED
#include <QtDBus>
#include "{{module.fullyQualifiedPath}}/{{interfaceName}}IPCDBusAdapter.h"
{% for struct in module.structs %}
#include "{{struct.fullyQualifiedPath}}.h"
{% endfor %}

{% for enum in module.enums %}
#include "{{enum.fullyQualifiedPath}}.h"
{% endfor %}

{% for property in interface.referencedInterfaceTypes %}
#include "{{property.fullyQualifiedPath}}{% if generateAsyncProxy %}Async{% endif %}IPCDBusAdapter.h"
{% endfor %}

{% for type in interface.referencedTypes %}
{% if (not type.is_primitive) %}
{% if (not type.is_model) %}
{% if (not type.is_interface) %}
{{type.requiredInclude}}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
#endif

{{module.namespaceCppOpen}}
Expand Down Expand Up @@ -80,6 +99,22 @@ struct {{interfaceName}}IPCAdapter::Impl {
{{interfaceName}}IPCAdapter::{{interfaceName}}IPCAdapter(QObject* parent) :
BaseType(facelift::InterfaceManager::instance(), parent)
{
#ifdef DBUS_IPC_ENABLED
{% for type in interface.referencedTypes %}
{% if (not type.is_primitive) %}
{% if (not type.is_model) %}
{% if (not type.is_interface) %}
qDBusRegisterMetaType<{{type.fullyQualifiedCppType}}>();
qDBusRegisterMetaType<QMap<QString,{{type.fullyQualifiedCppType}}>>();
qDBusRegisterMetaType<QList<{{type.fullyQualifiedCppType}}>>();
{% if type.is_struct %}
{{type.fullyQualifiedCppType}}::registerDBusTypes();
{% endif %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
#endif
}

{{interfaceName}}IPCAdapter::~{{interfaceName}}IPCAdapter() {
Expand Down
13 changes: 0 additions & 13 deletions codegen/facelift/templates/IPCCommon.template.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,12 @@ class {{classExport}} {{interfaceName}}IPCCommon
{{operation.name}},
{% endfor %}
{% for property in interface.properties %}
{% if (not property.readonly) %}
set{{property.name}},
{% endif %}
{% if (property.type.is_model) %}
{{property.name}}, // model
{% endif %}
{% endfor %}
};

enum class SignalID {
invalid = static_cast<int>(facelift::CommonSignalID::firstSpecific),
{% for signal in interface.signals %}
{{signal.name}},
{% endfor %}
{% for property in interface.properties %}
{{property.name}},
{% endfor %}
};

};

{{module.namespaceCppClose}}
9 changes: 6 additions & 3 deletions codegen/facelift/templates/IPCDBusServiceAdapter.template.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ class {{classExport}} {{className}}: public {{baseClass}}
using ServiceType = {{interfaceName}};
using BaseType = {{baseClass}};
using ThisType = {{className}};
using SignalID = {{interface}}IPCCommon::SignalID;
using MethodID = {{interface}}IPCCommon::MethodID;

{{className}}(QObject* parent = nullptr) :
Expand All @@ -87,7 +86,11 @@ class {{classExport}} {{className}}: public {{baseClass}}

void connectSignals() override;

void serializePropertyValues(OutputIPCMessage& msg, bool isCompleteSnapshot) override;
void marshalPropertyValues(const QList<QVariant>& arguments, OutputIPCMessage& msg) override;

void marshalProperty(const QList<QVariant>& arguments, OutputIPCMessage& msg) override;

void setProperty(const QList<QVariant>& arguments) override;

{% for event in interface.signals %}
void {{event}}(
Expand All @@ -96,7 +99,7 @@ class {{classExport}} {{className}}: public {{baseClass}}
{{ comma() }}{{parameter.interfaceCppType}} {{parameter.name}}
{%- endfor -%} )
{
sendSignal(SignalID::{{event}}
sendSignal("{{event}}"
{%- for parameter in event.parameters -%}
, {{parameter.name}}
{%- endfor -%} );
Expand Down
23 changes: 23 additions & 0 deletions codegen/facelift/templates/IPCProxy.template.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@

#ifdef DBUS_IPC_ENABLED
#include "{{module.fullyQualifiedPath}}/{{interfaceName}}IPCDBusProxy.h"
{% for type in interface.referencedTypes %}
{% if (not type.is_primitive) %}
{% if (not type.is_model) %}
{% if (not type.is_interface) %}
{{type.requiredInclude}}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
#endif

{% set className = interfaceName + "IPCProxy" %}
Expand Down Expand Up @@ -81,6 +90,20 @@ struct {{className}}::Impl {
{{className}}::{{className}}(QObject *parent) : BaseType(facelift::InterfaceManager::instance(), parent),
m_impl(std::make_unique<Impl>())
{
#ifdef DBUS_IPC_ENABLED
{% for type in interface.referencedTypes %}
{% if (not type.is_primitive) %}
{% if (not type.is_model) %}
{% if (not type.is_interface) %}
qDBusRegisterMetaType<{{type.fullyQualifiedCppType}}>();
qDBusRegisterMetaType<QMap<QString,{{type.fullyQualifiedCppType}}>>();
qDBusRegisterMetaType<QList<{{type.fullyQualifiedCppType}}>>();
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
#endif

ipc()->setObjectPath(SINGLETON_OBJECT_PATH);

{% if generateAsyncProxy %}
Expand Down
168 changes: 114 additions & 54 deletions codegen/facelift/templates/IPCProxyAdapter.template.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
{% set className = interfaceName + proxyTypeNameSuffix %}

#include "{{className}}.h"
#include "FaceliftEnum.h"
#include "DBusIPCCommon.h"

{{module.namespaceCppOpen}}

Expand All @@ -55,76 +57,135 @@
{% endif %}
}

void {{className}}::deserializePropertyValues(InputIPCMessage &msg, bool isCompleteSnapshot)
void {{className}}::unmarshalPropertyValues(InputIPCMessage &msg)
{
{% for property in interface.properties %}
{% if property.type.is_interface %}
bool emit_{{property.name}}ChangeSignal = false;
QString {{property.name}}_objectPath;
if (deserializeOptionalValue(msg, {{property.name}}_objectPath, isCompleteSnapshot))
{
m_{{property.name}}Proxy.update({{property.name}}_objectPath);
m_{{property.name}} = m_{{property.name}}Proxy.getValue();
emit_{{property.name}}ChangeSignal = true;
}
{% elif property.type.is_model %}
bool emit_{{property.name}}ChangeSignal = false;
if (isCompleteSnapshot) {
int {{property.name}}Size;
deserializeValue(msg, {{property.name}}Size);
m_{{property.name}}.beginResetModel();
m_{{property.name}}.reset({{property.name}}Size, std::bind(&ThisType::{{property.name}}Data, this, std::placeholders::_1));
m_{{property.name}}.endResetModel();
emit_{{property.name}}ChangeSignal = true;
QListIterator<QVariant> argumentsIterator(msg.arguments());
if (argumentsIterator.hasNext()) {
QMap<QString, QVariant> values = qdbus_cast<QMap<QString, QVariant>>(argumentsIterator.next());
for (const QString &propertyName: values.keys()) {
{% for property in interface.properties %}
{% if property.type.is_interface %}
if (propertyName == QStringLiteral("{{property.name}}")) {
bool emit_{{property.name}}ChangeSignal = false;
QString {{property.name}}_objectPath = qdbus_cast<QString>(values[propertyName]);
m_{{property.name}}Proxy.update({{property.name}}_objectPath);
m_{{property.name}} = m_{{property.name}}Proxy.getValue();
emit_{{property.name}}ChangeSignal = true;
if (emit_{{property.name}}ChangeSignal)
emit {{property.name}}Changed();
}
{% elif property.type.is_model %}
if (propertyName == QStringLiteral("{{property.name}}")) {
bool emit_{{property.name}}ChangeSignal = false;
int {{property.name}}Size = qdbus_cast<int>(values[propertyName]);
m_{{property.name}}.beginResetModel();
m_{{property.name}}.reset({{property.name}}Size, std::bind(&ThisType::{{property.name}}Data, this, std::placeholders::_1));
m_{{property.name}}.endResetModel();
emit_{{property.name}}ChangeSignal = true;
if (emit_{{property.name}}ChangeSignal)
emit {{property.name}}Changed();
}
{% else %}
if (propertyName == QStringLiteral("{{property.name}}")) {
const auto previous_{{property.name}}_Value = m_{{property.name}};
{% if (property.type.is_list and property.nestedType.interfaceCppType == 'QString') %}
m_{{property.name}} = qdbus_cast<QStringList>(values[propertyName]);
{% else %}
m_{{property.name}} = qdbus_cast<{{property.interfaceCppType}}>(values[propertyName]);
{% endif %}
bool emit_{{property.name}}ChangeSignal = ((previous_{{property.name}}_Value != m_{{property.name}}));
if (emit_{{property.name}}ChangeSignal)
emit {{property.name}}Changed();
}
{% endif %}
{% endfor %}
if (propertyName == QStringLiteral("ready")) {
bool previousIsReady = this->ready();
m_serviceReady = qdbus_cast<bool>(values[propertyName]);
bool emit_ReadyChangeSignal = (previousIsReady != m_serviceReady);
if (emit_ReadyChangeSignal)
emit readyChanged();
}
}
}
{% else %}
const auto previous_{{property.name}}_Value = m_{{property.name}};
deserializeOptionalValue(msg, m_{{property.name}}, isCompleteSnapshot);
bool emit_{{property.name}}ChangeSignal = isCompleteSnapshot && ((previous_{{property.name}}_Value != m_{{property.name}}));
{% endif %}
{% endfor %}

bool emit_ReadyChangeSignal = deserializeReadyValue(msg, isCompleteSnapshot) && isCompleteSnapshot;

{% for property in interface.properties %}
if (emit_{{property.name}}ChangeSignal)
emit {{property.name}}Changed();
{% endfor %}

if (emit_ReadyChangeSignal)
emit readyChanged();

}

void {{className}}::deserializeSignal(InputIPCMessage &msg)
void {{className}}::handleSignals(InputIPCMessage& msg)
{
SignalID member;
deserializeValue(msg, member);

{% for event in interface.signals %}
if (member == SignalID::{{event}})
{
if (msg.member() == QStringLiteral("{{event}}")) {
QListIterator<QVariant> argumentsIterator(msg.arguments());
{% for parameter in event.parameters %}
{{parameter.interfaceCppType}} param_{{parameter.name}};
deserializeValue(msg, param_{{parameter.name}});
param_{{parameter.name}} = (argumentsIterator.hasNext() ? qdbusToValue<{{parameter.interfaceCppType}}>(argumentsIterator.next()): {{parameter.interfaceCppType}}());
{% endfor %}
emit {{event}}(
{%- set comma = joiner(", ") -%}
{%- for parameter in event.parameters -%}
{{ comma() }}param_{{parameter.name}}
{%- endfor -%} );
} else
}
{% endfor %}

{% if interface.hasModelProperty %}
this->onModelUpdateEvent(msg);
{% endif %}
}

const QList<const char*>& {{className}}::getSignals() const
{
static QList<const char*> allSignals{
{% for event in interface.signals %}
"{{event}}",
{% endfor %}
{% if interface.hasModelProperty %}
"ModelUpdateEventDataChanged",
"ModelUpdateEventInsert",
"ModelUpdateEventRemove",
"ModelUpdateEventMove",
"ModelUpdateEventReset"
{% endif %}
};

return allSignals;
}

{% if interface.hasModelProperty %}
void {{className}}::onModelUpdateEvent(const InputIPCMessage& msg)
{
QListIterator<QVariant> argumentsIterator(msg.arguments());
const QString& modelPropertyName = (argumentsIterator.hasNext() ? qdbus_cast<QString>(argumentsIterator.next()): QString());
{% for property in interface.properties %}
if (member == SignalID::{{property.name}}) {
{% if property.type.is_model %}
if (modelPropertyName == QStringLiteral("{{property.name}}")) {
m_{{property.name}}.handleSignal(msg);
{% else %}
emit {{property.name}}Changed();
}
{% endif %}
} else
{% endfor %}
BaseType::deserializeCommonSignal(static_cast<facelift::CommonSignalID>(member), this);
}
{% endif %}

void {{className}}::unmarshalPropertiesChanged(InputIPCMessage &msg)
{
QListIterator<QVariant> argumentsIterator(msg.arguments());
QString interfaceName = (argumentsIterator.hasNext() ? qdbus_cast<QString>(argumentsIterator.next()): QString());
QVariantMap changedProperties = (argumentsIterator.hasNext() ? qdbus_cast<QVariantMap>(argumentsIterator.next()): QVariantMap());
for (const QString &propertyName: changedProperties.keys()) {
{% for property in interface.properties %}
{% if property.type.is_interface %}
{% elif property.type.is_model %}
{% else %}
if (propertyName == QStringLiteral("{{property.name}}")) {
{% if (property.type.is_list and property.nestedType.interfaceCppType == 'QString') %}
m_{{property.name}} = qdbusToValue<QStringList>(changedProperties[propertyName]);
{% else %}
m_{{property.name}} = qdbusToValue<{{property.cppType}}>(changedProperties[propertyName]);
{% endif %}
emit {{property.name}}Changed(); // trust the propertiesChanged signal and emit without checking
}
{% endif %}
{% endfor %}
}
}

{% for property in interface.properties %}
Expand All @@ -134,7 +195,7 @@ void {{className}}::deserializeSignal(InputIPCMessage &msg)
void {{className}}::set{{property}}({{property.cppMethodArgumentType}} newValue)
{
{% if (not property.type.is_interface) %}
ipc()->sendSetterCall(memberID(MethodID::set{{property.name}}, "set{{property.name}}"), newValue);
ipc()->sendSetterCall("{{property.name}}", newValue);
{% else %}
Q_ASSERT(false); // Writable interface properties are unsupported
{% endif %}
Expand Down Expand Up @@ -168,12 +229,11 @@ void {{className}}::{{operation.name}}(
{%- endfor -%} ){% if operation.is_const %} const{% endif %}
{
{% if (operation.hasReturnValue) %}
{{operation.interfaceCppType}} returnValue;
ipc()->sendMethodCallWithReturn(memberID(MethodID::{{operation.name}}, "{{operation.name}}"), returnValue
QList<QVariant> args = ipc()->sendMethodCallWithReturn(memberID(MethodID::{{operation.name}}, "{{operation.name}}")
{%- for parameter in operation.parameters -%}
, {{parameter.name}}
{%- endfor -%} );
return returnValue;
return (!args.isEmpty() ? qdbusToValue<{{operation.interfaceCppType}}>(args[0]): {{operation.interfaceCppType}}());
{% else %}
ipc()->sendMethodCall(memberID(MethodID::{{operation.name}}, "{{operation.name}}")
{%- for parameter in operation.parameters -%}
Expand Down
Loading

0 comments on commit a344cd6

Please sign in to comment.