logic: rewrote messages handling token activation for correct restoring on undo
* saving search query to undo stack with MessageSearch * saving node and edge with name to undo stack with MessageActivateNode and MessageActivateEdge * added FeatureController that handels distribution of MessageActivateTokens * clearing views when refreshing or changing project * clearing undo stack when changing project * added StorageCache derived from StorageAccessProxy
This commit is contained in:
+56
-11
@@ -7,6 +7,7 @@
|
||||
#include "utility/file/FileSystem.h"
|
||||
|
||||
#include "data/graph/filter/GraphFilterConductor.h"
|
||||
#include "data/graph/token_component/TokenComponentAggregation.h"
|
||||
#include "data/graph/token_component/TokenComponentConst.h"
|
||||
#include "data/graph/token_component/TokenComponentName.h"
|
||||
#include "data/graph/token_component/TokenComponentStatic.h"
|
||||
@@ -683,6 +684,42 @@ Id Storage::getIdForNodeWithName(const std::string& fullName) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
Id Storage::getIdForEdgeWithName(const std::string& name) const
|
||||
{
|
||||
Edge::EdgeType type;
|
||||
std::string fromName;
|
||||
std::string toName;
|
||||
|
||||
Edge::splitName(name, &type, &fromName, &toName);
|
||||
|
||||
Id fromId = getIdForNodeWithName(fromName);
|
||||
Node* from = m_graph.getNodeById(fromId);
|
||||
|
||||
if (from)
|
||||
{
|
||||
Edge* edge = from->findEdgeOfType(
|
||||
type,
|
||||
[&name](Edge* e)
|
||||
{
|
||||
return (e->getName() == name);
|
||||
}
|
||||
);
|
||||
|
||||
if (edge)
|
||||
{
|
||||
if (!edge->isType(type))
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Edge: " << name << " is not of type: " << Edge::getTypeString(type));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return edge->getId();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string Storage::getNameForNodeWithId(Id id) const
|
||||
{
|
||||
Token* token = m_graph.getTokenById(id);
|
||||
@@ -890,34 +927,28 @@ std::vector<Id> Storage::getActiveTokenIdsForId(Id tokenId, Id* declarationId) c
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<Id> Storage::getActiveTokenIdsForLocationId(Id locationId) const
|
||||
Id Storage::getActiveNodeIdForLocationId(Id locationId) const
|
||||
{
|
||||
std::vector<Id> ret;
|
||||
|
||||
TokenLocation* location = m_locationCollection.findTokenLocationById(locationId);
|
||||
if (!location)
|
||||
{
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Token* token = m_graph.getTokenById(location->getTokenId());
|
||||
if (!token)
|
||||
{
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (token->isNode())
|
||||
{
|
||||
Node* node = dynamic_cast<Node*>(token);
|
||||
ret.push_back(node->getId());
|
||||
return dynamic_cast<Node*>(token)->getId();
|
||||
}
|
||||
else
|
||||
{
|
||||
Edge* edge = dynamic_cast<Edge*>(token);
|
||||
ret.push_back(edge->getTo()->getId());
|
||||
return dynamic_cast<Edge*>(token)->getTo()->getId();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<Id> Storage::getTokenIdsForQuery(std::string query) const
|
||||
@@ -944,6 +975,20 @@ Id Storage::getTokenIdForFileNode(const FilePath& filePath) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<Id> Storage::getTokenIdsForAggregationEdge(Id aggregationId) const
|
||||
{
|
||||
Edge* edge = m_graph.getEdgeById(aggregationId);
|
||||
std::vector<Id> ids;
|
||||
|
||||
if (edge->isType(Edge::EDGE_AGGREGATION))
|
||||
{
|
||||
std::set<Id> i = edge->getComponent<TokenComponentAggregation>()->getAggregationIds();
|
||||
ids.insert(ids.end(), i.begin(), i.end());
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
TokenLocationCollection Storage::getTokenLocationsForTokenIds(const std::vector<Id>& tokenIds) const
|
||||
{
|
||||
TokenLocationCollection ret;
|
||||
|
||||
@@ -109,6 +109,8 @@ public:
|
||||
|
||||
// StorageAccess implementation
|
||||
virtual Id getIdForNodeWithName(const std::string& fullName) const;
|
||||
virtual Id getIdForEdgeWithName(const std::string& name) const;
|
||||
|
||||
virtual std::string getNameForNodeWithId(Id id) const;
|
||||
virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const;
|
||||
virtual std::vector<SearchMatch> getAutocompletionMatches(
|
||||
@@ -117,10 +119,11 @@ public:
|
||||
virtual std::shared_ptr<Graph> getGraphForActiveTokenIds(const std::vector<Id>& tokenIds) const;
|
||||
|
||||
virtual std::vector<Id> getActiveTokenIdsForId(Id tokenId, Id* declarationId) const;
|
||||
virtual std::vector<Id> getActiveTokenIdsForLocationId(Id locationId) const;
|
||||
virtual Id getActiveNodeIdForLocationId(Id locationId) const;
|
||||
|
||||
virtual std::vector<Id> getTokenIdsForQuery(std::string query) const;
|
||||
virtual Id getTokenIdForFileNode(const FilePath& filePath) const;
|
||||
virtual std::vector<Id> getTokenIdsForAggregationEdge(Id aggregationId) const;
|
||||
|
||||
virtual TokenLocationCollection getTokenLocationsForTokenIds(const std::vector<Id>& tokenIds) const;
|
||||
virtual std::shared_ptr<TokenLocationFile> getTokenLocationsForFile(const std::string& filePath) const;
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "data/StorageCache.h"
|
||||
|
||||
void StorageCache::clear()
|
||||
{
|
||||
m_queryToTokenIds.clear();
|
||||
}
|
||||
|
||||
std::vector<Id> StorageCache::getTokenIdsForQuery(std::string query) const
|
||||
{
|
||||
std::map<std::string, std::vector<Id>>::const_iterator it = m_queryToTokenIds.find(query);
|
||||
|
||||
if (it != m_queryToTokenIds.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
std::vector<Id> ids = StorageAccessProxy::getTokenIdsForQuery(query);
|
||||
|
||||
m_queryToTokenIds.emplace(query, ids);
|
||||
|
||||
return ids;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef STORAGE_CACHE_H
|
||||
#define STORAGE_CACHE_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "data/access/StorageAccessProxy.h"
|
||||
|
||||
class StorageCache
|
||||
: public StorageAccessProxy
|
||||
{
|
||||
public:
|
||||
void clear();
|
||||
|
||||
virtual std::vector<Id> getTokenIdsForQuery(std::string query) const;
|
||||
|
||||
private:
|
||||
mutable std::map<std::string, std::vector<Id>> m_queryToTokenIds;
|
||||
};
|
||||
|
||||
#endif // STORAGE_CACHE_H
|
||||
@@ -22,6 +22,8 @@ public:
|
||||
virtual ~StorageAccess();
|
||||
|
||||
virtual Id getIdForNodeWithName(const std::string& name) const = 0;
|
||||
virtual Id getIdForEdgeWithName(const std::string& name) const = 0;
|
||||
|
||||
virtual std::string getNameForNodeWithId(Id id) const = 0;
|
||||
virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const = 0;
|
||||
virtual std::vector<SearchMatch> getAutocompletionMatches(
|
||||
@@ -30,10 +32,11 @@ public:
|
||||
virtual std::shared_ptr<Graph> getGraphForActiveTokenIds(const std::vector<Id>& tokenIds) const = 0;
|
||||
|
||||
virtual std::vector<Id> getActiveTokenIdsForId(Id tokenId, Id* declarationId) const = 0;
|
||||
virtual std::vector<Id> getActiveTokenIdsForLocationId(Id locationId) const = 0;
|
||||
virtual Id getActiveNodeIdForLocationId(Id locationId) const = 0;
|
||||
|
||||
virtual std::vector<Id> getTokenIdsForQuery(std::string query) const = 0;
|
||||
virtual Id getTokenIdForFileNode(const FilePath& filePath) const = 0;
|
||||
virtual std::vector<Id> getTokenIdsForAggregationEdge(Id aggregationId) const = 0;
|
||||
|
||||
virtual TokenLocationCollection getTokenLocationsForTokenIds(const std::vector<Id>& tokenIds) const = 0;
|
||||
virtual std::shared_ptr<TokenLocationFile> getTokenLocationsForFile(const std::string& filePath) const = 0;
|
||||
|
||||
@@ -41,6 +41,16 @@ Id StorageAccessProxy::getIdForNodeWithName(const std::string& name) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
Id StorageAccessProxy::getIdForEdgeWithName(const std::string& name) const
|
||||
{
|
||||
if (hasSubject())
|
||||
{
|
||||
return m_subject->getIdForEdgeWithName(name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Node::NodeType StorageAccessProxy::getNodeTypeForNodeWithId(Id id) const
|
||||
{
|
||||
if(hasSubject())
|
||||
@@ -92,14 +102,14 @@ std::vector<Id> StorageAccessProxy::getActiveTokenIdsForId(Id tokenId, Id* delca
|
||||
return std::vector<Id>();
|
||||
}
|
||||
|
||||
std::vector<Id> StorageAccessProxy::getActiveTokenIdsForLocationId(Id locationId) const
|
||||
Id StorageAccessProxy::getActiveNodeIdForLocationId(Id locationId) const
|
||||
{
|
||||
if (hasSubject())
|
||||
{
|
||||
return m_subject->getActiveTokenIdsForLocationId(locationId);
|
||||
return m_subject->getActiveNodeIdForLocationId(locationId);
|
||||
}
|
||||
|
||||
return std::vector<Id>();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<Id> StorageAccessProxy::getTokenIdsForQuery(std::string query) const
|
||||
@@ -122,6 +132,16 @@ Id StorageAccessProxy::getTokenIdForFileNode(const FilePath& filePath) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<Id> StorageAccessProxy::getTokenIdsForAggregationEdge(Id aggregationId) const
|
||||
{
|
||||
if (hasSubject())
|
||||
{
|
||||
return m_subject->getTokenIdsForAggregationEdge(aggregationId);
|
||||
}
|
||||
|
||||
return std::vector<Id>();
|
||||
}
|
||||
|
||||
TokenLocationCollection StorageAccessProxy::getTokenLocationsForTokenIds(const std::vector<Id>& tokenIds) const
|
||||
{
|
||||
if (hasSubject())
|
||||
|
||||
@@ -14,6 +14,8 @@ public:
|
||||
|
||||
// StorageAccess implementation
|
||||
virtual Id getIdForNodeWithName(const std::string& name) const;
|
||||
virtual Id getIdForEdgeWithName(const std::string& name) const;
|
||||
|
||||
virtual std::string getNameForNodeWithId(Id id) const;
|
||||
virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const;
|
||||
virtual std::vector<SearchMatch> getAutocompletionMatches(
|
||||
@@ -22,10 +24,11 @@ public:
|
||||
virtual std::shared_ptr<Graph> getGraphForActiveTokenIds(const std::vector<Id>& tokenIds) const;
|
||||
|
||||
virtual std::vector<Id> getActiveTokenIdsForId(Id tokenId, Id* declarationId) const;
|
||||
virtual std::vector<Id> getActiveTokenIdsForLocationId(Id locationId) const;
|
||||
virtual Id getActiveNodeIdForLocationId(Id locationId) const;
|
||||
|
||||
virtual std::vector<Id> getTokenIdsForQuery(std::string query) const;
|
||||
virtual Id getTokenIdForFileNode(const FilePath& filePath) const;
|
||||
virtual std::vector<Id> getTokenIdsForAggregationEdge(Id aggregationId) const;
|
||||
|
||||
virtual TokenLocationCollection getTokenLocationsForTokenIds(const std::vector<Id>& tokenIds) const;
|
||||
virtual std::shared_ptr<TokenLocationFile> getTokenLocationsForFile(const std::string& filePath) const;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "data/graph/token_component/TokenComponentAggregation.h"
|
||||
#include "data/graph/token_component/TokenComponentAccess.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
Edge::Edge(EdgeType type, Node* from, Node* to)
|
||||
: m_type(type)
|
||||
@@ -67,6 +68,24 @@ std::string Edge::getName() const
|
||||
return getTypeString() + ":" + getFrom()->getFullName() + "->" + getTo()->getFullName();
|
||||
}
|
||||
|
||||
void Edge::splitName(const std::string& name, EdgeType* type, std::string* fromName, std::string* toName)
|
||||
{
|
||||
EdgeTypeMask mask = 1;
|
||||
std::string typeStr = utility::substrBefore(name, ':');
|
||||
|
||||
while (typeStr != getTypeString(static_cast<EdgeType>(mask)))
|
||||
{
|
||||
mask = mask << 1;
|
||||
}
|
||||
|
||||
*type = static_cast<EdgeType>(mask);
|
||||
|
||||
std::string names = utility::substrAfter(name, ':');
|
||||
|
||||
*fromName = utility::substrBefore(names, '-');
|
||||
*toName = utility::substrAfter(utility::substrAfter(names, '-'), '>');
|
||||
}
|
||||
|
||||
bool Edge::isNode() const
|
||||
{
|
||||
return false;
|
||||
@@ -110,7 +129,7 @@ void Edge::addComponentAccess(std::shared_ptr<TokenComponentAccess> component)
|
||||
}
|
||||
}
|
||||
|
||||
std::string Edge::getTypeString(EdgeType type) const
|
||||
std::string Edge::getTypeString(EdgeType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
||||
@@ -48,6 +48,7 @@ public:
|
||||
Node* getTo() const;
|
||||
|
||||
std::string getName() const;
|
||||
static void splitName(const std::string& name, EdgeType* type, std::string* fromName, std::string* toName);
|
||||
|
||||
// Token implementation
|
||||
virtual bool isNode() const;
|
||||
@@ -58,7 +59,7 @@ public:
|
||||
void addComponentAccess(std::shared_ptr<TokenComponentAccess> component);
|
||||
|
||||
// Logging.
|
||||
std::string getTypeString(EdgeType type) const;
|
||||
static std::string getTypeString(EdgeType type);
|
||||
virtual std::string getTypeString() const;
|
||||
std::string getAsString() const;
|
||||
|
||||
|
||||
@@ -257,15 +257,27 @@ public:
|
||||
|
||||
virtual void apply(const FilterableGraph* in, FilterableGraph* out)
|
||||
{
|
||||
if (m_tokenIds.size())
|
||||
std::vector<Node*> nodes;
|
||||
|
||||
for (Id tokenId : m_tokenIds)
|
||||
{
|
||||
for (Id tokenId : m_tokenIds)
|
||||
Node* node = in->getNodeById(tokenId);
|
||||
if (node)
|
||||
{
|
||||
Node* node = in->getNodeById(tokenId);
|
||||
if (node)
|
||||
{
|
||||
out->addNode(node);
|
||||
}
|
||||
nodes.push_back(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
nodes.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nodes.size())
|
||||
{
|
||||
for (Node* node : nodes)
|
||||
{
|
||||
out->addNode(node);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -129,7 +129,11 @@ std::deque<std::string> SearchMatch::searchMatchDequeToStringDeque(const std::de
|
||||
stringDeque.push_back(match.encodeForQuery());
|
||||
}
|
||||
return stringDeque;
|
||||
}
|
||||
|
||||
std::string SearchMatch::searchMatchDequeToString(const std::deque<SearchMatch>& searchMatchDeque)
|
||||
{
|
||||
return utility::join(searchMatchDequeToStringDeque(searchMatchDeque), "");
|
||||
}
|
||||
|
||||
std::string SearchMatch::getNodeTypeAsString() const
|
||||
|
||||
@@ -16,6 +16,7 @@ struct SearchMatch
|
||||
static void log(const std::vector<SearchMatch>& matches, const std::string& query);
|
||||
static std::deque<SearchMatch> stringDequeToSearchMatchDeque(const std::deque<std::string>& deque);
|
||||
static std::deque<std::string> searchMatchDequeToStringDeque(const std::deque<SearchMatch>& deque);
|
||||
static std::string searchMatchDequeToString(const std::deque<SearchMatch>& deque);
|
||||
|
||||
SearchMatch();
|
||||
SearchMatch(const std::string& query);
|
||||
|
||||
Reference in New Issue
Block a user