Mercurial > hg > svcore
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 |