Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_WorkshopItemAction.c
Go to the documentation of this file.
1/*
2SCR_WorkshopItemAction adds a concept of an asynchronous operation which can be
3started, paused, canceled, resumed, failed, restarted.
4
5It also provides event handlers for state changes.
6
7The action can be interacted with through public API.
8
9
10From this class other classes are derived which represent specific operation types.
11
12
13!!! Don't create an action yourself! Use the action returned by SCR_WorkshopItem instead.
14*/
15
17{
18//---- REFACTOR NOTE START: This code will need to be refactored as current implementation is not conforming to the standards ----
19// Old untyped script invokers, const ints instead of an enum, and a code architecture issue with m_Wrapper, as SCR_WorkshopItem and SCR_WorkshopItemAction include each other and are supposed to be tigtly coupled, but they can also end up holding unrelated instances: add actions persisting after failing/canceling for UI display purposes, and states often updating the next frame at the earliest, and it gets rather hard to ensure what data is available at what time
20
21 ref ScriptInvoker m_OnActivated = new ScriptInvoker;
22 ref ScriptInvoker m_OnCompleted = new ScriptInvoker;
23 ref ScriptInvoker m_OnCanceled = new ScriptInvoker;
24 ref ScriptInvoker m_OnResumed = new ScriptInvoker;
25 ref ScriptInvoker m_OnPaused = new ScriptInvoker;
26 ref ScriptInvoker m_OnFailed = new ScriptInvoker;
27 ref ScriptInvoker m_OnChanged = new ScriptInvoker;
28
29 // ---- States ----
30 protected const int STATE_INACTIVE = 0;
31 protected const int STATE_ACTIVE = 1;
32 protected const int STATE_COMPLETED = 2;
33 protected const int STATE_FAILED = 3;
34 protected const int STATE_CANCELED = 4;
35 protected const int STATE_PAUSED = 5;
36
37 // ---- Protected ----
38 protected int m_State;
39
41
42//---- REFACTOR NOTE END ----
43
44 protected bool m_bAttached;
45 protected ref Managed m_UserData; // Arbitrary user data, use GetUserData() SetUserData().
46
47 // Cached basic data about the addon. Because action might outlive the WorkshopItem object.
48 protected string m_sAddonName;
49 protected string m_sAddonId;
50
51 //-----------------------------------------------------------------------------------------------
52 // !!! Don't create an action yourself! Use API in SCR_WorkshopItem instead.
54 {
55 #ifdef WORKSHOP_DEBUG
56 _print("NEW");
57 #endif
58
59 m_Wrapper = wrapper;
60 m_bAttached = true;
61
62 // Cache basic addon data
63 m_sAddonName = wrapper.GetName();
64 m_sAddonId = wrapper.GetId();
65 }
66
67
68 //-----------------------------------------------------------------------------------------------
70 {
71 #ifdef WORKSHOP_DEBUG
72 _print("DELETE");
73 #endif
74 }
75
76 // ---- Public API ----
77
78 //-----------------------------------------------------------------------------------------------
79 // Public getters for internal state
80 bool IsInactive() { return m_State == STATE_INACTIVE; }
81 bool IsActive() { return m_State == STATE_ACTIVE; }
82 bool IsCompleted() { return m_State == STATE_COMPLETED; }
83 bool IsCanceled() { return m_State == STATE_CANCELED; }
84 bool IsPaused() { return m_State == STATE_PAUSED; }
85 bool IsFailed() { return m_State == STATE_FAILED; }
86
87 //-----------------------------------------------------------------------------------------------
91 bool IsAttached() { return m_bAttached; }
92
93 //-----------------------------------------------------------------------------------------------
95
96 //-----------------------------------------------------------------------------------------------
97 void SetUserData(Managed data) { m_UserData = data; }
98
99 //-----------------------------------------------------------------------------------------------
100 Managed GetUserData(Managed data) { return m_UserData; }
101
102 //-----------------------------------------------------------------------------------------------
105 {
106 if (m_Wrapper)
107 return m_Wrapper.GetName();
108 else
109 return m_sAddonName;
110 }
111
112 //-----------------------------------------------------------------------------------------------
114 string GetAddonId()
115 {
116 if (m_Wrapper)
117 return m_Wrapper.GetId();
118 else
119 return m_sAddonId;
120 }
121
122 //-----------------------------------------------------------------------------------------------
126 //-----------------------------------------------------------------------------------------------
127
128 //-----------------------------------------------------------------------------------------------
130 bool Activate()
131 {
132 #ifdef WORKSHOP_DEBUG
133 _print("Activate()");
134 #endif
135
136 if (!m_Wrapper || !m_bAttached)
137 return false;
138
139 if (m_State == STATE_INACTIVE)
140 {
141 #ifdef WORKSHOP_DEBUG
142 _print("OnActivate()");
143 #endif
144 bool success = OnActivate();
145 if (success)
146 {
148 m_OnActivated.Invoke(this);
150 m_Wrapper.Internal_OnChanged();
151 }
152 else
153 {
154 Fail();
155 }
156 return success;
157 }
158 if (m_State == STATE_PAUSED)
159 {
160 return this.Resume();
161 }
162 else if (m_State == STATE_ACTIVE)
163 {
164 return true;
165 }
166
167 return false;
168 }
169
170
171 //-----------------------------------------------------------------------------------------------
173 bool Cancel()
174 {
175 if (!m_Wrapper || !m_bAttached)
176 return false;
177
178 #ifdef WORKSHOP_DEBUG
179 _print("Cancel()");
180 #endif
181
183 {
184 #ifdef WORKSHOP_DEBUG
185 _print("OnCancel()");
186 #endif
187
188 bool success = OnCancel();
189 if (success)
190 {
192 m_OnCanceled.Invoke(this);
194 m_Wrapper.Internal_OnChanged();
195 }
196 else
197 {
198 Fail();
199 }
200 return success;
201 }
202 else if (m_State == STATE_CANCELED)
203 {
204 return true;
205 }
206
207 return false;
208 }
209
210
211 //-----------------------------------------------------------------------------------------------
213 bool Pause()
214 {
215 if (!m_Wrapper || !m_bAttached)
216 return false;
217
218 #ifdef WORKSHOP_DEBUG
219 _print("Pause()");
220 #endif
221
222 if (m_State == STATE_ACTIVE)
223 {
224 #ifdef WORKSHOP_DEBUG
225 _print("OnPause()");
226 #endif
227
228 bool success = OnPause();
229 if (success)
230 {
232 m_OnPaused.Invoke(this);
234 m_Wrapper.Internal_OnChanged();
235 }
236 else
237 {
238 Fail();
239 }
240 return success;
241 }
242 else if (m_State == STATE_PAUSED)
243 {
244 return true;
245 }
246
247 return false;
248 }
249
250
251 //-----------------------------------------------------------------------------------------------
253 bool Resume()
254 {
255 if (!m_Wrapper || !m_bAttached)
256 return false;
257
258 #ifdef WORKSHOP_DEBUG
259 _print("Resume()");
260 #endif
261
262 if (m_State == STATE_PAUSED)
263 {
264 #ifdef WORKSHOP_DEBUG
265 _print("OnResume()");
266 #endif
267
268 bool success = OnResume();
269 if (success)
270 {
272 m_OnResumed.Invoke(this);
274 m_Wrapper.Internal_OnChanged();
275 }
276 else
277 {
278 Fail();
279 }
280 return success;
281 }
282 else if (m_State == STATE_INACTIVE)
283 {
284 Activate();
285 }
286 else if (m_State == STATE_ACTIVE)
287 {
288 return true; // Resuming an active action doesn't mean an error
289 }
290
291 return false;
292 }
293
294 //-----------------------------------------------------------------------------------------------
297 {
298 if (!m_Wrapper || !m_bAttached)
299 return false;
300
301 #ifdef WORKSHOP_DEBUG
302 _print("Reactivate()");
303 #endif
304
305 if (m_State == STATE_FAILED)
306 {
307 #ifdef WORKSHOP_DEBUG
308 _print("OnReactivate()");
309 #endif
310
311 bool success = OnReactivate();
312 if (success)
313 {
315 m_OnActivated.Invoke(this);
317 m_Wrapper.Internal_OnChanged();
318 }
319 return success;
320 }
321 else if (m_State == STATE_ACTIVE)
322 {
323 return true;
324 }
325
326 return false;
327 }
328
329
330 // ---- Protected / private ----
331
332
333 //-----------------------------------------------------------------------------------------------
335 protected void Fail(int reason = -1)
336 {
337 if (!m_Wrapper || !m_bAttached)
338 return;
339
340 #ifdef WORKSHOP_DEBUG
341 _print("Fail()");
342 #endif
343
344 if (m_State != STATE_FAILED)
345 {
347 OnFail(reason);
348 m_OnFailed.Invoke(this, reason);
350 m_Wrapper.Internal_OnChanged();
351 }
352 }
353
354 //-----------------------------------------------------------------------------------------------
356 protected void Complete()
357 {
358 if (!m_Wrapper || !m_bAttached)
359 return;
360
361 #ifdef WORKSHOP_DEBUG
362 _print("Complete()");
363 #endif
364
366 {
368 OnComplete();
369 m_OnCompleted.Invoke(this);
371 m_Wrapper.Internal_OnChanged();
372 }
373 }
374
375 //-----------------------------------------------------------------------------------------------
377 protected void InvokeOnChanged()
378 {
379 m_OnChanged.Invoke(this);
380 }
381
382//---- REFACTOR NOTE START: This code will need to be refactored as current implementation is not conforming to the standards ----
383// Just a formatting note: as far as I know we don't want inline return
384
385 //------------------------------------------------------------------------------------------------
388 protected bool OnActivate() { return false; }
389 protected bool OnCancel() { return false; }
390 protected bool OnPause() { return false; }
391 protected bool OnResume() { return false; }
392 protected bool OnReactivate() { return false; }
393 protected void OnFail(int reason = -1);
394 protected void OnComplete();
395
396//---- REFACTOR NOTE END ----
397
398 //------------------------------------------------------------------------------------------------
401 void Internal_Update(float timeSlice);
402
403 //------------------------------------------------------------------------------------------------
405 {
406 m_bAttached = false;
407 }
408
409 //------------------------------------------------------------------------------------------------
410 void _print(string str, LogLevel logLevel = LogLevel.DEBUG)
411 {
412 Print(string.Format("[SCR_AddonManager] %1 %2", this, str), logLevel);
413 }
414};
415
416//---- REFACTOR NOTE START: This code will need to be refactored as current implementation is not conforming to the standards ----
417// auto
418
421{
422 ref array<ref SCR_WorkshopItemAction> m_aActions = new array<ref SCR_WorkshopItemAction>;
423
424 //-----------------------------------------------------------------------------------------------
426 array<ref SCR_WorkshopItemAction> GetActions()
427 {
428 array<ref SCR_WorkshopItemAction> actions = new array<ref SCR_WorkshopItemAction>;
429
430 foreach (auto a : m_aActions)
431 actions.Insert(a);
432
433 return actions;
434 }
435
436 //-----------------------------------------------------------------------------------------------
438 {
439 m_aActions.Insert(action);
440 }
441
442 //-----------------------------------------------------------------------------------------------
444 {
445 m_aActions.RemoveItem(action);
446 }
447
448 //-----------------------------------------------------------------------------------------------
449 protected void UnregisterActions(array<SCR_WorkshopItemAction> actions)
450 {
451 foreach (auto i : actions)
453 }
454
455 //-----------------------------------------------------------------------------------------------
456 protected bool AllCompleted()
457 {
458 int n = 0;
459
460 foreach (auto a : m_aActions)
461 if (a.IsCompleted())
462 n++;
463
464 return n == m_aActions.Count();
465 }
466
467 //-----------------------------------------------------------------------------------------------
468 protected bool AnyFailed()
469 {
470 foreach (auto a : m_aActions)
471 if (a.IsFailed())
472 return true;
473
474 return false;
475 }
476
477 //-----------------------------------------------------------------------------------------------
478 protected void CancelAll()
479 {
480 foreach (auto a : m_aActions)
481 a.Cancel();
482 }
483
484 //-----------------------------------------------------------------------------------------------
485 protected void PauseAll()
486 {
487 foreach (auto a : m_aActions)
488 a.Pause();
489 }
490
491 //-----------------------------------------------------------------------------------------------
492 protected void ResumeAll()
493 {
494 foreach (auto a : m_aActions)
495 a.Resume();
496 }
497
498 //-----------------------------------------------------------------------------------------------
499 protected void ActivateAll()
500 {
501 foreach (auto a : m_aActions)
502 a.Activate();
503 }
504
505 //---- REFACTOR NOTE END ----
506};
override void OnFail()
Get all prefabs that have the spawner data
array< ref SCR_MenuActionPreset > GetActions()
Composite action which includes multiple subactions.
void UnregisterAction(SCR_WorkshopItemAction action)
void UnregisterActions(array< SCR_WorkshopItemAction > actions)
void RegisterAction(SCR_WorkshopItemAction action)
void Internal_Update(float timeSlice)
void Fail(int reason=-1)
Action must call this when it has failed.
void SCR_WorkshopItemAction(SCR_WorkshopItem wrapper)
SCR_WorkshopItem GetWorkshopItem()
void Complete()
Action must call this when it is completed.
bool Reactivate()
Starts action again Only valid in failed state.
void _print(string str, LogLevel logLevel=LogLevel.DEBUG)
void InvokeOnChanged()
Call this in inherited classes to invoke the OnChanged event handler.
Managed GetUserData(Managed data)
bool Pause()
Pauses an active action.
bool Activate()
Activates an inactive action, or resumes a paused action.
string GetAddonName()
Returns the cached addon name, even if WorkshopItem object is already deleted.
bool Resume()
Resumes a paused action.
void OnFail(int reason=-1)
bool Cancel()
Cancels an action. Valid in active, inactive, paused states.
string GetAddonId()
Returns the cached addon ID, even if WorkshopItem object is already deleted.
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
ScriptInvokerBase< func > ScriptInvoker
Definition tools.c:134