344 lines
8.5 KiB
C++
344 lines
8.5 KiB
C++
/*
|
|
** Command & Conquer Renegade(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/******************************************************************************
|
|
*
|
|
* FILE
|
|
* $Archive: /Commando/Code/WWOnline/WaitCondition.h $
|
|
*
|
|
* DESCRIPTION
|
|
* This class encapsulates a wait condition.
|
|
*
|
|
* To wait on an event, create a wait condition. Pass the condition, or a
|
|
* set of conditions, to WaitingCondition::Wait_For(). This will block
|
|
* until the conditions are met, the user cancels the wait, or the timeout
|
|
* is reached. This will also cause the wait popup to be displayed.
|
|
*
|
|
* PROGRAMMER
|
|
* Steven Clinard
|
|
* $Author: Denzil_l $
|
|
*
|
|
* VERSION INFO
|
|
* $Modtime: 1/18/02 3:08p $
|
|
* $Revision: 9 $
|
|
*
|
|
******************************************************************************/
|
|
|
|
#ifndef __WAITCONDITION_H__
|
|
#define __WAITCONDITION_H__
|
|
|
|
#include "RefCounted.h"
|
|
#include "RefPtr.h"
|
|
#include <WWLib\Notify.h>
|
|
#include <WWLib\CallbackHook.h>
|
|
#include <WWLib\WideString.h>
|
|
|
|
#if defined(_MSC_VER)
|
|
#pragma warning(push, 3)
|
|
#endif
|
|
|
|
#include <vector>
|
|
|
|
#if defined(_MSC_VER)
|
|
#pragma warning(pop)
|
|
#endif
|
|
|
|
class CallbackHook;
|
|
|
|
class WaitCondition :
|
|
public RefCounted
|
|
{
|
|
public:
|
|
enum WaitResult {Waiting, ConditionMet, UserCancel, TimeOut, Error};
|
|
|
|
// Wait for this condition
|
|
virtual WaitResult WaitFor(CallbackHook& hook, unsigned long timeout = 30000);
|
|
|
|
/* Wait_Beginning is called when the wait actually begins.
|
|
* This useful if the activity being monitored should only begin after the
|
|
* wait has started.
|
|
*
|
|
* Normally, the request should begin as soon as possible and the condition
|
|
* may be met before the wait begins; this avoids the whole wait popup in
|
|
* the first place.
|
|
*
|
|
* Serially chained waits may require prerequisite conditions to be met
|
|
* before the request that initiates this wait. In this case, a derived
|
|
* wait class could override Wait_Beginning to make the request.
|
|
*/
|
|
virtual void WaitBeginning(void) = 0;
|
|
|
|
// Get the result of the wait in progress.
|
|
virtual WaitResult GetResult(void) = 0;
|
|
|
|
// End the wait.
|
|
virtual void EndWait(WaitResult, const wchar_t*) = 0;
|
|
|
|
// Get a text description of completed wait
|
|
virtual const wchar_t* GetResultText(void) const = 0;
|
|
|
|
// Get a text description of the wait in progress.
|
|
virtual const wchar_t* GetWaitText(void) const = 0;
|
|
|
|
// Get the timeout in milliseconds for this wait condition
|
|
virtual unsigned long GetTimeout(void) const = 0;
|
|
|
|
protected:
|
|
WaitCondition();
|
|
virtual ~WaitCondition();
|
|
|
|
WaitCondition(const WaitCondition&);
|
|
const WaitCondition& operator=(const WaitCondition&);
|
|
};
|
|
|
|
|
|
// Waits for a single event.
|
|
class SingleWait :
|
|
public WaitCondition
|
|
{
|
|
public:
|
|
static RefPtr<SingleWait> Create(const wchar_t* waitText, unsigned long timeout = 30000);
|
|
|
|
virtual void WaitBeginning(void);
|
|
virtual WaitResult GetResult(void);
|
|
|
|
virtual void EndWait(WaitResult, const wchar_t*);
|
|
|
|
virtual const wchar_t* GetResultText(void) const;
|
|
|
|
virtual const wchar_t* GetWaitText(void) const;
|
|
|
|
virtual void SetWaitText(const wchar_t* waitText);
|
|
|
|
virtual unsigned long GetTimeout(void) const;
|
|
|
|
protected:
|
|
SingleWait(const wchar_t* waitText, unsigned long timeout = 30000);
|
|
virtual ~SingleWait();
|
|
|
|
SingleWait(const SingleWait&);
|
|
const SingleWait& operator=(const SingleWait&);
|
|
|
|
WaitResult mEndResult;
|
|
WideStringClass mEndText;
|
|
WideStringClass mWaitText;
|
|
|
|
unsigned long mTimeout;
|
|
unsigned long mStartTime;
|
|
};
|
|
|
|
|
|
// Waits for multiple events.
|
|
// All events must be satisfied and must occur in the order in which they are added.
|
|
class SerialWait :
|
|
public WaitCondition
|
|
{
|
|
public:
|
|
static RefPtr<SerialWait> Create(void);
|
|
|
|
void Add(const RefPtr<WaitCondition>&);
|
|
|
|
int RemainingWaits(void) const;
|
|
|
|
virtual void WaitBeginning(void);
|
|
|
|
virtual WaitResult GetResult(void);
|
|
|
|
virtual void EndWait(WaitResult, const wchar_t*);
|
|
|
|
virtual const wchar_t* GetResultText(void) const;
|
|
|
|
virtual const wchar_t* GetWaitText(void) const;
|
|
|
|
virtual unsigned long GetTimeout(void) const;
|
|
|
|
protected:
|
|
SerialWait();
|
|
virtual ~SerialWait();
|
|
|
|
SerialWait(const SerialWait&);
|
|
const SerialWait& operator=(const SerialWait&);
|
|
|
|
std::vector< RefPtr<WaitCondition> > mWaits;
|
|
|
|
mutable int mCurrentWait;
|
|
mutable WaitResult mEndResult;
|
|
mutable WideStringClass mEndText;
|
|
|
|
unsigned long mMaxTimeout;
|
|
unsigned long mStartTime;
|
|
};
|
|
|
|
|
|
// Waits for multiple events.
|
|
// All events are started at the same time. All events must be satisfied,
|
|
// but may occur in any order.
|
|
class ANDWait :
|
|
public WaitCondition
|
|
{
|
|
public:
|
|
static RefPtr<ANDWait> Create(const wchar_t*);
|
|
|
|
void Add(const RefPtr<WaitCondition>&);
|
|
|
|
virtual void WaitBeginning(void);
|
|
|
|
virtual WaitResult GetResult(void);
|
|
|
|
virtual void EndWait(WaitResult, const wchar_t*);
|
|
|
|
virtual const wchar_t* GetResultText(void) const;
|
|
|
|
virtual const wchar_t* GetWaitText(void) const;
|
|
|
|
virtual unsigned long GetTimeout(void) const;
|
|
|
|
protected:
|
|
ANDWait(const wchar_t*);
|
|
virtual ~ANDWait();
|
|
|
|
ANDWait(const ANDWait&);
|
|
const ANDWait& operator=(const ANDWait&);
|
|
|
|
std::vector< RefPtr<WaitCondition> > mWaits;
|
|
|
|
mutable WaitResult mEndResult;
|
|
mutable WideStringClass mEndText;
|
|
WideStringClass mWaitText;
|
|
|
|
unsigned long mMaxTimeout;
|
|
unsigned long mStartTime;
|
|
};
|
|
|
|
|
|
// ORWait: Waits for multiple events.
|
|
// All events are started at the same time. Wait ends when any event is satisfied.
|
|
class ORWait :
|
|
public WaitCondition
|
|
{
|
|
public:
|
|
static RefPtr<ORWait> Create(const wchar_t*);
|
|
|
|
void Add(const RefPtr<WaitCondition>&);
|
|
|
|
virtual void WaitBeginning(void);
|
|
|
|
virtual WaitResult GetResult(void);
|
|
|
|
virtual void EndWait(WaitResult, const wchar_t*);
|
|
|
|
virtual const wchar_t* GetResultText(void) const;
|
|
|
|
virtual const wchar_t* GetWaitText(void) const;
|
|
|
|
virtual unsigned long GetTimeout(void) const
|
|
{return mMaxTimeout;}
|
|
|
|
protected:
|
|
ORWait(const wchar_t*);
|
|
virtual ~ORWait();
|
|
|
|
ORWait(const ORWait&);
|
|
const ORWait& operator=(const ORWait&);
|
|
|
|
std::vector< RefPtr<WaitCondition> > mWaits;
|
|
|
|
mutable WaitResult mEndResult;
|
|
mutable WideStringClass mEndText;
|
|
WideStringClass mWaitText;
|
|
|
|
unsigned long mMaxTimeout;
|
|
unsigned long mStartTime;
|
|
};
|
|
|
|
|
|
// Wait for an event from a notifier
|
|
template<typename Event> class EventWait :
|
|
public SingleWait,
|
|
public Observer<Event>
|
|
{
|
|
public:
|
|
static RefPtr< EventWait<Event> > Create(const wchar_t* waitText)
|
|
{new EventWait(waitText);}
|
|
|
|
static RefPtr< EventWait<Event> > CreateAndObserve(Notifier<Event>& notifier,
|
|
const wchar_t* waitText)
|
|
{
|
|
EventWait<Event>* wait = new EventWait(waitText);
|
|
notifier.AddObserver(*wait);
|
|
return wait;
|
|
}
|
|
|
|
virtual void HandleNotification(Event&)
|
|
{if (mEndResult == Waiting) {EndWait(ConditionMet);}}
|
|
|
|
protected:
|
|
EventWait(const wchar_t* waitText) :
|
|
SingleWait(waitText)
|
|
{}
|
|
|
|
EventWait(const EventWait<Event>&);
|
|
const EventWait<Event>& operator=(const EventWait<Event>&);
|
|
};
|
|
|
|
|
|
// Wait for an event with a particular value from a notifier
|
|
template<typename Event> class EventValueWait :
|
|
public SingleWait,
|
|
public Observer<Event>
|
|
{
|
|
public:
|
|
static RefPtr< EventValueWait<Event> > Create(const Event& value, const wchar_t* waitText)
|
|
{new EventValueWait(value, waitText);}
|
|
|
|
static RefPtr< EventValueWait<Event> > CreateAndObserve(Notifier<Event>& notifier,
|
|
const Event value, const wchar_t* waitText)
|
|
{
|
|
EventValueWait<Event>* wait = new EventValueWait(value, waitText);
|
|
notifier.AddObserver(*wait);
|
|
return wait;
|
|
}
|
|
|
|
virtual void HandleNotification(Event& event)
|
|
{
|
|
if (mEndResult == Waiting)
|
|
{
|
|
if (event == mMatchValue)
|
|
{
|
|
EndWait(ConditionMet, L"");
|
|
}
|
|
else
|
|
{
|
|
EndWait(mEndResult, L"");
|
|
}
|
|
}
|
|
}
|
|
|
|
protected:
|
|
EventValueWait(const Event& value, const wchar_t* waitText) :
|
|
SingleWait(waitText),
|
|
mMatchValue(value)
|
|
{}
|
|
|
|
EventValueWait(const EventValueWait<Event>&);
|
|
const EventValueWait& operator=(const EventValueWait&);
|
|
|
|
Event mMatchValue;
|
|
};
|
|
|
|
#endif // __WAITCONDITION_H__
|