WaitCondition.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227
  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.cpp $
  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.
  30. *
  31. * PROGRAMMER
  32. * Steven Clinard
  33. * $Author: Denzil_l $
  34. *
  35. * VERSION INFO
  36. * $Modtime: 1/11/02 6:20p $
  37. * $Revision: 13 $
  38. *
  39. ******************************************************************************/
  40. #include "always.h"
  41. #include "WaitCondition.h"
  42. #include "WOLString.h"
  43. #include <WWLib\Win.h>
  44. #ifdef _MSC_VER
  45. #pragma warning (push,3)
  46. #endif
  47. #include "systimer.h"
  48. #ifdef _MSC_VER
  49. #pragma warning (pop)
  50. #endif
  51. /******************************************************************************
  52. *
  53. * NAME
  54. * WaitCondition::WaitCondition
  55. *
  56. * DESCRIPTION
  57. * Constructor
  58. *
  59. * INPUTS
  60. * NONE
  61. *
  62. * RESULT
  63. * NONE
  64. *
  65. ******************************************************************************/
  66. WaitCondition::WaitCondition()
  67. {
  68. }
  69. /******************************************************************************
  70. *
  71. * NAME
  72. * WaitCondition::~WaitCondition
  73. *
  74. * DESCRIPTION
  75. * Destructor
  76. *
  77. * INPUTS
  78. * NONE
  79. *
  80. * RESULT
  81. * NONE
  82. *
  83. ******************************************************************************/
  84. WaitCondition::~WaitCondition()
  85. {
  86. }
  87. /******************************************************************************
  88. *
  89. * NAME
  90. * WaitCondition::WaitFor
  91. *
  92. * DESCRIPTION
  93. * Wait for condition to be satisfied.
  94. *
  95. * INPUTS
  96. * Callback to invoke while waiting.
  97. * Timeout value in milliseconds
  98. *
  99. * RESULT
  100. * Wait result
  101. *
  102. ******************************************************************************/
  103. WaitCondition::WaitResult WaitCondition::WaitFor(CallbackHook& hook, unsigned long timeout)
  104. {
  105. WaitBeginning();
  106. DWORD startTime = TIMEGETTIME();
  107. while (GetResult() == Waiting)
  108. {
  109. // Yeild time to client callback
  110. if (hook.DoCallback())
  111. {
  112. EndWait(UserCancel, WOLSTRING("WOL_CANCELED"));
  113. break;
  114. }
  115. // Watch for timeout
  116. if ((TIMEGETTIME() - startTime) > timeout)
  117. {
  118. EndWait(TimeOut, WOLSTRING("WOL_TIMEDOUT"));
  119. }
  120. }
  121. return GetResult();
  122. }
  123. /******************************************************************************
  124. *
  125. * NAME
  126. * SingleWait::Create
  127. *
  128. * DESCRIPTION
  129. * Create a single wait instance
  130. *
  131. * INPUTS
  132. * Text - Text description of wait condition.
  133. * Timeout - Time to allow for wait condition to complete. If the wait
  134. * condition exceeds this time then it should be considered an
  135. * error.
  136. *
  137. * RESULT
  138. * SingleWait - New instance to a single wait condition
  139. *
  140. ******************************************************************************/
  141. RefPtr<SingleWait> SingleWait::Create(const wchar_t* text, unsigned long timeout)
  142. {
  143. return new SingleWait(text, timeout);
  144. }
  145. /******************************************************************************
  146. *
  147. * NAME
  148. * SingleWait::SingleWait
  149. *
  150. * DESCRIPTION
  151. * Constructor
  152. *
  153. * INPUTS
  154. * Text - Text description of wait condition.
  155. * Timeout - Time to allow for wait condition to complete. If the wait
  156. * condition exceeds this time then it should be considered an
  157. * error.
  158. *
  159. * RESULT
  160. * NONE
  161. *
  162. ******************************************************************************/
  163. SingleWait::SingleWait(const wchar_t* waitText, unsigned long timeout) :
  164. mWaitText(waitText),
  165. mEndResult(Waiting),
  166. mTimeout(timeout)
  167. {
  168. }
  169. /******************************************************************************
  170. *
  171. * NAME
  172. * SingleWait::~SingleWait
  173. *
  174. * DESCRIPTION
  175. * Destructor
  176. *
  177. * INPUTS
  178. * NONE
  179. *
  180. * RESULT
  181. * NONE
  182. *
  183. ******************************************************************************/
  184. SingleWait::~SingleWait()
  185. {
  186. }
  187. /******************************************************************************
  188. *
  189. * NAME
  190. * SingleWait::WaitBeginning
  191. *
  192. * DESCRIPTION
  193. * Begin this wait condition.
  194. *
  195. * INPUTS
  196. * NONE
  197. *
  198. * RESULT
  199. * NONE
  200. *
  201. ******************************************************************************/
  202. void SingleWait::WaitBeginning(void)
  203. {
  204. }
  205. /******************************************************************************
  206. *
  207. * NAME
  208. * SingleWait::GetResult
  209. *
  210. * DESCRIPTION
  211. * Get the result status of this wait condition.
  212. *
  213. * INPUTS
  214. * NONE
  215. *
  216. * RESULT
  217. * Result -
  218. *
  219. ******************************************************************************/
  220. WaitCondition::WaitResult SingleWait::GetResult(void)
  221. {
  222. return mEndResult;
  223. }
  224. /******************************************************************************
  225. *
  226. * NAME
  227. * SingleWait::GetResultText
  228. *
  229. * DESCRIPTION
  230. * Get text description of wait result.
  231. *
  232. * INPUTS
  233. * NONE
  234. *
  235. * RESULT
  236. * Text - Text description of the result of the wait condition.
  237. *
  238. ******************************************************************************/
  239. const wchar_t* SingleWait::GetResultText(void) const
  240. {
  241. return mEndText;
  242. }
  243. /******************************************************************************
  244. *
  245. * NAME
  246. * SingleWait::EndWait
  247. *
  248. * DESCRIPTION
  249. * Terminate the wait condition.
  250. *
  251. * INPUTS
  252. * Result - Reason for ending the wait.
  253. * Text - Text description of ending
  254. *
  255. * RESULT
  256. * NONE
  257. *
  258. ******************************************************************************/
  259. void SingleWait::EndWait(WaitResult result, const wchar_t* endText)
  260. {
  261. mEndResult = result;
  262. mEndText = endText;
  263. }
  264. /******************************************************************************
  265. *
  266. * NAME
  267. * SingleWait::GetWaitText
  268. *
  269. * DESCRIPTION
  270. * Get wait description text
  271. *
  272. * INPUTS
  273. * NONE
  274. *
  275. * RESULT
  276. * Text - Text description of the wait operation.
  277. *
  278. ******************************************************************************/
  279. const wchar_t* SingleWait::GetWaitText(void) const
  280. {
  281. return mWaitText;
  282. }
  283. /******************************************************************************
  284. *
  285. * NAME
  286. * SingleWait::SetWaitText
  287. *
  288. * DESCRIPTION
  289. * Changes the wait text in the dialog.
  290. *
  291. * INPUTS
  292. * New text to display
  293. *
  294. * RESULT
  295. * NONE
  296. *
  297. ******************************************************************************/
  298. void SingleWait::SetWaitText(const wchar_t* waitText)
  299. {
  300. mWaitText = waitText;
  301. }
  302. /******************************************************************************
  303. *
  304. * NAME
  305. * SingleWait::GetTimeout
  306. *
  307. * DESCRIPTION
  308. * Get the time allowed for this wait condition to complete.
  309. *
  310. * INPUTS
  311. * NONE
  312. *
  313. * RESULT
  314. * Timeout - Timeout time in milliseconds.
  315. *
  316. ******************************************************************************/
  317. unsigned long SingleWait::GetTimeout(void) const
  318. {
  319. return mTimeout;
  320. }
  321. /******************************************************************************
  322. *
  323. * NAME
  324. * SerialWait::Create
  325. *
  326. * DESCRIPTION
  327. * Create an instance of a serialized wait. SerialWait is primarily used
  328. * to hold other wait conditions that need to be executed in sequence.
  329. *
  330. * INPUTS
  331. * NONE
  332. *
  333. * RESULT
  334. * Wait - New wait condition
  335. *
  336. ******************************************************************************/
  337. RefPtr<SerialWait> SerialWait::Create(void)
  338. {
  339. return new SerialWait;
  340. }
  341. /******************************************************************************
  342. *
  343. * NAME
  344. * SerialWait::SerialWait
  345. *
  346. * DESCRIPTION
  347. * Constructor
  348. *
  349. * INPUTS
  350. * NONE
  351. *
  352. * RESULT
  353. * NONE
  354. *
  355. ******************************************************************************/
  356. SerialWait::SerialWait() :
  357. mCurrentWait(-1),
  358. mEndResult(Waiting),
  359. mStartTime(0)
  360. {
  361. }
  362. /******************************************************************************
  363. *
  364. * NAME
  365. * SerialWait::~SerialWait
  366. *
  367. * DESCRIPTION
  368. * Destructor
  369. *
  370. * INPUTS
  371. * NONE
  372. *
  373. * RESULT
  374. * NONE
  375. *
  376. ******************************************************************************/
  377. SerialWait::~SerialWait()
  378. {
  379. }
  380. /******************************************************************************
  381. *
  382. * NAME
  383. * SerialWait::Add
  384. *
  385. * DESCRIPTION
  386. * Add a wait condition. Wait conditions are processed in the order they
  387. * are added.
  388. *
  389. * INPUTS
  390. * Wait - Wait condition to add.
  391. *
  392. * RESULT
  393. * NONE
  394. *
  395. ******************************************************************************/
  396. void SerialWait::Add(const RefPtr<WaitCondition>& wait)
  397. {
  398. if (wait.IsValid())
  399. {
  400. mWaits.push_back(wait);
  401. }
  402. else
  403. {
  404. assert(wait.IsValid() && "SerialWait: Invalid wait condition");
  405. EndWait(Error, L"Invalid wait condition.");
  406. }
  407. }
  408. /******************************************************************************
  409. *
  410. * NAME
  411. * SerialWait::RemainingWaits
  412. *
  413. * DESCRIPTION
  414. * Get then number of remaining wait conditions.
  415. *
  416. * INPUTS
  417. * NONE
  418. *
  419. * RESULT
  420. * Number of waits
  421. *
  422. ******************************************************************************/
  423. int SerialWait::RemainingWaits(void) const
  424. {
  425. int count = mWaits.size();
  426. return (mCurrentWait == -1) ? count :
  427. (mCurrentWait >= count) ? 0 : (count - mCurrentWait);
  428. }
  429. /******************************************************************************
  430. *
  431. * NAME
  432. * SerialWait::WaitBeginning
  433. *
  434. * DESCRIPTION
  435. * Begin wait condition
  436. *
  437. * INPUTS
  438. * NONE
  439. *
  440. * RESULT
  441. * NONE
  442. *
  443. ******************************************************************************/
  444. void SerialWait::WaitBeginning(void)
  445. {
  446. // WaitBeginning should only be called once.
  447. if (mCurrentWait != -1)
  448. {
  449. assert(mCurrentWait == -1);
  450. return;
  451. }
  452. // Start the first wait condition in the queue.
  453. mCurrentWait = 0;
  454. if (mWaits.size() > 0)
  455. {
  456. RefPtr<WaitCondition> wait = mWaits[0];
  457. wait->WaitBeginning();
  458. }
  459. mStartTime = TIMEGETTIME();
  460. }
  461. /******************************************************************************
  462. *
  463. * NAME
  464. * SerialWait::GetResult
  465. *
  466. * DESCRIPTION
  467. * Get the current wait status result.
  468. *
  469. * INPUTS
  470. * NONE
  471. *
  472. * RESULT
  473. * Result -
  474. *
  475. ******************************************************************************/
  476. WaitCondition::WaitResult SerialWait::GetResult(void)
  477. {
  478. // If we are not waiting the we must be done.
  479. if (mEndResult != Waiting)
  480. {
  481. return mEndResult;
  482. }
  483. // If there isn't a current wait processing then we must be waiting to begin.
  484. if (mCurrentWait == -1)
  485. {
  486. return Waiting;
  487. }
  488. // If all of the wait conditions have completed successfully then the wait
  489. // condition has been met.
  490. if ((unsigned)mCurrentWait >= mWaits.size())
  491. {
  492. return ConditionMet;
  493. }
  494. // Process outstanding waits
  495. do
  496. {
  497. RefPtr<WaitCondition>& wait = mWaits[mCurrentWait];
  498. // Get the result of the current wait.
  499. mEndResult = wait->GetResult();
  500. switch (mEndResult)
  501. {
  502. case Error:
  503. mEndText = wait->GetResultText();
  504. break;
  505. // If the current wait has completed successfully then advance to the
  506. // next wait condition.
  507. case ConditionMet:
  508. mEndText = wait->GetResultText();
  509. ++mCurrentWait;
  510. if ((unsigned)mCurrentWait < mWaits.size())
  511. {
  512. mWaits[mCurrentWait]->WaitBeginning();
  513. mStartTime = TIMEGETTIME();
  514. }
  515. break;
  516. case Waiting:
  517. // Check for timeout
  518. if ((TIMEGETTIME() - mStartTime) > wait->GetTimeout())
  519. {
  520. wait->EndWait(TimeOut, WOLSTRING("WOL_TIMEDOUT"));
  521. EndWait(TimeOut, wait->GetWaitText());
  522. }
  523. break;
  524. default:
  525. break;
  526. }
  527. } while ((mEndResult == ConditionMet) && ((unsigned)mCurrentWait < mWaits.size()));
  528. return mEndResult;
  529. }
  530. /******************************************************************************
  531. *
  532. * NAME
  533. * SerialWait::EndWait
  534. *
  535. * DESCRIPTION
  536. * End the wait condition.
  537. *
  538. * INPUTS
  539. * Result - Reason for ending the wait condition.
  540. * Description - Text description of end.
  541. *
  542. * RESULT
  543. * NONE
  544. *
  545. ******************************************************************************/
  546. void SerialWait::EndWait(WaitResult result, const wchar_t* endText)
  547. {
  548. mEndResult = result;
  549. mEndText = endText;
  550. // End the current wait.
  551. if ((mCurrentWait >= 0) && ((unsigned)mCurrentWait < mWaits.size()))
  552. {
  553. mWaits[mCurrentWait]->EndWait(result, endText);
  554. }
  555. }
  556. /******************************************************************************
  557. *
  558. * NAME
  559. * SerialWait::GetResultText
  560. *
  561. * DESCRIPTION
  562. * Get a text description of the wait condition result.
  563. *
  564. * INPUTS
  565. * NONE
  566. *
  567. * RESULT
  568. * ResultText
  569. *
  570. ******************************************************************************/
  571. const wchar_t* SerialWait::GetResultText(void) const
  572. {
  573. return mEndText;
  574. }
  575. /******************************************************************************
  576. *
  577. * NAME
  578. * SerialWait::GetWaitText
  579. *
  580. * DESCRIPTION
  581. * Get a text description of the current wait.
  582. *
  583. * INPUTS
  584. * NONE
  585. *
  586. * RESULT
  587. *
  588. ******************************************************************************/
  589. const wchar_t* SerialWait::GetWaitText(void) const
  590. {
  591. if ((mCurrentWait >= 0) && ((unsigned)mCurrentWait < mWaits.size()))
  592. {
  593. return (mWaits[mCurrentWait]->GetWaitText());
  594. }
  595. return NULL;
  596. }
  597. /******************************************************************************
  598. *
  599. * NAME
  600. * SerialWait::GetTimeout
  601. *
  602. * DESCRIPTION
  603. * Get the timeout for the current wait condition being processed.
  604. *
  605. * INPUTS
  606. * NONE
  607. *
  608. * RESULT
  609. * Timeout
  610. *
  611. ******************************************************************************/
  612. unsigned long SerialWait::GetTimeout(void) const
  613. {
  614. if ((mCurrentWait >= 0) && ((unsigned)mCurrentWait < mWaits.size()))
  615. {
  616. return (mWaits[mCurrentWait]->GetTimeout());
  617. }
  618. return 0;
  619. }
  620. /******************************************************************************
  621. *
  622. * NAME
  623. * ANDWait::Create
  624. *
  625. * DESCRIPTION
  626. * Create a logical AND wait condition. When this wait condition is begun
  627. * all the waits will be started at once. When all the waits complete the
  628. * AND wait condition is finished. If any condition fails then the entire
  629. * condition fails.
  630. *
  631. * INPUTS
  632. * Text - Text description of this wait condition.
  633. *
  634. * RESULT
  635. * ANDWait - Instance of newly created ANDWait condition.
  636. *
  637. ******************************************************************************/
  638. RefPtr<ANDWait> ANDWait::Create(const wchar_t* waitText)
  639. {
  640. return new ANDWait(waitText);
  641. }
  642. /******************************************************************************
  643. *
  644. * NAME
  645. * ANDWait::ANDWait
  646. *
  647. * DESCRIPTION
  648. * Constructor
  649. *
  650. * INPUTS
  651. * Text - Text describing the wait condition.
  652. *
  653. * RESULT
  654. * NONE
  655. *
  656. ******************************************************************************/
  657. ANDWait::ANDWait(const wchar_t* waitText) :
  658. mEndResult(Waiting),
  659. mWaitText(waitText),
  660. mMaxTimeout(0)
  661. {
  662. }
  663. /******************************************************************************
  664. *
  665. * NAME
  666. * ANDWait::~ANDWait
  667. *
  668. * DESCRIPTION
  669. * Destructor
  670. *
  671. * INPUTS
  672. * NONE
  673. *
  674. * RESULT
  675. * NONE
  676. *
  677. ******************************************************************************/
  678. ANDWait::~ANDWait()
  679. {
  680. }
  681. /******************************************************************************
  682. *
  683. * NAME
  684. * ANDWait::Add
  685. *
  686. * DESCRIPTION
  687. * Add a wait condition.
  688. *
  689. * INPUTS
  690. * Wait - Wait condition to add.
  691. *
  692. * RESULT
  693. * NONE
  694. *
  695. ******************************************************************************/
  696. void ANDWait::Add(const RefPtr<WaitCondition>& wait)
  697. {
  698. if (wait.IsValid())
  699. {
  700. mWaits.push_back(wait);
  701. // The timeout should be the longest of the all the waits
  702. unsigned long timeout = wait->GetTimeout();
  703. if (timeout > mMaxTimeout)
  704. {
  705. mMaxTimeout = timeout;
  706. }
  707. }
  708. else
  709. {
  710. assert(wait.IsValid() && "ORWait: Invalid wait condition");
  711. EndWait(Error, L"Invalid wait condition.");
  712. }
  713. }
  714. /******************************************************************************
  715. *
  716. * NAME
  717. * ANDWait::WaitBeginning
  718. *
  719. * DESCRIPTION
  720. * Begin the wait conditions
  721. *
  722. * INPUTS
  723. * NONE
  724. *
  725. * RESULT
  726. * NONE
  727. *
  728. ******************************************************************************/
  729. void ANDWait::WaitBeginning(void)
  730. {
  731. for (unsigned int index = 0; index < mWaits.size(); index++)
  732. {
  733. mWaits[index]->WaitBeginning();
  734. }
  735. mStartTime = TIMEGETTIME();
  736. }
  737. /******************************************************************************
  738. *
  739. * NAME
  740. * ANDWait::
  741. *
  742. * DESCRIPTION
  743. *
  744. * INPUTS
  745. *
  746. * RESULT
  747. *
  748. ******************************************************************************/
  749. WaitCondition::WaitResult ANDWait::GetResult(void)
  750. {
  751. if (mEndResult == Waiting)
  752. {
  753. unsigned int metConditions = 0;
  754. unsigned int count = mWaits.size();
  755. // Get the result of all the wait conditions being processed. If they are
  756. // all finished then the entire wait finished.
  757. for (unsigned int index = 0; index < count; ++index)
  758. {
  759. RefPtr<WaitCondition>& wait = mWaits[index];
  760. WaitResult result = wait->GetResult();
  761. if (ConditionMet == result)
  762. {
  763. ++metConditions;
  764. }
  765. else if (Waiting != result)
  766. {
  767. EndWait(result, wait->GetResultText());
  768. return result;
  769. }
  770. }
  771. if (metConditions == count)
  772. {
  773. EndWait(ConditionMet, GetWaitText());
  774. }
  775. else
  776. {
  777. // Check for timeout while we are still waiting
  778. if ((TIMEGETTIME() - mStartTime) > GetTimeout())
  779. {
  780. EndWait(TimeOut, WOLSTRING("WOL_TIMEDOUT"));
  781. }
  782. }
  783. }
  784. return mEndResult;
  785. }
  786. /******************************************************************************
  787. *
  788. * NAME
  789. * ANDWait::EndWait
  790. *
  791. * DESCRIPTION
  792. *
  793. * INPUTS
  794. *
  795. * RESULT
  796. *
  797. ******************************************************************************/
  798. void ANDWait::EndWait(WaitResult result, const wchar_t* endText)
  799. {
  800. mEndResult = result;
  801. mEndText = endText;
  802. for (unsigned int index = 0; index < mWaits.size(); ++index)
  803. {
  804. mWaits[index]->EndWait(result, L"");
  805. }
  806. }
  807. /******************************************************************************
  808. *
  809. * NAME
  810. * ANDWait::
  811. *
  812. * DESCRIPTION
  813. *
  814. * INPUTS
  815. *
  816. * RESULT
  817. *
  818. ******************************************************************************/
  819. const wchar_t* ANDWait::GetResultText(void) const
  820. {
  821. return mEndText;
  822. }
  823. /******************************************************************************
  824. *
  825. * NAME
  826. * ANDWait::
  827. *
  828. * DESCRIPTION
  829. *
  830. * INPUTS
  831. *
  832. * RESULT
  833. *
  834. ******************************************************************************/
  835. const wchar_t* ANDWait::GetWaitText(void) const
  836. {
  837. return mWaitText;
  838. }
  839. /******************************************************************************
  840. *
  841. * NAME
  842. * ANDWait::
  843. *
  844. * DESCRIPTION
  845. *
  846. * INPUTS
  847. *
  848. * RESULT
  849. *
  850. ******************************************************************************/
  851. unsigned long ANDWait::GetTimeout(void) const
  852. {
  853. return mMaxTimeout;
  854. }
  855. /******************************************************************************
  856. *
  857. * NAME
  858. * ORWait::Create
  859. *
  860. * DESCRIPTION
  861. * Create a OR wait condition. When this wait condition is begun all the
  862. * waits will be started at once. When any wait completes for any reason
  863. * the OR wait condition is finished.
  864. *
  865. * INPUTS
  866. * Text - Text description of this wait condition.
  867. *
  868. * RESULT
  869. *
  870. ******************************************************************************/
  871. RefPtr<ORWait> ORWait::Create(const wchar_t* waitText)
  872. {
  873. return new ORWait(waitText);
  874. }
  875. /******************************************************************************
  876. *
  877. * NAME
  878. * ORWait::ORWait
  879. *
  880. * DESCRIPTION
  881. * Constructor
  882. *
  883. * INPUTS
  884. * Text -
  885. *
  886. * RESULT
  887. * NONE
  888. *
  889. ******************************************************************************/
  890. ORWait::ORWait(const wchar_t* waitText) :
  891. mEndResult(Waiting),
  892. mWaitText(waitText),
  893. mMaxTimeout(0)
  894. {
  895. }
  896. /******************************************************************************
  897. *
  898. * NAME
  899. * ORWait::~ORWait
  900. *
  901. * DESCRIPTION
  902. * Destructor
  903. *
  904. * INPUTS
  905. * NONE
  906. *
  907. * RESULT
  908. * NONE
  909. *
  910. ******************************************************************************/
  911. ORWait::~ORWait()
  912. {
  913. }
  914. /******************************************************************************
  915. *
  916. * NAME
  917. * ORWait::Add
  918. *
  919. * DESCRIPTION
  920. * Add wait condition. All the wait conditions will be started at once.
  921. *
  922. * INPUTS
  923. * Wait condition
  924. *
  925. * RESULT
  926. * NONE
  927. *
  928. ******************************************************************************/
  929. void ORWait::Add(const RefPtr<WaitCondition>& wait)
  930. {
  931. if (wait.IsValid())
  932. {
  933. mWaits.push_back(wait);
  934. // Use the longest timeout value.
  935. unsigned long timeout = wait->GetTimeout();
  936. if (timeout > mMaxTimeout)
  937. {
  938. mMaxTimeout = timeout;
  939. }
  940. }
  941. else
  942. {
  943. assert(wait.IsValid() && "ORWait: Invalid wait condition");
  944. EndWait(Error, L"Invalid wait condition.");
  945. }
  946. }
  947. /******************************************************************************
  948. *
  949. * NAME
  950. * ORWait::WaitBeginning
  951. *
  952. * DESCRIPTION
  953. *
  954. * INPUTS
  955. * NONE
  956. *
  957. * RESULT
  958. * NONE
  959. *
  960. ******************************************************************************/
  961. void ORWait::WaitBeginning(void)
  962. {
  963. for (unsigned int index = 0; index < mWaits.size(); index++)
  964. {
  965. mWaits[index]->WaitBeginning();
  966. }
  967. }
  968. /******************************************************************************
  969. *
  970. * NAME
  971. * ORWait::GetResult
  972. *
  973. * DESCRIPTION
  974. *
  975. * INPUTS
  976. * NONE
  977. *
  978. * RESULT
  979. *
  980. ******************************************************************************/
  981. WaitCondition::WaitResult ORWait::GetResult(void)
  982. {
  983. // If we are not waiting the we are finished
  984. if (mEndResult != Waiting)
  985. {
  986. return mEndResult;
  987. }
  988. // Get the result of all the wait conditions being processed. If any one
  989. // is finished then the entire wait finished.
  990. for (unsigned int index = 0; index < mWaits.size(); index++)
  991. {
  992. mEndResult = mWaits[index]->GetResult();
  993. if (mEndResult != Waiting)
  994. {
  995. mEndText = mWaits[index]->GetResultText();
  996. return mEndResult;
  997. }
  998. }
  999. return Waiting;
  1000. }
  1001. /******************************************************************************
  1002. *
  1003. * NAME
  1004. * ORWait::EndWait
  1005. *
  1006. * DESCRIPTION
  1007. *
  1008. * INPUTS
  1009. *
  1010. * RESULT
  1011. * NONE
  1012. *
  1013. ******************************************************************************/
  1014. void ORWait::EndWait(WaitResult result, const wchar_t* endText)
  1015. {
  1016. mEndText = endText;
  1017. mEndResult = result;
  1018. for (unsigned int index = 0; index < mWaits.size(); ++index)
  1019. {
  1020. mWaits[index]->EndWait(result, L"");
  1021. }
  1022. }
  1023. /******************************************************************************
  1024. *
  1025. * NAME
  1026. * ORWait::GetResultText
  1027. *
  1028. * DESCRIPTION
  1029. *
  1030. * INPUTS
  1031. * NONE
  1032. *
  1033. * RESULT
  1034. *
  1035. ******************************************************************************/
  1036. const wchar_t* ORWait::GetResultText(void) const
  1037. {
  1038. return mEndText;
  1039. }
  1040. /******************************************************************************
  1041. *
  1042. * NAME
  1043. * ORWait::WaitText
  1044. *
  1045. * DESCRIPTION
  1046. *
  1047. * INPUTS
  1048. * NONE
  1049. *
  1050. * RESULT
  1051. *
  1052. ******************************************************************************/
  1053. const wchar_t* ORWait::GetWaitText(void) const
  1054. {
  1055. return mWaitText;
  1056. }