Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_ResourceSystemSubscriptionManager.c
Go to the documentation of this file.
2 {
3  static const int REPLICATION_MAX_FRAME_BUDGET = 10;
4  static const int GRACEFUL_HANDLES_MAX_FRAME_BUDGET = 10;
5 
6  protected ref SCR_ContainerBudgetManager<array<ref SCR_ResourceSystemSubscriptionListing>, SCR_ResourceSystemSubscriptionListing> m_ReplicationBudgetManager;
7  protected ref SCR_ContainerBudgetManager<array<ref SCR_ResourceSystemSubscriptionHandleBase>, SCR_ResourceSystemSubscriptionHandleBase> m_GracefulHandlesBudgetManager;
8  protected ref array<ref SCR_ResourceSystemSubscriptionListing> m_aListings = {};
9  protected ref array<SCR_ResourceSystemSubscriptionHandleBase> m_aHandles = {};
10  protected ref array<ref SCR_ResourceSystemSubscriptionHandleBase> m_aGracefulHandles = {};
11 
12  //------------------------------------------------------------------------------------------------
13  protected SCR_ResourceSystemSubscriptionListing GetListing(notnull SCR_ResourceInteractor interactor)
14  {
15  int higherLimitPosition = m_aListings.Count();
16 
17  if (higherLimitPosition == 0)
18  return null;
19 
20  int position;
22 
23  while (position < higherLimitPosition)
24  {
25  if (GetNextListingCandidate(position, higherLimitPosition, listing, interactor))
26  break;
27  }
28 
29  if (listing
30  && position == m_aListings.Count()
31  && listing.GetInteractor() != interactor)
32  return null;
33 
34  return listing;
35  }
36 
37  //------------------------------------------------------------------------------------------------
38  protected bool GetNextListingCandidate(inout int position, inout int higherLimitPosition, inout SCR_ResourceSystemSubscriptionListing listing, notnull SCR_ResourceInteractor interactor)
39  {
40  int comparePosition = position + ((higherLimitPosition - position) >> 1);
41  listing = m_aListings[comparePosition];
42 
43  if (!listing)
44  return false;
45 
46  SCR_ResourceInteractor compareInteractor = listing.GetInteractor();
47 
48  if (interactor > compareInteractor)
49  position = comparePosition + 1;
50  else if (interactor < compareInteractor)
51  higherLimitPosition = comparePosition;
52  else
53  {
54  listing = m_aListings[comparePosition];
55 
56  return true;
57  }
58 
59  listing = null;
60 
61  return false;
62  }
63 
64  //------------------------------------------------------------------------------------------------
65  SCR_ResourceSystemSubscriptionHandleBase GetHandle(RplId resourceComponentRplId, typename interactorType, EResourceType resourceType, EResourceGeneratorID resourceIdentifier)
66  {
67  int higherLimitPosition = m_aHandles.Count();
68 
69  if (higherLimitPosition == 0)
70  return null;
71 
72  int position;
74 
75  while (position < higherLimitPosition)
76  {
77  if (GetNextHandleCandidate(position, higherLimitPosition, handle, resourceComponentRplId, interactorType, resourceType, resourceIdentifier))
78  break;
79  }
80 
81  if (handle
82  && position == m_aHandles.Count()
83  && (handle.GetResourceComponentRplId() != resourceComponentRplId
84  || handle.GetInteractorType() != interactorType
85  || handle.GetResourceType() != resourceType
86  || handle.GetResourceIdentifier() != resourceIdentifier))
87  return null;
88 
89  return handle;
90  }
91 
92  //------------------------------------------------------------------------------------------------
93  protected bool GetNextHandleCandidate(inout int position, inout int higherLimitPosition, inout SCR_ResourceSystemSubscriptionHandleBase handle, RplId resourceComponentRplId, typename interactorType, EResourceType resourceType, EResourceGeneratorID resourceIdentifier)
94  {
95  int comparePosition = position + ((higherLimitPosition - position) >> 1);
96  handle = m_aHandles[comparePosition];
97 
98  if (!handle)
99  return false;
100 
101  RplId compareResourceComponentRplId = handle.GetResourceComponentRplId();
102  typename compareInteractorType = handle.GetInteractorType();
103  EResourceType compareResourceType = handle.GetResourceType();
104  EResourceGeneratorID compareResourceIdentifier = handle.GetResourceIdentifier();
105 
107  if (resourceComponentRplId > compareResourceComponentRplId)
108  position = comparePosition + 1;
109  else if (resourceComponentRplId < compareResourceComponentRplId)
110  higherLimitPosition = comparePosition;
111 
113  else if (interactorType.ToString() > compareInteractorType.ToString())
114  position = comparePosition + 1;
115  else if (interactorType.ToString() < compareInteractorType.ToString())
116  higherLimitPosition = comparePosition;
117 
119  else if (resourceType > compareResourceType)
120  position = comparePosition + 1;
121  else if (resourceType < compareResourceType)
122  higherLimitPosition = comparePosition;
123 
125  else if (resourceIdentifier > compareResourceIdentifier)
126  position = comparePosition + 1;
127  else if (resourceIdentifier < compareResourceIdentifier)
128  higherLimitPosition = comparePosition;
129 
131  else
132  {
133  handle = m_aHandles[comparePosition];
134 
135  return true;
136  }
137 
138  handle = null;
139 
140  return false;
141  }
142 
143  //------------------------------------------------------------------------------------------------
144  bool SubscribeListener(RplId listener, notnull SCR_ResourceInteractor interactor)
145  {
146  if (!listener.IsValid())
147  return false;
148 
149  SCR_ResourceSystemSubscriptionListing listing = GetListing(interactor);
150 
151  if (listing)
152  {
153  listing.SubscribeListener(listener);
154 
155  return true;
156  }
157 
158  int position;
159  int comparePosition;
160  int maxPosition = m_aListings.Count();
161  SCR_ResourceInteractor compareInteractor;
163 
164  while (position < maxPosition)
165  {
166  comparePosition = position + ((maxPosition - position) >> 1);
167  compareListing = m_aListings[comparePosition];
168  compareInteractor = compareListing.GetInteractor();
169 
170  if (interactor > compareInteractor)
171  position = comparePosition + 1;
172  else if (interactor < compareInteractor)
173  maxPosition = comparePosition;
174 
175  else
176  break;
177  }
178 
179  listing = new SCR_ResourceSystemSubscriptionListing(interactor);
180 
181  listing.SubscribeListener(listener);
182  m_aListings.InsertAt(listing, position);
183 
184  return true;
185  }
186 
187  //------------------------------------------------------------------------------------------------
188  bool UnsubscribeListener(RplId listener, notnull SCR_ResourceInteractor interactor)
189  {
190  if (!listener.IsValid())
191  return false;
192 
193  SCR_ResourceSystemSubscriptionListing listing = GetListing(interactor);
194 
195  if (!listing)
196  return false;
197 
198  listing.UnsubscribeListener(listener);
199 
200  if (listing.IsEmpty())
201  m_aListings.RemoveOrdered(m_aListings.Find(listing));
202 
203  return true;
204  }
205 
206  //------------------------------------------------------------------------------------------------
207  void UnsubscribeListenerCompletely(RplId listener)
208  {
209  if (!listener.IsValid())
210  return;
211 
213 
214  for (int i = m_aListings.Count() - 1; i >= 0; --i)
215  {
216  listing = m_aListings[i];
217 
218  if (!listing)
219  {
220  m_aListings.RemoveOrdered(i);
221 
222  continue;
223  }
224 
225  listing.UnsubscribeListener(listener)
226  }
227  }
228 
229  //------------------------------------------------------------------------------------------------
230  void ProcessGracefulHandles()
231  {
232  WorldTimestamp currentTime = GetGame().GetWorld().GetTimestamp();
233 
234  foreach (SCR_ResourceSystemSubscriptionHandleBase handle : m_GracefulHandlesBudgetManager.ProcessNextBatch())
235  {
240  if (!handle || currentTime.DiffMilliseconds(handle.GetLastPokedAt()) >= 10000)
241  m_aGracefulHandles.RemoveItem(handle);
242  }
243  }
244 
245  //------------------------------------------------------------------------------------------------
246  void ReplicateListeners()
247  {
248  foreach (SCR_ResourceSystemSubscriptionListing listing : m_ReplicationBudgetManager.ProcessNextBatch())
249  {
250  if (listing)
251  listing.Replicate();
252  else
257  m_aListings.RemoveItem(listing);
258  }
259  }
260 
261  //------------------------------------------------------------------------------------------------
262  SCR_ResourceSystemSubscriptionHandleBase RequestSubscriptionListenerHandle(notnull SCR_ResourceInteractor interactor, RplId ownerRplId)
263  {
264  if (!ownerRplId.IsValid())
265  return null;
266 
267  RplId resourceComponentRplId = Replication.FindId(interactor.GetComponent());
268 
269  if (!resourceComponentRplId.IsValid())
270  return null;
271 
272  typename interactorType = interactor.Type();
273  EResourceType resourceType = interactor.GetResourceType();
274  EResourceGeneratorID resourceIdentifier = interactor.GetIdentifier();
275 
276  SCR_ResourceSystemSubscriptionHandleBase handle = GetHandle(resourceComponentRplId, interactorType, resourceType, resourceIdentifier);
277 
278  if (handle)
279  return handle;
280 
281  int position;
282  int comparePosition;
283  int maxPosition = m_aHandles.Count();
285  RplId compareResourceComponentRplId;
286  typename compareInteractorType;
287  EResourceType compareResourceType;
288  EResourceGeneratorID compareResourceIdentifier;
289 
290  while (position < maxPosition)
291  {
292  comparePosition = position + ((maxPosition - position) >> 1);
293  compareHandle = m_aHandles[comparePosition];
294  compareResourceComponentRplId = compareHandle.GetResourceComponentRplId();
295  compareInteractorType = compareHandle.GetInteractorType();
296  compareResourceType = compareHandle.GetResourceType();
297  compareResourceIdentifier = compareHandle.GetResourceIdentifier();
298 
300  if (resourceComponentRplId > compareResourceComponentRplId)
301  position = comparePosition + 1;
302  else if (resourceComponentRplId < compareResourceComponentRplId)
303  maxPosition = comparePosition;
304 
306  else if (interactorType.ToString() > compareInteractorType.ToString())
307  position = comparePosition + 1;
308  else if (interactorType.ToString() < compareInteractorType.ToString())
309  maxPosition = comparePosition;
310 
312  else if (resourceType > compareResourceType)
313  position = comparePosition + 1;
314  else if (resourceType < compareResourceType)
315  maxPosition = comparePosition;
316 
318  else if (resourceIdentifier > compareResourceIdentifier)
319  position = comparePosition + 1;
320  else if (resourceIdentifier < compareResourceIdentifier)
321  maxPosition = comparePosition;
322 
323  else
324  break;
325  }
326 
327  handle = SCR_ResourceSystemSubscriptionHandleBase.CreateHandle(this, ownerRplId, resourceComponentRplId, interactorType, resourceType, resourceIdentifier);
328 
329  if (!handle)
330  return null;
331 
332  m_aHandles.InsertAt(handle, position);
333 
334  return handle;
335  }
336 
337  //------------------------------------------------------------------------------------------------
338  SCR_ResourceSystemSubscriptionHandleBase RequestSubscriptionListenerHandleGraceful(notnull SCR_ResourceInteractor interactor, RplId ownerRplId)
339  {
340  if (!ownerRplId.IsValid())
341  return null;
342 
343  RplId resourceComponentRplId = Replication.FindId(interactor.GetComponent());
344 
345  if (!resourceComponentRplId.IsValid())
346  return null;
347 
348  typename interactorType = interactor.Type();
349  EResourceType resourceType = interactor.GetResourceType();
350  EResourceGeneratorID resourceIdentifier = interactor.GetIdentifier();
351 
352  SCR_ResourceSystemSubscriptionHandleBase handle = GetHandle(resourceComponentRplId, interactorType, resourceType, resourceIdentifier);
353 
354  if (handle)
355  {
356  handle.Poke();
357 
358  return handle;
359  }
360 
361  int position;
362  int comparePosition;
363  int maxPosition = m_aHandles.Count();
365  RplId compareResourceComponentRplId;
366  typename compareInteractorType;
367  EResourceType compareResourceType;
368  EResourceGeneratorID compareResourceIdentifier;
369 
370  while (position < maxPosition)
371  {
372  comparePosition = position + ((maxPosition - position) >> 1);
373  compareHandle = m_aHandles[comparePosition];
374  compareResourceComponentRplId = compareHandle.GetResourceComponentRplId();
375  compareInteractorType = compareHandle.GetInteractorType();
376  compareResourceType = compareHandle.GetResourceType();
377  compareResourceIdentifier = compareHandle.GetResourceIdentifier();
378 
380  if (resourceComponentRplId > compareResourceComponentRplId)
381  position = comparePosition + 1;
382  else if (resourceComponentRplId < compareResourceComponentRplId)
383  maxPosition = comparePosition;
384 
386  else if (interactorType.ToString() > compareInteractorType.ToString())
387  position = comparePosition + 1;
388  else if (interactorType.ToString() < compareInteractorType.ToString())
389  maxPosition = comparePosition;
390 
392  else if (resourceType > compareResourceType)
393  position = comparePosition + 1;
394  else if (resourceType < compareResourceType)
395  maxPosition = comparePosition;
396 
398  else if (resourceIdentifier > compareResourceIdentifier)
399  position = comparePosition + 1;
400  else if (resourceIdentifier < compareResourceIdentifier)
401  maxPosition = comparePosition;
402 
403  else
404  break;
405  }
406 
407  handle = SCR_ResourceSystemSubscriptionHandleBase.CreateHandle(this, ownerRplId, resourceComponentRplId, interactorType, resourceType, resourceIdentifier);
408 
409  if (!handle)
410  return null;
411 
412  m_aHandles.InsertAt(handle, position);
413  m_aGracefulHandles.Insert(handle);
414  handle.Poke();
415 
416  return handle;
417  }
418 
419  //------------------------------------------------------------------------------------------------
420  void OnSubscriptionListenerHandleDeleted(notnull SCR_ResourceSystemSubscriptionHandleBase handle)
421  {
422  m_aHandles.RemoveOrdered(m_aHandles.Find(handle));
423 
424  if (m_aGracefulHandles.Contains(handle))
425  m_aGracefulHandles.RemoveItem(handle);
426  }
427 
428  //------------------------------------------------------------------------------------------------
429  void OnResourceInteractorDeleted(notnull SCR_ResourceInteractor interactor)
430  {
431  SCR_ResourceSystemSubscriptionListing listing = GetListing(interactor);
432 
433  if (!listing)
434  return;
435 
436  m_aListings.RemoveItem(listing);
437  }
438 
439  //------------------------------------------------------------------------------------------------
441  {
442  m_ReplicationBudgetManager = new SCR_ContainerBudgetManager<array<ref SCR_ResourceSystemSubscriptionListing>, SCR_ResourceSystemSubscriptionListing>(m_aListings, REPLICATION_MAX_FRAME_BUDGET);
443  m_GracefulHandlesBudgetManager = new SCR_ContainerBudgetManager<array<ref SCR_ResourceSystemSubscriptionHandleBase>, SCR_ResourceSystemSubscriptionHandleBase>(m_aGracefulHandles, GRACEFUL_HANDLES_MAX_FRAME_BUDGET);
444  }
445 }
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_ResourceSystemSubscriptionManager
Definition: SCR_ResourceSystemSubscriptionManager.c:1
EResourceType
EResourceType
Definition: SCR_ResourceContainer.c:1
SCR_ResourceSystemSubscriptionHandleBase
Definition: SCR_ResourceSystemSubscriptionHandleBase.c:1
position
vector position
Definition: SCR_DestructibleTreeV2.c:30
SCR_ResourceSystemSubscriptionListing
Definition: SCR_ResourceSystemSubscriptionListing.c:1
EResourceGeneratorID
EResourceGeneratorID
Definition: SCR_ResourceGenerator.c:1