#ifndef _TASK_LOOP_H
#define _TASK_LOOP_H
#include <Locker.h>
#include <ObjectList.h>
#include "FunctionObject.h"
namespace BPrivate {
class DelayedTask {
public:
DelayedTask(bigtime_t delay);
virtual ~DelayedTask();
virtual bool RunIfNeeded(bigtime_t currentTime) = 0;
bigtime_t RunAfterTime() const;
protected:
bigtime_t fRunAfter;
};
class OneShotDelayedTask : public DelayedTask {
public:
OneShotDelayedTask(FunctionObject* functor, bigtime_t delay);
virtual ~OneShotDelayedTask();
virtual bool RunIfNeeded(bigtime_t currentTime);
protected:
FunctionObject* fFunctor;
};
class PeriodicDelayedTask : public DelayedTask {
public:
PeriodicDelayedTask(FunctionObjectWithResult<bool>* functor,
bigtime_t initialDelay, bigtime_t period);
virtual ~PeriodicDelayedTask();
virtual bool RunIfNeeded(bigtime_t currentTime);
protected:
bigtime_t fPeriod;
FunctionObjectWithResult<bool>* fFunctor;
};
class PeriodicDelayedTaskWithTimeout : public PeriodicDelayedTask {
public:
PeriodicDelayedTaskWithTimeout(FunctionObjectWithResult<bool>* functor,
bigtime_t initialDelay, bigtime_t period, bigtime_t timeout);
virtual bool RunIfNeeded(bigtime_t currentTime);
protected:
bigtime_t fTimeoutAfter;
};
class RunWhenIdleTask : public PeriodicDelayedTask {
public:
RunWhenIdleTask(FunctionObjectWithResult<bool>* functor,
bigtime_t initialDelay, bigtime_t idleFor, bigtime_t heartBeat);
virtual ~RunWhenIdleTask();
virtual bool RunIfNeeded(bigtime_t currentTime);
protected:
void ResetIdleTimer(bigtime_t currentTime);
bool IdleTimerExpired(bigtime_t currentTime);
bool StillIdle(bigtime_t currentTime);
bool IsIdle(bigtime_t currentTime, float taskOverhead);
bigtime_t fIdleFor;
enum State {
kInitialDelay,
kInitialIdleWait,
kInIdleState
};
State fState;
bigtime_t fActivityLevelStart;
bigtime_t fActivityLevel;
bigtime_t fLastCPUTooBusyTime;
private:
typedef PeriodicDelayedTask _inherited;
};
class AccumulatingFunctionObject : public FunctionObject {
public:
virtual bool CanAccumulate(const AccumulatingFunctionObject*) const = 0;
virtual void Accumulate(AccumulatingFunctionObject*) = 0;
};
class TaskLoop {
public:
TaskLoop(bigtime_t heartBeat = 10000);
virtual ~TaskLoop();
void RunLater(DelayedTask*);
void RunLater(FunctionObject* functor, bigtime_t delay);
void RunLater(FunctionObjectWithResult<bool>* functor, bigtime_t delay,
bigtime_t period);
void RunLater(FunctionObjectWithResult<bool>* functor, bigtime_t delay,
bigtime_t period, bigtime_t timeout);
void AccumulatedRunLater(AccumulatingFunctionObject* functor,
bigtime_t delay, bigtime_t maxAccumulatingTime = 0,
int32 maxAccumulateCount = 0);
void RunWhenIdle(FunctionObjectWithResult<bool>* functor,
bigtime_t initialDelay, bigtime_t idleTime,
bigtime_t heartBeat = 1000000);
protected:
void AddTask(DelayedTask*);
void RemoveTask(DelayedTask*);
bool Pulse();
bigtime_t LatestRunTime() const;
virtual bool KeepPulsingWhenEmpty() const = 0;
virtual void StartPulsingIfNeeded() = 0;
BLocker fLock;
BObjectList<DelayedTask, true> fTaskList;
bigtime_t fHeartBeat;
};
class StandAloneTaskLoop : public TaskLoop {
public:
StandAloneTaskLoop(bool keepThread, bigtime_t heartBeat = 400000);
~StandAloneTaskLoop();
protected:
void AddTask(DelayedTask*);
private:
static status_t RunBinder(void*);
void Run();
virtual bool KeepPulsingWhenEmpty() const;
virtual void StartPulsingIfNeeded();
volatile bool fNeedToQuit;
volatile thread_id fScanThread;
bool fKeepThread;
typedef TaskLoop _inherited;
};
class PiggybackTaskLoop : public TaskLoop {
public:
PiggybackTaskLoop(bigtime_t heartBeat = 100000);
~PiggybackTaskLoop();
virtual void PulseMe();
private:
virtual bool KeepPulsingWhenEmpty() const;
virtual void StartPulsingIfNeeded();
bigtime_t fNextHeartBeatTime;
bool fPulseMe;
};
inline bigtime_t
DelayedTask::RunAfterTime() const
{
return fRunAfter;
}
}
using namespace BPrivate;
#endif