Line data Source code
1 : /**
2 : Copyright (c) 2022 Roman Katuntsev <sbkarr@stappler.org>
3 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
4 :
5 : Permission is hereby granted, free of charge, to any person obtaining a copy
6 : of this software and associated documentation files (the "Software"), to deal
7 : in the Software without restriction, including without limitation the rights
8 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : copies of the Software, and to permit persons to whom the Software is
10 : furnished to do so, subject to the following conditions:
11 :
12 : The above copyright notice and this permission notice shall be included in
13 : all copies or substantial portions of the Software.
14 :
15 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : THE SOFTWARE.
22 : **/
23 :
24 : #ifndef XENOLITH_SCENE_ACTIONS_XLACTIONMANAGER_H_
25 : #define XENOLITH_SCENE_ACTIONS_XLACTIONMANAGER_H_
26 :
27 : #include "XLNodeInfo.h"
28 : #include "XLAction.h"
29 : #include "SPHashTable.h"
30 : #include "SPRefContainer.h"
31 :
32 : namespace STAPPLER_VERSIONIZED stappler::xenolith {
33 :
34 : class Node;
35 :
36 : struct ActionContainer : RefContainer<Action> {
37 : Rc<Node> target;
38 : bool paused = false;
39 :
40 : virtual ~ActionContainer();
41 : ActionContainer(Node *);
42 : };
43 :
44 : struct HashTraitActionContainer {
45 : static uint32_t hash(uint32_t salt, const ActionContainer &value) {
46 : auto target = value.target.get();
47 : return hash::hash32((const char *)&target, sizeof(Node *), salt);
48 : }
49 :
50 86819 : static uint32_t hash(uint32_t salt, const Node *value) {
51 86819 : return hash::hash32((const char *)&value, sizeof(Node *), salt);
52 : }
53 :
54 : static bool equal(const ActionContainer &l, const ActionContainer &r) {
55 : return l.target == r.target;
56 : }
57 :
58 7886 : static bool equal(const ActionContainer &l, const Node *value) {
59 7886 : return l.target == value;
60 : }
61 : };
62 :
63 : }
64 :
65 : namespace STAPPLER_VERSIONIZED stappler {
66 :
67 : template <>
68 : struct HashTraitDiscovery<xenolith::ActionContainer> {
69 : using type = xenolith::HashTraitActionContainer;
70 : };
71 :
72 : }
73 :
74 : namespace STAPPLER_VERSIONIZED stappler::xenolith {
75 :
76 : class ActionManager : public Ref {
77 : public:
78 : virtual ~ActionManager();
79 :
80 : ActionManager();
81 :
82 : bool init();
83 :
84 : // actions
85 :
86 : /** Adds an action with a target.
87 : If the target is already present, then the action will be added to the existing target.
88 : If the target is not present, a new instance of this target will be created either paused or not, and the action will be added to the newly created target.
89 : When the target is paused, the queued actions won't be 'ticked'.
90 : *
91 : * @param action A certain action.
92 : * @param target The target which need to be added an action.
93 : * @param paused Is the target paused or not.
94 : */
95 : void addAction(Action *action, Node *target, bool paused);
96 :
97 : /** Removes all actions from all the targets. */
98 : void removeAllActions();
99 :
100 : /** Removes all actions from a certain target.
101 : All the actions that belongs to the target will be removed.
102 : *
103 : * @param target A certain target.
104 : */
105 : void removeAllActionsFromTarget(Node *target);
106 :
107 : /** Removes an action given an action reference.
108 : *
109 : * @param action A certain target.
110 : */
111 : void removeAction(Action *action);
112 :
113 : /** Removes an action given its tag and the target.
114 : *
115 : * @param tag The action's tag.
116 : * @param target A certain target.
117 : */
118 : void removeActionByTag(uint32_t tag, Node *target);
119 :
120 : /** Removes all actions given its tag and the target.
121 : *
122 : * @param tag The actions' tag.
123 : * @param target A certain target.
124 : */
125 : void removeAllActionsByTag(uint32_t tag, Node *target);
126 :
127 : /** Gets an action given its tag an a target.
128 : *
129 : * @param tag The action's tag.
130 : * @param target A certain target.
131 : * @return The Action the with the given tag.
132 : */
133 : Action* getActionByTag(uint32_t tag, const Node *target) const;
134 :
135 : /** Returns the numbers of actions that are running in a certain target.
136 : * Composable actions are counted as 1 action. Example:
137 : * - If you are running 1 Sequence of 7 actions, it will return 1.
138 : * - If you are running 7 Sequences of 2 actions, it will return 7.
139 : *
140 : * @param target A certain target.
141 : * @return The numbers of actions that are running in a certain target.
142 : */
143 : size_t getNumberOfRunningActionsInTarget(const Node *target) const;
144 :
145 : /** Pauses the target: all running actions and newly added actions will be paused.
146 : *
147 : * @param target A certain target.
148 : */
149 : void pauseTarget(Node *target);
150 :
151 : /** Resumes the target. All queued actions will be resumed.
152 : *
153 : * @param target A certain target.
154 : */
155 : void resumeTarget(Node *target);
156 :
157 : /** Pauses all running actions, returning a list of targets whose actions were paused.
158 : *
159 : * @return A list of targets whose actions were paused.
160 : */
161 : Vector<Node*> pauseAllRunningActions();
162 :
163 : /** Resume a set of targets (convenience function to reverse a pauseAllRunningActions call).
164 : *
165 : * @param targetsToResume A set of targets need to be resumed.
166 : */
167 : void resumeTargets(const Vector<Node*> &targetsToResume);
168 :
169 : /** Main loop of ActionManager. */
170 : void update(const UpdateTime &);
171 :
172 : bool empty() const;
173 :
174 : protected:
175 : struct PendingAction {
176 : Rc<Action> action;
177 : Rc<Node> target;
178 : bool paused;
179 : };
180 :
181 : bool _inUpdate = false;
182 : ActionContainer *_current = nullptr;
183 : HashTable<ActionContainer> _actions;
184 : Vector<PendingAction> _pending;
185 : };
186 :
187 : }
188 :
189 : #endif /* XENOLITH_SCENE_ACTIONS_XLACTIONMANAGER_H_ */
|