rainprocurementhandler.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. class RainProcurementHandler : Managed
  2. {
  3. protected MissionBaseWorld m_Mission;
  4. protected ref set<RainProcurementComponentBase> m_ActiveComponents;
  5. protected ref set<RainProcurementComponentBase> m_ChangedQueue;
  6. protected ref set<int> m_CleanupQueue;
  7. protected const int UPDATE_BATCH_SIZE = 20; //Tweak this to adjust max batch size
  8. const int UPDATE_TIME = 10; //seconds
  9. protected bool m_Update;
  10. protected bool m_ProcessComponents;
  11. protected bool m_ProcessingFinished;
  12. protected int m_NextToProcessIdx;
  13. protected float m_UpdateTimer;
  14. protected float m_LiquidAmountCoef;
  15. void RainProcurementHandler(MissionBaseWorld mission)
  16. {
  17. m_Mission = mission;
  18. m_Update = false;
  19. m_ProcessComponents = false;
  20. m_ProcessingFinished = true;
  21. m_ActiveComponents = new set<RainProcurementComponentBase>;
  22. m_ChangedQueue = new set<RainProcurementComponentBase>;
  23. m_CleanupQueue = new set<int>;
  24. m_NextToProcessIdx = 0;
  25. m_UpdateTimer = 0;
  26. }
  27. void QueueStart(RainProcurementComponentBase component)
  28. {
  29. m_ChangedQueue.Insert(component);
  30. m_Update = true;
  31. }
  32. void QueueStop(RainProcurementComponentBase component)
  33. {
  34. m_ChangedQueue.Insert(component);
  35. m_Update = true;
  36. }
  37. void Update(float timeslice)
  38. {
  39. if (!m_Update)
  40. return;
  41. if (m_ProcessComponents)
  42. {
  43. if (m_ProcessingFinished) //do on start and after the batch is finished
  44. {
  45. m_LiquidAmountCoef = DetermineAmountCoef();
  46. if (m_LiquidAmountCoef == 0) //skip processing when not raining
  47. {
  48. Reset();
  49. return;
  50. }
  51. }
  52. m_ProcessingFinished = ProcessBatch();
  53. if (m_ProcessingFinished)
  54. {
  55. Reset();
  56. }
  57. }
  58. else
  59. {
  60. m_UpdateTimer += timeslice;
  61. if (m_UpdateTimer >= UPDATE_TIME)
  62. {
  63. HandleChangedComponents();
  64. Cleanup();
  65. CheckUpdating();
  66. m_ProcessComponents = m_Update;
  67. if (!m_Update)
  68. Reset();
  69. }
  70. }
  71. }
  72. //! returns 'true' when all the batches are finished
  73. protected bool ProcessBatch()
  74. {
  75. bool ret = false;
  76. int count = m_ActiveComponents.Count();
  77. int target = (int)Math.Clamp(m_NextToProcessIdx + UPDATE_BATCH_SIZE,0,count);
  78. for (m_NextToProcessIdx; m_NextToProcessIdx < target; m_NextToProcessIdx++)
  79. {
  80. if (m_ActiveComponents[m_NextToProcessIdx])
  81. m_ActiveComponents[m_NextToProcessIdx].OnUpdate(m_UpdateTimer, m_LiquidAmountCoef);
  82. else
  83. m_CleanupQueue.Insert(m_NextToProcessIdx);
  84. }
  85. ret = target == count;
  86. if (ret)
  87. {
  88. m_NextToProcessIdx = 0;
  89. }
  90. return ret;
  91. }
  92. protected void Cleanup()
  93. {
  94. int count = m_CleanupQueue.Count();
  95. if (count == 0)
  96. return;
  97. for (int i = count - 1; i > -1; i--)
  98. {
  99. m_ActiveComponents.Remove(m_CleanupQueue[i]);
  100. }
  101. m_CleanupQueue.Clear();
  102. }
  103. protected void Reset()
  104. {
  105. m_ProcessComponents = false;
  106. m_ProcessingFinished = true;
  107. m_UpdateTimer = 0;
  108. }
  109. protected void HandleChangedComponents()
  110. {
  111. RainProcurementComponentBase component;
  112. int count = m_ChangedQueue.Count();
  113. int idx;
  114. for (int i = 0; i < count; i++)
  115. {
  116. component = m_ChangedQueue[i];
  117. if (!component)
  118. continue;
  119. if (component.IsActive())
  120. {
  121. m_ActiveComponents.Insert(component);
  122. }
  123. else
  124. {
  125. idx = m_ActiveComponents.Find(component);
  126. if (idx != -1)
  127. m_ActiveComponents.Remove(idx);
  128. }
  129. }
  130. m_ChangedQueue.Clear();
  131. }
  132. protected void CheckUpdating()
  133. {
  134. m_Update = m_ActiveComponents.Count() != 0;
  135. }
  136. float GetLiquidAmountCoef()
  137. {
  138. return m_LiquidAmountCoef;
  139. }
  140. //! scalable on handler level. Now also handles SNOW, total value can exceed 1.0
  141. float DetermineAmountCoef()
  142. {
  143. return GetGame().GetWeather().GetRain().GetActual() + GetGame().GetWeather().GetSnowfall().GetActual();
  144. }
  145. };