Files
softbus_daemon/src/device_bus/tree/DeviceTreeModel.h

90 lines
3.4 KiB
C
Raw Normal View History

2026-03-12 14:56:53 +08:00
#pragma once
#include <QJsonObject>
2026-03-18 16:31:32 +08:00
#include <QJsonArray>
2026-03-12 14:56:53 +08:00
#include <QVector>
#include <QString>
#include <QHash>
2026-05-13 16:45:31 +08:00
#include <atomic>
#include <QMutex>
2026-03-12 14:56:53 +08:00
// 轻量级设备树模型:从 daemon_config.json 的 device_tree 字段加载
struct DeviceTreeNode
{
QString id;
QString name;
QString type;
QString endpoint;
QString driver;
QString capabilitiesRef;
QJsonObject params;
QVector<QString> childrenIds;
bool enabled{true};
};
class DeviceTreeModel
{
public:
// 从给定的 JSON 根对象(包含 device_tree 字段)加载
bool loadFromDaemonConfig(const QJsonObject& root, QString* errorMessage = nullptr);
const QVector<DeviceTreeNode>& nodes() const { return m_nodes; }
2026-03-18 16:31:32 +08:00
QVector<DeviceTreeNode>& nodesMutable() { return m_nodes; }
2026-03-12 14:56:53 +08:00
const DeviceTreeNode* findById(const QString& id) const;
2026-03-20 17:19:29 +08:00
int findIndexById(const QString& id) const;
2026-03-26 17:22:52 +08:00
int findIndexByEndpoint(const QString& endpoint) const;
2026-03-20 17:19:29 +08:00
int findIndexByStableKey(const QString& stableKey) const;
// Monitor/register path: upsert or mark online/offline
QString upsertNodeByStableKey(const QString& stableKey,
const QString& preferredId,
const QString& type,
const QString& endpoint,
const QString& name,
const QJsonObject& extraParams,
bool online,
const QString& lastSeenTs);
bool markOfflineByStableKey(const QString& stableKey, const QString& lastSeenTs);
2026-03-12 14:56:53 +08:00
2026-03-18 16:31:32 +08:00
// 序列化为 daemon_config.json 所需格式
QJsonArray toDeviceTreeJson() const;
QJsonObject toDaemonConfigRoot() const;
// 当外部直接修改 nodesMutable() 后,需要重建索引
void rebuildIndex();
2026-05-13 16:45:31 +08:00
// 与 D-Bus patch / 边缘 CTRL_TREE_PROPOSE 共用的写锁与 revision见 docs/EDGE_UPLINK_PROTOCOL_v1.md
QMutex& writeMutex() { return m_writeMutex; }
qint64 treeRevision() const { return m_treeRevision.load(std::memory_order_relaxed); }
void bumpTreeRevision();
bool applyPatchToNodeById(const QString& id, const QJsonObject& patch);
struct EdgeProposeResult
{
bool ok{false};
QString code; // OK, CONFLICT, FORBIDDEN_SCOPE, NODE_NOT_FOUND, INVALID_JSON
QString message;
qint64 newRevision{0};
qint64 currentRevision{0};
};
EdgeProposeResult applyEdgePropose(const QString& edgeId, qint64 baseRevision, const QJsonArray& entries);
/** 导出属于该 edge 的节点子集(与 applyEdgePropose 作用域规则一致),用于下行 TREE_FULL。
* outRevisionAtExport treeRevision nodes */
QJsonArray exportSubtreeForEdge(const QString& edgeId, qint64* outRevisionAtExport = nullptr) const;
/** 节点若处于边缘作用域params.edgeId 或 id 前缀 edges/<edgeId>/...),返回应尝试下行 TREE_FULL 的 edgeId去重。 */
QVector<QString> downlinkEdgeIdsForNode(const DeviceTreeNode& node) const;
2026-03-12 14:56:53 +08:00
private:
2026-05-13 16:45:31 +08:00
static bool nodeBelongsToEdge(const DeviceTreeNode& node, const QString& edgeId);
2026-03-12 14:56:53 +08:00
QVector<DeviceTreeNode> m_nodes;
QHash<QString, int> m_indexById;
2026-05-13 16:45:31 +08:00
mutable QMutex m_writeMutex;
std::atomic<qint64> m_treeRevision{1};
2026-03-12 14:56:53 +08:00
};