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:
Anna Schumaker 2015-11-10 13:52:24 -05:00
parent 8e25c4d89e
commit 8474ff1907
5 changed files with 47 additions and 131 deletions

View File

@ -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++;

View File

@ -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);
}
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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++) {