From badad741b0cf9ee0453a2c391dd2962a1420742d Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Sat, 21 May 2016 04:44:31 +0200 Subject: [PATCH] logic: Fixed slow aggregation click and nodes not staying expanded --- .../component/controller/GraphController.cpp | 102 ++++++++++++------ .../component/controller/GraphController.h | 8 +- .../helper/ActivationTranslator.cpp | 6 +- src/lib/data/PersistentStorage.cpp | 36 ------- src/lib/data/PersistentStorage.h | 1 - src/lib/data/access/StorageAccess.h | 1 - src/lib/data/access/StorageAccessProxy.cpp | 10 -- src/lib/data/access/StorageAccessProxy.h | 1 - .../messaging/type/MessageActivateEdge.h | 7 +- .../qt/view/graphElements/QtGraphEdge.cpp | 13 ++- 10 files changed, 92 insertions(+), 93 deletions(-) diff --git a/src/lib/component/controller/GraphController.cpp b/src/lib/component/controller/GraphController.cpp index fcc6b82a..c50bd8b9 100644 --- a/src/lib/component/controller/GraphController.cpp +++ b/src/lib/component/controller/GraphController.cpp @@ -198,6 +198,8 @@ void GraphController::createDummyGraphForTokenIds(const std::vector& tokenId return; } + std::vector expandedNodeIds = getExpandedNodeIds(); + m_dummyEdges.clear(); m_dummyGraphNodes.clear(); @@ -215,7 +217,7 @@ void GraphController::createDummyGraphForTokenIds(const std::vector& tokenId } addedNodes.insert(id); - dummyNodes.push_back(createDummyNodeTopDown(parent)); + dummyNodes.push_back(createDummyNodeTopDown(parent, parent->getId())); } ); @@ -239,40 +241,26 @@ void GraphController::createDummyGraphForTokenIds(const std::vector& tokenId m_dummyNodes = dummyNodes; + bool noActive = setActive(tokenIds); + autoExpandActiveNode(tokenIds); - setActiveAndVisibility(tokenIds); + setExpandedNodeIds(expandedNodeIds); + + setVisibility(noActive); m_graph = graph; } -std::shared_ptr GraphController::createDummyNodeTopDown(Node* node) +std::shared_ptr GraphController::createDummyNodeTopDown(Node* node, Id parentId) { std::shared_ptr result = std::make_shared(); result->data = node; result->tokenId = node->getId(); result->name = node->getName(); - - // there is a global root node with id 0 afaik, so here we actually want the one node below this global root - Node* parent = node; - while (parent != NULL && parent->getParentNode() != NULL) - { - parent = parent->getParentNode(); - } - - if (parent != NULL) - { - result->topLevelAncestorId = parent->getId(); - } - - // Expand nodes that were expanded before, except functions. - DummyNode* oldNode = getDummyGraphNodeById(node->getId()); - if (oldNode && oldNode->isGraphNode() && !oldNode->data->isType(Node::NODE_FUNCTION | Node::NODE_METHOD)) - { - result->expanded = oldNode->isExpanded(); - } + result->topLevelAncestorId = parentId; node->forEachChildNode( - [node, &result, this](Node* child) + [node, &parentId, &result, this](Node* child) { DummyNode* parent = nullptr; @@ -316,15 +304,46 @@ std::shared_ptr GraphController::createDummyNodeTopDown(Node* node) } } - parent->subNodes.push_back(createDummyNodeTopDown(child)); + parent->subNodes.push_back(createDummyNodeTopDown(child, parentId)); } ); - m_dummyGraphNodes.emplace(result->data->getId(), result.get()); + m_dummyGraphNodes.emplace(result->data->getId(), result); return result; } +std::vector GraphController::getExpandedNodeIds() const +{ + std::vector nodeIds; + for (std::pair> p : m_dummyGraphNodes) + { + DummyNode* oldNode = p.second.get(); + if (oldNode->expanded && oldNode->isGraphNode() && !oldNode->data->isType(Node::NODE_FUNCTION | Node::NODE_METHOD)) + { + nodeIds.push_back(p.first); + } + } + return nodeIds; +} + +void GraphController::setExpandedNodeIds(const std::vector& nodeIds) +{ + for (Id id : nodeIds) + { + DummyNode* node = getDummyGraphNodeById(id); + if (node && node->topLevelAncestorId) + { + DummyNode* parent = getDummyGraphNodeById(node->topLevelAncestorId); + + if (parent && parent->hasActiveSubNode()) + { + node->expanded = true; + } + } + } +} + void GraphController::autoExpandActiveNode(const std::vector& activeTokenIds) { DummyNode* node = nullptr; @@ -339,7 +358,7 @@ void GraphController::autoExpandActiveNode(const std::vector& activeTokenIds } } -void GraphController::setActiveAndVisibility(const std::vector& activeTokenIds) +bool GraphController::setActive(const std::vector& activeTokenIds) { bool noActive = activeTokenIds.size() == 0; if (activeTokenIds.size() > 0) @@ -376,6 +395,11 @@ void GraphController::setActiveAndVisibility(const std::vector& activeTokenI } } + return noActive; +} + +void GraphController::setVisibility(bool noActive) +{ for (std::shared_ptr node : m_dummyNodes) { removeImplicitChildrenRecursive(node.get()); @@ -384,6 +408,11 @@ void GraphController::setActiveAndVisibility(const std::vector& activeTokenI } } +void GraphController::setActiveAndVisibility(const std::vector& activeTokenIds) +{ + setVisibility(setActive(activeTokenIds)); +} + void GraphController::setNodeActiveRecursive(DummyNode* node, const std::vector& activeTokenIds, bool* noActive) const { node->active = false; @@ -416,7 +445,8 @@ void GraphController::removeImplicitChildrenRecursive(DummyNode* node) bool removeNode = false; DummyNode* subNode = node->subNodes[i].get(); - if (subNode->isGraphNode() && subNode->data->isImplicit() && !subNode->connected && !subNode->active && !subNode->subNodes.size()) + if (subNode->isGraphNode() && subNode->data->isImplicit() && + !subNode->connected && !subNode->active && !subNode->subNodes.size()) { removeNode = true; } @@ -621,8 +651,9 @@ void GraphController::bundleNodes() ); } -void GraphController::bundleNodesAndEdgesMatching(std::function matcher, size_t count, const std::string& name) -{ +void GraphController::bundleNodesAndEdgesMatching( + std::function matcher, size_t count, const std::string& name +){ std::vector matchedNodeIndices; for (size_t i = 0; i < m_dummyNodes.size(); i++) { @@ -711,8 +742,9 @@ void GraphController::bundleNodesAndEdgesMatching(std::function>& nodes, std::function matcher, const std::string& name) -{ +void GraphController::bundleNodesMatching( + std::list>& nodes, std::function matcher, const std::string& name +){ std::vector>::iterator> matchedNodes; for (std::list>::iterator it = nodes.begin(); it != nodes.end(); it++) { @@ -857,7 +889,8 @@ void GraphController::layoutNestingRecursive(DummyNode* node) const width = margins.charWidth * node->name.size(); - if (node->data->isType(Node::NODE_TYPE | Node::NODE_CLASS | Node::NODE_STRUCT | Node::NODE_ENUM) && node->subNodes.size()) + if (node->data->isType(Node::NODE_TYPE | Node::NODE_CLASS | Node::NODE_STRUCT | Node::NODE_ENUM) && + node->subNodes.size()) { addExpandToggleNode(node); } @@ -1049,10 +1082,10 @@ void GraphController::layoutGraph(bool sort) DummyNode* GraphController::getDummyGraphNodeById(Id tokenId) const { - std::map::const_iterator it = m_dummyGraphNodes.find(tokenId); + std::map>::const_iterator it = m_dummyGraphNodes.find(tokenId); if (it != m_dummyGraphNodes.end()) { - return it->second; + return it->second.get(); } return nullptr; @@ -1063,6 +1096,5 @@ void GraphController::buildGraph(MessageBase* message) if (!message->isReplayed()) { getView()->rebuildGraph(m_graph, m_dummyNodes, m_dummyEdges); - m_graph.reset(); } } diff --git a/src/lib/component/controller/GraphController.h b/src/lib/component/controller/GraphController.h index b19e8f4b..dda20bdb 100644 --- a/src/lib/component/controller/GraphController.h +++ b/src/lib/component/controller/GraphController.h @@ -61,10 +61,14 @@ private: void clear(); void createDummyGraphForTokenIds(const std::vector& tokenIds, const std::shared_ptr graph); - std::shared_ptr createDummyNodeTopDown(Node* node); + std::shared_ptr createDummyNodeTopDown(Node* node, Id parentId); + std::vector getExpandedNodeIds() const; + void setExpandedNodeIds(const std::vector& nodeIds); void autoExpandActiveNode(const std::vector& activeTokenIds); + bool setActive(const std::vector& activeTokenIds); + void setVisibility(bool noActive); void setActiveAndVisibility(const std::vector& activeTokenIds); void setNodeActiveRecursive(DummyNode* node, const std::vector& activeTokenIds, bool* noActive) const; void removeImplicitChildrenRecursive(DummyNode* node); @@ -92,7 +96,7 @@ private: std::vector> m_dummyNodes; std::vector> m_dummyEdges; - std::map m_dummyGraphNodes; + std::map> m_dummyGraphNodes; std::vector m_activeNodeIds; std::vector m_activeEdgeIds; diff --git a/src/lib/component/controller/helper/ActivationTranslator.cpp b/src/lib/component/controller/helper/ActivationTranslator.cpp index 1e6a97da..0e9bef7e 100644 --- a/src/lib/component/controller/helper/ActivationTranslator.cpp +++ b/src/lib/component/controller/helper/ActivationTranslator.cpp @@ -25,10 +25,8 @@ std::shared_ptr ActivationTranslator::translateMessage(co std::shared_ptr m; if (message->isAggregation()) { - const Id sourceId = m_storageAccess->getIdForNodeWithNameHierarchy(message->fromNameHierarchy); - const Id targetId = m_storageAccess->getIdForNodeWithNameHierarchy(message->toNameHierarchy); - - m = std::make_shared(message, m_storageAccess->getTokenIdsForAggregationEdge(sourceId, targetId)); + // TODO: validate aggregationIds + m = std::make_shared(message, message->aggregationIds); m->setKeepContent(false); m->isAggregation = true; } diff --git a/src/lib/data/PersistentStorage.cpp b/src/lib/data/PersistentStorage.cpp index a5f999ae..77d609b9 100644 --- a/src/lib/data/PersistentStorage.cpp +++ b/src/lib/data/PersistentStorage.cpp @@ -797,42 +797,6 @@ Id PersistentStorage::getTokenIdForFileNode(const FilePath& filePath) const return m_sqliteStorage.getFileByPath(filePath.str()).id; } -std::vector PersistentStorage::getTokenIdsForAggregationEdge(Id sourceId, Id targetId) const -{ - std::vector edgeIds; - - std::vector aggregationEndpointsA = getAllChildNodeIds(sourceId); - std::set aggregationEndpointsB; - aggregationEndpointsB.insert(targetId); - for (const Id targetChildId: getAllChildNodeIds(targetId)) - { - aggregationEndpointsB.insert(targetChildId); - } - - for (size_t i = 0; i < aggregationEndpointsA.size(); i++) - { - std::vector outgoingEdges = m_sqliteStorage.getEdgesBySourceId(aggregationEndpointsA[i]); - for (size_t j = 0; j < outgoingEdges.size(); j++) - { - if (aggregationEndpointsB.find(outgoingEdges[j].targetNodeId) != aggregationEndpointsB.end()) - { - edgeIds.push_back(outgoingEdges[j].id); - } - } - - std::vector incomingEdges = m_sqliteStorage.getEdgesByTargetId(aggregationEndpointsA[i]); - for (size_t j = 0; j < incomingEdges.size(); j++) - { - if (aggregationEndpointsB.find(incomingEdges[j].sourceNodeId) != aggregationEndpointsB.end()) - { - edgeIds.push_back(incomingEdges[j].id); - } - } - } - - return edgeIds; -} - std::shared_ptr PersistentStorage::getTokenLocationsForTokenIds(const std::vector& tokenIds) const { std::shared_ptr collection = std::make_shared(); diff --git a/src/lib/data/PersistentStorage.h b/src/lib/data/PersistentStorage.h index 504f2e34..69171289 100644 --- a/src/lib/data/PersistentStorage.h +++ b/src/lib/data/PersistentStorage.h @@ -92,7 +92,6 @@ public: virtual std::vector getTokenIdsForMatches(const std::vector& matches) const; virtual Id getTokenIdForFileNode(const FilePath& filePath) const; - virtual std::vector getTokenIdsForAggregationEdge(Id sourceId, Id targetId) const; virtual std::shared_ptr getTokenLocationsForTokenIds( const std::vector& tokenIds diff --git a/src/lib/data/access/StorageAccess.h b/src/lib/data/access/StorageAccess.h index d5fccbb5..d17fcdab 100644 --- a/src/lib/data/access/StorageAccess.h +++ b/src/lib/data/access/StorageAccess.h @@ -50,7 +50,6 @@ public: virtual std::vector getTokenIdsForMatches(const std::vector& matches) const = 0; virtual Id getTokenIdForFileNode(const FilePath& filePath) const = 0; - virtual std::vector getTokenIdsForAggregationEdge(Id sourceId, Id targetId) const = 0; virtual std::shared_ptr getTokenLocationsForTokenIds( const std::vector& tokenIds) const = 0; diff --git a/src/lib/data/access/StorageAccessProxy.cpp b/src/lib/data/access/StorageAccessProxy.cpp index 44b1b894..8251c656 100644 --- a/src/lib/data/access/StorageAccessProxy.cpp +++ b/src/lib/data/access/StorageAccessProxy.cpp @@ -174,16 +174,6 @@ Id StorageAccessProxy::getTokenIdForFileNode(const FilePath& filePath) const return 0; } -std::vector StorageAccessProxy::getTokenIdsForAggregationEdge(Id sourceId, Id targetId) const -{ - if (hasSubject()) - { - return m_subject->getTokenIdsForAggregationEdge(sourceId, targetId); - } - - return std::vector(); -} - std::shared_ptr StorageAccessProxy::getTokenLocationsForTokenIds( const std::vector& tokenIds) const { diff --git a/src/lib/data/access/StorageAccessProxy.h b/src/lib/data/access/StorageAccessProxy.h index 16f1936d..d7c3a924 100644 --- a/src/lib/data/access/StorageAccessProxy.h +++ b/src/lib/data/access/StorageAccessProxy.h @@ -34,7 +34,6 @@ public: virtual std::vector getTokenIdsForMatches(const std::vector& matches) const; virtual Id getTokenIdForFileNode(const FilePath& filePath) const; - virtual std::vector getTokenIdsForAggregationEdge(Id sourceId, Id targetId) const; virtual std::shared_ptr getTokenLocationsForTokenIds( const std::vector& tokenIds diff --git a/src/lib/utility/messaging/type/MessageActivateEdge.h b/src/lib/utility/messaging/type/MessageActivateEdge.h index a22ddec9..9333a6d7 100644 --- a/src/lib/utility/messaging/type/MessageActivateEdge.h +++ b/src/lib/utility/messaging/type/MessageActivateEdge.h @@ -32,7 +32,10 @@ public: std::string getFullName() const { - return Edge::getTypeString(type) + ":" + fromNameHierarchy.getQualifiedNameWithSignature() + "->" + toNameHierarchy.getQualifiedNameWithSignature(); + std::string name = Edge::getTypeString(type) + ":"; + name += fromNameHierarchy.getQualifiedNameWithSignature() + "->"; + name += toNameHierarchy.getQualifiedNameWithSignature(); + return name; } virtual void print(std::ostream& os) const @@ -44,6 +47,8 @@ public: const Edge::EdgeType type; const NameHierarchy fromNameHierarchy; const NameHierarchy toNameHierarchy; + + std::vector aggregationIds; }; #endif // MESSAGE_ACTIVATE_EDGE_H diff --git a/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp b/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp index 468eaa01..200549c3 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp +++ b/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp @@ -6,6 +6,7 @@ #include "utility/messaging/type/MessageFocusIn.h" #include "utility/messaging/type/MessageFocusOut.h" #include "utility/messaging/type/MessageGraphNodeBundleSplit.h" +#include "utility/utility.h" #include "component/view/GraphViewStyle.h" #include "data/graph/Edge.h" @@ -182,12 +183,20 @@ void QtGraphEdge::onClick() } else { - MessageActivateEdge( + MessageActivateEdge msg( getData()->getId(), getData()->getType(), getData()->getFrom()->getNameHierarchy(), getData()->getTo()->getNameHierarchy() - ).dispatch(); + ); + + if (getData()->getType() == Edge::EDGE_AGGREGATION) + { + msg.aggregationIds = + utility::toVector(getData()->getComponent()->getAggregationIds()); + } + + msg.dispatch(); } }