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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@ public:
|
||||
};
|
||||
|
||||
static void dispatch(std::shared_ptr<Task> task);
|
||||
static void dispatchNext(std::shared_ptr<Task> task);
|
||||
|
||||
Task();
|
||||
virtual ~Task();
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
Reference in New Issue
Block a user