DiagramDesigner/diagramCavas/source/topologyManager.cpp

454 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <QJsonArray>
#include <QJsonDocument>
#include "topologyManager.h"
#include "powerEntity.h"
#include "graphicsItem/graphicsBaseItem.h"
TopologyManager& TopologyManager::instance()
{
static TopologyManager instance;
return instance;
}
TopologyManager::TopologyManager(QObject* parent)
: QObject(parent) {}
TopologyManager::~TopologyManager() {
clearAllData();
}
void TopologyManager::clearAllData()
{
// 删除所有连接
qDeleteAll(m_connections);
m_connections.clear();
m_connectionIndex.clear();
// 删除所有实体(自动删除子对象)
qDeleteAll(m_entities);
m_entities.clear();
m_allTerminals.clear(); //端点由父亲entity释放
}
PowerEntity* TopologyManager::createEntity(EntityType type,const QString& uuid, const QString& name)
{
PowerEntity* entity = nullptr;
switch(type) {
case EntityType::ConfigurationDiagram:
entity = new ConfigurationDiagram(uuid,name);
break;
case EntityType::Grid:
case EntityType::Zone:
case EntityType::Station:
entity = new PowerDivision(type, uuid,name);
default:
entity = new PowerComponent(type, uuid,name);
}
m_entities.insert(entity->id(), entity);
emit entityCreated(entity->id()); // 发送信号通知
return entity;
}
PowerEntity* TopologyManager::findEntity(const QString& id) const
{
return m_entities.value(id, nullptr); // 避免异常的安全查询
}
bool TopologyManager::deleteEntity(const QString& id)
{
if (!m_entities.contains(id)) return false;
PowerEntity* entity = m_entities[id];
// 步骤1删除所有相关连接
auto relatedConns = getConnectionsFor(id);
for (auto conn : relatedConns) {
removeConnection(conn->id());
}
// 步骤2从父节点移除防止悬空指针
if (PowerEntity* parent = entity->parent()) {
parent->removeChild(entity);
}
// 步骤3递归删除子实体
auto children = entity->children();
for (auto child : children) {
deleteEntity(child->id()); // 递归删除
}
// 步骤4从哈希表移除并释放内存
m_entities.remove(id);
delete entity; // 触发PowerEntity析构函数
emit entityDeleted(id);
return true;
}
PowerConnection* TopologyManager::createConnection(const QString& connId,const QString& fromTerId, const QString& toTerId,const QString& fromId,const QString& toId)
{
// 验证有效性
if (!m_allTerminals.contains(fromTerId) ||
!m_allTerminals.contains(toTerId) ||
fromTerId == toTerId)
{
qWarning() << "Invalid connection endpoints";
return nullptr;
}
// 防止重复连接
foreach (auto conn, m_connections) {
if (conn->fromTerminalId() == fromTerId &&
conn->toTerminalId() == toTerId)
{
return conn; // 返回已存在的连接
}
}
// 创建新连接
PowerConnection* conn = new PowerConnection(connId,fromTerId, toTerId,fromId,toId);
m_connections[connId] = conn;
// 更新索引
m_connectionIndex.insert(fromTerId, conn);
m_connectionIndex.insert(toTerId, conn);
emit connectionCreated(connId);
return conn;
}
QList<PowerConnection*> TopologyManager::getConnectionsForTerminal(const QString& terminalId) const
{
return m_connectionIndex.values(terminalId);
}
void TopologyManager::removeConnection(const QString& connId)
{
if (!m_connections.contains(connId)) return;
PowerConnection* conn = m_connections[connId];
// 更新索引
m_connectionIndex.remove(conn->fromTerminalId(), conn);
m_connectionIndex.remove(conn->toTerminalId(), conn);
// 清理内存
m_connections.remove(connId);
delete conn;
emit connectionRemoved(connId);
}
bool TopologyManager::validateConnection(const QString& fromTermId, const QString& toTermId) const
{
PowerTerminal* fromTerm = getTerminal(fromTermId);
PowerTerminal* toTerm = getTerminal(toTermId);
if (!fromTerm || !toTerm) return false;
// 类型兼容性检查(示例规则)
switch(fromTerm->type()) {
case TerminalType::PowerOutput:
if (toTerm->type() != TerminalType::PowerInput && toTerm->type() != TerminalType::PowerConnect) return false;
break;
case TerminalType::PowerInput:
if (toTerm->type() != TerminalType::PowerOutput && toTerm->type() != TerminalType::PowerConnect) return false;
break;
case TerminalType::PowerConnect:
break;
case TerminalType::ControlSignal:
if (toTerm->type() != TerminalType::ControlSignal) return false;
break;
default:
return false;
}
int a =1;
// 禁止自连接
return (fromTerm->parentEntityId() != toTerm->parentEntityId());
}
// 连接查询接口
QList<PowerConnection*> TopologyManager::connectionsFrom(const QString& elementId) const
{
QList<PowerConnection*> res;
/*QList<PowerConnection*> lst = m_connectionIndex.values(elementId);
for(auto &val:lst)
{
if(val->fromTerminalId() == elementId)
res.append(val);
}*/
return res;
}
QList<PowerConnection*> TopologyManager::connectionsTo(const QString& elementId) const
{
QList<PowerConnection*> res;
/*QList<PowerConnection*> lst = m_connectionIndex.values(elementId);
for(auto &val:lst)
{
if(val->toTerminalId() == elementId)
res.append(val);
}*/
return res;
}
QList<PowerConnection*> TopologyManager::getConnectionsFor(const QString& entityId) const
{
QList<PowerConnection*> lst;
QList<PowerTerminal*> lstTerminal = getTerminalsForEntity(entityId);
for(auto &terminal:lstTerminal)
{
PowerConnection* con = getConnectionContainsTerminal(terminal->id());
if(con)
lst.append(con);
}
return lst;
}
PowerConnection* TopologyManager::connection(const QString& conId) const
{
return m_connections.value(conId,nullptr);
}
PowerConnection* TopologyManager::connection(const QString& fromPin,const QString& toPin)
{
for(auto &con:m_connections)
{
if(con->fromTerminalId() == fromPin && con->toTerminalId() == toPin)
return con;
}
return nullptr;
}
QHash<QString,PowerConnection*> TopologyManager::getAllConnections()
{
return m_connections;
}
/*void TopologyManager::saveToDB(const QString& path)
{
QJsonObject root;
// 序列化实体(含接线点)
QJsonArray entities;
foreach (auto entity, m_entities) {
QJsonObject entObj = entity->toJson();
QJsonArray terminalsArray;
foreach (auto term, entity->terminals()) {
terminalsArray.append(term->toJson());
}
entObj["terminals"] = terminalsArray;
entities.append(entObj);
}
root["entities"] = entities;
QJsonArray connectionsArray;
for (auto conn : m_connections)
connectionsArray.append(conn->toJson());
root["connections"] = connectionsArray;
//todo:写入到数据库
}*/
/*void TopologyManager::loadFromDB(const QString& path)
{
//todo::将读到的字为json
QString strJson;
QJsonDocument doc = QJsonDocument::fromJson(strJson.toLocal8Bit());
QJsonObject root = doc.object();
clearAllData(); // 清除现有数据
// 阶段1创建所有实体
QHash<QString, QStringList> pendingChildren;
QJsonArray entities = root["entities"].toArray();
foreach (QJsonValue entVal, entities) {
QJsonObject entObj = entVal.toObject();
// 创建实体
EntityType type = static_cast<EntityType>(entObj["type"].toInt());
QString id = entObj["id"].toString();
QString name = entObj["name"].toString();
PowerEntity* entity = createEntity(type, id, name);
foreach (auto termJson, entObj["terminals"].toArray()) {
PowerTerminal* term = PowerTerminal::fromJson(termJson.toObject(), entity);
m_allTerminals[term->id()] = term;
m_terminalsByEntity[entity->id()].append(term);
}
// 记录待处理的子关系
pendingChildren[id] = entObj["children"].toVariant().toStringList();
}
// 阶段2建立父子关系
QHashIterator<QString, QStringList> it(pendingChildren);
while (it.hasNext()) {
it.next();
PowerEntity* parent = getEntity(it.key());
if (!parent) continue;
foreach (QString childId, it.value()) {
if (PowerEntity* child = getEntity(childId)) {
parent->addChild(child);
}
}
}
// 阶段3创建连接
QJsonArray connections = root["connections"].toArray();
foreach (QJsonValue connVal, connections) {
QJsonObject connObj = connVal.toObject();
createConnection(
connObj["id"].toString(),
connObj["from"].toString(),
connObj["to"].toString()
);
}
}*/
PowerEntity* TopologyManager::getEntity(const QString& id) const
{
auto it = m_entities.find(id);
return (it != m_entities.end()) ? it.value() : nullptr;
}
QList<PowerEntity*> TopologyManager::findEntitiesByName(const QString& name) const
{
QList<PowerEntity*> results;
foreach (auto entity, m_entities) {
if (entity->name() == name) {
results.append(entity);
}
}
return results;
}
PowerEntity* TopologyManager::createDiagram(const QString& id,const QString& name)
{
PowerEntity* entity = nullptr;
if(!m_diagrams.contains(id))
{
entity = new ConfigurationDiagram(id,name);
m_diagrams.insert(entity->id(), entity);
}
return entity;
}
PowerEntity* TopologyManager::findDiagram(const QString& id) const
{
return m_diagrams.value(id, nullptr); // 避免异常的安全查询
}
bool TopologyManager::deleteDiagram(const QString& id)
{
if (!m_diagrams.contains(id)) return false;
PowerEntity* entity = m_diagrams[id];
// 步骤2从父节点移除防止悬空指针
if (PowerEntity* parent = entity->parent()) {
parent->removeChild(entity);
}
// 步骤3递归删除子实体
auto children = entity->children();
for (auto child : children) {
deleteDiagram(child->id()); // 递归删除
}
// 步骤4从哈希表移除并释放内存
m_diagrams.remove(id);
delete entity; // 触发析构函数
return true;
}
PowerTerminal* TopologyManager::createTerminal(const QString& parentEntityId,
TerminalType type,
const QString& name,
const QPointF& relPos,
const QString& uuid) {
if (!m_entities.contains(parentEntityId)) return nullptr;
PowerTerminal* term = new PowerTerminal(parentEntityId, type, name, relPos, uuid);
m_allTerminals[term->id()] = term;
m_terminalsByEntity[parentEntityId].append(term);
// 关联到父实体
if (PowerEntity* parent = getEntity(parentEntityId)) {
parent->addTerminal(term);
}
return term;
}
bool TopologyManager::deleteTerminal(const QString& terminalId) {
if (!m_allTerminals.contains(terminalId)) return false;
PowerTerminal* term = m_allTerminals[terminalId];
QString parentId = term->parentEntityId();
// 从父实体移除
if (PowerEntity* parent = getEntity(parentId)) {
parent->removeTerminal(terminalId);
}
// 清理全局存储
m_terminalsByEntity[parentId].removeAll(term);
m_allTerminals.remove(terminalId);
//delete term; //在parent中已经delete
return true;
}
PowerTerminal* TopologyManager::getTerminal(const QString& terminalId) const
{
auto it = m_allTerminals.find(terminalId);
return (it != m_allTerminals.end()) ? it.value() : nullptr;
}
QList<PowerTerminal*> TopologyManager::getTerminalsForEntity(const QString& entityId) const {
return m_terminalsByEntity.value(entityId);
}
PowerEntity* TopologyManager::getEntityByTerminal(const QString& terminalId) const
{
QHash<QString, QList<PowerTerminal*>>::ConstIterator iter;
for(iter = m_terminalsByEntity.begin();iter != m_terminalsByEntity.end();++iter)
{
for(auto &terminal:iter.value())
{
if(terminal->id() == terminalId)
{
return m_entities[iter.key()];
}
}
}
return nullptr;
}
PowerConnection* TopologyManager::getConnectionContainsTerminal(const QString& terminalId) const
{
for(auto &con:m_connections)
{
if(con->fromTerminalId() == terminalId || con->toTerminalId() == terminalId)
{
return con;
}
}
return nullptr;
}