From de3e0dedc7043c8054a35a235b8818ab1547c29b Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Mon, 16 Jul 2018 13:43:37 +0200 Subject: [PATCH] allow multiple inheritance with interfaces --- libnymea/interfaces/extendedawning.json | 2 +- libnymea/interfaces/extendedblind.json | 2 +- libnymea/interfaces/extendedshutter.json | 2 +- libnymea/plugin/deviceplugin.cpp | 40 ++++++++++++++++++++++-- libnymea/plugin/deviceplugin.h | 1 + 5 files changed, 42 insertions(+), 5 deletions(-) diff --git a/libnymea/interfaces/extendedawning.json b/libnymea/interfaces/extendedawning.json index 94b3894a..b947c4ce 100644 --- a/libnymea/interfaces/extendedawning.json +++ b/libnymea/interfaces/extendedawning.json @@ -1,3 +1,3 @@ { - "extends": "extendedclosable" + "extends": ["awning", "extendedclosable"] } diff --git a/libnymea/interfaces/extendedblind.json b/libnymea/interfaces/extendedblind.json index 22512060..e6313d90 100644 --- a/libnymea/interfaces/extendedblind.json +++ b/libnymea/interfaces/extendedblind.json @@ -1,3 +1,3 @@ { - "extends": "blind" + "extends": ["blind", "extendedclosable"] } diff --git a/libnymea/interfaces/extendedshutter.json b/libnymea/interfaces/extendedshutter.json index 94b3894a..48ab7ada 100644 --- a/libnymea/interfaces/extendedshutter.json +++ b/libnymea/interfaces/extendedshutter.json @@ -1,3 +1,3 @@ { - "extends": "extendedclosable" + "extends": ["shutter", "extendedclosable"] } diff --git a/libnymea/plugin/deviceplugin.cpp b/libnymea/plugin/deviceplugin.cpp index 948f257d..4f690cb2 100644 --- a/libnymea/plugin/deviceplugin.cpp +++ b/libnymea/plugin/deviceplugin.cpp @@ -1173,7 +1173,14 @@ Interface DevicePlugin::loadInterface(const QString &name) } QVariantMap content = jsonDoc.toVariant().toMap(); if (content.contains("extends")) { - iface = loadInterface(content.value("extends").toString()); + if (!content.value("extends").toString().isEmpty()) { + iface = loadInterface(content.value("extends").toString()); + } else if (content.value("extends").toList().count() > 0) { + foreach (const QVariant &extendedIface, content.value("extends").toList()) { + Interface tmp = loadInterface(extendedIface.toString()); + iface = mergeInterfaces(iface, tmp); + } + } } StateTypes stateTypes; @@ -1243,6 +1250,29 @@ Interface DevicePlugin::loadInterface(const QString &name) return Interface(name, iface.actionTypes() << actionTypes, iface.eventTypes() << eventTypes, iface.stateTypes() << stateTypes); } +Interface DevicePlugin::mergeInterfaces(const Interface &iface1, const Interface &iface2) +{ + EventTypes eventTypes = iface1.eventTypes(); + foreach (const EventType &et, iface2.eventTypes()) { + if (eventTypes.findByName(et.name()).name().isEmpty()) { + eventTypes.append(et); + } + } + StateTypes stateTypes = iface1.stateTypes(); + foreach (const StateType &st, iface2.stateTypes()) { + if (stateTypes.findByName(st.name()).name().isEmpty()) { + stateTypes.append(st); + } + } + ActionTypes actionTypes = iface1.actionTypes(); + foreach (const ActionType &at, iface2.actionTypes()) { + if (actionTypes.findByName(at.name()).name().isEmpty()) { + actionTypes.append(at); + } + } + return Interface(QString(), actionTypes, eventTypes, stateTypes); +} + QStringList DevicePlugin::generateInterfaceParentList(const QString &interface) { QFile f(QString(":/interfaces/%1.json").arg(interface)); @@ -1259,7 +1289,13 @@ QStringList DevicePlugin::generateInterfaceParentList(const QString &interface) QStringList ret = {interface}; QVariantMap content = jsonDoc.toVariant().toMap(); if (content.contains("extends")) { - ret << generateInterfaceParentList(content.value("extends").toString()); + if (!content.value("extends").toString().isEmpty()) { + ret << generateInterfaceParentList(content.value("extends").toString()); + } else if (content.value("extends").toList().count() > 0) { + foreach (const QVariant &extendedIface, content.value("extends").toList()) { + ret << generateInterfaceParentList(extendedIface.toString()); + } + } } return ret; } diff --git a/libnymea/plugin/deviceplugin.h b/libnymea/plugin/deviceplugin.h index 94f9f996..5bdeacbd 100644 --- a/libnymea/plugin/deviceplugin.h +++ b/libnymea/plugin/deviceplugin.h @@ -124,6 +124,7 @@ private: // I didn't want to add even more dependencies on the devicemanager into here, so reading the list here for now. static Interfaces allInterfaces(); static Interface loadInterface(const QString &name); + static Interface mergeInterfaces(const Interface &iface1, const Interface &iface2); static QStringList generateInterfaceParentList(const QString &interface); QTranslator *m_translator = nullptr;