ui: graph showing neighbours
The graph view can now display the n1 neighbours of the active node, including connections between neighbours.
This commit is contained in:
@@ -22,6 +22,8 @@ add_files(
|
||||
qt/view/graphElements/QtGraphEdge.h
|
||||
qt/view/graphElements/QtGraphNode.cpp
|
||||
qt/view/graphElements/QtGraphNode.h
|
||||
qt/view/graphElements/QtGraphNodeMovable.cpp
|
||||
qt/view/graphElements/QtGraphNodeMovable.h
|
||||
|
||||
qt/view/QtCodeView.cpp
|
||||
qt/view/QtCodeView.h
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "qt/QtWidgetWrapper.h"
|
||||
#include "qt/view/graphElements/QtGraphEdge.h"
|
||||
#include "qt/view/graphElements/QtGraphNode.h"
|
||||
#include "qt/view/graphElements/QtGraphNodeMovable.h"
|
||||
|
||||
QtGraphView::QtGraphView(ViewLayout* viewLayout)
|
||||
: GraphView(viewLayout)
|
||||
@@ -70,15 +71,41 @@ QGraphicsView* QtGraphView::getView()
|
||||
|
||||
void QtGraphView::doRebuildGraph(const std::vector<DummyNode>& nodes, const std::vector<DummyEdge>& edges)
|
||||
{
|
||||
doClear();
|
||||
|
||||
QGraphicsView* view = getView();
|
||||
|
||||
if (view != NULL)
|
||||
{
|
||||
std::map<Id, std::weak_ptr<GraphNode>> weakNodes; // used when creating the edges
|
||||
std::list<std::shared_ptr<GraphNode>> newNodes; // temporary stores all nodes (existing and newly created) needed in the new graph
|
||||
// this is a relatively easy and cheap way to save existing nodes that are still needed
|
||||
|
||||
// create nodes (or find existing nodes for re-use)
|
||||
for(unsigned int i = 0; i < nodes.size(); i++)
|
||||
{
|
||||
std::shared_ptr<GraphNode> newNode = findOrCreateNode(view, nodes[i]);
|
||||
newNodes.push_back(newNode);
|
||||
weakNodes[nodes[i].tokenId] = newNode;
|
||||
}
|
||||
|
||||
doClear();
|
||||
m_nodes = newNodes;
|
||||
|
||||
// create edges
|
||||
for(unsigned int i = 0; i < edges.size(); i++)
|
||||
{
|
||||
if (weakNodes.find(edges[i].ownerId) != weakNodes.end() && weakNodes.find(edges[i].targetId) != weakNodes.end())
|
||||
{
|
||||
if (weakNodes[edges[i].ownerId].expired() == false && weakNodes[edges[i].targetId].expired() == false)
|
||||
{
|
||||
std::shared_ptr<QtGraphEdge> newEdge = std::make_shared<QtGraphEdge>(weakNodes[edges[i].ownerId], weakNodes[edges[i].targetId]);
|
||||
view->scene()->addItem(newEdge.get());
|
||||
if(weakNodes[edges[i].ownerId].lock()->addOutEdge(newEdge))
|
||||
{
|
||||
weakNodes[edges[i].targetId].lock()->addInEdge(newEdge);
|
||||
m_edges.push_back(newEdge);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -126,10 +153,18 @@ std::shared_ptr<GraphNode> QtGraphView::createNode(QGraphicsView* view, const Du
|
||||
{
|
||||
if(view != NULL)
|
||||
{
|
||||
std::shared_ptr<QtGraphNode> newNode = std::make_shared<QtGraphNode>(node.position, node.name, node.tokenId);
|
||||
std::shared_ptr<QtGraphNodeMovable> newNode = std::make_shared<QtGraphNodeMovable>(node.position, node.name, node.tokenId);
|
||||
view->scene()->addItem(newNode.get());
|
||||
m_nodes.push_back(newNode);
|
||||
|
||||
// create debug sub node
|
||||
std::shared_ptr<QtGraphNode> subNode = std::make_shared<QtGraphNode>(Vec2i(10, 30), node.name + " member", 666);
|
||||
subNode->setParentItem(newNode.get());
|
||||
view->scene()->addItem(subNode.get());
|
||||
newNode->addSubNode(subNode);
|
||||
|
||||
subNode->setRect(0, 0, 80, 20);
|
||||
|
||||
return newNode;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -17,7 +17,7 @@ QtGraphEdge::QtGraphEdge(const std::weak_ptr<GraphNode>& owner, const std::weak_
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARNING("Either the owner or the target node could is null.");
|
||||
LOG_WARNING("Either the owner or the target node is null.");
|
||||
}
|
||||
|
||||
QPen blackPen(Qt::black);
|
||||
@@ -57,3 +57,27 @@ void QtGraphEdge::targetMoved()
|
||||
LOG_WARNING("Target node is null.");
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphEdge::removeEdgeFromScene()
|
||||
{
|
||||
std::shared_ptr<GraphNode> node = m_owner.lock();
|
||||
|
||||
if(node != NULL)
|
||||
{
|
||||
node->removeOutEdge(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARNING("Target node is null.");
|
||||
}
|
||||
}
|
||||
|
||||
std::weak_ptr<GraphNode> QtGraphEdge::getOwner()
|
||||
{
|
||||
return m_owner;
|
||||
}
|
||||
|
||||
std::weak_ptr<GraphNode> QtGraphEdge::getTarget()
|
||||
{
|
||||
return m_target;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,11 @@ public:
|
||||
virtual void ownerMoved();
|
||||
virtual void targetMoved();
|
||||
|
||||
virtual void removeEdgeFromScene();
|
||||
|
||||
virtual std::weak_ptr<GraphNode> getOwner();
|
||||
virtual std::weak_ptr<GraphNode> getTarget();
|
||||
|
||||
private:
|
||||
std::weak_ptr<GraphNode> m_owner;
|
||||
std::weak_ptr<GraphNode> m_target;
|
||||
|
||||
@@ -20,6 +20,15 @@ QtGraphNode::QtGraphNode(const Vec2i& position, const std::string& name, const I
|
||||
|
||||
QtGraphNode::~QtGraphNode()
|
||||
{
|
||||
std::list<std::weak_ptr<GraphEdge> >::iterator it = m_inEdges.begin();
|
||||
for(it; it != m_inEdges.end(); it++)
|
||||
{
|
||||
std::shared_ptr<GraphEdge> edge = it->lock();
|
||||
if(edge != NULL)
|
||||
{
|
||||
edge->removeEdgeFromScene();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string QtGraphNode::getName()
|
||||
@@ -32,61 +41,63 @@ Vec2i QtGraphNode::getPosition()
|
||||
return Vec2i(this->scenePos().x(), this->scenePos().y());
|
||||
}
|
||||
|
||||
void QtGraphNode::addOutEdge(const std::shared_ptr<GraphEdge>& edge)
|
||||
{
|
||||
m_outEdges.push_back(edge);
|
||||
}
|
||||
|
||||
void QtGraphNode::addInEdge(const std::weak_ptr<GraphEdge>& edge)
|
||||
{
|
||||
m_inEdges.push_back(edge);
|
||||
}
|
||||
|
||||
void QtGraphNode::removeOutEdge(const std::shared_ptr<GraphEdge>& edge)
|
||||
bool QtGraphNode::addOutEdge(const std::shared_ptr<GraphEdge>& edge)
|
||||
{
|
||||
std::list<std::shared_ptr<GraphEdge> >::iterator it = m_outEdges.begin();
|
||||
for(it; it != m_outEdges.end(); it++)
|
||||
{
|
||||
if(*it == edge)
|
||||
if ((*it)->getOwner().lock() == edge->getOwner().lock() && (*it)->getTarget().lock() == edge->getTarget().lock())
|
||||
{
|
||||
m_outEdges.erase(it, it);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_outEdges.push_back(edge);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QtGraphNode::addInEdge(const std::weak_ptr<GraphEdge>& edge)
|
||||
{
|
||||
std::list<std::weak_ptr<GraphEdge> >::iterator it = m_inEdges.begin();
|
||||
for(it; it != m_inEdges.end(); it++)
|
||||
{
|
||||
std::shared_ptr<GraphEdge> existingEdge = it->lock();
|
||||
if(existingEdge != NULL)
|
||||
{
|
||||
if (existingEdge->getOwner().lock() == edge.lock()->getOwner().lock() &&
|
||||
existingEdge->getTarget().lock() == edge.lock()->getTarget().lock())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_inEdges.push_back(edge);
|
||||
return true;
|
||||
}
|
||||
|
||||
void QtGraphNode::removeOutEdge(GraphEdge* edge)
|
||||
{
|
||||
std::list<std::shared_ptr<GraphEdge> >::iterator it = m_outEdges.begin();
|
||||
while(it != m_outEdges.end())
|
||||
{
|
||||
if((*it).get() == edge)
|
||||
{
|
||||
m_outEdges.erase(it);
|
||||
break;
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNode::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
void QtGraphNode::addSubNode(const std::shared_ptr<GraphNode>& node)
|
||||
{
|
||||
m_mouseOffset.x = event->pos().x();
|
||||
m_mouseOffset.y = event->pos().y();
|
||||
m_subNodes.push_back(node);
|
||||
}
|
||||
|
||||
void QtGraphNode::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
MessageActivateToken message(m_tokenId);
|
||||
message.dispatch();
|
||||
}
|
||||
|
||||
void QtGraphNode::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
this->setPos(event->scenePos().x() - m_mouseOffset.x, event->scenePos().y() - m_mouseOffset.y);
|
||||
|
||||
Vec2i p(event->scenePos().x(), event->scenePos().y());
|
||||
|
||||
std::list<std::shared_ptr<GraphEdge> >::iterator it = m_outEdges.begin();
|
||||
for(it; it != m_outEdges.end(); it++)
|
||||
{
|
||||
(*it)->ownerMoved();
|
||||
}
|
||||
|
||||
std::list<std::weak_ptr<GraphEdge> >::iterator it2 = m_inEdges.begin();
|
||||
for(it2; it2 != m_inEdges.end(); it2++)
|
||||
{
|
||||
std::shared_ptr<GraphEdge> edge = it2->lock();
|
||||
if(edge.get() != NULL)
|
||||
{
|
||||
edge->targetMoved();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_inEdges.erase(it2, it2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,21 +21,23 @@ public:
|
||||
virtual std::string getName();
|
||||
virtual Vec2i getPosition();
|
||||
|
||||
virtual void addOutEdge(const std::shared_ptr<GraphEdge>& edge);
|
||||
virtual void addInEdge(const std::weak_ptr<GraphEdge>& edge);
|
||||
virtual bool addOutEdge(const std::shared_ptr<GraphEdge>& edge);
|
||||
virtual bool addInEdge(const std::weak_ptr<GraphEdge>& edge);
|
||||
|
||||
virtual void removeOutEdge(const std::shared_ptr<GraphEdge>& edge);
|
||||
virtual void removeOutEdge(GraphEdge* edge);
|
||||
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||
virtual void addSubNode(const std::shared_ptr<GraphNode>& node);
|
||||
|
||||
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event);
|
||||
|
||||
protected:
|
||||
std::list<std::shared_ptr<GraphEdge> > m_outEdges;
|
||||
std::list<std::weak_ptr<GraphEdge> > m_inEdges;
|
||||
|
||||
private:
|
||||
QGraphicsTextItem* m_text;
|
||||
|
||||
std::list<std::shared_ptr<GraphEdge> > m_outEdges;
|
||||
std::list<std::weak_ptr<GraphEdge> > m_inEdges;
|
||||
|
||||
Vec2i m_mouseOffset;
|
||||
std::list<std::shared_ptr<GraphNode> > m_subNodes;
|
||||
};
|
||||
|
||||
#endif // QT_GRAPH_NODE_H
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#include "qt/view/graphElements/QtGraphNodeMovable.h"
|
||||
|
||||
#include "qgraphicssceneevent.h"
|
||||
|
||||
#include "qt/view/graphElements/QtGraphEdge.h"
|
||||
|
||||
QtGraphNodeMovable::QtGraphNodeMovable(const Vec2i& position, const std::string& name, const Id tokenId)
|
||||
: QtGraphNode(position, name, tokenId)
|
||||
{
|
||||
}
|
||||
|
||||
QtGraphNodeMovable::~QtGraphNodeMovable()
|
||||
{
|
||||
}
|
||||
|
||||
void QtGraphNodeMovable::mousePressEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
m_mouseOffset.x = event->pos().x();
|
||||
m_mouseOffset.y = event->pos().y();
|
||||
}
|
||||
|
||||
void QtGraphNodeMovable::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
this->setPos(event->scenePos().x() - m_mouseOffset.x, event->scenePos().y() - m_mouseOffset.y);
|
||||
|
||||
Vec2i p(event->scenePos().x(), event->scenePos().y());
|
||||
|
||||
std::list<std::shared_ptr<GraphEdge> >::iterator it = m_outEdges.begin();
|
||||
for(it; it != m_outEdges.end(); it++)
|
||||
{
|
||||
(*it)->ownerMoved();
|
||||
}
|
||||
|
||||
std::list<std::weak_ptr<GraphEdge> >::iterator it2 = m_inEdges.begin();
|
||||
while(it2 != m_inEdges.end())
|
||||
{
|
||||
std::shared_ptr<GraphEdge> edge = it2->lock();
|
||||
if(edge.get() != NULL)
|
||||
{
|
||||
edge->targetMoved();
|
||||
++it2;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_inEdges.erase(it2++);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef QT_GRAPH_NODE_MOVABLE_H
|
||||
#define QT_GRAPH_NODE_MOVABLE_H
|
||||
|
||||
#include "qt/view/graphElements/QtGraphNode.h"
|
||||
|
||||
class QtGraphNodeMovable : public QtGraphNode
|
||||
{
|
||||
public:
|
||||
QtGraphNodeMovable(const Vec2i& position, const std::string& name, const Id tokenId);
|
||||
virtual ~QtGraphNodeMovable();
|
||||
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent* event);
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
|
||||
|
||||
private:
|
||||
Vec2i m_mouseOffset;
|
||||
};
|
||||
|
||||
#endif // QT_GRAPH_NODE_MOVABLE_H
|
||||
@@ -22,6 +22,8 @@ void GraphController::handleMessage(MessageActivateToken* message)
|
||||
if (view != NULL)
|
||||
{
|
||||
std::string name = m_graphAccess->getNameForNodeWithId(message->tokenId);
|
||||
std::vector<std::pair<Id, Id> > rawEdges = m_graphAccess->getConnectedEdges(message->tokenId);
|
||||
std::vector<Id> neighbourIds = m_graphAccess->getIdsOfNeighbours(message->tokenId);
|
||||
|
||||
DummyNode node(name, message->tokenId, Vec2i(0,0));
|
||||
|
||||
@@ -30,6 +32,48 @@ void GraphController::handleMessage(MessageActivateToken* message)
|
||||
|
||||
std::vector<DummyEdge> edges;
|
||||
|
||||
int offset = 20; // temporary
|
||||
|
||||
for(unsigned int i = 0; i < rawEdges.size(); i++)
|
||||
{
|
||||
edges.push_back(DummyEdge(rawEdges[i].first, rawEdges[i].second));
|
||||
|
||||
Id newId = 0;
|
||||
|
||||
if (rawEdges[i].first != message->tokenId)
|
||||
{
|
||||
name = m_graphAccess->getNameForNodeWithId(rawEdges[i].first);
|
||||
newId = rawEdges[i].first;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = m_graphAccess->getNameForNodeWithId(rawEdges[i].second);
|
||||
newId = rawEdges[i].second;
|
||||
}
|
||||
|
||||
nodes.push_back(DummyNode(name, newId, Vec2i(0, offset)));
|
||||
offset += 20;
|
||||
}
|
||||
|
||||
// find edges between neighbour nodes
|
||||
for(unsigned int i = 1; i < nodes.size(); i++)
|
||||
{
|
||||
std::vector<std::pair<Id, Id>> newEdges = m_graphAccess->getConnectedEdges(nodes[i].tokenId);
|
||||
for(unsigned int j = 0; j < newEdges.size(); j++)
|
||||
{
|
||||
if (std::find(neighbourIds.begin(), neighbourIds.end(), newEdges[j].first) != neighbourIds.end() &&
|
||||
std::find(neighbourIds.begin(), neighbourIds.end(), newEdges[j].second) != neighbourIds.end())
|
||||
{
|
||||
DummyEdge newEdge(newEdges[j].first, newEdges[j].second);
|
||||
|
||||
if (std::find(edges.begin(), edges.end(), newEdge) == edges.end())
|
||||
{
|
||||
edges.push_back(newEdge);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
view->rebuildGraph(nodes, edges);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "utility/types.h"
|
||||
|
||||
class GraphNode;
|
||||
|
||||
class GraphEdge
|
||||
@@ -13,20 +15,39 @@ public:
|
||||
|
||||
virtual void ownerMoved() = 0;
|
||||
virtual void targetMoved() = 0;
|
||||
|
||||
virtual void removeEdgeFromScene() = 0;
|
||||
|
||||
virtual std::weak_ptr<GraphNode> getOwner() = 0;
|
||||
virtual std::weak_ptr<GraphNode> getTarget() = 0;
|
||||
};
|
||||
|
||||
// temporary data structure for (visual) graph creation process
|
||||
struct DummyEdge
|
||||
{
|
||||
public:
|
||||
DummyEdge(const std::weak_ptr<GraphNode> o, const std::weak_ptr<GraphNode> t)
|
||||
: owner(o)
|
||||
, target(t)
|
||||
DummyEdge(const Id o, const Id t)
|
||||
: ownerId(o)
|
||||
, targetId(t)
|
||||
{
|
||||
}
|
||||
|
||||
std::weak_ptr<GraphNode> owner;
|
||||
std::weak_ptr<GraphNode> target;
|
||||
Id ownerId;
|
||||
Id targetId;
|
||||
|
||||
bool operator==(const DummyEdge& other) const
|
||||
{
|
||||
if(ownerId == other.ownerId && targetId == other.targetId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator!=(const DummyEdge& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // GRAPH_EDGE_H
|
||||
@@ -18,10 +18,12 @@ public:
|
||||
Id getTokenId();
|
||||
virtual Vec2i getPosition() = 0;
|
||||
|
||||
virtual void addOutEdge(const std::shared_ptr<GraphEdge>& edge) = 0;
|
||||
virtual void addInEdge(const std::weak_ptr<GraphEdge>& edge) = 0;
|
||||
virtual bool addOutEdge(const std::shared_ptr<GraphEdge>& edge) = 0;
|
||||
virtual bool addInEdge(const std::weak_ptr<GraphEdge>& edge) = 0;
|
||||
|
||||
virtual void removeOutEdge(const std::shared_ptr<GraphEdge>& edge) = 0;
|
||||
virtual void removeOutEdge(GraphEdge* edge) = 0;
|
||||
|
||||
virtual void addSubNode(const std::shared_ptr<GraphNode>& node) = 0;
|
||||
|
||||
protected:
|
||||
Id m_tokenId;
|
||||
|
||||
@@ -239,6 +239,63 @@ std::vector<std::string> Storage::getNamesForNodesWithNamePrefix(const std::stri
|
||||
return names;
|
||||
}
|
||||
|
||||
std::vector<Id> Storage::getIdsOfNeighbours(const Id id) const
|
||||
{
|
||||
std::vector<Id> result;
|
||||
|
||||
Node* node = m_graph.findNode([&](Node* node){
|
||||
return node->getId() == id;
|
||||
});
|
||||
|
||||
if (node != NULL)
|
||||
{
|
||||
std::map<Id, bool> addedIds;
|
||||
addedIds[id] = true;
|
||||
|
||||
node->forEachEdge(
|
||||
[&result, &addedIds](Edge* e)
|
||||
{
|
||||
Id fromId = e->getFrom()->getId();
|
||||
if (addedIds.find(fromId) == addedIds.end())
|
||||
{
|
||||
result.push_back(fromId);
|
||||
addedIds[fromId] = true;
|
||||
}
|
||||
|
||||
Id toId = e->getTo()->getId();
|
||||
if (addedIds.find(toId) == addedIds.end())
|
||||
{
|
||||
result.push_back(toId);
|
||||
addedIds[toId] = true;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::pair<Id, Id>> Storage::getConnectedEdges(const Id id) const
|
||||
{
|
||||
std::vector<std::pair<Id, Id>> result;
|
||||
|
||||
Node* node = m_graph.findNode([&](Node* node){
|
||||
return node->getId() == id;
|
||||
});
|
||||
|
||||
if (node != NULL)
|
||||
{
|
||||
node->forEachEdge(
|
||||
[&result, &id](Edge* e)
|
||||
{
|
||||
result.push_back(std::pair<Id, Id>(e->getFrom()->getId(), e->getTo()->getId()));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TokenLocationCollection Storage::getTokenLocationsForTokenId(Id id) const
|
||||
{
|
||||
TokenLocationCollection ret;
|
||||
|
||||
@@ -57,6 +57,8 @@ public:
|
||||
virtual Id getIdForNodeWithName(const std::string& name) const;
|
||||
virtual std::string getNameForNodeWithId(Id id) const;
|
||||
virtual std::vector<std::string> getNamesForNodesWithNamePrefix(const std::string& prefix) const;
|
||||
virtual std::vector<Id> getIdsOfNeighbours(const Id id) const;
|
||||
virtual std::vector<std::pair<Id, Id>> getConnectedEdges(const Id id) const;
|
||||
|
||||
// LocationAccess implementation
|
||||
virtual TokenLocationCollection getTokenLocationsForTokenId(Id locationId) const;
|
||||
|
||||
@@ -16,6 +16,8 @@ public:
|
||||
virtual Id getIdForNodeWithName(const std::string& name) const = 0;
|
||||
virtual std::string getNameForNodeWithId(Id id) const = 0;
|
||||
virtual std::vector<std::string> getNamesForNodesWithNamePrefix(const std::string& prefix) const = 0;
|
||||
virtual std::vector<Id> getIdsOfNeighbours(const Id id) const = 0;
|
||||
virtual std::vector<std::pair<Id, Id>> getConnectedEdges(const Id id) const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user