124 lines
1.8 KiB
C++
124 lines
1.8 KiB
C++
// Copyright (c) 2011 Bryan Schumaker.
|
|
#include <notify.h>
|
|
#include <idle.h>
|
|
#include <print.h>
|
|
|
|
#include <queue>
|
|
using namespace std;
|
|
|
|
class IdleTask
|
|
{
|
|
private:
|
|
void (*func)();
|
|
void (*func2)(void *);
|
|
void *data;
|
|
|
|
public:
|
|
IdleTask(void (*)());
|
|
IdleTask(void (*)(void *), void *);
|
|
~IdleTask();
|
|
void run();
|
|
bool should_cancel(void *);
|
|
};
|
|
|
|
static deque<IdleTask *> idle_queue;
|
|
static float queued = 0.0;
|
|
static float serviced = 0.0;
|
|
|
|
IdleTask::IdleTask(void (*f)())
|
|
{
|
|
func = f;
|
|
func2 = NULL;
|
|
data = NULL;
|
|
}
|
|
|
|
IdleTask::IdleTask(void (*f)(void *), void *d)
|
|
{
|
|
func = NULL;
|
|
func2 = f;
|
|
data = d;
|
|
}
|
|
|
|
IdleTask::~IdleTask()
|
|
{
|
|
}
|
|
|
|
void IdleTask::run()
|
|
{
|
|
if (func)
|
|
func();
|
|
else
|
|
func2(data);
|
|
}
|
|
|
|
bool IdleTask::should_cancel(void *d)
|
|
{
|
|
if (data && (data == d))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
static void queue_task(IdleTask *task)
|
|
{
|
|
idle_queue.push_back(task);
|
|
queued += 1.0;
|
|
libsaria::notify(IDLE_ADD, NULL);
|
|
}
|
|
|
|
namespace libsaria
|
|
{
|
|
|
|
float idle::progress()
|
|
{
|
|
if (queued == 0)
|
|
return 1.0;
|
|
return (serviced / queued);
|
|
}
|
|
|
|
int idle::size()
|
|
{
|
|
return idle_queue.size();
|
|
}
|
|
|
|
void idle::schedule(void (*func)())
|
|
{
|
|
IdleTask *task = new IdleTask(func);
|
|
queue_task(task);
|
|
}
|
|
|
|
void idle::schedule(void (*func)(void *), void *data)
|
|
{
|
|
IdleTask *task = new IdleTask(func, data);
|
|
queue_task(task);
|
|
}
|
|
|
|
int idle::run_task()
|
|
{
|
|
if (size() == 0)
|
|
return 0;
|
|
|
|
idle_queue[0]->run();
|
|
delete idle_queue[0];
|
|
|
|
idle_queue.pop_front();
|
|
if (size() == 0) {
|
|
queued = 0.0;
|
|
serviced = 0.0;
|
|
} else
|
|
serviced += 1.0;
|
|
return size();
|
|
}
|
|
|
|
void idle::cancel_all(void *data)
|
|
{
|
|
deque<IdleTask *>::iterator it;
|
|
for (it = idle_queue.begin(); it != idle_queue.end();) {
|
|
if ((*it)->should_cancel(data))
|
|
idle_queue.erase(it);
|
|
else
|
|
it++;
|
|
}
|
|
}
|
|
|
|
};
|