logic: Fixed slow aggregation click and nodes not staying expanded

This commit is contained in:
Eberhard Graether
2016-05-21 04:44:31 +02:00
parent 5d2a476813
commit badad741b0
10 changed files with 92 additions and 93 deletions
@@ -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;
}
-36
View File
@@ -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>();
-1
View File
@@ -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
-1
View File
@@ -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
{
-1
View File
@@ -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();
}
}