changed list fn's to accept lists instead of list pointers
parent
1197f4d682
commit
e560e476f7
|
@ -4,9 +4,6 @@
|
|||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
// TODO: change from using pointers to everything, to just using the things
|
||||
// (since they're structs anyway)
|
||||
|
||||
/** description
|
||||
* An interface to a simple linked-list that can be used to implement lists,
|
||||
* queues, stacks, and things
|
||||
|
@ -37,7 +34,7 @@
|
|||
*
|
||||
* - If you want to iterate through a list, use something like
|
||||
*
|
||||
* for (node_t * node = list->head; node; node = node->_private.next) {
|
||||
* for (node_t * node = list.head; node; node = node->_private.next) {
|
||||
* // do stuff
|
||||
* }
|
||||
*
|
||||
|
@ -69,25 +66,23 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
|
||||
typedef struct list__node_t {
|
||||
void * next; // will be cast to `list__node_t` before use
|
||||
void * next; // will be cast to `list__node_t *` before use
|
||||
} list__node_t;
|
||||
|
||||
typedef struct list__list_t {
|
||||
void * head; // will be cast to `list__node_t` before use
|
||||
void * tail; // will be cast to `list__node_t` before use
|
||||
void * head; // will be cast to `list__node_t *` before use
|
||||
void * tail; // will be cast to `list__node_t *` before use
|
||||
uint8_t length;
|
||||
} list__list_t;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void * list__insert ( list__list_t * list,
|
||||
int8_t index,
|
||||
void * node );
|
||||
void * list__peek (list__list_t * list, int8_t index);
|
||||
void * list__pop_index (list__list_t * list, int8_t index);
|
||||
void * list__pop_node (list__list_t * list, void * node);
|
||||
void * list__pop_node_next (list__list_t * list, void * node);
|
||||
void list__free (list__list_t * list);
|
||||
void * list__insert (list__list_t list, int8_t index, void * node);
|
||||
void * list__peek (list__list_t list, int8_t index);
|
||||
void * list__pop_index (list__list_t list, int8_t index);
|
||||
void * list__pop_node (list__list_t list, void * node);
|
||||
void * list__pop_node_next (list__list_t list, void * node);
|
||||
void list__free_all (list__list_t list);
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -125,12 +120,12 @@ void list__free (list__list_t * list);
|
|||
* Insert `node` at position `index % list->length`
|
||||
*
|
||||
* Arguments:
|
||||
* - `list`: A pointer to the list to be operated on
|
||||
* - `list`: The list to be operated on
|
||||
* - `index`: An `int8_t` indicating the position the new node will occupy
|
||||
* - `node`: A pointer to the node to insert
|
||||
* - `node`: A `void *` pointer to the node to insert
|
||||
*
|
||||
* Returns:
|
||||
* - success: A `void *` pointer to the new node
|
||||
* - success: A `void *` pointer to the inserted node
|
||||
* - failure: `NULL`
|
||||
*/
|
||||
|
||||
|
@ -139,8 +134,8 @@ void list__free (list__list_t * list);
|
|||
* Return a pointer to the node at position `index % list->length`
|
||||
*
|
||||
* Arguments:
|
||||
* - `list`: A pointer to the list to be operated on
|
||||
* - `index`: An `int8_t` indicating the position of the node to peek at
|
||||
* - `list`: The list to be operated on
|
||||
* - `index`: An `int8_t` indicating the position the new node will occupy
|
||||
*
|
||||
* Returns:
|
||||
* - success: A `void *` pointer to the node at position `index % list->length`
|
||||
|
@ -153,12 +148,12 @@ void list__free (list__list_t * list);
|
|||
* the node from the list
|
||||
*
|
||||
* Warnings:
|
||||
* - Does not free the node's memory - this is the calling function's
|
||||
* - Does not free the node's memory; this is the calling function's
|
||||
* responsibility.
|
||||
*
|
||||
* Arguments:
|
||||
* - `list`: A pointer to the list to be operated on
|
||||
* - `index`: An `int8_t` indicating the position of the node to pop
|
||||
* - `list`: The list to be operated on
|
||||
* - `index`: An `int8_t` indicating the position the new node will occupy
|
||||
*
|
||||
* Returns:
|
||||
* - success: A `void *` pointer to the node at position `index % list->length`
|
||||
|
@ -170,12 +165,12 @@ void list__free (list__list_t * list);
|
|||
* Remove `node` from the list, and return a pointer to it
|
||||
*
|
||||
* Warnings:
|
||||
* - Does not free the node's memory - this is the calling function's
|
||||
* - Does not free the node's memory; this is the calling function's
|
||||
* responsibility.
|
||||
*
|
||||
* Arguments:
|
||||
* - `list`: A pointer to the list to be operated on
|
||||
* - `node`: A pointer to the node to pop (and free)
|
||||
* - `list`: The list to be operated on
|
||||
* - `node`: A `void *` pointer to the node to pop
|
||||
*
|
||||
* Returns:
|
||||
* - success: A `void *` pointer to `node`
|
||||
|
@ -185,11 +180,11 @@ void list__free (list__list_t * list);
|
|||
// === list__pop_node_next() ===
|
||||
/** functions/list__pop_node_next/description
|
||||
* Remove `node` from the list, free its memory, and return a pointer to the
|
||||
* next element, if the node exists
|
||||
* next element, if such an element exists
|
||||
*
|
||||
* Arguments:
|
||||
* - `list`: A pointer to the list to be operated on
|
||||
* - `node`: A pointer to the node to pop (and free)
|
||||
* - `list`: The list to be operated on
|
||||
* - `node`: A `void *` pointer to the node to pop (and free)
|
||||
*
|
||||
* Returns:
|
||||
* - success: A `void *` pointer to the next node in the list
|
||||
|
@ -199,14 +194,14 @@ void list__free (list__list_t * list);
|
|||
* - This is helpful, sometimes, when iterating through a list, some of who's
|
||||
* members need to be removed. If performance is critical, keep in mind that
|
||||
* it does have the O(n) time penalty of having to re-search the list for the
|
||||
* given node's predecesor before removing the node.
|
||||
* given node's predecessor before removing the node.
|
||||
*/
|
||||
|
||||
// === list__free() ===
|
||||
/** functions/list__free/description
|
||||
// === list__free_all() ===
|
||||
/** functions/list__free_all/description
|
||||
* Free all node pointers in `list`
|
||||
*
|
||||
* Arguments:
|
||||
* - `list`: A pointer to the list to be operated on
|
||||
* - `list`: The list to be operated on
|
||||
*/
|
||||
|
||||
|
|
|
@ -15,151 +15,154 @@
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// since we'll be casting to type `list__node_t *` a lot
|
||||
#define N(name) ((list__node_t *)name)
|
||||
#define list_t list__list_t
|
||||
#define node_t list__node_t
|
||||
|
||||
// since we'll be casting to `node_t *` a lot
|
||||
#define N(name) ((node_t *) name)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void * list__insert(list__list_t * list, int8_t index, void * node) {
|
||||
if (!node) return NULL;
|
||||
void * list__insert(list_t list, int8_t index, void * node) {
|
||||
// if `node` does not exist
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
list->length++;
|
||||
list.length++;
|
||||
|
||||
if (list->length == 1) {
|
||||
if (list.length == 1) {
|
||||
// insert as only node (no others exist yet)
|
||||
list->head = node;
|
||||
list->tail = node;
|
||||
list.head = node;
|
||||
list.tail = node;
|
||||
N(node)->next = NULL;
|
||||
|
||||
} else {
|
||||
index %= list->length;
|
||||
index %= list.length;
|
||||
|
||||
if (index == 0) {
|
||||
// insert as first node
|
||||
N(node)->next = list->head;
|
||||
list->head = node;
|
||||
N(node)->next = list.head;
|
||||
list.head = node;
|
||||
|
||||
} else if (index == list->length-1) {
|
||||
} else if (index == list.length-1) {
|
||||
// insert as last node
|
||||
N(list->tail)->next = node;
|
||||
list->tail = node;
|
||||
N(list.tail)->next = node;
|
||||
list.tail = node;
|
||||
N(node)->next = NULL;
|
||||
|
||||
} else {
|
||||
// insert as other node
|
||||
void * previous = list->head;
|
||||
node_t * previous = list.head;
|
||||
for (uint8_t i=1; i<index; i++)
|
||||
previous = N(previous)->next;
|
||||
N(node)->next = N(previous)->next;
|
||||
N(previous)->next = node;
|
||||
previous = previous->next;
|
||||
N(node)->next = previous->next;
|
||||
previous->next = node;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void * list__peek(list__list_t * list, int8_t index) {
|
||||
void * list__peek(list_t list, int8_t index) {
|
||||
// if no nodes exist
|
||||
if (list->length == 0)
|
||||
if (list.length == 0)
|
||||
return NULL;
|
||||
|
||||
index %= list->length;
|
||||
index %= list.length;
|
||||
|
||||
// if last node
|
||||
if (index == list->length-1)
|
||||
return list->tail;
|
||||
if (index == list.length-1)
|
||||
return list.tail;
|
||||
|
||||
// else
|
||||
void * node = list->head;
|
||||
node_t * node = list.head;
|
||||
for (uint8_t i=0; i<index; i++)
|
||||
node = N(node)->next;
|
||||
return node;
|
||||
}
|
||||
|
||||
void * list__pop_index(list__list_t * list, int8_t index) {
|
||||
void * list__pop_index(list_t list, int8_t index) {
|
||||
// if no nodes exist
|
||||
if (list->length == 0)
|
||||
if (list.length == 0)
|
||||
return NULL;
|
||||
|
||||
index %= list->length;
|
||||
index %= list.length;
|
||||
|
||||
void * node;
|
||||
node_t * node;
|
||||
|
||||
if (index == 0) {
|
||||
// pop first node
|
||||
node = list->head;
|
||||
list->head = N(node)->next;
|
||||
node = list.head;
|
||||
list.head = N(node)->next;
|
||||
|
||||
} else {
|
||||
// find the `index-1`th node
|
||||
void * previous = list->head;
|
||||
node_t * previous = list.head;
|
||||
for (uint8_t i=1; i<index; i++)
|
||||
previous = N(previous)->next;
|
||||
previous = previous->next;
|
||||
|
||||
// if last node
|
||||
if (index == list->length-1)
|
||||
list->tail = previous;
|
||||
if (index == list.length-1)
|
||||
list.tail = previous;
|
||||
|
||||
// pop the node at `index`
|
||||
node = N(previous)->next;
|
||||
N(previous)->next = N(node)->next;
|
||||
node = previous->next;
|
||||
previous->next = N(node)->next;
|
||||
}
|
||||
|
||||
list->length--;
|
||||
list.length--;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void * list__pop_node(list__list_t * list, void * node) {
|
||||
// if `node` is `NULL` or no nodes exist
|
||||
if (!node || !list->head)
|
||||
void * list__pop_node(list_t list, void * node) {
|
||||
// if `node` does not exist, or no nodes exist
|
||||
if (!node || list.length == 0)
|
||||
return NULL;
|
||||
|
||||
void * previous = list->head;
|
||||
node_t * previous = list.head;
|
||||
|
||||
if (node == list->head) {
|
||||
if (node == list.head) {
|
||||
// pop first node
|
||||
list->head = N(node)->next;
|
||||
list.head = N(node)->next;
|
||||
|
||||
} else {
|
||||
// find the previous node (if `node` is in `list`)
|
||||
while (N(previous)->next != node) {
|
||||
previous = N(previous)->next;
|
||||
while (previous->next != node) {
|
||||
previous = previous->next;
|
||||
if (!previous)
|
||||
return NULL; // `node` not found
|
||||
}
|
||||
|
||||
// if last node
|
||||
if (node == list->tail)
|
||||
list->tail = previous;
|
||||
if (node == list.tail)
|
||||
list.tail = previous;
|
||||
|
||||
// pop the node
|
||||
N(previous)->next = N(node)->next;
|
||||
previous->next = N(node)->next;
|
||||
}
|
||||
|
||||
list->length--;
|
||||
list.length--;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void * list__pop_node_next(list__list_t * list, void * node) {
|
||||
void * list__pop_node_next(list_t list, void * node ) {
|
||||
if (!list__pop_node(list, node))
|
||||
return NULL;
|
||||
return NULL; // `node` was not in `list`
|
||||
|
||||
void * next = N(node)->next;
|
||||
node_t * next = N(node)->next;
|
||||
free(node);
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
void list__free(list__list_t * list) {
|
||||
if (list) {
|
||||
void * node;
|
||||
while (list->head) {
|
||||
node = list->head;
|
||||
list->head = N(list->head)->next;
|
||||
free(node);
|
||||
}
|
||||
void list__free_all(list_t list) {
|
||||
node_t * node;
|
||||
while (list.head) {
|
||||
node = list.head;
|
||||
list.head = node->next;
|
||||
free(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
|
||||
static volatile uint16_t _milliseconds__counter;
|
||||
static list__list_t * _milliseconds__scheduled_events = &(list__list_t){};
|
||||
static list__list_t _milliseconds__scheduled_events;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -45,10 +45,10 @@
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
uint8_t event_list__append ( list__list_t * list,
|
||||
uint16_t ticks,
|
||||
uint8_t event_list__append ( list__list_t list,
|
||||
uint16_t ticks,
|
||||
void(*function)(void) );
|
||||
void event_list__tick (list__list_t * list);
|
||||
void event_list__tick (list__list_t list);
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
@ -29,10 +29,10 @@ typedef struct {
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
uint8_t event_list__append( list__list_t * list,
|
||||
uint16_t ticks,
|
||||
uint8_t event_list__append( list__list_t list,
|
||||
uint16_t ticks,
|
||||
void(*function)(void) ) {
|
||||
if (!function || !list) return 0; // success: nothing to do
|
||||
if (!function) return 0; // success: nothing to do
|
||||
|
||||
event_t * event = malloc(sizeof(event_t));
|
||||
if (!event) return 1; // error
|
||||
|
@ -47,9 +47,7 @@ uint8_t event_list__append( list__list_t * list,
|
|||
return 0; // success
|
||||
}
|
||||
|
||||
void event_list__tick(list__list_t * list) {
|
||||
if (!list) return;
|
||||
|
||||
void event_list__tick(list__list_t list) {
|
||||
event_t * next;
|
||||
event_t * run = NULL; // for keeping track of events to run
|
||||
|
||||
|
@ -57,7 +55,7 @@ void event_list__tick(list__list_t * list) {
|
|||
// - keep track of the events that need to be run this "tick"
|
||||
// - note that every other event is one "tick" closer to being run
|
||||
ATOMIC_BLOCK( ATOMIC_RESTORESTATE ) {
|
||||
for (event_t * event = list->head; event;) {
|
||||
for (event_t * event = list.head; event;) {
|
||||
if (event->ticks == 0) {
|
||||
next = event->_private.next;
|
||||
list__pop_node(list, event);
|
||||
|
|
|
@ -17,15 +17,15 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define DEFINE_TIMER(name) \
|
||||
static uint16_t _##name##__counter; \
|
||||
static list__list_t * _##name##__scheduled_events = &(list__list_t){}; \
|
||||
static uint16_t _##name##__counter; \
|
||||
static list__list_t _##name##__scheduled_events; \
|
||||
\
|
||||
uint16_t timer__get_##name(void) { \
|
||||
return _##name##__counter; \
|
||||
} \
|
||||
uint8_t timer__schedule_##name(uint16_t name, void(*function)(void)) { \
|
||||
uint8_t timer__schedule_##name(uint16_t ticks, void(*function)(void)) { \
|
||||
return event_list__append( \
|
||||
_##name##__scheduled_events, name, function ); \
|
||||
_##name##__scheduled_events, ticks, function ); \
|
||||
} \
|
||||
void timer___tick_##name(void) { \
|
||||
_##name##__counter++; \
|
||||
|
|
Loading…
Reference in New Issue