data/logic/ui: added aggregation edges
This change adds the creation of aggregation edges to the StorageGraph, which save the connection counts between children in their parents. Aggregation edges are displayed using a straight line, that is thicker than more connections it represents with the connection count in the middle.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
#include <sstream>
|
||||
|
||||
#include "data/graph/Node.h"
|
||||
#include "data/graph/token_component/TokenComponentAggregation.h"
|
||||
#include "data/graph/token_component/TokenComponentAccess.h"
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
@@ -76,6 +77,22 @@ bool Edge::isEdge() const
|
||||
return true;
|
||||
}
|
||||
|
||||
void Edge::addComponentAggregation(std::shared_ptr<TokenComponentAggregation> component)
|
||||
{
|
||||
if (getComponent<TokenComponentAggregation>())
|
||||
{
|
||||
LOG_ERROR("TokenComponentAggregation has been set before!");
|
||||
}
|
||||
else if (m_type != EDGE_AGGREGATION)
|
||||
{
|
||||
LOG_ERROR("TokenComponentAggregation can't be set on edge of type: " + getTypeString());
|
||||
}
|
||||
else
|
||||
{
|
||||
addComponent(component);
|
||||
}
|
||||
}
|
||||
|
||||
void Edge::addComponentAccess(std::shared_ptr<TokenComponentAccess> component)
|
||||
{
|
||||
if (getComponent<TokenComponentAccess>())
|
||||
@@ -118,6 +135,8 @@ std::string Edge::getTypeString(EdgeType type) const
|
||||
return "template parameter";
|
||||
case EDGE_TEMPLATE_SPECIALIZATION_OF:
|
||||
return "template specialization";
|
||||
case EDGE_AGGREGATION:
|
||||
return "aggregation";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -132,10 +151,16 @@ std::string Edge::getAsString() const
|
||||
std::stringstream str;
|
||||
str << "[" << getId() << "] " << getTypeString() << ": \"" << m_from->getName() << "\" -> \"" + m_to->getName() << "\"";
|
||||
|
||||
TokenComponentAccess* component = getComponent<TokenComponentAccess>();
|
||||
if (component)
|
||||
TokenComponentAccess* access = getComponent<TokenComponentAccess>();
|
||||
if (access)
|
||||
{
|
||||
str << " " << component->getAccessString();
|
||||
str << " " << access->getAccessString();
|
||||
}
|
||||
|
||||
TokenComponentAggregation* aggregation = getComponent<TokenComponentAggregation>();
|
||||
if (aggregation)
|
||||
{
|
||||
str << " " << aggregation->getAggregationCount();
|
||||
}
|
||||
|
||||
return str.str();
|
||||
@@ -222,6 +247,13 @@ bool Edge::checkType() const
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
||||
case EDGE_AGGREGATION:
|
||||
if (!m_from->isType(typeMask | variableMask | functionMask) || !m_to->isType(typeMask | variableMask | functionMask))
|
||||
{
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_ERROR_STREAM(
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "data/graph/Token.h"
|
||||
|
||||
class Node;
|
||||
class TokenComponentAggregation;
|
||||
class TokenComponentAccess;
|
||||
class TokenComponentDataType;
|
||||
|
||||
@@ -26,7 +27,9 @@ public:
|
||||
EDGE_INHERITANCE = 0x80,
|
||||
EDGE_TYPEDEF_OF = 0x100,
|
||||
EDGE_TEMPLATE_PARAMETER_OF = 0x200,
|
||||
EDGE_TEMPLATE_SPECIALIZATION_OF = 0x400
|
||||
EDGE_TEMPLATE_SPECIALIZATION_OF = 0x400,
|
||||
|
||||
EDGE_AGGREGATION = 0x800
|
||||
};
|
||||
|
||||
Edge(EdgeType type, Node* from, Node* to);
|
||||
@@ -46,6 +49,7 @@ public:
|
||||
virtual bool isEdge() const;
|
||||
|
||||
// Component setters
|
||||
void addComponentAggregation(std::shared_ptr<TokenComponentAggregation> component);
|
||||
void addComponentAccess(std::shared_ptr<TokenComponentAccess> component);
|
||||
|
||||
// Logging.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "data/graph/StorageGraph.h"
|
||||
|
||||
#include "data/graph/token_component/TokenComponentAggregation.h"
|
||||
#include "data/graph/token_component/TokenComponentName.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/utilityString.h"
|
||||
@@ -87,7 +88,16 @@ Edge* StorageGraph::createEdge(Edge::EdgeType type, Node* from, Node* to)
|
||||
return edge;
|
||||
}
|
||||
|
||||
return insertEdge(type, from, to);
|
||||
edge = insertEdge(type, from, to);
|
||||
|
||||
if (from->getLastParentNode() != to->getLastParentNode())
|
||||
{
|
||||
Id edgeId = edge->getId();
|
||||
updateAggregationEdges(from->getParentNode(), to, edgeId);
|
||||
updateAggregationEdges(from, to->getParentNode(), edgeId);
|
||||
}
|
||||
|
||||
return edge;
|
||||
}
|
||||
|
||||
Node* StorageGraph::insertNodeHierarchy(Node::NodeType type, SearchNode* searchNode)
|
||||
@@ -140,3 +150,39 @@ Edge* StorageGraph::insertEdge(Edge::EdgeType type, Node* from, Node* to)
|
||||
m_edges.emplace(edgePtr->getId(), edgePtr);
|
||||
return edgePtr.get();
|
||||
}
|
||||
|
||||
void StorageGraph::updateAggregationEdges(Node* from, Node* to, Id edgeId)
|
||||
{
|
||||
if (!from || !to || from == to)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const Node::NodeTypeMask mask = Node::NODE_UNDEFINED_TYPE | Node::NODE_CLASS | Node::NODE_STRUCT | Node::NODE_ENUM;
|
||||
const Node::NodeTypeMask varFuncMask =
|
||||
Node::NODE_UNDEFINED_FUNCTION | Node::NODE_FUNCTION | Node::NODE_UNDEFINED_VARIABLE | Node::NODE_GLOBAL_VARIABLE;
|
||||
|
||||
if ((from->isType(mask) && to->isType(mask | varFuncMask)) ||
|
||||
(from->isType(mask | varFuncMask) && to->isType(mask)))
|
||||
{
|
||||
Edge* edge = from->findEdgeOfType(Edge::EDGE_AGGREGATION,
|
||||
[from, to](Edge* e)
|
||||
{
|
||||
const Node* f = e->getFrom();
|
||||
const Node* t = e->getTo();
|
||||
return (f == from && t == to) || (f == to && t == from);
|
||||
}
|
||||
);
|
||||
|
||||
if (!edge)
|
||||
{
|
||||
edge = insertEdge(Edge::EDGE_AGGREGATION, from, to);
|
||||
edge->addComponentAggregation(std::make_shared<TokenComponentAggregation>());
|
||||
}
|
||||
|
||||
edge->getComponent<TokenComponentAggregation>()->addAggregationId(edgeId);
|
||||
}
|
||||
|
||||
updateAggregationEdges(from->getParentNode(), to, edgeId);
|
||||
updateAggregationEdges(from, to->getParentNode(), edgeId);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ private:
|
||||
Node* insertNodeHierarchy(Node::NodeType type, SearchNode* searchNode);
|
||||
Node* insertNode(Node::NodeType type, Node* parentNode, SearchNode* searchNode);
|
||||
Edge* insertEdge(Edge::EdgeType type, Node* from, Node* to);
|
||||
|
||||
void updateAggregationEdges(Node* from, Node* to, Id edgeId);
|
||||
};
|
||||
|
||||
#endif // STORAGE_GRAPH_H
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "data/graph/token_component/TokenComponentAggregation.h"
|
||||
|
||||
TokenComponentAggregation::TokenComponentAggregation()
|
||||
{
|
||||
}
|
||||
|
||||
TokenComponentAggregation::~TokenComponentAggregation()
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<TokenComponent> TokenComponentAggregation::copy() const
|
||||
{
|
||||
return std::make_shared<TokenComponentAggregation>(*this);
|
||||
}
|
||||
|
||||
int TokenComponentAggregation::getAggregationCount() const
|
||||
{
|
||||
return m_ids.size();
|
||||
}
|
||||
|
||||
void TokenComponentAggregation::addAggregationId(Id id)
|
||||
{
|
||||
m_ids.insert(id);
|
||||
}
|
||||
|
||||
const std::set<Id>& TokenComponentAggregation::getAggregationIds() const
|
||||
{
|
||||
return m_ids;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef TOKEN_COMPONENT_AGGREGATION_H
|
||||
#define TOKEN_COMPONENT_AGGREGATION_H
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "utility/types.h"
|
||||
|
||||
#include "data/graph/token_component/TokenComponent.h"
|
||||
|
||||
class TokenComponentAggregation
|
||||
: public TokenComponent
|
||||
{
|
||||
public:
|
||||
TokenComponentAggregation();
|
||||
virtual ~TokenComponentAggregation();
|
||||
|
||||
virtual std::shared_ptr<TokenComponent> copy() const;
|
||||
|
||||
int getAggregationCount() const;
|
||||
void addAggregationId(Id id);
|
||||
const std::set<Id>& getAggregationIds() const;
|
||||
|
||||
private:
|
||||
std::set<Id> m_ids;
|
||||
};
|
||||
|
||||
#endif // TOKEN_COMPONENT_AGGREGATION_H
|
||||
Reference in New Issue
Block a user