Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_DownloadSequence.c
Go to the documentation of this file.
1 
10 //-----------------------------------------------------------------------------------------------
13 
14 //-----------------------------------------------------------------------------------------------
15 void ScriptInvoker_DownloadSequenceDependencies(SCR_DownloadSequence sequence, array<ref SCR_WorkshopItem> dependencies);
17 
18 //------------------------------------------------------------------------------------------------
20 {
21  // When true, we will subscribe automatically when download is started
22  protected bool m_bSubscribeToAddons;
23 
24  protected ref array<ref SCR_WorkshopItem> m_aDependencies = {};
25  protected bool m_bWaitingResponse; // Set to false when data fetching is complete
26  protected bool m_bCanceled; // When true, finishing data reception will not trigger further downloading or other actions.
27  protected bool m_bFailed; // True when failed due to timeour or error
28  protected bool m_bRestrictedAddons;
29  protected bool m_bBlockedAddons;
30  protected bool m_bPatchSizeLoaded;
31 
32  // True - skip loading of addon details which speed up loading time, useful for getting downloading list like in Server broweser
33  protected bool m_bSkipDetails;
34 
35  protected int m_iDependencyDetailsLoadedCount = 0;
36  protected bool m_bAllDependencyDetailsLoaded;
37 
38  protected int m_iPatchesLoaded = 0;
39 
40  protected ref array<ref SCR_BackendCallbackWorkshopItem> m_aPatchSizeCallbacks = {};
41 
42  protected ref array<ref SCR_WorkshopItem> m_aDependenciesIssues = {};
43 
44  //------------------------------------------------------------------------------------------------
45  // Invokers
46  //------------------------------------------------------------------------------------------------
47 
48  protected ref ScriptInvokerBase<ScriptInvoker_DownloadSequence> m_OnInit;
49  protected ref ScriptInvokerBase<ScriptInvoker_DownloadSequence> m_OnDetailsLoaded;
50  protected ref ScriptInvokerBase<ScriptInvoker_DownloadSequence> m_OnDependenciesLoaded;
51  protected ref ScriptInvokerBase<ScriptInvoker_DownloadSequenceDependencies> m_OnRestrictedDependencies;
52  protected ref ScriptInvokerBase<ScriptInvoker_DownloadSequenceDependencies> m_OnDependenciesLoadingPrevented;
53  protected ref ScriptInvokerBase<ScriptInvoker_DownloadSequence> m_OnError;
54  protected ref ScriptInvokerBase<ScriptInvoker_DownloadSequence> m_OnReady;
55 
56  protected ref ScriptInvokerBase<ScriptInvoker_DownloadSequence> m_OnCancel;
57  protected ref ScriptInvokerBase<ScriptInvoker_DownloadSequence> m_OnDestroyed;
58 
59  //------------------------------------------------------------------------------------------------
60  ScriptInvokerBase<ScriptInvoker_DownloadSequenceDependencies> GetOnRestrictedDependency()
61  {
62  if (!m_OnRestrictedDependencies)
63  m_OnRestrictedDependencies = new ScriptInvokerBase<ScriptInvoker_DownloadSequenceDependencies>();
64 
65  return m_OnRestrictedDependencies;
66  }
67 
68  //------------------------------------------------------------------------------------------------
69  ScriptInvokerBase<ScriptInvoker_DownloadSequenceDependencies> GetOnDependenciesLoadingPrevented()
70  {
71  if (!m_OnDependenciesLoadingPrevented)
72  m_OnDependenciesLoadingPrevented = new ScriptInvokerBase<ScriptInvoker_DownloadSequenceDependencies>();
73 
74  return m_OnDependenciesLoadingPrevented;
75  }
76 
77  //------------------------------------------------------------------------------------------------
78  ScriptInvokerBase<ScriptInvoker_DownloadSequence> GetOnError()
79  {
80  if (!m_OnError)
81  m_OnError = new ScriptInvokerBase<ScriptInvoker_DownloadSequence>();
82 
83  return m_OnError;
84  }
85 
86  //------------------------------------------------------------------------------------------------
87  ScriptInvokerBase<ScriptInvoker_DownloadSequence> GetOnReady()
88  {
89  if (!m_OnReady)
90  m_OnReady = new ScriptInvokerBase<ScriptInvoker_DownloadSequence>();
91 
92  return m_OnReady;
93  }
94 
95  //------------------------------------------------------------------------------------------------
96  ScriptInvokerBase<ScriptInvoker_DownloadSequence> GetOnCancel()
97  {
98  if (!m_OnCancel)
99  m_OnCancel = new ScriptInvokerBase<ScriptInvoker_DownloadSequence>();
100 
101  return m_OnCancel;
102  }
103 
104  //------------------------------------------------------------------------------------------------
105  // Public
106  //------------------------------------------------------------------------------------------------
107 
108  //------------------------------------------------------------------------------------------------
109  static SCR_DownloadSequence Create(array<ref SCR_WorkshopItem> dependencies, SCR_DownloadSequence previous, bool skipDetails = false)
110  {
111  if (previous && previous.m_bWaitingResponse)
112  return previous;
113 
115  sequence.Setup(dependencies, skipDetails);
116 
117  return sequence;
118  }
119 
120  //------------------------------------------------------------------------------------------------
121  // Call on creating to start download sequence
122  // Start load details
123  void Init()
124  {
125  m_bWaitingResponse = true;
126  m_bRestrictedAddons = false;
127  m_bBlockedAddons = false;
128 
129  // Skip details loading
130  if (m_bSkipDetails)
131  {
132  OnAllDependenciesDetailsLoaded();
133  return;
134  }
135 
136  // Load
137  LoadDependenciesDetails();
138  }
139 
140  //------------------------------------------------------------------------------------------------
143  SCR_ReportedAddonsDialog ShowRestrictedDependenciesDialog()
144  {
145  array<ref SCR_WorkshopItem> restrictedDependencies = SCR_AddonManager.SelectItemsBasic(m_aDependencies, EWorkshopItemQuery.RESTRICTED);
146  SCR_AddonListDialog addonsDialog = SCR_AddonListDialog.CreateRestrictedAddonsDownload(restrictedDependencies);
147 
148  // Handle cancel reports done
149  SCR_ReportedAddonsDialog reportedDialog = SCR_ReportedAddonsDialog.Cast(addonsDialog);
150  if (reportedDialog)
151  reportedDialog.GetOnAllReportsCanceled().Insert(OnAllReportsCanceled);
152 
153  return reportedDialog;
154  }
155 
156  //------------------------------------------------------------------------------------------------
158  void Cancel()
159  {
160  m_bCanceled = true;
161  m_bWaitingResponse = false;
162 
163  if (m_OnCancel)
164  m_OnCancel.Invoke(this);
165  }
166 
167  //------------------------------------------------------------------------------------------------
168  // Protected
169  //------------------------------------------------------------------------------------------------
170 
171  //------------------------------------------------------------------------------------------------
173  protected void Setup(notnull array<ref SCR_WorkshopItem> dependencies, bool skipDetails)
174  {
175  m_bSubscribeToAddons = true;
176  m_bSkipDetails = skipDetails;
177 
178  foreach (SCR_WorkshopItem dependency : dependencies)
179  {
180  m_aDependencies.Insert(dependency);
181  }
182  }
183 
184  //------------------------------------------------------------------------------------------------
186  protected bool HasAllDetails()
187  {
188  if (m_bFailed || m_bCanceled || m_bWaitingResponse)
189  return false;
190 
191  if (m_bSkipDetails && !m_bAllDependencyDetailsLoaded)
192  return false;
193 
194  return true;
195  }
196 
197  //------------------------------------------------------------------------------------------------
198  // Load all dependencies details in list
199  protected void LoadDependenciesDetails()
200  {
201  m_iDependencyDetailsLoadedCount = 0;
202 
203  // No dependenciees - Skip dependency loading
204  if (m_aDependencies.IsEmpty())
205  {
206  OnAllDependenciesDetailsLoaded();
207  return;
208  }
209 
210  // Load details of all dependencies
211  foreach (SCR_WorkshopItem dep : m_aDependencies)
212  {
213  // Skip loaded
214  if (dep.GetDetailsLoaded() || dep.GetOffline())
215  {
216  OnDependencyDetailsLoaded(dep);
217  continue;
218  }
219 
220  // Setup callbacks and load details
221  dep.m_OnGetAsset.Insert(OnDependencyDetailsLoaded);
222  dep.m_OnError.Insert(OnItemError);
223  dep.m_OnTimeout.Insert(OnItemError);
224 
225  dep.LoadDetails();
226  }
227  }
228 
229  //------------------------------------------------------------------------------------------------
231  protected void OnAllDependenciesDetailsLoaded()
232  {
233  m_bAllDependencyDetailsLoaded = true;
234 
235  // Bail if this was canceled or failed
236  if (m_bFailed || m_bCanceled)
237  return;
238 
239  // Check if any dependencies are restricted
240  array<ref SCR_WorkshopItem> restricted = SCR_AddonManager.SelectItemsBasic(m_aDependencies, EWorkshopItemQuery.RESTRICTED);
241  if (!restricted.IsEmpty())
242  {
243  m_bRestrictedAddons = true;
244 
245  array<ref SCR_WorkshopItem> blocked = SCR_AddonManager.SelectItemsBasic(restricted, EWorkshopItemQuery.BLOCKED);
246  m_bBlockedAddons = !blocked.IsEmpty();
247 
248  if (m_OnRestrictedDependencies)
249  m_OnRestrictedDependencies.Invoke(this, restricted);
250  }
251 
252  // Skip dependencies patch size loading
253  if (m_aDependencies.IsEmpty())
254  {
255  AllPatchSizeLoaded();
256  return;
257  }
258 
259  // Load dependencies patch sizes
260  m_iPatchesLoaded = 0;
261 
262  foreach (SCR_WorkshopItem dependency : m_aDependencies)
263  {
264  // Skip blocked (banned)
265  if (dependency.GetBlocked())
266  {
267  OnDependencyPatchSizeLoadResponse(null);
268  continue;
269  }
270 
271  float patchSize;
272 
273  // Catch missing
274  Revision revision = null;
275 
276  if (dependency.GetDependency())
277  revision = dependency.GetDependency().GetRevision();
278 
279  // Pending download
280  if (!revision)
281  revision = dependency.GetWorkshopItem().GetPendingDownload();
282 
283  if (!revision)
284  continue;
285 
286  // Skip patch compute if dependency is running download
287  SCR_WorkshopItemActionDownload downloading = SCR_DownloadManager.GetInstance().DownloadingActionAddonById(dependency.GetId());
288 
289  if (downloading)
290  {
291  // Proccess with same version
292  OnDependencyPatchSizeLoadResponse(null);
293 
294  continue;
295  }
296 
297  // Skip patch size compute if addon is not downloaded
298  if (!dependency.GetOffline())
299  {
300  SetDependencySize(dependency, dependency.GetSizeBytes());
301  continue;
302  }
303 
304  // Setup callback and compute
306  callback.GetEventOnResponse().Insert(OnDependencyPatchSizeLoadResponse);
307  m_aPatchSizeCallbacks.Insert(callback);
308 
309  revision.ComputePatchSize(callback);
310  }
311  }
312 
313  //------------------------------------------------------------------------------------------------
314  protected array<ref SCR_WorkshopItem> MissingWorkshopItems()
315  {
316  array<ref SCR_WorkshopItem> missingItems = {};
317 
318  foreach (SCR_WorkshopItem dependency : m_aDependencies)
319  {
320  if (!dependency.GetWorkshopItem())
321  missingItems.Insert(dependency);
322  }
323 
324  return missingItems;
325  }
326 
327  //------------------------------------------------------------------------------------------------
328  protected void AllPatchSizeLoaded()
329  {
330  m_bWaitingResponse = false;
331 
332  if (m_OnReady && HasAllDetails())
333  m_OnReady.Invoke(this);
334  }
335 
336  //------------------------------------------------------------------------------------------------
338  void OnAllReportsCanceled(SCR_ReportedAddonsDialog dialog)
339  {
340  dialog.GetOnAllReportsCanceled().Remove(OnAllReportsCanceled);
341 
342  m_bRestrictedAddons = false;
343  OnAllDependenciesDetailsLoaded();
344  }
345 
346  //------------------------------------------------------------------------------------------------
347  // Callbacks
348  //------------------------------------------------------------------------------------------------
349 
350  //------------------------------------------------------------------------------------------------
352  protected void OnDependencyDetailsLoaded(notnull SCR_WorkshopItem item)
353  {
354  item.m_OnGetAsset.Remove(OnDependencyDetailsLoaded);
355 
356  m_iDependencyDetailsLoadedCount++;
357 
358  // All details loaded
359  if (m_iDependencyDetailsLoadedCount == m_aDependencies.Count())
360  OnAllDependenciesDetailsLoaded();
361  }
362 
363  //------------------------------------------------------------------------------------------------
365  protected void OnDependencyPatchSizeLoadResponse(SCR_BackendCallbackWorkshopItem callback)
366  {
367  // Handle callback reponse
368  if (callback)
369  {
370  // Cleanup
371  callback.GetEventOnResponse().Remove(OnDependencyPatchSizeLoadResponse);
372 
373  if (callback.GetResponseType() != EBackendCallbackResponse.SUCCESS)
374  {
375  OnItemError(callback.GetItem());
376  return;
377  }
378 
379  float size;
380  callback.GetItem().GetDependency().GetRevision().GetPatchSize(size);
381  callback.GetItem().SetTargetRevisionPatchSize(size);
382  }
383 
384  m_iPatchesLoaded++;
385  CheckAllPatchSizeLoaded();
386  }
387 
388  //------------------------------------------------------------------------------------------------
389  protected void SetDependencySize(SCR_WorkshopItem item, float size)
390  {
391  item.SetTargetRevisionPatchSize(size);
392 
393  m_iPatchesLoaded++;
394  CheckAllPatchSizeLoaded();
395  }
396 
397  //------------------------------------------------------------------------------------------------
398  protected void CheckAllPatchSizeLoaded()
399  {
400  // All loaded
401  if (m_iPatchesLoaded == m_aDependencies.Count())
402  {
403  m_aPatchSizeCallbacks.Clear();
404  AllPatchSizeLoaded();
405  }
406 
407  // Check issues
408  if (m_OnDependenciesLoadingPrevented && !m_aDependenciesIssues.IsEmpty() && m_aDependencies.Count() == m_iPatchesLoaded + m_aDependenciesIssues.Count())
409  m_OnDependenciesLoadingPrevented.Invoke(this, m_aDependenciesIssues);
410  }
411 
412  //------------------------------------------------------------------------------------------------
413  protected void OnItemError(SCR_WorkshopItem item)
414  {
415  if (m_OnError)
416  m_OnError.Invoke(this);
417  }
418 
419  //------------------------------------------------------------------------------------------------
420  protected void OnItemTimeout(SCR_WorkshopItem item)
421  {
422  if (m_OnError)
423  m_OnError.Invoke(this);
424  }
425 
426  //------------------------------------------------------------------------------------------------
427  // Get set
428  //------------------------------------------------------------------------------------------------
429 
430  //------------------------------------------------------------------------------------------------
431  bool GetRestrictedAddons()
432  {
433  return m_bRestrictedAddons;
434  }
435 
436  //------------------------------------------------------------------------------------------------
437  bool GetBlockedAddons()
438  {
439  return m_bBlockedAddons;
440  }
441 
442  //------------------------------------------------------------------------------------------------
443  // Construct
444  //------------------------------------------------------------------------------------------------
445 
446  //------------------------------------------------------------------------------------------------
447  void ~SCR_DownloadSequence()
448  {
449  // Unsubscribe
450 
451  if (m_OnDestroyed)
452  m_OnDestroyed.Invoke(this);
453  }
454 }
m_OnDestroyed
protected ref ScriptInvokerEntity m_OnDestroyed
Definition: SCR_EditableCharacterComponent.c:25
SCR_DownloadSequence
Definition: SCR_DownloadSequence.c:19
SCR_BackendCallbackWorkshopItem
void SCR_BackendCallbackWorkshopItem(SCR_WorkshopItem item)
Definition: SCR_AddonPatchSizeLoader.c:149
SCR_WorkshopItemActionDownload
Definition: SCR_WorkshopItemActionDownload.c:9
func
func
Definition: SCR_AIThreatSystem.c:5
SCR_WorkshopItem
Definition: SCR_WorkshopItem.c:21
ScriptInvoker_DownloadSequence
func ScriptInvoker_DownloadSequence
Definition: SCR_DownloadSequence.c:12
m_aDependencies
protected ref array< ref SCR_WorkshopItem > m_aDependencies
Definition: SCR_ModDetailsSuperMenuComponent.c:10
SCR_ReportedAddonsDialog
Show list of reported mods and provide option to cancel reports.
Definition: SCR_ReportedAddonsDialog.c:3
SCR_AddonManager
Definition: SCR_AddonManager.c:72
EBackendCallbackResponse
EBackendCallbackResponse
Basic callback responses.
Definition: SCR_BackendCallback.c:12
ScriptInvoker_DownloadSequenceDependencies
func ScriptInvoker_DownloadSequenceDependencies
Definition: SCR_DownloadSequence.c:16
callback
DownloadConfigCallback callback
SCR_AddonListDialog
Shows a list of addons and some text.
Definition: SCR_WorkshopUiCommon.c:820
SCR_DownloadManager
Definition: SCR_DownloadManager.c:20
EWorkshopItemQuery
EWorkshopItemQuery
Definition: SCR_AddonManager.c:34