idle: Update design and unit test

I didn't have any changes to make to the IdleQueue itself, but I did
need to update the unit test and reword a few things in the design.

Signed-off-by: Anna Schuamker <schumaker.anna@gmail.com>
This commit is contained in:
Anna Schumaker 2014-03-16 13:09:33 -04:00 committed by Anna Schumaker
parent 58ed47b37c
commit 14879b03fd
10 changed files with 83 additions and 99 deletions

14
DESIGN
View File

@ -457,15 +457,13 @@ Filter:
Idle queue: (lib/idle.cpp)
The idle queue is used to schedule tasks to run at a later time. Idle
tasks must inherit from the IdleBase class so that multiple templated
IdleTask pointers can be placed on the same idle queue.
Idle queue:
The idle queue is used to schedule function calls that run at a later
time.
Creating an idle queue in idle.hpp will create a new queue for every
file that idle.h is included in. I want to have a single, shared
idle queue used by the entire application so to get around this the
IdleBase class is used and implemented in lib/idle.cpp.
A single queue instance needs to be able to run functions that take
different types of arguments. This is done by creating an IdleBase
base class that the templated IdleTask class inherits from.
- IdleBase:
class IdleBase {

View File

@ -10,6 +10,7 @@ namespace idle
class IdleBase {
protected:
void schedule();
public:
IdleBase();
virtual ~IdleBase();
@ -22,6 +23,7 @@ namespace idle
private:
void (*func)(T &);
T data;
public:
IdleTask(void (*)(T &), T);
~IdleTask();

View File

@ -9,7 +9,7 @@
template <class T>
idle :: IdleTask<T> :: IdleTask(void (*fn)(T &), T param)
: func(fn), data(param)
: func(fn), data(param)
{
IdleBase :: schedule();
}

View File

@ -6,8 +6,8 @@
#include <queue>
static std::queue<idle :: IdleBase *> idle_queue;
static float queued = 0;
static float serviced = 0;
static float queued = 0.0;
static float serviced = 0.0;
idle :: IdleBase :: IdleBase()
{
@ -36,14 +36,14 @@ bool idle :: run_task()
if (idle_queue.size() > 0)
return true;
queued = 0;
serviced = 0;
queued = 0.0;
serviced = 0.0;
return false;
}
float idle :: get_progress()
{
if (idle_queue.size() == 0)
return 1;
return 1.0;
return serviced / queued;
}

View File

@ -8,8 +8,8 @@ if sys.argv.count("tests") > 0:
src = SConscript("src/Sconscript")
tests = [ "version", "file", "db_entry", "database", "index", "filter" ]
#scripts = [ "idle", "playlist", "library", "playqueue", "deck", "audio", "gui" ]
tests = [ "version", "file", "db_entry", "database", "index", "filter", "idle" ]
#scripts = [ "playlist", "library", "playqueue", "deck", "audio", "gui" ]
prev = None

7
tests/idle Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash
# Copyright 2014 (c) Anna Schumaker
. $(dirname $0)/_functions
new_test "Idle Queue Test"
src/idle.run

View File

@ -1,6 +0,0 @@
#!/usr/bin/python
Import("Test", "CONFIG")
CONFIG.IDLE = True
Test("idle", "idle.cpp")

View File

@ -1,64 +0,0 @@
/*
* Copyright 2013 (c) Anna Schumaker.
*/
#include <idle.h>
#include <print.h>
#include <string>
struct TestStruct {
int i;
unsigned int u;
char c;
std::string s;
};
static void test_0(unsigned int &i)
{
print("Test 0: %u\n", i);
}
static void test_1(int &i)
{
print("Test 1: %d\n", i);
}
static void test_2(char &i)
{
print("Test 2: %c\n", i);
}
static void test_3(std::string &str)
{
print("Test 3: %s\n", str.c_str());
}
static void test_4(TestStruct &struc)
{
print("Test 4: %d %u %c %s\n", struc.i, struc.u, struc.c, struc.s.c_str());
}
static void test_5(TestStruct *&struc)
{
print("Test 5: %d %u %c %s\n", struc->i, struc->u, struc->c, struc->s.c_str());
}
int main(int argc, char **argv)
{
std::string string = "This is a string";
TestStruct struc1 = { -4, 4, 'd', "This is another string", };
TestStruct struc2 = { -5, 5, 'e', "This is yet another string", };
idle :: schedule(test_0, (unsigned int) 0);
idle :: schedule(test_1, 1);
idle :: schedule(test_2, 'b');
idle :: schedule(test_3, string);
idle :: schedule(test_4, struc1);
idle :: schedule(test_5, &struc2);
do {
print("Idle queue progress: %f\n", idle :: get_progress());
} while (idle :: run_task() == true);
print("Idle queue progress: %f\n", idle :: get_progress());
return 0;
}

View File

@ -1,13 +0,0 @@
Idle queue progress: 0.000000
Test 0: 0
Idle queue progress: 0.166667
Test 1: 1
Idle queue progress: 0.333333
Test 2: b
Idle queue progress: 0.500000
Test 3: This is a string
Idle queue progress: 0.666667
Test 4: -4 4 d This is another string
Idle queue progress: 0.833333
Test 5: -5 5 e This is yet another string
Idle queue progress: 1.000000

60
tests/src/idle.cpp Normal file
View File

@ -0,0 +1,60 @@
/*
* Copyright 2014 (c) Anna Schumaker.
* Test the idle queue
*/
#include <idle.h>
#include <print.h>
#include <stdlib.h>
static unsigned int test_num = 0;
static unsigned int cur = -1;
void test_results(bool success, unsigned int line)
{
print(" %u: ", test_num);
if (success)
print("Success!\n");
else {
print("FAILED (%u) =(", line);
exit(1);
}
test_num++;
}
void test_progress(unsigned int expected, unsigned int multiplier,
unsigned int line)
{
unsigned int prog = (idle :: get_progress() * multiplier);
test_results(prog == expected, line);
}
void inc_cur(unsigned int &expected)
{
cur++;
test_results(cur == expected, __LINE__);
}
int main(int argc, char **argv)
{
unsigned int i, num = 10;
test_progress(num, num, __LINE__);
for (i = 0; i < num; i++)
idle :: schedule(inc_cur, i);
test_progress(0, num, __LINE__);
test_results(idle :: get_progress() == 0.0, __LINE__);
for (i = 0; i < (num - 1); i++) {
test_results(idle :: run_task(), __LINE__);
test_progress(i + 1, num, __LINE__);
}
test_results(idle :: run_task() == false, __LINE__);
test_progress(i + 1, num, __LINE__);
test_results(idle :: run_task() == false, __LINE__);
test_progress(num, num, __LINE__);
return 0;
}