design: Sort potential nodes by name
This will give some better stability to the design document, since entries won't shift around based on python memory locations. Signed-off-by: Bryan Schumaker <bjschuma@gmail.com>
This commit is contained in:
parent
c65e0bdb2a
commit
72c7261ac8
236
design.txt
236
design.txt
|
@ -63,12 +63,6 @@ Install:
|
|||
|
||||
|
||||
|
||||
Versioning: (include/version.h)
|
||||
This file contains a simple function for returning a string stating
|
||||
the current version.
|
||||
|
||||
|
||||
|
||||
Printing: (include/print.h>
|
||||
Sometimes text needs to be printed to the screen so users (or debuggers)
|
||||
know what is going on.
|
||||
|
@ -81,44 +75,13 @@ API:
|
|||
|
||||
|
||||
|
||||
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
|
||||
types can be placed on the same idle queue.
|
||||
Versioning: (include/version.h)
|
||||
This file contains a simple function for returning a string stating
|
||||
the current version.
|
||||
|
||||
- IdleBase:
|
||||
class IdleBase {
|
||||
IdleBase();
|
||||
~IdleBase();
|
||||
virtual void run() = 0;
|
||||
};
|
||||
|
||||
- IdleTask:
|
||||
template <class T>
|
||||
class IdleTask : IdleBase {
|
||||
private:
|
||||
void (*func)(T *);
|
||||
T *data;
|
||||
|
||||
public:
|
||||
IdleTask(void (*)(T *), T *);
|
||||
void run();
|
||||
};
|
||||
|
||||
- Queue:
|
||||
deque(IdleTask *> idle_queue;
|
||||
float queued = 0.0
|
||||
float serviced = 0.0
|
||||
|
||||
- API:
|
||||
template <class T>
|
||||
void idle :: schedule(void (*)(T *), T *);
|
||||
Schedule a function to run later.
|
||||
queued++
|
||||
bool idle :: run_task()
|
||||
Run the next task on the queue. Return true if a task was
|
||||
found, and false otherwise.
|
||||
scheduled++, reset to zero if idle queue is empty.
|
||||
API:
|
||||
const char *get_version();
|
||||
Returns a string describing the current version.
|
||||
|
||||
|
||||
|
||||
|
@ -226,18 +189,44 @@ On-disk files: (lib/file.cpp)
|
|||
|
||||
|
||||
|
||||
Preferences: (lib/prefs.cpp)
|
||||
Preferences make use of a special index where the set<int> is always
|
||||
size 1. Preferences will be in the prefs namespace.
|
||||
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
|
||||
types can be placed on the same idle queue.
|
||||
|
||||
- Index:
|
||||
Index prefs(prefs.idx);
|
||||
- IdleBase:
|
||||
class IdleBase {
|
||||
IdleBase();
|
||||
~IdleBase();
|
||||
virtual void run() = 0;
|
||||
};
|
||||
|
||||
- IdleTask:
|
||||
template <class T>
|
||||
class IdleTask : IdleBase {
|
||||
private:
|
||||
void (*func)(T *);
|
||||
T *data;
|
||||
|
||||
public:
|
||||
IdleTask(void (*)(T *), T *);
|
||||
void run();
|
||||
};
|
||||
|
||||
- Queue:
|
||||
deque(IdleTask *> idle_queue;
|
||||
float queued = 0.0
|
||||
float serviced = 0.0
|
||||
|
||||
- API:
|
||||
prefs :: set(string, val);
|
||||
prefs.replace(string, val);
|
||||
prefs :: get(string)
|
||||
return prefs[string].begin()
|
||||
template <class T>
|
||||
void idle :: schedule(void (*)(T *), T *);
|
||||
Schedule a function to run later.
|
||||
queued++
|
||||
bool idle :: run_task()
|
||||
Run the next task on the queue. Return true if a task was
|
||||
found, and false otherwise.
|
||||
scheduled++, reset to zero if idle queue is empty.
|
||||
|
||||
|
||||
|
||||
|
@ -317,70 +306,6 @@ Database: (lib/database.cpp)
|
|||
|
||||
|
||||
|
||||
Playlist: (lib/playlist.cpp)
|
||||
Playlists are a list of songs that the user has configured to play. I
|
||||
will create a pool of playlists that will be filled by user actions.
|
||||
|
||||
Playlists will be put on a "deck" that is used to give an order to the
|
||||
next songs played. When deck :: next() is called, find the first
|
||||
playlist with PL_ENABLED set and call that playlists next() function.
|
||||
|
||||
When a playlist is empty, remove it from the deck.
|
||||
|
||||
- Flags:
|
||||
enum playlist_flags {
|
||||
PL_ENABLED (1 << 0),
|
||||
PL_RANDOM (1 << 1),
|
||||
PL_DRAIN (1 << 2),
|
||||
};
|
||||
|
||||
- Playlist:
|
||||
class Playlist : public Database {
|
||||
private:
|
||||
database<track_id> tracks; /* Keyed on track id */
|
||||
unsigned int cur;
|
||||
unsigned int flags;
|
||||
public:
|
||||
Playlist();
|
||||
void add(vector<track_id> &);
|
||||
void del(vector<track_id> &);
|
||||
void set_flag(playlist_flags);
|
||||
const unsigned int get_flags();
|
||||
unsigned int size()
|
||||
|
||||
File &operator<<(File &);
|
||||
File &operator>>(File &);
|
||||
|
||||
void sort();
|
||||
void next();
|
||||
}
|
||||
|
||||
File << flags << cur << tracks[0] << tracks[1] << ... << tracks[N];
|
||||
|
||||
- Deck:
|
||||
list<Playlist> deck;
|
||||
File << deck[0] << endl;
|
||||
File << deck[1] << endl;
|
||||
File << deck[N] << endl;
|
||||
|
||||
- API
|
||||
deck :: init();
|
||||
Read in the playlist file
|
||||
deck :: new();
|
||||
Adds a new playlist to the deck
|
||||
deck :: rm(N)
|
||||
Removes playlist N from the deck
|
||||
Playlist *deck :: get(N)
|
||||
Return playlist N from the deck
|
||||
|
||||
- TODO <<<<<
|
||||
What if each playlist has its own playlist_id for tracks? This would
|
||||
allow for simpler removals, since I won't need to search for a track id.
|
||||
I can easily create a function for mapping a list of playlist_ids to
|
||||
track_ids...
|
||||
|
||||
|
||||
|
||||
Index: (lib/index.cpp)
|
||||
An inverted index allows me to map multiple values to a single key.
|
||||
|
||||
|
@ -607,6 +532,85 @@ Library: (lib/library.cpp)
|
|||
|
||||
|
||||
|
||||
Playlist: (lib/playlist.cpp)
|
||||
Playlists are a list of songs that the user has configured to play. I
|
||||
will create a pool of playlists that will be filled by user actions.
|
||||
|
||||
Playlists will be put on a "deck" that is used to give an order to the
|
||||
next songs played. When deck :: next() is called, find the first
|
||||
playlist with PL_ENABLED set and call that playlists next() function.
|
||||
|
||||
When a playlist is empty, remove it from the deck.
|
||||
|
||||
- Flags:
|
||||
enum playlist_flags {
|
||||
PL_ENABLED (1 << 0),
|
||||
PL_RANDOM (1 << 1),
|
||||
PL_DRAIN (1 << 2),
|
||||
};
|
||||
|
||||
- Playlist:
|
||||
class Playlist : public Database {
|
||||
private:
|
||||
database<track_id> tracks; /* Keyed on track id */
|
||||
unsigned int cur;
|
||||
unsigned int flags;
|
||||
public:
|
||||
Playlist();
|
||||
void add(vector<track_id> &);
|
||||
void del(vector<track_id> &);
|
||||
void set_flag(playlist_flags);
|
||||
const unsigned int get_flags();
|
||||
unsigned int size()
|
||||
|
||||
File &operator<<(File &);
|
||||
File &operator>>(File &);
|
||||
|
||||
void sort();
|
||||
void next();
|
||||
}
|
||||
|
||||
File << flags << cur << tracks[0] << tracks[1] << ... << tracks[N];
|
||||
|
||||
- Deck:
|
||||
list<Playlist> deck;
|
||||
File << deck[0] << endl;
|
||||
File << deck[1] << endl;
|
||||
File << deck[N] << endl;
|
||||
|
||||
- API
|
||||
deck :: init();
|
||||
Read in the playlist file
|
||||
deck :: new();
|
||||
Adds a new playlist to the deck
|
||||
deck :: rm(N)
|
||||
Removes playlist N from the deck
|
||||
Playlist *deck :: get(N)
|
||||
Return playlist N from the deck
|
||||
|
||||
- TODO <<<<<
|
||||
What if each playlist has its own playlist_id for tracks? This would
|
||||
allow for simpler removals, since I won't need to search for a track id.
|
||||
I can easily create a function for mapping a list of playlist_ids to
|
||||
track_ids...
|
||||
|
||||
|
||||
|
||||
Preferences: (lib/prefs.cpp)
|
||||
Preferences make use of a special index where the set<int> is always
|
||||
size 1. Preferences will be in the prefs namespace.
|
||||
|
||||
- Index:
|
||||
Index prefs(prefs.idx);
|
||||
|
||||
- API:
|
||||
prefs :: set(string, val);
|
||||
prefs.replace(string, val);
|
||||
prefs :: get(string)
|
||||
return prefs[string].begin()
|
||||
|
||||
|
||||
|
||||
Future work:
|
||||
I want to set reasonable expectations for Ocarina 6 so that I don't
|
||||
have to spend a large amount of time coding before releasing something
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import os
|
||||
|
||||
created_files = dict()
|
||||
nodes = dict()
|
||||
node_names = dict()
|
||||
|
||||
class DesignFile:
|
||||
def read_files(self, file):
|
||||
|
@ -41,15 +41,17 @@ class DesignFile:
|
|||
self.read_depends(f)
|
||||
else:
|
||||
self.lines += [line]
|
||||
nodes[self.name] = self
|
||||
node_names[self.name] = self
|
||||
|
||||
|
||||
def pump_depends(nodes):
|
||||
options = []
|
||||
res = None
|
||||
for n in nodes:
|
||||
if len(n.depend_nodes) == 0:
|
||||
res = n
|
||||
break
|
||||
options += [ n.name ]
|
||||
options.sort()
|
||||
res = node_names[ options[0] ]
|
||||
nodes.remove(res)
|
||||
for n in nodes:
|
||||
if res in n.depend_nodes:
|
||||
|
@ -61,14 +63,14 @@ def resolve_dependencies():
|
|||
tmp = set()
|
||||
res = []
|
||||
|
||||
for key, node in nodes.items():
|
||||
for key, node in node_names.items():
|
||||
tmp.add(node)
|
||||
for depend in node.depends:
|
||||
if depend == "*":
|
||||
node.depend_nodes = set(nodes.values())
|
||||
node.depend_nodes = set(node_names.values())
|
||||
else:
|
||||
node.depend_nodes.add(nodes[depend])
|
||||
node.depend_nodes.discard(nodes[node.name])
|
||||
node.depend_nodes.add(node_names[depend])
|
||||
node.depend_nodes.discard(node_names[node.name])
|
||||
|
||||
while len(tmp) > 0:
|
||||
res += [ pump_depends(tmp) ]
|
||||
|
|
|
@ -8,3 +8,7 @@ install
|
|||
Versioning: (include/version.h)
|
||||
This file contains a simple function for returning a string stating
|
||||
the current version.
|
||||
|
||||
API:
|
||||
const char *get_version();
|
||||
Returns a string describing the current version.
|
||||
|
|
Loading…
Reference in New Issue