logic: Fixed slow aggregation click and nodes not staying expanded
This commit is contained in:
@@ -198,6 +198,8 @@ void GraphController::createDummyGraphForTokenIds(const std::vector<Id>& tokenId
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<Id> expandedNodeIds = getExpandedNodeIds();
|
||||
|
||||
m_dummyEdges.clear();
|
||||
m_dummyGraphNodes.clear();
|
||||
|
||||
@@ -215,7 +217,7 @@ void GraphController::createDummyGraphForTokenIds(const std::vector<Id>& 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<Id>& tokenId
|
||||
|
||||
m_dummyNodes = dummyNodes;
|
||||
|
||||
bool noActive = setActive(tokenIds);
|
||||
|
||||
autoExpandActiveNode(tokenIds);
|
||||
setActiveAndVisibility(tokenIds);
|
||||
setExpandedNodeIds(expandedNodeIds);
|
||||
|
||||
setVisibility(noActive);
|
||||
|
||||
m_graph = graph;
|
||||
}
|
||||
|
||||
std::shared_ptr<DummyNode> GraphController::createDummyNodeTopDown(Node* node)
|
||||
std::shared_ptr<DummyNode> GraphController::createDummyNodeTopDown(Node* node, Id parentId)
|
||||
{
|
||||
std::shared_ptr<DummyNode> result = std::make_shared<DummyNode>();
|
||||
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<DummyNode> 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<Id> GraphController::getExpandedNodeIds() const
|
||||
{
|
||||
std::vector<Id> nodeIds;
|
||||
for (std::pair<Id, std::shared_ptr<DummyNode>> 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<Id>& 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<Id>& activeTokenIds)
|
||||
{
|
||||
DummyNode* node = nullptr;
|
||||
@@ -339,7 +358,7 @@ void GraphController::autoExpandActiveNode(const std::vector<Id>& activeTokenIds
|
||||
}
|
||||
}
|
||||
|
||||
void GraphController::setActiveAndVisibility(const std::vector<Id>& activeTokenIds)
|
||||
bool GraphController::setActive(const std::vector<Id>& activeTokenIds)
|
||||
{
|
||||
bool noActive = activeTokenIds.size() == 0;
|
||||
if (activeTokenIds.size() > 0)
|
||||
@@ -376,6 +395,11 @@ void GraphController::setActiveAndVisibility(const std::vector<Id>& activeTokenI
|
||||
}
|
||||
}
|
||||
|
||||
return noActive;
|
||||
}
|
||||
|
||||
void GraphController::setVisibility(bool noActive)
|
||||
{
|
||||
for (std::shared_ptr<DummyNode> node : m_dummyNodes)
|
||||
{
|
||||
removeImplicitChildrenRecursive(node.get());
|
||||
@@ -384,6 +408,11 @@ void GraphController::setActiveAndVisibility(const std::vector<Id>& activeTokenI
|
||||
}
|
||||
}
|
||||
|
||||
void GraphController::setActiveAndVisibility(const std::vector<Id>& activeTokenIds)
|
||||
{
|
||||
setVisibility(setActive(activeTokenIds));
|
||||
}
|
||||
|
||||
void GraphController::setNodeActiveRecursive(DummyNode* node, const std::vector<Id>& 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<bool(const DummyNode::BundleInfo&)> matcher, size_t count, const std::string& name)
|
||||
{
|
||||
void GraphController::bundleNodesAndEdgesMatching(
|
||||
std::function<bool(const DummyNode::BundleInfo&)> matcher, size_t count, const std::string& name
|
||||
){
|
||||
std::vector<size_t> matchedNodeIndices;
|
||||
for (size_t i = 0; i < m_dummyNodes.size(); i++)
|
||||
{
|
||||
@@ -711,8 +742,9 @@ void GraphController::bundleNodesAndEdgesMatching(std::function<bool(const Dummy
|
||||
m_dummyEdges.insert(m_dummyEdges.end(), bundleEdges.begin(), bundleEdges.end());
|
||||
}
|
||||
|
||||
void GraphController::bundleNodesMatching(std::list<std::shared_ptr<DummyNode>>& nodes, std::function<bool(const DummyNode*)> matcher, const std::string& name)
|
||||
{
|
||||
void GraphController::bundleNodesMatching(
|
||||
std::list<std::shared_ptr<DummyNode>>& nodes, std::function<bool(const DummyNode*)> matcher, const std::string& name
|
||||
){
|
||||
std::vector<std::list<std::shared_ptr<DummyNode>>::iterator> matchedNodes;
|
||||
for (std::list<std::shared_ptr<DummyNode>>::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<Id, DummyNode*>::const_iterator it = m_dummyGraphNodes.find(tokenId);
|
||||
std::map<Id, std::shared_ptr<DummyNode>>::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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,10 +61,14 @@ private:
|
||||
void clear();
|
||||
|
||||
void createDummyGraphForTokenIds(const std::vector<Id>& tokenIds, const std::shared_ptr<Graph> graph);
|
||||
std::shared_ptr<DummyNode> createDummyNodeTopDown(Node* node);
|
||||
std::shared_ptr<DummyNode> createDummyNodeTopDown(Node* node, Id parentId);
|
||||
|
||||
std::vector<Id> getExpandedNodeIds() const;
|
||||
void setExpandedNodeIds(const std::vector<Id>& nodeIds);
|
||||
void autoExpandActiveNode(const std::vector<Id>& activeTokenIds);
|
||||
|
||||
bool setActive(const std::vector<Id>& activeTokenIds);
|
||||
void setVisibility(bool noActive);
|
||||
void setActiveAndVisibility(const std::vector<Id>& activeTokenIds);
|
||||
void setNodeActiveRecursive(DummyNode* node, const std::vector<Id>& activeTokenIds, bool* noActive) const;
|
||||
void removeImplicitChildrenRecursive(DummyNode* node);
|
||||
@@ -92,7 +96,7 @@ private:
|
||||
std::vector<std::shared_ptr<DummyNode>> m_dummyNodes;
|
||||
std::vector<std::shared_ptr<DummyEdge>> m_dummyEdges;
|
||||
|
||||
std::map<Id, DummyNode*> m_dummyGraphNodes;
|
||||
std::map<Id, std::shared_ptr<DummyNode>> m_dummyGraphNodes;
|
||||
|
||||
std::vector<Id> m_activeNodeIds;
|
||||
std::vector<Id> m_activeEdgeIds;
|
||||
|
||||
@@ -25,10 +25,8 @@ std::shared_ptr<MessageActivateTokens> ActivationTranslator::translateMessage(co
|
||||
std::shared_ptr<MessageActivateTokens> m;
|
||||
if (message->isAggregation())
|
||||
{
|
||||
const Id sourceId = m_storageAccess->getIdForNodeWithNameHierarchy(message->fromNameHierarchy);
|
||||
const Id targetId = m_storageAccess->getIdForNodeWithNameHierarchy(message->toNameHierarchy);
|
||||
|
||||
m = std::make_shared<MessageActivateTokens>(message, m_storageAccess->getTokenIdsForAggregationEdge(sourceId, targetId));
|
||||
// TODO: validate aggregationIds
|
||||
m = std::make_shared<MessageActivateTokens>(message, message->aggregationIds);
|
||||
m->setKeepContent(false);
|
||||
m->isAggregation = true;
|
||||
}
|
||||
|
||||
@@ -797,42 +797,6 @@ Id PersistentStorage::getTokenIdForFileNode(const FilePath& filePath) const
|
||||
return m_sqliteStorage.getFileByPath(filePath.str()).id;
|
||||
}
|
||||
|
||||
std::vector<Id> PersistentStorage::getTokenIdsForAggregationEdge(Id sourceId, Id targetId) const
|
||||
{
|
||||
std::vector<Id> edgeIds;
|
||||
|
||||
std::vector<Id> aggregationEndpointsA = getAllChildNodeIds(sourceId);
|
||||
std::set<Id> aggregationEndpointsB;
|
||||
aggregationEndpointsB.insert(targetId);
|
||||
for (const Id targetChildId: getAllChildNodeIds(targetId))
|
||||
{
|
||||
aggregationEndpointsB.insert(targetChildId);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < aggregationEndpointsA.size(); i++)
|
||||
{
|
||||
std::vector<StorageEdge> 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<StorageEdge> 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<TokenLocationCollection> PersistentStorage::getTokenLocationsForTokenIds(const std::vector<Id>& tokenIds) const
|
||||
{
|
||||
std::shared_ptr<TokenLocationCollection> collection = std::make_shared<TokenLocationCollection>();
|
||||
|
||||
@@ -92,7 +92,6 @@ public:
|
||||
|
||||
virtual std::vector<Id> getTokenIdsForMatches(const std::vector<SearchMatch>& matches) const;
|
||||
virtual Id getTokenIdForFileNode(const FilePath& filePath) const;
|
||||
virtual std::vector<Id> getTokenIdsForAggregationEdge(Id sourceId, Id targetId) const;
|
||||
|
||||
virtual std::shared_ptr<TokenLocationCollection> getTokenLocationsForTokenIds(
|
||||
const std::vector<Id>& tokenIds
|
||||
|
||||
@@ -50,7 +50,6 @@ public:
|
||||
|
||||
virtual std::vector<Id> getTokenIdsForMatches(const std::vector<SearchMatch>& matches) const = 0;
|
||||
virtual Id getTokenIdForFileNode(const FilePath& filePath) const = 0;
|
||||
virtual std::vector<Id> getTokenIdsForAggregationEdge(Id sourceId, Id targetId) const = 0;
|
||||
|
||||
virtual std::shared_ptr<TokenLocationCollection> getTokenLocationsForTokenIds(
|
||||
const std::vector<Id>& tokenIds) const = 0;
|
||||
|
||||
@@ -174,16 +174,6 @@ Id StorageAccessProxy::getTokenIdForFileNode(const FilePath& filePath) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<Id> StorageAccessProxy::getTokenIdsForAggregationEdge(Id sourceId, Id targetId) const
|
||||
{
|
||||
if (hasSubject())
|
||||
{
|
||||
return m_subject->getTokenIdsForAggregationEdge(sourceId, targetId);
|
||||
}
|
||||
|
||||
return std::vector<Id>();
|
||||
}
|
||||
|
||||
std::shared_ptr<TokenLocationCollection> StorageAccessProxy::getTokenLocationsForTokenIds(
|
||||
const std::vector<Id>& tokenIds) const
|
||||
{
|
||||
|
||||
@@ -34,7 +34,6 @@ public:
|
||||
|
||||
virtual std::vector<Id> getTokenIdsForMatches(const std::vector<SearchMatch>& matches) const;
|
||||
virtual Id getTokenIdForFileNode(const FilePath& filePath) const;
|
||||
virtual std::vector<Id> getTokenIdsForAggregationEdge(Id sourceId, Id targetId) const;
|
||||
|
||||
virtual std::shared_ptr<TokenLocationCollection> getTokenLocationsForTokenIds(
|
||||
const std::vector<Id>& tokenIds
|
||||
|
||||
@@ -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<Id> aggregationIds;
|
||||
};
|
||||
|
||||
#endif // MESSAGE_ACTIVATE_EDGE_H
|
||||
|
||||
@@ -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<Id>(getData()->getComponent<TokenComponentAggregation>()->getAggregationIds());
|
||||
}
|
||||
|
||||
msg.dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user