logic: correctly undoing graph interactions by replaying actions since last active token change

This change introdoces a classification of commands by order in the undo stack. Undoing the last action will resend the
message of the last active token change and all messages changing the ui after that.
This commit is contained in:
Eberhard Graether
2015-06-24 01:15:31 +02:00
parent 3587b487dd
commit 7275082284
20 changed files with 262 additions and 95 deletions
+1 -1
View File
@@ -175,7 +175,7 @@ void QtGraphView::doRebuildGraph(
if (m_transition && m_transition->currentTime() < m_transition->totalDuration())
{
m_transition->stop();
switchToNewGraphData();
finishedTransition();
}
QGraphicsView* view = getView();
@@ -10,7 +10,8 @@
#include "qt/view/graphElements/QtGraphNodeData.h"
QtGraphNodeExpandToggle::QtGraphNodeExpandToggle(bool expanded, int invisibleSubNodeCount)
: m_allVisible(invisibleSubNodeCount == 0)
: m_invisibleSubNodeCount(invisibleSubNodeCount)
, m_expanded(expanded)
{
if (!expanded && !invisibleSubNodeCount)
{
@@ -52,7 +53,7 @@ void QtGraphNodeExpandToggle::onClick()
if (parent && parent->getTokenId())
{
MessageGraphNodeExpand(parent->getTokenId()).dispatch();
MessageGraphNodeExpand(parent->getTokenId(), !m_expanded).dispatch();
}
}
@@ -68,6 +69,6 @@ void QtGraphNodeExpandToggle::updateStyle()
m_icon->setPos(
(m_rect->rect().width() - m_icon->pixmap().width() / QtDeviceScaledPixmap::devicePixelRatio()) / 2,
(m_allVisible ? 9 : 14)
(m_invisibleSubNodeCount == 0 ? 9 : 14)
);
}
@@ -20,7 +20,8 @@ public:
private:
QGraphicsPixmapItem* m_icon;
bool m_allVisible;
bool m_invisibleSubNodeCount;
bool m_expanded;
};
#endif // QT_EXPAND_TOGGLE_H
@@ -25,6 +25,11 @@ const uint CodeController::s_lineRadius = 2;
void CodeController::handleMessage(MessageActivateTokens* message)
{
if (message->isIgnorable())
{
return;
}
std::vector<Id> activeTokenIds = message->tokenIds;
Id declarationId = 0; // 0 means that no token is found.
@@ -29,18 +29,23 @@ void FeatureController::handleMessage(MessageActivateEdge* message)
if (message->type == Edge::EDGE_AGGREGATION)
{
MessageActivateTokens(m_storageAccess->getTokenIdsForAggregationEdge(edgeId)).dispatch();
MessageActivateTokens m(m_storageAccess->getTokenIdsForAggregationEdge(edgeId));
m.undoRedoType = message->undoRedoType;
m.dispatch();
return;
}
MessageActivateTokens msg(std::vector<Id>(1, edgeId));
msg.isEdge = true;
msg.dispatch();
msg.undoRedoType = message->undoRedoType;
msg.dispatchImmediately();
}
void FeatureController::handleMessage(MessageActivateFile* message)
{
MessageActivateTokens(std::vector<Id>(1, m_storageAccess->getTokenIdForFileNode(message->filePath))).dispatch();
MessageActivateTokens m(std::vector<Id>(1, m_storageAccess->getTokenIdForFileNode(message->filePath)));
m.undoRedoType = message->undoRedoType;
m.dispatchImmediately();
}
void FeatureController::handleMessage(MessageActivateNode* message)
@@ -54,9 +59,10 @@ void FeatureController::handleMessage(MessageActivateNode* message)
if (nodeId)
{
MessageActivateTokens msg(nodeId);
msg.isFromSystem = message->isFromSystem;
msg.dispatch();
MessageActivateTokens m(nodeId);
m.isFromSystem = message->isFromSystem;
m.undoRedoType = message->undoRedoType;
m.dispatchImmediately();
}
}
@@ -69,11 +75,13 @@ void FeatureController::handleMessage(MessageActivateTokenLocation* message)
nodeId,
m_storageAccess->getNodeTypeForNodeWithId(nodeId),
m_storageAccess->getNameForNodeWithId(nodeId)
).dispatch();
).dispatchImmediately();
}
}
void FeatureController::handleMessage(MessageSearch* message)
{
MessageActivateTokens(m_storageAccess->getTokenIdsForQuery(message->getQuery())).dispatch();
MessageActivateTokens m(m_storageAccess->getTokenIdsForQuery(message->getQuery()));
m.undoRedoType = message->undoRedoType;
m.dispatchImmediately();
}
@@ -15,6 +15,8 @@
GraphController::GraphController(StorageAccess* storageAccess)
: m_storageAccess(storageAccess)
, m_rebuild(true)
, m_restore(false)
{
}
@@ -24,12 +26,14 @@ GraphController::~GraphController()
void GraphController::handleMessage(MessageActivateTokens* message)
{
setRebuildState(message);
m_activeTokenIds = message->tokenIds;
if (message->isEdge && message->tokenIds.size() == 1)
{
setActiveAndVisibility(message->tokenIds);
getView()->rebuildGraph(nullptr, m_dummyNodes, m_dummyEdges);
rebuildGraph();
return;
}
@@ -53,6 +57,8 @@ void GraphController::handleMessage(MessageFocusOut *message)
void GraphController::handleMessage(MessageGraphNodeBundleSplit* message)
{
setRebuildState(message);
for (size_t i = 0; i < m_dummyNodes.size(); i++)
{
DummyNode& node = m_dummyNodes[i];
@@ -80,40 +86,44 @@ void GraphController::handleMessage(MessageGraphNodeBundleSplit* message)
GraphLayouter::layoutSpectralPrototype(m_dummyNodes, m_dummyEdges);
GraphPostprocessor::doPostprocessing(m_dummyNodes);
getView()->rebuildGraph(nullptr, m_dummyNodes, m_dummyEdges);
rebuildGraph();
}
void GraphController::handleMessage(MessageGraphNodeExpand* message)
{
setRebuildState(message);
DummyNode* node = findDummyNodeRecursive(m_dummyNodes, message->tokenId);
if (node)
{
if (node->autoExpanded)
{
node->autoExpanded = false;
node->expanded = false;
}
else
{
node->expanded = !node->expanded;
}
node->expanded = message->expand;
setActiveAndVisibility(m_activeTokenIds);
layoutNesting();
GraphPostprocessor::doPostprocessing(m_dummyNodes);
getView()->rebuildGraph(nullptr, m_dummyNodes, m_dummyEdges);
rebuildGraph();
}
}
void GraphController::handleMessage(MessageGraphNodeMove* message)
{
setRebuildState(message);
DummyNode* node = findDummyNodeRecursive(m_dummyNodes, message->tokenId);
if (node)
{
node->position += message->delta;
getView()->resizeView();
if (message->isFresh())
{
getView()->resizeView();
}
else
{
rebuildGraph();
}
}
}
@@ -164,7 +174,8 @@ void GraphController::createDummyGraphForTokenIds(const std::vector<Id>& tokenId
GraphLayouter::layoutSpectralPrototype(m_dummyNodes, m_dummyEdges);
GraphPostprocessor::doPostprocessing(m_dummyNodes);
view->rebuildGraph(graph, m_dummyNodes, m_dummyEdges);
m_graph = graph;
rebuildGraph();
}
DummyNode GraphController::createDummyNodeTopDown(Node* node)
@@ -186,7 +197,7 @@ DummyNode GraphController::createDummyNodeTopDown(Node* node)
}
DummyNode* oldNode = findDummyNodeRecursive(m_dummyNodes, node->getId());
if (oldNode)
if (oldNode && !m_restore)
{
result.expanded = oldNode->isExpanded();
}
@@ -269,7 +280,7 @@ void GraphController::autoExpandActiveNode(const std::vector<Id>& activeTokenIds
if (node && node->data->isType(Node::NODE_CLASS | Node::NODE_STRUCT))
{
node->autoExpanded = true;
node->expanded = true;
}
}
@@ -762,7 +773,6 @@ void GraphController::addExpandToggleNode(DummyNode& node) const
DummyNode expandNode;
expandNode.visible = true;
expandNode.expanded = node.expanded;
expandNode.autoExpanded = node.autoExpanded;
for (size_t i = 0; i < node.subNodes.size(); i++)
{
@@ -871,3 +881,31 @@ DummyNode* GraphController::findDummyNodeAccessRecursive(
}
return nullptr;
}
void GraphController::setRebuildState(MessageBase* message)
{
m_restore = false;
switch (message->undoRedoType)
{
case MessageBase::UNDOTYPE_UNDO:
m_restore = true;
case MessageBase::UNDOTYPE_NORMAL:
case MessageBase::UNDOTYPE_REDO:
m_rebuild = true;
break;
case MessageBase::UNDOTYPE_IGNORE:
m_restore = true;
m_rebuild = false;
break;
}
}
void GraphController::rebuildGraph()
{
if (m_rebuild)
{
getView()->rebuildGraph(m_graph, m_dummyNodes, m_dummyEdges);
m_graph.reset();
}
}
@@ -72,12 +72,19 @@ private:
DummyNode* findDummyNodeRecursive(std::vector<DummyNode>& nodes, Id tokenId) const;
DummyNode* findDummyNodeAccessRecursive(std::vector<DummyNode>& nodes, Id parentId, TokenComponentAccess::AccessType type) const;
void setRebuildState(MessageBase* message);
void rebuildGraph();
StorageAccess* m_storageAccess;
std::vector<DummyNode> m_dummyNodes;
std::vector<DummyEdge> m_dummyEdges;
std::vector<Id> m_activeTokenIds;
std::shared_ptr<Graph> m_graph;
bool m_rebuild;
bool m_restore;
};
#endif // GRAPH_CONTROLLER_H
@@ -14,6 +14,11 @@ SearchController::~SearchController()
void SearchController::handleMessage(MessageActivateEdge* message)
{
if (message->isIgnorable())
{
return;
}
SearchMatch match;
match.fullName = message->name;
match.nodeType = Node::NODE_CLASS;
@@ -25,6 +30,11 @@ void SearchController::handleMessage(MessageActivateEdge* message)
void SearchController::handleMessage(MessageActivateFile* message)
{
if (message->isIgnorable())
{
return;
}
SearchMatch match;
match.fullName = message->filePath.fileName();
match.nodeType = Node::NODE_FILE;
@@ -36,6 +46,11 @@ void SearchController::handleMessage(MessageActivateFile* message)
void SearchController::handleMessage(MessageActivateNode* message)
{
if (message->isIgnorable())
{
return;
}
SearchMatch match;
match.fullName = message->name;
match.nodeType = message->type;
@@ -57,6 +72,11 @@ void SearchController::handleMessage(MessageFinishedParsing* message)
void SearchController::handleMessage(MessageSearch* message)
{
if (message->isIgnorable())
{
return;
}
getView()->setMatches(message->getMatches());
}
@@ -5,7 +5,7 @@
#include "component/view/UndoRedoView.h"
UndoRedoController::UndoRedoController()
: m_lastCommand(nullptr)
: m_lastCommand(nullptr, 0)
{
}
@@ -18,45 +18,64 @@ UndoRedoView* UndoRedoController::getView()
return Controller::getView<UndoRedoView>();
}
UndoRedoController::Command::Command(std::shared_ptr<MessageBase> message, size_t order)
: message(message)
, order(order)
{
}
void UndoRedoController::handleMessage(MessageActivateEdge* message)
{
if (m_lastCommand && m_lastCommand->getType() == message->getType() &&
static_cast<MessageActivateEdge*>(m_lastCommand.get())->name == message->name)
if (m_lastCommand.message && m_lastCommand.message->getType() == message->getType() &&
static_cast<MessageActivateEdge*>(m_lastCommand.message.get())->name == message->name)
{
return;
}
processMessage(std::make_shared<MessageActivateEdge>(*message));
Command command(std::make_shared<MessageActivateEdge>(*message), (message->type == Edge::EDGE_AGGREGATION ? 0 : 1));
processCommand(command);
}
void UndoRedoController::handleMessage(MessageActivateFile* message)
{
if (m_lastCommand && m_lastCommand->getType() == message->getType() &&
static_cast<MessageActivateFile*>(m_lastCommand.get())->filePath == message->filePath)
if (m_lastCommand.message && m_lastCommand.message->getType() == message->getType() &&
static_cast<MessageActivateFile*>(m_lastCommand.message.get())->filePath == message->filePath)
{
return;
}
processMessage(std::make_shared<MessageActivateFile>(*message));
Command command(std::make_shared<MessageActivateFile>(*message), 0);
processCommand(command);
}
void UndoRedoController::handleMessage(MessageActivateNode* message)
{
if (m_lastCommand && m_lastCommand->getType() == message->getType() &&
static_cast<MessageActivateNode*>(m_lastCommand.get())->name == message->name)
if (m_lastCommand.message && m_lastCommand.message->getType() == message->getType() &&
static_cast<MessageActivateNode*>(m_lastCommand.message.get())->name == message->name)
{
return;
}
processMessage(std::make_shared<MessageActivateNode>(*message));
Command command(std::make_shared<MessageActivateNode>(*message), 0);
processCommand(command);
}
void UndoRedoController::handleMessage(MessageGraphNodeBundleSplit* message)
{
Command command(std::make_shared<MessageGraphNodeBundleSplit>(*message), 1);
processCommand(command);
}
void UndoRedoController::handleMessage(MessageGraphNodeExpand* message)
{
Command command(std::make_shared<MessageGraphNodeExpand>(*message), 1);
processCommand(command);
}
void UndoRedoController::handleMessage(MessageGraphNodeMove* message)
{
Command command(std::make_shared<MessageGraphNodeMove>(*message), 1);
processCommand(command);
}
void UndoRedoController::handleMessage(MessageLoadProject* message)
@@ -73,69 +92,87 @@ void UndoRedoController::handleMessage(MessageRedo* message)
{
if (!m_redo.empty())
{
std::shared_ptr<MessageBase> m = m_redo.back();
std::shared_ptr<MessageBase> m = m_redo.back().message;
m_redo.pop_back();
m->undoRedoType = MessageBase::UndoType_Redo;
m->undoRedoType = MessageBase::UNDOTYPE_REDO;
m->dispatch();
}
}
void UndoRedoController::handleMessage(MessageSearch* message)
{
if (m_lastCommand && m_lastCommand->getType() == message->getType() &&
static_cast<MessageSearch*>(m_lastCommand.get())->getQuery() == message->getQuery())
if (m_lastCommand.message && m_lastCommand.message->getType() == message->getType() &&
static_cast<MessageSearch*>(m_lastCommand.message.get())->getQuery() == message->getQuery())
{
return;
}
processMessage(std::make_shared<MessageSearch>(*message));
Command command(std::make_shared<MessageSearch>(*message), 0);
processCommand(command);
}
void UndoRedoController::handleMessage(MessageUndo* message)
{
if (!m_undo.empty())
{
std::shared_ptr<MessageBase> m = m_undo.back();
int i = m_undo.size() - 1;
while (i >= 1 && m_undo[i].order > 0)
{
i--;
}
std::shared_ptr<MessageBase> m;
while (i < int(m_undo.size() - 1))
{
m = m_undo[i].message;
m->undoRedoType = MessageBase::UNDOTYPE_IGNORE;
m->dispatch();
i++;
}
m = m_undo.back().message;
m_undo.pop_back();
m->undoRedoType = MessageBase::UndoType_Undo;
m->undoRedoType = MessageBase::UNDOTYPE_UNDO;
m->dispatch();
}
}
void UndoRedoController::processMessage(std::shared_ptr<MessageBase> message)
void UndoRedoController::processCommand(const Command& command)
{
switch (message->undoRedoType)
switch (command.message->undoRedoType)
{
case MessageBase::UndoType_Normal:
processNormalMessage(message);;
case MessageBase::UNDOTYPE_NORMAL:
processNormalCommand(command);
break;
case MessageBase::UndoType_Redo:
processRedoMessage(message);
case MessageBase::UNDOTYPE_REDO:
processRedoCommand(command);
break;
case MessageBase::UndoType_Undo:
processUndoMessage(message);
case MessageBase::UNDOTYPE_UNDO:
processUndoCommand(command);
break;
case MessageBase::UNDOTYPE_IGNORE:
break;
}
}
void UndoRedoController::processNormalMessage(std::shared_ptr<MessageBase> message)
void UndoRedoController::processNormalCommand(const Command& command)
{
if (m_lastCommand)
if (m_lastCommand.message)
{
m_undo.push_back(m_lastCommand);
getView()->setUndoButtonEnabled(true);
}
m_lastCommand = message;
m_lastCommand = command;
m_redo.clear();
getView()->setRedoButtonEnabled(false);
}
void UndoRedoController::processRedoMessage(std::shared_ptr<MessageBase> message)
void UndoRedoController::processRedoCommand(const Command& command)
{
m_undo.push_back(m_lastCommand);
m_lastCommand = message;
m_lastCommand = command;
getView()->setUndoButtonEnabled(true);
@@ -145,10 +182,10 @@ void UndoRedoController::processRedoMessage(std::shared_ptr<MessageBase> message
}
}
void UndoRedoController::processUndoMessage(std::shared_ptr<MessageBase> message)
void UndoRedoController::processUndoCommand(const Command& command)
{
m_redo.push_back(m_lastCommand);
m_lastCommand = message;
m_lastCommand = command;
getView()->setRedoButtonEnabled(true);
@@ -160,7 +197,7 @@ void UndoRedoController::processUndoMessage(std::shared_ptr<MessageBase> message
void UndoRedoController::clear()
{
m_lastCommand = nullptr;
m_lastCommand = Command(nullptr, 0);
m_undo.clear();
m_redo.clear();
@@ -8,6 +8,7 @@
#include "utility/messaging/type/MessageActivateEdge.h"
#include "utility/messaging/type/MessageActivateFile.h"
#include "utility/messaging/type/MessageActivateNode.h"
#include "utility/messaging/type/MessageGraphNodeBundleSplit.h"
#include "utility/messaging/type/MessageGraphNodeExpand.h"
#include "utility/messaging/type/MessageGraphNodeMove.h"
#include "utility/messaging/type/MessageLoadProject.h"
@@ -25,6 +26,7 @@ class UndoRedoController
, public MessageListener<MessageActivateEdge>
, public MessageListener<MessageActivateFile>
, public MessageListener<MessageActivateNode>
, public MessageListener<MessageGraphNodeBundleSplit>
, public MessageListener<MessageGraphNodeExpand>
, public MessageListener<MessageGraphNodeMove>
, public MessageListener<MessageLoadProject>
@@ -40,9 +42,18 @@ public:
UndoRedoView* getView();
private:
struct Command
{
Command(std::shared_ptr<MessageBase> message, size_t order);
std::shared_ptr<MessageBase> message;
size_t order;
};
virtual void handleMessage(MessageActivateEdge* message);
virtual void handleMessage(MessageActivateFile* message);
virtual void handleMessage(MessageActivateNode* message);
virtual void handleMessage(MessageGraphNodeBundleSplit* message);
virtual void handleMessage(MessageGraphNodeExpand* message);
virtual void handleMessage(MessageGraphNodeMove* message);
virtual void handleMessage(MessageLoadProject* message);
@@ -51,17 +62,17 @@ private:
virtual void handleMessage(MessageSearch* message);
virtual void handleMessage(MessageUndo* message);
void processMessage(std::shared_ptr<MessageBase> message);
void processNormalMessage(std::shared_ptr<MessageBase> message);
void processRedoMessage(std::shared_ptr<MessageBase> message);
void processUndoMessage(std::shared_ptr<MessageBase> message);
void processCommand(const Command& command);
void processNormalCommand(const Command& command);
void processRedoCommand(const Command& command);
void processUndoCommand(const Command& command);
void clear();
std::shared_ptr<MessageBase> m_lastCommand;
Command m_lastCommand;
std::deque<std::shared_ptr<MessageBase>> m_undo;
std::deque<std::shared_ptr<MessageBase>> m_redo;
std::deque<Command> m_undo;
std::deque<Command> m_redo;
};
#endif // UNDO_REDO_CONTROLLER_H
@@ -22,7 +22,6 @@ public:
, connected(false)
, aggregated(false)
, expanded(false)
, autoExpanded(false)
, accessType(TokenComponentAccess::ACCESS_NONE)
, invisibleSubNodeCount(0)
{
@@ -50,7 +49,7 @@ public:
bool isExpanded() const
{
return expanded || autoExpanded;
return expanded;
}
bool hasVisibleSubNode() const
@@ -119,7 +118,6 @@ public:
bool connected;
bool aggregated;
bool expanded;
bool autoExpanded;
// AccessNode
TokenComponentAccess::AccessType accessType;
+6
View File
@@ -26,6 +26,12 @@ public:
std::shared_ptr<MessageBase> message = std::make_shared<MessageType>(*dynamic_cast<MessageType*>(this));
MessageQueue::getInstance()->pushMessage(message);
}
virtual void dispatchImmediately()
{
std::shared_ptr<MessageBase> message = std::make_shared<MessageType>(*dynamic_cast<MessageType*>(this));
MessageQueue::getInstance()->processMessage(message, true);
}
};
#endif // MESSAGE_H
+11 -5
View File
@@ -8,13 +8,14 @@ class MessageBase
public:
enum UndoType
{
UndoType_Normal,
UndoType_Redo,
UndoType_Undo
UNDOTYPE_NORMAL,
UNDOTYPE_REDO,
UNDOTYPE_UNDO,
UNDOTYPE_IGNORE
};
MessageBase()
: undoRedoType(UndoType_Normal)
: undoRedoType(UNDOTYPE_NORMAL)
, m_sendAsTask(true)
{
}
@@ -38,7 +39,12 @@ public:
bool isFresh() const
{
return (undoRedoType == UndoType_Normal);
return (undoRedoType == UNDOTYPE_NORMAL);
}
bool isIgnorable() const
{
return (undoRedoType == UNDOTYPE_IGNORE);
}
UndoType undoRedoType;
+22 -10
View File
@@ -59,6 +59,18 @@ void MessageQueue::pushMessage(std::shared_ptr<MessageBase> message)
m_backMessageBuffer->push(message);
}
void MessageQueue::processMessage(std::shared_ptr<MessageBase> message, bool asNextTask)
{
if (m_sendMessagesAsTasks && message->sendAsTask())
{
sendMessageAsTask(message, asNextTask);
}
else
{
sendMessage(message);
}
}
void MessageQueue::startMessageLoopThreaded()
{
std::thread(&MessageQueue::startMessageLoop, this).detach();
@@ -189,14 +201,7 @@ void MessageQueue::processMessages()
m_frontMessageBuffer->pop();
}
if (m_sendMessagesAsTasks && message->sendAsTask())
{
sendMessageAsTask(message);
}
else
{
sendMessage(message);
}
processMessage(message, false);
}
}
@@ -224,7 +229,7 @@ void MessageQueue::sendMessage(std::shared_ptr<MessageBase> message)
}
}
void MessageQueue::sendMessageAsTask(std::shared_ptr<MessageBase> message) const
void MessageQueue::sendMessageAsTask(std::shared_ptr<MessageBase> message, bool asNextTask) const
{
std::shared_ptr<TaskGroupSequential> taskGroup = std::make_shared<TaskGroupSequential>();
@@ -244,5 +249,12 @@ void MessageQueue::sendMessageAsTask(std::shared_ptr<MessageBase> message) const
}
}
Task::dispatch(taskGroup);
if (asNextTask)
{
Task::dispatchNext(taskGroup);
}
else
{
Task::dispatch(taskGroup);
}
}
+2 -1
View File
@@ -17,6 +17,7 @@ public:
void unregisterListener(MessageListenerBase* listener);
void pushMessage(std::shared_ptr<MessageBase> message);
void processMessage(std::shared_ptr<MessageBase> message, bool asNextTask);
void startMessageLoopThreaded();
void startMessageLoop();
@@ -38,7 +39,7 @@ private:
void processMessages();
void sendMessage(std::shared_ptr<MessageBase> message);
void sendMessageAsTask(std::shared_ptr<MessageBase> message) const;
void sendMessageAsTask(std::shared_ptr<MessageBase> message, bool asNextTask) const;
std::shared_ptr<MessageBufferType> m_frontMessageBuffer;
std::shared_ptr<MessageBufferType> m_backMessageBuffer;
@@ -8,8 +8,9 @@ class MessageGraphNodeExpand
: public Message<MessageGraphNodeExpand>
{
public:
MessageGraphNodeExpand(Id tokenId)
MessageGraphNodeExpand(Id tokenId, bool expand)
: tokenId(tokenId)
, expand(expand)
{
}
@@ -19,6 +20,7 @@ public:
}
const Id tokenId;
const bool expand;
};
#endif // MESSAGE_GRAPH_NODE_EXPAND_H
+5
View File
@@ -8,6 +8,11 @@ void Task::dispatch(std::shared_ptr<Task> task)
TaskScheduler::getInstance()->pushTask(task);
}
void Task::dispatchNext(std::shared_ptr<Task> task)
{
TaskScheduler::getInstance()->pushNextTask(task);
}
Task::Task()
: m_state(STATE_NEW)
{
+1
View File
@@ -15,6 +15,7 @@ public:
};
static void dispatch(std::shared_ptr<Task> task);
static void dispatchNext(std::shared_ptr<Task> task);
Task();
virtual ~Task();
+10 -3
View File
@@ -19,7 +19,13 @@ std::shared_ptr<TaskScheduler> TaskScheduler::getInstance()
void TaskScheduler::pushTask(std::shared_ptr<Task> task)
{
std::lock_guard<std::mutex> lock(m_tasksMutex);
m_tasks.push(task);
m_tasks.push_back(task);
}
void TaskScheduler::pushNextTask(std::shared_ptr<Task> task)
{
std::lock_guard<std::mutex> lock(m_tasksMutex);
m_tasks.push_front(task);
}
void TaskScheduler::interruptCurrentTask()
@@ -136,14 +142,15 @@ void TaskScheduler::updateTasks()
while (m_tasks.size())
{
std::shared_ptr<Task> task = m_tasks.front();
m_tasks.pop_front();
m_tasksMutex.unlock();
Task::TaskState state = task->process(interrupt);
m_tasksMutex.lock();
if (state == Task::STATE_FINISHED || state == Task::STATE_CANCELED)
if (state != Task::STATE_FINISHED && state != Task::STATE_CANCELED)
{
m_tasks.pop();
m_tasks.push_front(task);
}
interrupt = m_interruptTask;
+3 -2
View File
@@ -3,7 +3,7 @@
#include <memory>
#include <mutex>
#include <queue>
#include <deque>
#include "utility/messaging/MessageListener.h"
#include "utility/messaging/type/MessageInterruptTasks.h"
@@ -16,6 +16,7 @@ public:
static std::shared_ptr<TaskScheduler> getInstance();
void pushTask(std::shared_ptr<Task> task);
void pushNextTask(std::shared_ptr<Task> task);
void interruptCurrentTask();
void startSchedulerLoopThreaded();
@@ -39,7 +40,7 @@ private:
bool m_loopIsRunning;
bool m_threadIsRunning;
std::queue<std::shared_ptr<Task>> m_tasks;
std::deque<std::shared_ptr<Task>> m_tasks;
bool m_interruptTask;
mutable std::mutex m_tasksMutex;