WaitCondition.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /******************************************************************************
  19. *
  20. * FILE
  21. * $Archive: /Commando/Code/WWOnline/WaitCondition.h $
  22. *
  23. * DESCRIPTION
  24. * This class encapsulates a wait condition.
  25. *
  26. * To wait on an event, create a wait condition. Pass the condition, or a
  27. * set of conditions, to WaitingCondition::Wait_For(). This will block
  28. * until the conditions are met, the user cancels the wait, or the timeout
  29. * is reached. This will also cause the wait popup to be displayed.
  30. *
  31. * PROGRAMMER
  32. * Steven Clinard
  33. * $Author: Denzil_l $
  34. *
  35. * VERSION INFO
  36. * $Modtime: 1/18/02 3:08p $
  37. * $Revision: 9 $
  38. *
  39. ******************************************************************************/
  40. #ifndef __WAITCONDITION_H__
  41. #define __WAITCONDITION_H__
  42. #include "RefCounted.h"
  43. #include "RefPtr.h"
  44. #include <WWLib\Notify.h>
  45. #include <WWLib\CallbackHook.h>
  46. #include <WWLib\WideString.h>
  47. #if defined(_MSC_VER)
  48. #pragma warning(push, 3)
  49. #endif
  50. #include <vector>
  51. #if defined(_MSC_VER)
  52. #pragma warning(pop)
  53. #endif
  54. class CallbackHook;
  55. class WaitCondition :
  56. public RefCounted
  57. {
  58. public:
  59. enum WaitResult {Waiting, ConditionMet, UserCancel, TimeOut, Error};
  60. // Wait for this condition
  61. virtual WaitResult WaitFor(CallbackHook& hook, unsigned long timeout = 30000);
  62. /* Wait_Beginning is called when the wait actually begins.
  63. * This useful if the activity being monitored should only begin after the
  64. * wait has started.
  65. *
  66. * Normally, the request should begin as soon as possible and the condition
  67. * may be met before the wait begins; this avoids the whole wait popup in
  68. * the first place.
  69. *
  70. * Serially chained waits may require prerequisite conditions to be met
  71. * before the request that initiates this wait. In this case, a derived
  72. * wait class could override Wait_Beginning to make the request.
  73. */
  74. virtual void WaitBeginning(void) = 0;
  75. // Get the result of the wait in progress.
  76. virtual WaitResult GetResult(void) = 0;
  77. // End the wait.
  78. virtual void EndWait(WaitResult, const wchar_t*) = 0;
  79. // Get a text description of completed wait
  80. virtual const wchar_t* GetResultText(void) const = 0;
  81. // Get a text description of the wait in progress.
  82. virtual const wchar_t* GetWaitText(void) const = 0;
  83. // Get the timeout in milliseconds for this wait condition
  84. virtual unsigned long GetTimeout(void) const = 0;
  85. protected:
  86. WaitCondition();
  87. virtual ~WaitCondition();
  88. WaitCondition(const WaitCondition&);
  89. const WaitCondition& operator=(const WaitCondition&);
  90. };
  91. // Waits for a single event.
  92. class SingleWait :
  93. public WaitCondition
  94. {
  95. public:
  96. static RefPtr<SingleWait> Create(const wchar_t* waitText, unsigned long timeout = 30000);
  97. virtual void WaitBeginning(void);
  98. virtual WaitResult GetResult(void);
  99. virtual void EndWait(WaitResult, const wchar_t*);
  100. virtual const wchar_t* GetResultText(void) const;
  101. virtual const wchar_t* GetWaitText(void) const;
  102. virtual void SetWaitText(const wchar_t* waitText);
  103. virtual unsigned long GetTimeout(void) const;
  104. protected:
  105. SingleWait(const wchar_t* waitText, unsigned long timeout = 30000);
  106. virtual ~SingleWait();
  107. SingleWait(const SingleWait&);
  108. const SingleWait& operator=(const SingleWait&);
  109. WaitResult mEndResult;
  110. WideStringClass mEndText;
  111. WideStringClass mWaitText;
  112. unsigned long mTimeout;
  113. unsigned long mStartTime;
  114. };
  115. // Waits for multiple events.
  116. // All events must be satisfied and must occur in the order in which they are added.
  117. class SerialWait :
  118. public WaitCondition
  119. {
  120. public:
  121. static RefPtr<SerialWait> Create(void);
  122. void Add(const RefPtr<WaitCondition>&);
  123. int RemainingWaits(void) const;
  124. virtual void WaitBeginning(void);
  125. virtual WaitResult GetResult(void);
  126. virtual void EndWait(WaitResult, const wchar_t*);
  127. virtual const wchar_t* GetResultText(void) const;
  128. virtual const wchar_t* GetWaitText(void) const;
  129. virtual unsigned long GetTimeout(void) const;
  130. protected:
  131. SerialWait();
  132. virtual ~SerialWait();
  133. SerialWait(const SerialWait&);
  134. const SerialWait& operator=(const SerialWait&);
  135. std::vector< RefPtr<WaitCondition> > mWaits;
  136. mutable int mCurrentWait;
  137. mutable WaitResult mEndResult;
  138. mutable WideStringClass mEndText;
  139. unsigned long mMaxTimeout;
  140. unsigned long mStartTime;
  141. };
  142. // Waits for multiple events.
  143. // All events are started at the same time. All events must be satisfied,
  144. // but may occur in any order.
  145. class ANDWait :
  146. public WaitCondition
  147. {
  148. public:
  149. static RefPtr<ANDWait> Create(const wchar_t*);
  150. void Add(const RefPtr<WaitCondition>&);
  151. virtual void WaitBeginning(void);
  152. virtual WaitResult GetResult(void);
  153. virtual void EndWait(WaitResult, const wchar_t*);
  154. virtual const wchar_t* GetResultText(void) const;
  155. virtual const wchar_t* GetWaitText(void) const;
  156. virtual unsigned long GetTimeout(void) const;
  157. protected:
  158. ANDWait(const wchar_t*);
  159. virtual ~ANDWait();
  160. ANDWait(const ANDWait&);
  161. const ANDWait& operator=(const ANDWait&);
  162. std::vector< RefPtr<WaitCondition> > mWaits;
  163. mutable WaitResult mEndResult;
  164. mutable WideStringClass mEndText;
  165. WideStringClass mWaitText;
  166. unsigned long mMaxTimeout;
  167. unsigned long mStartTime;
  168. };
  169. // ORWait: Waits for multiple events.
  170. // All events are started at the same time. Wait ends when any event is satisfied.
  171. class ORWait :
  172. public WaitCondition
  173. {
  174. public:
  175. static RefPtr<ORWait> Create(const wchar_t*);
  176. void Add(const RefPtr<WaitCondition>&);
  177. virtual void WaitBeginning(void);
  178. virtual WaitResult GetResult(void);
  179. virtual void EndWait(WaitResult, const wchar_t*);
  180. virtual const wchar_t* GetResultText(void) const;
  181. virtual const wchar_t* GetWaitText(void) const;
  182. virtual unsigned long GetTimeout(void) const
  183. {return mMaxTimeout;}
  184. protected:
  185. ORWait(const wchar_t*);
  186. virtual ~ORWait();
  187. ORWait(const ORWait&);
  188. const ORWait& operator=(const ORWait&);
  189. std::vector< RefPtr<WaitCondition> > mWaits;
  190. mutable WaitResult mEndResult;
  191. mutable WideStringClass mEndText;
  192. WideStringClass mWaitText;
  193. unsigned long mMaxTimeout;
  194. unsigned long mStartTime;
  195. };
  196. // Wait for an event from a notifier
  197. template<typename Event> class EventWait :
  198. public SingleWait,
  199. public Observer<Event>
  200. {
  201. public:
  202. static RefPtr< EventWait<Event> > Create(const wchar_t* waitText)
  203. {new EventWait(waitText);}
  204. static RefPtr< EventWait<Event> > CreateAndObserve(Notifier<Event>& notifier,
  205. const wchar_t* waitText)
  206. {
  207. EventWait<Event>* wait = new EventWait(waitText);
  208. notifier.AddObserver(*wait);
  209. return wait;
  210. }
  211. virtual void HandleNotification(Event&)
  212. {if (mEndResult == Waiting) {EndWait(ConditionMet);}}
  213. protected:
  214. EventWait(const wchar_t* waitText) :
  215. SingleWait(waitText)
  216. {}
  217. EventWait(const EventWait<Event>&);
  218. const EventWait<Event>& operator=(const EventWait<Event>&);
  219. };
  220. // Wait for an event with a particular value from a notifier
  221. template<typename Event> class EventValueWait :
  222. public SingleWait,
  223. public Observer<Event>
  224. {
  225. public:
  226. static RefPtr< EventValueWait<Event> > Create(const Event& value, const wchar_t* waitText)
  227. {new EventValueWait(value, waitText);}
  228. static RefPtr< EventValueWait<Event> > CreateAndObserve(Notifier<Event>& notifier,
  229. const Event value, const wchar_t* waitText)
  230. {
  231. EventValueWait<Event>* wait = new EventValueWait(value, waitText);
  232. notifier.AddObserver(*wait);
  233. return wait;
  234. }
  235. virtual void HandleNotification(Event& event)
  236. {
  237. if (mEndResult == Waiting)
  238. {
  239. if (event == mMatchValue)
  240. {
  241. EndWait(ConditionMet, L"");
  242. }
  243. else
  244. {
  245. EndWait(mEndResult, L"");
  246. }
  247. }
  248. }
  249. protected:
  250. EventValueWait(const Event& value, const wchar_t* waitText) :
  251. SingleWait(waitText),
  252. mMatchValue(value)
  253. {}
  254. EventValueWait(const EventValueWait<Event>&);
  255. const EventValueWait& operator=(const EventValueWait&);
  256. Event mMatchValue;
  257. };
  258. #endif // __WAITCONDITION_H__