core/idle: Move idle_schedule() out of the idle namespace
And rewrite it to use void pointers instead of inheritance. Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
parent
8e25c4d89e
commit
8474ff1907
|
@ -5,29 +5,32 @@
|
|||
|
||||
#include <queue>
|
||||
|
||||
static std::queue<idle :: IdleBase *> idle_queue;
|
||||
|
||||
struct idle_task {
|
||||
void (*idle_func)(void *);
|
||||
void *idle_data;
|
||||
};
|
||||
|
||||
|
||||
static std::queue<struct idle_task *> idle_queue;
|
||||
static float queued = 0.0;
|
||||
static float serviced = 0.0;
|
||||
|
||||
idle :: IdleBase :: IdleBase()
|
||||
{
|
||||
}
|
||||
|
||||
idle :: IdleBase :: ~IdleBase()
|
||||
void idle_schedule(void (*func)(void *), void *data)
|
||||
{
|
||||
}
|
||||
struct idle_task *task = new idle_task;
|
||||
task->idle_func = func;
|
||||
task->idle_data = data;
|
||||
|
||||
void idle :: IdleBase :: schedule()
|
||||
{
|
||||
idle_queue.push(this);
|
||||
idle_queue.push(task);
|
||||
queued++;
|
||||
}
|
||||
|
||||
|
||||
bool idle_run_task()
|
||||
{
|
||||
if (idle_queue.size() > 0) {
|
||||
idle_queue.front()->run();
|
||||
idle_queue.front()->idle_func(idle_queue.front()->idle_data);
|
||||
delete idle_queue.front();
|
||||
idle_queue.pop();
|
||||
serviced++;
|
||||
|
|
|
@ -71,7 +71,7 @@ struct scan_info {
|
|||
std :: string path;
|
||||
};
|
||||
|
||||
static void scan_path(struct scan_info &);
|
||||
static void scan_path(void *);
|
||||
|
||||
|
||||
|
||||
|
@ -88,37 +88,41 @@ static void tag_track(struct library *library, const std::string &filepath)
|
|||
static void process_path(struct library *library, const std :: string &dir,
|
||||
const std :: string &name)
|
||||
{
|
||||
struct scan_info scan = {
|
||||
.library = library,
|
||||
.path = dir + "/" + name,
|
||||
};
|
||||
struct scan_info *scan = new struct scan_info;
|
||||
scan->library = library;
|
||||
scan->path = dir + "/" + name;
|
||||
|
||||
if (g_file_test(scan.path.c_str(), G_FILE_TEST_IS_DIR) == true)
|
||||
idle :: schedule (scan_path, scan);
|
||||
else
|
||||
tag_track(library, scan.path);
|
||||
if (g_file_test(scan->path.c_str(), G_FILE_TEST_IS_DIR) == true)
|
||||
idle_schedule (scan_path, scan);
|
||||
else {
|
||||
tag_track(library, scan->path);
|
||||
delete scan;
|
||||
}
|
||||
}
|
||||
|
||||
static void scan_path(struct scan_info &scan)
|
||||
static void scan_path(void *data)
|
||||
{
|
||||
GDir *dir;
|
||||
const char *name;
|
||||
struct scan_info *scan = (struct scan_info *)data;
|
||||
|
||||
dir = g_dir_open(scan.path.c_str(), 0, NULL);
|
||||
dir = g_dir_open(scan->path.c_str(), 0, NULL);
|
||||
if (dir == NULL)
|
||||
return;
|
||||
|
||||
name = g_dir_read_name(dir);
|
||||
while (name != NULL) {
|
||||
process_path(scan.library, scan.path, name);
|
||||
process_path(scan->library, scan->path, name);
|
||||
name = g_dir_read_name(dir);
|
||||
}
|
||||
|
||||
track_db_commit();
|
||||
delete scan;
|
||||
}
|
||||
|
||||
static void validate_library(struct library *&library)
|
||||
static void validate_library(void *data)
|
||||
{
|
||||
struct library *library = (struct library *)data;
|
||||
struct db_entry *dbe, *next;
|
||||
struct track *track;
|
||||
|
||||
|
@ -176,14 +180,13 @@ void collection :: remove(struct library *library)
|
|||
|
||||
void collection :: update(struct library *library)
|
||||
{
|
||||
struct scan_info scan = {
|
||||
.library = library,
|
||||
};
|
||||
struct scan_info *scan = new struct scan_info;
|
||||
scan->library = library;
|
||||
|
||||
if (library) {
|
||||
scan.path = library->li_path;
|
||||
idle :: schedule(validate_library, library);
|
||||
idle :: schedule(scan_path, scan);
|
||||
scan->path = library->li_path;
|
||||
idle_schedule(validate_library, library);
|
||||
idle_schedule(scan_path, scan);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
/**
|
||||
* Copyright 2013 (c) Anna Schumaker.
|
||||
*/
|
||||
#ifndef OCARINA_CORE_IDLE_H
|
||||
#define OCARINA_CORE_IDLE_H
|
||||
|
||||
/**
|
||||
*
|
||||
* The idle queue is used to schedule function calls to run at a
|
||||
* later time. It is expected that a higher layer can determine
|
||||
* when the application is idle and call idle::run_task() accordingly.
|
||||
* when the application is idle and call idle_run_task() accordingly.
|
||||
*
|
||||
* The idle layer keeps a count of the number of tasks added to the queue
|
||||
* since the last time the queue was empty. Whenever a task is scheduled,
|
||||
|
@ -15,68 +11,11 @@
|
|||
* count is incremented by 1. These counters are reset to 0 once the queue
|
||||
* is empty.
|
||||
*/
|
||||
namespace idle
|
||||
{
|
||||
|
||||
/**
|
||||
* Base class used by the templated IdleTask class. This lets
|
||||
* us create an idle queue storing IdleBase pointers to get
|
||||
* around potential templating issues.
|
||||
*/
|
||||
class IdleBase {
|
||||
protected:
|
||||
/**
|
||||
* Adds the IdleBase to the idle queue and increments
|
||||
* the "queued" counter by 1.
|
||||
*/
|
||||
void schedule();
|
||||
|
||||
public:
|
||||
IdleBase(); /**< IdleBase constructor. */
|
||||
virtual ~IdleBase(); /**< IdleBase destructor. */
|
||||
virtual void run() = 0; /**< Run the idle task. */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generic IdleTask class. This class is templated to allow
|
||||
* for scheduling functions that take different types of data
|
||||
* parameters.
|
||||
*/
|
||||
template <class T>
|
||||
class IdleTask : public IdleBase {
|
||||
private:
|
||||
void (*_func)(T &); /**< Function to call when run. */
|
||||
T _data; /**< Data to pass to the function. */
|
||||
|
||||
public:
|
||||
/**
|
||||
* IdleTask constructor.
|
||||
*
|
||||
* @param func Function to call when running this task.
|
||||
* @param data Data to pass to the function.
|
||||
*/
|
||||
IdleTask(void (*)(T &), T);
|
||||
|
||||
~IdleTask(); /**< IdleTask destructor. */
|
||||
void run(); /**< Call func(), passing data as the argument. */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new IdleTask and adds it to the queue.
|
||||
*
|
||||
* @param func Function to call when running the new task.
|
||||
* @param data Data to pass to the function.
|
||||
*/
|
||||
template <class T>
|
||||
static inline void schedule(void (*func)(T &), T data)
|
||||
{
|
||||
new IdleTask<T>(func, data);
|
||||
}
|
||||
|
||||
};
|
||||
#ifndef OCARINA_CORE_IDLE_H
|
||||
#define OCARINA_CORE_IDLE_H
|
||||
|
||||
/* Called to schedule a function to run later. */
|
||||
void idle_schedule(void (*)(void *), void *);
|
||||
|
||||
/*
|
||||
* Called to run the next task on the idle queue.
|
||||
|
@ -87,6 +26,4 @@ bool idle_run_task();
|
|||
/* Called to find the percentage of idle tasks that have been run. */
|
||||
float idle_progress();
|
||||
|
||||
#include "idle.hpp"
|
||||
|
||||
#endif /* OCARINA_CORE_IDLE_H */
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
/**
|
||||
* Copyright 2013 (c) Anna Schumaker.
|
||||
*
|
||||
* DO NOT INCLUDE THIS FILE DIRECTLY. THIS IS A TEMPLATE DEFINITION FILE
|
||||
* AND ONLY MEANT TO BE INCLUDED BY include/idle.h!
|
||||
*/
|
||||
#ifndef OCARINA_IDLE_HPP
|
||||
#define OCARINA_IDLE_HPP
|
||||
|
||||
template <class T>
|
||||
idle :: IdleTask<T> :: IdleTask(void (*func)(T &), T data)
|
||||
: _func(func), _data(data)
|
||||
{
|
||||
IdleBase :: schedule();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
idle :: IdleTask<T> :: ~IdleTask()
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void idle :: IdleTask<T> :: run()
|
||||
{
|
||||
_func(_data);
|
||||
}
|
||||
|
||||
#endif /* OCARINA_IDLE_HPP */
|
|
@ -6,11 +6,12 @@
|
|||
#include <core/string.h>
|
||||
#include "test.h"
|
||||
|
||||
static float cur = -1;
|
||||
static unsigned int cur = -1;
|
||||
static bool func_passed = false;
|
||||
|
||||
static void inc_cur(float &expected)
|
||||
static void inc_cur(void *data)
|
||||
{
|
||||
unsigned int expected = GPOINTER_TO_INT(data);
|
||||
cur++;
|
||||
func_passed = (cur == expected);
|
||||
}
|
||||
|
@ -23,8 +24,8 @@ static void test_idle_queue(unsigned int n)
|
|||
test_equal(idle_progress(), (float)1.0);
|
||||
test_equal(idle_run_task(), false);
|
||||
|
||||
for (float i = 0; i < n; i++)
|
||||
idle :: schedule(inc_cur, i);
|
||||
for (unsigned int i = 0; i < n; i++)
|
||||
idle_schedule(inc_cur, GINT_TO_POINTER(i));
|
||||
test_equal(idle_progress(), (float)0.0);
|
||||
|
||||
for (unsigned int i = 0; i < (n - 1); i++) {
|
||||
|
|
Loading…
Reference in New Issue