Loading...
Searching...
No Matches
OngoingCommandDispatcher.hpp
1#pragma once
2#include <score/command/Dispatchers/ICommandDispatcher.hpp>
3#include <score/command/Dispatchers/SendStrategy.hpp>
4#include <score/plugins/StringFactoryKey.hpp>
5#include <score/tools/Debug.hpp>
6#include <score/tools/SafeCast.hpp>
7
8#include <memory>
9
26class SCORE_LIB_BASE_EXPORT OngoingCommandDispatcher final : public ICommandDispatcher
27{
28public:
31
32 // In Document.cpp
33 void watch(const QObject* obj);
34 void unwatch(const QObject* obj);
35
38 template <typename TheCommand, typename Watched, typename... Args>
39 void submit(Watched&& watched, Args&&... args)
40 {
41 using decayed = std::remove_cvref_t<Watched>;
42 if constexpr(std::is_pointer_v<decayed>)
43 {
44 static_assert(std::is_base_of_v<QObject, std::remove_cvref_t<decltype(*watched)>>);
45 watch(watched);
46 }
47 else
48 {
49 static_assert(std::is_base_of_v<QObject, decayed>);
50 watch(&watched);
51 }
52
53 if(!m_cmd)
54 {
55 stack().disableActions();
56 m_cmd = std::make_unique<TheCommand>(watched, std::forward<Args>(args)...);
57 m_cmd->redo(stack().context());
58 }
59 else
60 {
61 if(m_cmd->key() != TheCommand::static_key())
62 {
63 throw std::runtime_error(
64 "Ongoing command mismatch: current command " + m_cmd->key().toString()
65 + " does not match new command " + TheCommand{}.key().toString());
66 }
67
68 safe_cast<TheCommand*>(m_cmd.get())->update(watched, std::forward<Args>(args)...);
69 m_cmd->redo(stack().context());
70 }
71 }
72
75 void commit();
76
78 void rollback();
79 void rollback_without_undo();
80
81private:
82 std::unique_ptr<score::Command> m_cmd;
83 const QObject* m_watched{};
84};
The ICommandDispatcher class.
Definition ICommandDispatcher.hpp:21
The OngoingCommandDispatcher class.
Definition OngoingCommandDispatcher.hpp:27
void submit(Watched &&watched, Args &&... args)
Definition OngoingCommandDispatcher.hpp:39
A small abstraction layer over the score::CommandStack.
Definition CommandStackFacade.hpp:20