Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_DownloadManager.c
Go to the documentation of this file.
1 /*
2 This entity is required for SCR_DownloadManager_Dialog to work.
3 
4 It performs tracking of current downloads, while the Dialog class just visualizes them when opened.
5 
6 !!! This entity relies on SCR_AddonManager, which also must be placed into the world.
7 */
8 
9 [EntityEditorProps(category: "", description: "Entity of the download manager. Most likely only needed in the main menu world.")]
10 class SCR_DownloadManagerClass: GenericEntityClass
11 {
12 };
13 
16 
19 
21 {
22  protected const int DOWNLOAD_STUCK_DELAY = 60; // Max time in which download needs to progress in seconds
23 
24  protected static SCR_DownloadManager s_Instance;
25 
26  // All download actions
27  protected ref array<ref SCR_DownloadManager_Entry> m_aDownloadActions = new array<ref SCR_DownloadManager_Entry>();
28 
29  // Download queue - it gets empty once all active downloads are complete, but keeps added up if new downloads are started
30  // While previous are in progress.
31  // This is mainly used by the panel.
32  protected ref array<ref SCR_WorkshopItemActionDownload> m_aDownloadQueue = new array<ref SCR_WorkshopItemActionDownload>;
33  protected int m_iQueueDownloadsCompleted; // Amount of completed downloads in the queue
34 
35  protected float m_fNoDownloadProgressTimer = 0; // Track how long there was no progress on downloading until stuck delay
36  protected float m_fDownloadQueueSize;
37  protected float m_fDownloadedSize;
38 
39  // Bool to pause all downloads
40  protected bool m_bDownloadsPaused;
41 
42  protected const int FAIL_TIME = 500;
43  protected ref array<ref SCR_WorkshopItemActionDownload> m_aFailedDownloads = {};
44 
47  ref ScriptInvoker m_OnNewDownload = new ScriptInvoker; // (SCR_WorkshopItem item, SCR_WorkshopItemActionDownload action)
48 
49  protected ref ScriptInvoker<> Event_OnDownloadFail;
50  ref ScriptInvokerBase<ScriptInvoker_DownloadManagerAction> m_OnDownloadComplete = new ScriptInvokerBase<ScriptInvoker_DownloadManagerAction>();
51  ref ScriptInvokerBase<ScriptInvoker_DownloadManagerActionError> m_OnDownloadFailed = new ScriptInvokerBase<ScriptInvoker_DownloadManagerActionError>();
52  protected ref ScriptInvokerBase<ScriptInvoker_ActionDownloadFullStorage> m_OnFullStorageError;
53  ref ScriptInvokerBase<ScriptInvoker_DownloadManagerAction> m_OnDownloadCanceled = new ScriptInvokerBase<ScriptInvoker_DownloadManagerAction>();
54  protected ref ScriptInvokerVoid m_OnDownloadQueueCompleted
55  protected ref ScriptInvokerVoid m_OnAllDownloadsStopped;
56 
57  //------------------------------------------------------------------------------------------------
58  void InvokeEventOnDownloadFail()
59  {
60  if (Event_OnDownloadFail)
61  Event_OnDownloadFail.Invoke();
62  }
63 
64  //------------------------------------------------------------------------------------------------
65  ScriptInvoker GetEventOnDownloadFail()
66  {
67  if (!Event_OnDownloadFail)
68  Event_OnDownloadFail = new ScriptInvoker();
69 
70  return Event_OnDownloadFail;
71  }
72 
73  //------------------------------------------------------------------------------------------------
74  ScriptInvokerBase<ScriptInvoker_ActionDownloadFullStorage> GetOnFullStorageError()
75  {
76  if (!m_OnFullStorageError)
77  m_OnFullStorageError = new ScriptInvokerBase<ScriptInvoker_ActionDownloadFullStorage>();
78 
79  return m_OnFullStorageError;
80  }
81 
82  //-----------------------------------------------------------------------------------------------
83  ScriptInvokerVoid GetOnDownloadQueueCompleted()
84  {
85  if (!m_OnDownloadQueueCompleted)
86  m_OnDownloadQueueCompleted = new ScriptInvokerVoid();
87 
88  return m_OnDownloadQueueCompleted;
89  }
90 
91  //-----------------------------------------------------------------------------------------------
92  ScriptInvokerVoid GetOnAllDownloadsStopped()
93  {
94  if (!m_OnAllDownloadsStopped)
95  m_OnAllDownloadsStopped = new ScriptInvokerVoid();
96 
97  return m_OnAllDownloadsStopped;
98  }
99 
100  //-----------------------------------------------------------------------------------------------
101  // P U B L I C A P I
102  //-----------------------------------------------------------------------------------------------
103 
104 
105  //-----------------------------------------------------------------------------------------------
106  static SCR_DownloadManager GetInstance()
107  {
108  return s_Instance;
109  }
110 
111  //-----------------------------------------------------------------------------------------------
113  void GetAllDownloads(array<ref SCR_DownloadManager_Entry> downloads)
114  {
115  downloads.Clear();
116 
117  foreach (auto dl : m_aDownloadActions)
118  downloads.Insert(dl);
119  }
120 
121 
122  //-----------------------------------------------------------------------------------------------
124  void GetDownloadQueueState(out int nCompleted, out int nTotal)
125  {
126  nTotal = m_aDownloadQueue.Count();
127  nCompleted = m_iQueueDownloadsCompleted;
128  }
129 
130  //-----------------------------------------------------------------------------------------------
131  bool HasRunningDownloads()
132  {
133  return !m_aDownloadQueue.IsEmpty();
134  }
135 
136  //-----------------------------------------------------------------------------------------------
138  SCR_WorkshopItemActionDownload DownloadingActionAddonById(string id, bool runningOnly = true)
139  {
140  foreach (SCR_WorkshopItemActionDownload download : m_aDownloadQueue)
141  {
142  if (download.m_Wrapper.GetId() != id)
143  continue;
144 
145  if (runningOnly && download.IsActive() && !download.IsCompleted() && !download.IsFailed() && !download.IsCanceled())
146  return download;
147  }
148 
149  return null;
150  }
151 
152  //-----------------------------------------------------------------------------------------------
153  array<ref SCR_WorkshopItemActionDownload> GetDownloadQueue()
154  {
155  array<ref SCR_WorkshopItemActionDownload> downloads = {};
156 
157  if (!m_aDownloadQueue)
158  return downloads;
159 
160  foreach (auto i : m_aDownloadQueue)
161  downloads.Insert(i);
162 
163  return downloads;
164  }
165 
166  //-----------------------------------------------------------------------------------------------
169  {
170  foreach (SCR_DownloadManager_Entry entry : m_aDownloadActions)
171  {
172  if (entry.m_Item == item)
173  return entry.m_Action;
174  }
175 
176  return null;
177  }
178 
179  //-----------------------------------------------------------------------------------------------
183  void SetDownloadsPaused(bool pause, int count = -1)
184  {
185  if (pause == m_bDownloadsPaused)
186  return;
187 
188  m_bDownloadsPaused = pause;
189 
190  // Setup calls count
191  if (count == -1)
192  count = m_aDownloadQueue.Count() - 1;
193 
194  // Paseu/resume
195  PauseAction(m_aDownloadQueue[count], pause);
196 
197  // Late call
198  if (count > 0)
199  GetGame().GetCallqueue().CallLater(SetDownloadsPaused, 0, false, pause, count - 1);
200  }
201 
202  //-----------------------------------------------------------------------------------------------
203  protected void PauseAction(SCR_WorkshopItemActionDownload action, bool pause)
204  {
205  // Pause
206  if (pause)
207  {
208  if (action.IsActive())
209  action.Pause();
210 
211  return;
212  }
213 
214  // Resume
215  if (action.IsPaused())
216  action.Resume();
217  else if (action.IsInactive())
218  action.Activate();
219  }
220 
221  //-----------------------------------------------------------------------------------------------
222  bool GetDownloadsPaused()
223  {
224  return m_bDownloadsPaused;
225  }
226 
227 
228  //-----------------------------------------------------------------------------------------------
232  void EndAllDownloads()
233  {
234  foreach (SCR_WorkshopItemActionDownload a : m_aDownloadQueue)
235  {
236  a.Cancel();
237  }
238  }
239 
240  //-----------------------------------------------------------------------------------------------
241  // Given an array of required items, returns all those queued items that are outside of it, including mismatching versions
242  array<ref SCR_WorkshopItemActionDownload> GetUnrelatedDownloads(array<ref SCR_WorkshopItem> requiredItems)
243  {
244  array<ref SCR_WorkshopItemActionDownload> unrelatedDownloads = {};
245 
246  foreach (SCR_WorkshopItemActionDownload action : m_aDownloadQueue)
247  {
248  if (!IsDownloadingActionRequired(action, requiredItems))
249  unrelatedDownloads.Insert(action);
250  }
251 
252  return unrelatedDownloads;
253  }
254 
255  //-----------------------------------------------------------------------------------------------
256  // Given an array of required items, returns true if the input action's item is part of it and is the correct version
257  bool IsDownloadingActionRequired(SCR_WorkshopItemActionDownload action, array<ref SCR_WorkshopItem> requiredItems)
258  {
259  SCR_WorkshopItem item = action.GetWorkshopItem();
260  if (!item)
261  return true;
262 
263  bool required;
264  bool sameId;
265  bool sameVersion;
266 
267  foreach (SCR_WorkshopItem requiredItem : requiredItems)
268  {
269  sameId = requiredItem.GetId() == item.GetId();
270  sameVersion = requiredItem.GetDependency().GetVersion() == action.GetTargetRevision().GetVersion();
271  required = sameId && sameVersion;
272 
273  if (required)
274  return true;
275  }
276 
277  return false;
278  }
279 
280  // --- Helper functions for generic download functionality ---
281 
282  //-----------------------------------------------------------------------------------------------
286  static bool IsLatestDownloadRequired(SCR_WorkshopItem item)
287  {
288  if (!item.GetOffline())
289  return true;
290 
291  Revision latestRevision = item.GetLatestRevision();
292  Revision targetRevision;
293  bool downloading, paused;
294  float progress;
295  item.GetDownloadState(downloading, paused, progress, targetRevision);
296 
297  if (!downloading)
298  {
299  return !Revision.AreEqual(item.GetCurrentLocalRevision(), latestRevision);
300  }
301  else
302  {
303  // We are already downloading this, but what versoin?
304  if (Revision.AreEqual(item.GetLatestRevision(), targetRevision))
305  return false; // Already downloading this version, no need to start a new download
306  else
307  return true; // Downloading a different version, we must download another one
308  }
309  }
310 
311 
312  //-----------------------------------------------------------------------------------------------
313  static void SelectAddonsForLatestDownload(array<ref SCR_WorkshopItem> arrayIn, array<ref SCR_WorkshopItem> arrayOut)
314  {
315  foreach (SCR_WorkshopItem addon : arrayIn)
316  {
317  if (IsLatestDownloadRequired(addon))
318  arrayOut.Insert(addon);
319  }
320  }
321 
322  //-----------------------------------------------------------------------------------------------
326  array<ref SCR_WorkshopItemAction> DownloadLatestWithDependencies(notnull SCR_WorkshopItem mainItem, bool downloadMainItem, array<ref SCR_WorkshopItem> dependencies)
327  {
328  array<ref SCR_WorkshopItemAction> actions = {};
329 
330  if (IsLatestDownloadRequired(mainItem) && downloadMainItem)
331  {
332  auto actionMain = mainItem.DownloadLatestVersion();
333  if (actionMain)
334  {
335  actions.Insert(actionMain);
336  if (!m_bDownloadsPaused)
337  actionMain.Activate();
338  }
339  }
340 
341  if (dependencies)
342  {
343  if (dependencies.Count() > 0)
344  {
345  auto actionDependencies = mainItem.DownloadDependenciesLatest(dependencies);
346  if (actionDependencies)
347  {
348  if (!m_bDownloadsPaused)
349  actionDependencies.Activate();
350 
351  actions.Insert(actionDependencies);
352  }
353  }
354  }
355 
356  return actions;
357  }
358 
359  //-----------------------------------------------------------------------------------------------
360 
361  //-----------------------------------------------------------------------------------------------
364  array<ref SCR_WorkshopItemActionDownload> DownloadItems(array<ref SCR_WorkshopItem> items)
365  {
366  array<ref SCR_WorkshopItemActionDownload> actions = {};
367 
368  for (int i = 0, count = items.Count(); i < count; i++)
369  {
370  Revision target = items[i].GetItemTargetRevision();
371 
372  if (!target)
373  target = items[i].GetDependency().GetRevision();
374 
375  if (!target)
376  {
377  return null;
378  }
379 
380  // Create download action from dependency and depdency revision
381  SCR_WorkshopItemActionDownload action = items[i].Download(target);
382  actions.Insert(action);
383  action.Activate();
384  }
385 
386  return actions;
387  }
388 
389  //-----------------------------------------------------------------------------------------------
392  void DownloadDependecies(array<Dependency> dependencies)
393  {
394  for (int i = 0, count = dependencies.Count(); i < count; i++)
395  {
396  SCR_WorkshopItem item = SCR_WorkshopItem.Internal_CreateFromDependency(dependencies[i]);
397 
398  // Create download action from dependency and depdency revision
399  SCR_WorkshopItemActionDownload action = item.Download(dependencies[i].GetRevision());
400  action.Activate();
401  }
402  }
403 
404  //-----------------------------------------------------------------------------------------------
405  static float GetTotalSizeBytes(array<ref SCR_WorkshopItem> arrayIn, SCR_WorkshopItem extraItem = null)
406  {
407  float sizeOut = 0;
408 
409  foreach (SCR_WorkshopItem addon : arrayIn)
410  {
411  float s = addon.GetTargetRevisionPatchSize();
412  sizeOut += s;
413  }
414 
415  if (extraItem)
416  {
417  float s = extraItem.GetTargetRevisionPatchSize();
418  sizeOut += s;
419  }
420 
421  return sizeOut;
422  }
423 
424  //-----------------------------------------------------------------------------------------------
425  protected float DownloadQueueSize()
426  {
427  array<ref SCR_WorkshopItem> downloading = {};
428  for (int i = 0, count = m_aDownloadQueue.Count(); i < count; i++)
429  {
430  downloading.Insert(m_aDownloadQueue[i].m_Wrapper);
431  }
432 
433  return GetTotalSizeBytes(downloading);
434  }
435 
436  //-----------------------------------------------------------------------------------------------
438  static float GetDownloadActionsProgress(array<ref SCR_WorkshopItemActionDownload> actions)
439  {
440  float totalSizeBytes = 0;
441  float totalBytesDownloaded = 0;
442 
443  foreach (SCR_WorkshopItemActionDownload dl : actions)
444  {
445  float dlsize = dl.GetSizeBytes();
446  totalSizeBytes += dlsize;
447  totalBytesDownloaded += dl.GetProgress() * dlsize;
448  }
449 
450  if (totalSizeBytes == 0) // Don't divide by 0
451  return 0;
452 
453  float progress = totalBytesDownloaded / totalSizeBytes;
454  return progress;
455  }
456 
457  //-----------------------------------------------------------------------------------------------
459  static float GetItemDownloadActionsProgress(SCR_WorkshopItem item)
460  {
461  // Create an array of all download actions started from this tile
462  // Get their aggregated progress
463 
464  auto actionThisItem = item.GetDownloadAction(); // Action for downloading this item
465  auto actionDependencies = item.GetDependencyCompositeAction(); // Action for downloading dependencies
466 
467  array<ref SCR_WorkshopItemAction> allActions;
468  if (actionDependencies)
469  allActions = actionDependencies.GetActions();
470  else
471  allActions = new array<ref SCR_WorkshopItemAction>;
472 
473  if (actionThisItem)
474  allActions.Insert(actionThisItem);
475 
476  // Cast all actions to download actions...
477  auto allDownloadActions = new array<ref SCR_WorkshopItemActionDownload>;
478  foreach (auto a : allActions)
479  {
480  auto downloadAction = SCR_WorkshopItemActionDownload.Cast(a);
481  if (downloadAction)
482  allDownloadActions.Insert(downloadAction);
483  }
484 
485  float progress = SCR_DownloadManager.GetDownloadActionsProgress(allDownloadActions);
486 
487  return progress;
488  }
489 
490  //-----------------------------------------------------------------------------------------------
491  array<ref SCR_WorkshopItemActionDownload> GetFailedDownloads()
492  {
493  array<ref SCR_WorkshopItemActionDownload> actions = {};
494  for (int i = 0, count = m_aFailedDownloads.Count(); i < count; i++)
495  {
496  actions.Insert(m_aFailedDownloads[i]);
497  }
498 
499  return actions;
500  }
501 
502  //-----------------------------------------------------------------------------------------------
503  void ClearFailedDownloads()
504  {
505  m_aFailedDownloads.Clear();
506  }
507 
508  //-----------------------------------------------------------------------------------------------
509  void AddDownloadManagerEntry(notnull SCR_WorkshopItem item, notnull SCR_WorkshopItemActionDownload action)
510  {
511  RemoveSameAddonFromDownloads(item);
512 
513  SCR_DownloadManager_Entry entry = new SCR_DownloadManager_Entry(item, action);
514  m_aDownloadActions.Insert(entry);
515  }
516 
517  //-----------------------------------------------------------------------------------------------
520  protected void RemoveSameAddonFromDownloads(notnull SCR_WorkshopItem item)
521  {
522  // Release download actions
523  for (int i = 0, count = m_aDownloadActions.Count(); i < count; i++)
524  {
525  // Same addon ids?
526  if (m_aDownloadActions[i].m_Item.GetId() == item.GetId())
527  {
528  m_aDownloadActions.Remove(i);
529  break;
530  }
531  }
532 
533  // Release download queue
534  for (int i = 0, count = m_aDownloadQueue.Count(); i < count; i++)
535  {
536  // Same addon ids?
537  if (m_aDownloadQueue[i].m_Wrapper.GetId() == item.GetId())
538  {
539  m_aDownloadQueue.Remove(i);
540  break;
541  }
542  }
543  }
544 
545  //-----------------------------------------------------------------------------------------------
546  float GetDownloadQueueSize()
547  {
548  return m_fDownloadQueueSize;
549  }
550 
551  //-----------------------------------------------------------------------------------------------
552  float GetDownloadedSize()
553  {
554  return m_fDownloadedSize;
555  }
556 
557  //-----------------------------------------------------------------------------------------------
558  //-----------------------------------------------------------------------------------------------
559  //-----------------------------------------------------------------------------------------------
560 
561 
562 
563 
564 
565 
566 
567 
568  //-----------------------------------------------------------------------------------------------
569  // P R O T E C T E D / P R I V A T E
570  //-----------------------------------------------------------------------------------------------
571 
572 
573 
574  //-----------------------------------------------------------------------------------------------
575  override void EOnFrame(IEntity owner, float timeSlice)
576  {
577  int pausedCount = 0;
578 
579  // Remove failed or canceled actions from the download queue
580  for (int i = m_aDownloadQueue.Count() - 1; i >= 0; i--)
581  {
582  SCR_WorkshopItemActionDownload action = m_aDownloadQueue[i];
583 
584  if (action.IsCanceled() || action.IsFailed())
585  ClearUnfinishedAction(action);
586  else if (action.IsPaused())
587  pausedCount++;
588  }
589 
590  // Restart no progress timer check
591  if (pausedCount == m_aDownloadQueue.Count())
592  {
593  m_fNoDownloadProgressTimer = 0;
594  }
595 
596  // If all are completed, clear the queue entirely
597  // And reset 'all downloads paused' state.
598  if (!m_aDownloadQueue.IsEmpty() && m_iQueueDownloadsCompleted == m_aDownloadQueue.Count())
599  {
600  m_aDownloadQueue.Clear();
601  m_iQueueDownloadsCompleted = 0;
602  m_fDownloadedSize = 0;
603  m_bDownloadsPaused = false;
604 
605  if (m_OnDownloadQueueCompleted)
606  m_OnDownloadQueueCompleted.Invoke();
607 
608  m_fNoDownloadProgressTimer = 0;
609  }
610 
611  /*
612  else
613  {
614  // Increase time from last download progress
615  m_fNoDownloadProgressTimer += timeSlice;
616 
617  // Quit downloads if nothing is progressing
618  if (m_fNoDownloadProgressTimer >= DOWNLOAD_STUCK_DELAY)
619  {
620  // TODO: Display error if no progress for 1 min istead of force fail
621  }
622  }
623  */
624  }
625 
626  //-----------------------------------------------------------------------------------------------
627  override void EOnInit(IEntity owner)
628  {
629  SCR_AddonManager addonManager = SCR_AddonManager.GetInstance();
630 
631  if (!addonManager)
632  {
633  Print("SCR_DownloadManager_Entity: SCR_AddonManager was not found. It must be placed in the world for download manager to work.", LogLevel.ERROR);
634  return;
635  }
636 
637  addonManager.m_OnNewDownload.Insert(Callback_OnNewDownload);
638  }
639 
640  //-----------------------------------------------------------------------------------------------
644  protected void Callback_OnNewDownload(SCR_WorkshopItem item, SCR_WorkshopItemActionDownload action)
645  {
646  #ifdef WORKSHOP_DEBUG
647  Revision rev = action.GetTargetRevision();
648  if (rev)
649  _print(string.Format("Callback_OnNewDownloadStarted: %1, %2", item.GetName(), action.GetTargetRevision().GetVersion()));
650  else
651  _print(string.Format("Callback_OnNewDownloadStarted: %1", item.GetName()));
652  #endif
653 
654  RemoveSameAddonFromDownloads(item);
655 
656  // Create a new entry
657  SCR_DownloadManager_Entry entry = new SCR_DownloadManager_Entry(item, action);
658  m_aDownloadActions.Insert(entry);
659 
660  // Add the action to the queue
661  m_aDownloadQueue.Insert(action);
662  m_fDownloadQueueSize = DownloadQueueSize();
663 
664  m_OnNewDownload.Invoke(item, action);
665 
666  action.GetOnDownloadProgress().Insert(OnDownloadProgress);
667  action.m_OnCompleted.Insert(Callback_OnDownloadCompleted);
668  action.m_OnFailed.Insert(Callback_OnFailed);
669  action.GetOnFullStorageError().Insert(Callback_OnFullStorageError);
670  action.m_OnCanceled.Insert(Callback_OnCanceled);
671 
672  m_fNoDownloadProgressTimer = 0;
673  }
674 
675  //-----------------------------------------------------------------------------------------------
676  protected void OnDownloadProgress(SCR_WorkshopItemActionDownload action, float progressSize)
677  {
678  m_fDownloadedSize += progressSize;
679 
680  // Restart progress timer
681  m_fNoDownloadProgressTimer = 0;
682  }
683 
684  //-----------------------------------------------------------------------------------------------
686  protected void Callback_OnDownloadCompleted(SCR_WorkshopItemActionDownload action)
687  {
688  // Check user's settings if we need to enable the addon automatically
689  // Ignore this if it was an update of an addon
691  if (settings.m_bAutoEnableDownloadedAddons && !action.GetUpdate())
692  {
693  SCR_WorkshopItem item = action.GetWorkshopItem();
694 
695  if (!item)
696  return;
697 
698  item.SetEnabled(true);
699  }
700 
701  // Invoke for UI
702  m_iQueueDownloadsCompleted++;
703  m_OnDownloadComplete.Invoke(action);
704  }
705 
706  protected const int ERROR_FULL_STORAGE = 19;
707 
708  //-----------------------------------------------------------------------------------------------
710  protected void Callback_OnFailed(SCR_WorkshopItemActionDownload action, int reason)
711  {
712  m_aFailedDownloads.Insert(action);
713 
714  if (!SCR_DownloadManager_Dialog.IsOpened())
716 
717  // Prevent error on full storage error
718  if (reason == ERROR_FULL_STORAGE)
719  return;
720 
721  // Generic error
722  m_OnDownloadFailed.Invoke(action, reason);
723  }
724 
725  //-----------------------------------------------------------------------------------------------
727  protected void Callback_OnFullStorageError(SCR_WorkshopItemActionDownload action, float size)
728  {
729  if (m_OnFullStorageError)
730  m_OnFullStorageError.Invoke(action, size);
731  }
732 
733  //-----------------------------------------------------------------------------------------------
734  protected void Callback_OnCanceled(SCR_WorkshopItemActionDownload action)
735  {
736  m_aFailedDownloads.Insert(action);
737  m_OnDownloadCanceled.Invoke(action);
738  }
739 
740  //-----------------------------------------------------------------------------------------------
742  protected void ForceFailRunningDownloads()
743  {
744  for (int i = 0, count = m_aDownloadQueue.Count(); i < count; i++)
745  {
746  m_aDownloadQueue[i].ForceFail();
747  }
748  }
749 
750  //-----------------------------------------------------------------------------------------------
752  void DownloadAddons(array<ref SCR_WorkshopItem> items)
753  {
754  SCR_DownloadSequence sequence = SCR_DownloadSequence.Create(items, null, true);
755  sequence.GetOnReady().Insert(OnDownloadAddonsReady);
756  sequence.Init();
757 
758  /*
759  array<ref SCR_WorkshopItem> offline = SCR_AddonManager.GetInstance().GetOfflineAddons();
760  array<SCR_WorkshopItem> unfinished = {};
761 
762  // Filter out unfinished
763  foreach (SCR_WorkshopItem item : offline)
764  {
765  bool inProgress, paused;
766  int progress;
767  Revision targetRevision;
768 
769  item.GetDownloadState(inProgress, paused, progress, targetRevision);
770  Print("item: " + item.GetName());
771  Print("in progress: " + inProgress);
772  Print("----------------------------------");
773 
774  //Print("item: " + item.GetDownloadState());
775  //if (offline.ge)
776  }
777  */
778  }
779 
780  //-----------------------------------------------------------------------------------------------
781  protected void OnDownloadAddonsReady(SCR_DownloadSequence sequence)
782  {
783  sequence.GetOnReady().Remove(OnDownloadAddonsReady);
784  //sequence.
785  }
786 
787  //-----------------------------------------------------------------------------------------------
788  protected void ClearUnfinishedAction(SCR_WorkshopItemActionDownload action)
789  {
790  m_aDownloadQueue.RemoveItem(action);
791 
792  // Remove canceled and failed from size count
793  m_fDownloadQueueSize = Math.Clamp(m_fDownloadQueueSize - action.GetDownloadSize(), 0, float.MAX);
794  m_fDownloadedSize = Math.Clamp(m_fDownloadedSize - action.GetDownloadSize(), 0, float.MAX);
795 
796  if (m_OnAllDownloadsStopped && m_aDownloadQueue.IsEmpty())
797  m_OnAllDownloadsStopped.Invoke();
798  }
799 
800  //-----------------------------------------------------------------------------------------------
801  private void SCR_DownloadManager(IEntitySource src, IEntity parent)
802  {
803  SetEventMask( EntityEvent.FRAME | EntityEvent.INIT);
804  SetFlags(EntityFlags.NO_TREE | EntityFlags.NO_LINK);
805 
806  s_Instance = this;
807  }
808 
809  //-----------------------------------------------------------------------------------------------
810  private void ~SCR_DownloadManager()
811  {
812  s_Instance = null;
813  }
814 
815 
816  //-----------------------------------------------------------------------------------------------
817  //-----------------------------------------------------------------------------------------------
818  //-----------------------------------------------------------------------------------------------
819 
820 
821  //------------------------------------------------------------------------------------------------
822  void _print(string str, LogLevel logLevel = LogLevel.DEBUG)
823  {
824  Print(string.Format("[SCR_DownloadManager] %1 %2", this, str), logLevel);
825  }
826 };
827 
828 
829 //------------------------------------------------------------------------------------------------
832 {
833  ref SCR_WorkshopItem m_Item; // We hold strong refs to both item and action!
834  ref SCR_WorkshopItemActionDownload m_Action;
835 
836  //------------------------------------------------------------------------------------------------
838  {
839  m_Item = item;
840  m_Action = action;
841  }
842 };
843 
844 //------------------------------------------------------------------------------------------------
847 {
852 };
ScriptInvoker_DownloadManagerActionError
func ScriptInvoker_DownloadManagerActionError
Definition: SCR_DownloadManager.c:18
EDownloadManagerActionState
EDownloadManagerActionState
Enum describing current state of downloading action.
Definition: SCR_DownloadManager.c:846
EntityEditorProps
enum EQueryType EntityEditorProps(category:"GameScripted/Sound", description:"THIS IS THE SCRIPT DESCRIPTION.", color:"0 0 255 255")
Definition: SCR_AmbientSoundsComponent.c:12
SCR_DownloadSequence
Definition: SCR_DownloadSequence.c:19
m_Item
NewsFeedItem m_Item
Definition: SCR_NewsSubMenu.c:2
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_WorkshopItemActionDownload
Definition: SCR_WorkshopItemActionDownload.c:9
GenericEntity
SCR_GenericBoxEntityClass GenericEntity
func
func
Definition: SCR_AIThreatSystem.c:5
SCR_WorkshopItem
Definition: SCR_WorkshopItem.c:21
SCR_WorkshopSettings
Definition: SCR_WorkshopSettings.c:5
INACTIVE
@ INACTIVE
Definition: SCR_DownloadManager.c:848
s_Instance
SCR_SpawnerSlotManagerClass s_Instance
Class used for managing changes and removals of slots present in world.
SCR_DownloadManagerClass
Definition: SCR_DownloadManager.c:10
DOWNLOADED
@ DOWNLOADED
Definition: SCR_DownloadManager.c:851
SCR_DownloadManager_Entry
Helper class to store current downloads and their attributes.
Definition: SCR_DownloadManager.c:831
FAILED
@ FAILED
Definition: SCR_DownloadManager.c:850
ScriptInvokerVoid
ScriptInvokerBase< ScriptInvokerVoidMethod > ScriptInvokerVoid
Definition: SCR_ScriptInvokerHelper.c:9
SCR_DownloadManager_Dialog
void SCR_DownloadManager_Dialog()
Definition: SCR_DownloadManager_Dialog.c:491
SCR_AddonManager
Definition: SCR_AddonManager.c:72
RUNNING
@ RUNNING
Definition: SCR_DownloadManager.c:849
SCR_DownloadManager
Definition: SCR_DownloadManager.c:20
ScriptInvoker_DownloadManagerAction
func ScriptInvoker_DownloadManagerAction
Definition: SCR_DownloadManager.c:15
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180