comparison data/model/EventCommands.h @ 1742:52705a328b34 by-id

Rejig ById so as to put everything in a single pool, so that at the core you can go from numeric id (untyped) to anything the object can be dynamic_cast to. Useful for building other abstractions like PlayParameter-type registrations that don't know about e.g. Models. Probably some more tweaking needed. Also add tests
author Chris Cannam
date Fri, 28 Jun 2019 17:36:30 +0100
parents 9d82b164f264
children
comparison
equal deleted inserted replaced
1741:9d82b164f264 1742:52705a328b34
28 public: 28 public:
29 virtual void add(Event e) = 0; 29 virtual void add(Event e) = 0;
30 virtual void remove(Event e) = 0; 30 virtual void remove(Event e) = 0;
31 }; 31 };
32 32
33 template <typename Base>
34 class WithEditable 33 class WithEditable
35 { 34 {
36 typedef typename Base::Id Id;
37 Id m_id;
38
39 protected: 35 protected:
40 WithEditable(Id id) : m_id(id) { } 36 WithEditable(int editableId) : m_editableId(editableId) { }
41 37
42 std::shared_ptr<EventEditable> getEditable() { 38 std::shared_ptr<EventEditable> getEditable() {
43 auto base = StaticById<Base, Id>::get(m_id); 39 auto editable = AnyById::getAs<EventEditable>(m_editableId);
44 if (!base) return {}; // acceptable - item has expired
45 auto editable = std::dynamic_pointer_cast<EventEditable>(base);
46 if (!editable) { 40 if (!editable) {
47 SVCERR << "WARNING: Id passed to EventEditable command is not that of an EventEditable" << endl; 41 SVCERR << "WARNING: Id passed to EventEditable command is not that of an EventEditable" << endl;
48 } 42 }
49 return editable; 43 return editable;
50 } 44 }
45
46 private:
47 int m_editableId;
51 }; 48 };
52 49
53 /** 50 /**
54 * Command to add an event to an editable containing events, with 51 * Command to add an event to an editable containing events, with
55 * undo. The template parameter must be a type that can be 52 * undo. The id must be that of a type that can be retrieved from the
56 * dynamic_cast to EventEditable and that has a ById store. 53 * AnyById store and dynamic_cast to EventEditable.
57 */ 54 */
58 template <typename Base>
59 class AddEventCommand : public Command, 55 class AddEventCommand : public Command,
60 public WithEditable<Base> 56 public WithEditable
61 { 57 {
62 public: 58 public:
63 AddEventCommand(typename Base::Id editable, const Event &e, QString name) : 59 AddEventCommand(int editableId, const Event &e, QString name) :
64 WithEditable<Base>(editable), m_event(e), m_name(name) { } 60 WithEditable(editableId), m_event(e), m_name(name) { }
65 61
66 QString getName() const override { return m_name; } 62 QString getName() const override { return m_name; }
67 Event getEvent() const { return m_event; } 63 Event getEvent() const { return m_event; }
68 64
69 void execute() override { 65 void execute() override {
76 } 72 }
77 73
78 private: 74 private:
79 Event m_event; 75 Event m_event;
80 QString m_name; 76 QString m_name;
81 using WithEditable<Base>::getEditable;
82 }; 77 };
83 78
84 /** 79 /**
85 * Command to remove an event from an editable containing events, with 80 * Command to remove an event from an editable containing events, with
86 * undo. The template parameter must be a type that implements 81 * undo. The id must be that of a type that can be retrieved from the
87 * EventBase and that has a ById store. 82 * AnyById store and dynamic_cast to EventEditable.
88 */ 83 */
89 template <typename Base>
90 class RemoveEventCommand : public Command, 84 class RemoveEventCommand : public Command,
91 public WithEditable<Base> 85 public WithEditable
92 { 86 {
93 public: 87 public:
94 RemoveEventCommand(typename Base::Id editable, const Event &e, QString name) : 88 RemoveEventCommand(int editableId, const Event &e, QString name) :
95 WithEditable<Base>(editable), m_event(e), m_name(name) { } 89 WithEditable(editableId), m_event(e), m_name(name) { }
96 90
97 QString getName() const override { return m_name; } 91 QString getName() const override { return m_name; }
98 Event getEvent() const { return m_event; } 92 Event getEvent() const { return m_event; }
99 93
100 void execute() override { 94 void execute() override {
107 } 101 }
108 102
109 private: 103 private:
110 Event m_event; 104 Event m_event;
111 QString m_name; 105 QString m_name;
112 using WithEditable<Base>::getEditable;
113 }; 106 };
114 107
115 /** 108 /**
116 * Command to add or remove a series of events to or from an editable, 109 * Command to add or remove a series of events to or from an editable,
117 * with undo. Creates and immediately executes a sub-command for each 110 * with undo. Creates and immediately executes a sub-command for each
118 * add/remove requested. Consecutive add/remove pairs for the same 111 * add/remove requested. Consecutive add/remove pairs for the same
119 * point are collapsed. The template parameter must be a type that 112 * point are collapsed. The id must be that of a type that can be
120 * implements EventBase and that has a ById store. 113 * retrieved from the AnyById store and dynamic_cast to EventEditable.
121 */ 114 */
122 template <typename Base>
123 class ChangeEventsCommand : public MacroCommand 115 class ChangeEventsCommand : public MacroCommand
124 { 116 {
125 typedef typename Base::Id Id;
126
127 public: 117 public:
128 ChangeEventsCommand(Id editable, QString name) : 118 ChangeEventsCommand(int editableId, QString name) :
129 MacroCommand(name), m_editable(editable) { } 119 MacroCommand(name), m_editableId(editableId) { }
130 120
131 void add(Event e) { 121 void add(Event e) {
132 addCommand(new AddEventCommand<Base>(m_editable, e, getName()), 122 addCommand(new AddEventCommand(m_editableId, e, getName()), true);
133 true);
134 } 123 }
135 void remove(Event e) { 124 void remove(Event e) {
136 addCommand(new RemoveEventCommand<Base>(m_editable, e, getName()), 125 addCommand(new RemoveEventCommand(m_editableId, e, getName()), true);
137 true);
138 } 126 }
139 127
140 /** 128 /**
141 * Stack an arbitrary other command in the same sequence. 129 * Stack an arbitrary other command in the same sequence.
142 */ 130 */
164 if (m_commands.empty()) { 152 if (m_commands.empty()) {
165 MacroCommand::addCommand(command); 153 MacroCommand::addCommand(command);
166 return; 154 return;
167 } 155 }
168 156
169 RemoveEventCommand<Base> *r = 157 RemoveEventCommand *r =
170 dynamic_cast<RemoveEventCommand<Base> *>(command); 158 dynamic_cast<RemoveEventCommand *>(command);
171 AddEventCommand<Base> *a = 159 AddEventCommand *a =
172 dynamic_cast<AddEventCommand<Base> *>(*m_commands.rbegin()); 160 dynamic_cast<AddEventCommand *>(*m_commands.rbegin());
173 if (r && a) { 161 if (r && a) {
174 if (a->getEvent() == r->getEvent()) { 162 if (a->getEvent() == r->getEvent()) {
175 deleteCommand(a); 163 deleteCommand(a);
176 return; 164 return;
177 } 165 }
178 } 166 }
179 167
180 MacroCommand::addCommand(command); 168 MacroCommand::addCommand(command);
181 } 169 }
182 170
183 Id m_editable; 171 int m_editableId;
184 }; 172 };
185 173
186 #endif 174 #endif