(still working on the layer-stack)
parent
e3df599b85
commit
98970c0698
|
@ -45,12 +45,12 @@ uint8_t layer_stack__size (void);
|
|||
* Return the `offset`th element of the layer stack
|
||||
*
|
||||
* Arguments:
|
||||
* - `offset`: the offset of the element to return (with the top being
|
||||
* - `offset`: the offset of the element to return (with the top element being
|
||||
* `offset = 0`)
|
||||
*
|
||||
* Returns:
|
||||
* - success: the layer-number of the `offset`th element, or `0` if `offset`
|
||||
* was out of bounds
|
||||
* - success: the layer-number of the `offset`th element (which may be `0`), or
|
||||
* `0` if `offset` was out of bounds
|
||||
*/
|
||||
|
||||
// === layer_stack__push() ===
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
* Implements the layer-stack defined in "../layer-stack.h"
|
||||
*
|
||||
* TODO:
|
||||
* - reorganize (if necessary) / check everything
|
||||
* - properly document (with script-readable comment blocks...)
|
||||
* - see the '.h' for interface TODOs
|
||||
* - should we split most of this functionality into a general 'flex_array' or
|
||||
* something? we probably should... think about how to do that.
|
||||
*/
|
||||
|
||||
|
||||
|
@ -20,33 +20,45 @@
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define BLOCK_SIZE 5 // the number of elements to (de)allocate at once
|
||||
#define MARGIN 3 // the number of elements keep open (when deallocating)
|
||||
/** macros/BLOCK_SIZE/description
|
||||
* The number of positions to allocate or deallocate at once
|
||||
*/
|
||||
#define BLOCK_SIZE 5
|
||||
|
||||
/** macros/MARGIN/description
|
||||
* The number of positions to keep unused when deallocating
|
||||
*/
|
||||
#define MARGIN 3
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
typedef struct {
|
||||
uint8_t id;
|
||||
uint8_t number;
|
||||
uint8_t id; // layer-id
|
||||
uint8_t number; // layer-number
|
||||
} element_t;
|
||||
|
||||
uint8_t _allocated = 0;
|
||||
uint8_t _filled = 0;
|
||||
element_t * _stack = NULL;
|
||||
uint8_t _allocated = 0; // the number of positions allocated
|
||||
uint8_t _filled = 0; // the number of positions filled
|
||||
element_t * _stack = NULL; // (to be used as an array)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// TODO: is this the cleanest implemenetation?
|
||||
// TODO: should this be split out into a separate "lib/data-types/flex-array"
|
||||
// or something?
|
||||
/** functions/_resize_stack/description
|
||||
* Resize the stack (in increments of `BLOCK_SIZE` positions) so that at least
|
||||
* 1 and no more than `MARGIN + BLOCK_SIZE - 1` positions are unused.
|
||||
*
|
||||
* Returns:
|
||||
* - success: `0`
|
||||
* - failure: [other]
|
||||
*/
|
||||
static uint8_t _resize_stack(void) {
|
||||
uint8_t margin = _allocated - _filled;
|
||||
if (margin == 0 || margin > MARGIN + BLOCK_SIZE) {
|
||||
if (margin == 0 || margin >= MARGIN + BLOCK_SIZE) {
|
||||
uint8_t change = (margin == 0) ? BLOCK_SIZE : -BLOCK_SIZE;
|
||||
uint8_t new_size = sizeof(element_t) * (_allocated + change);
|
||||
element_t * temp = (element_t *) realloc(_data, new_size);
|
||||
element_t * temp = (element_t *) realloc(_stack, new_size);
|
||||
if (temp) {
|
||||
_data = temp;
|
||||
_stack = temp;
|
||||
_allocated += change;
|
||||
return 0; // success
|
||||
} else {
|
||||
|
@ -55,31 +67,87 @@ static uint8_t _resize_stack(void) {
|
|||
}
|
||||
}
|
||||
|
||||
/** functions/_shift_elements/description
|
||||
* Shift the elements above the given location either up or down by one.
|
||||
*
|
||||
* Arguments:
|
||||
* - `offset`: The offset of the element above which to operate (with the top
|
||||
* element being `offset = 0`)
|
||||
* - `up` : Whether to shift the elements "up" or "down" the stack
|
||||
*
|
||||
* Returns:
|
||||
* - success: `0`
|
||||
* - failure: [other]
|
||||
*
|
||||
* Notes:
|
||||
* - This function *only* copies elements. It does not zero or otherwise
|
||||
* modify locations that logically should no longer have any element in them.
|
||||
* It also does not modify the stack's counter for how many elements are
|
||||
* filled.
|
||||
*
|
||||
* - We must have at least one element free (at the top of the stack) in order
|
||||
* to copy up.
|
||||
*
|
||||
* - Copying down will do nothing if `offset` is `0`.
|
||||
*
|
||||
*
|
||||
* Illustration:
|
||||
*
|
||||
* ```
|
||||
* ,- top = 4 = filled-1
|
||||
* |
|
||||
* +---+---+---+---+---+---+---+
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | allocated = 7 filled = 5
|
||||
* +---+---+---+---+---+---+---+
|
||||
* ^
|
||||
* ` offset = 3
|
||||
*
|
||||
*
|
||||
* copy up: start = 4 = top = filled-1
|
||||
* increment: i-- (start at the top and work down)
|
||||
* end = 1 = top-offset = filled-1-offset
|
||||
*
|
||||
* copy down: start = 2 = top-offset+1 = filled-1-offset+1 = filled-offset
|
||||
* increment: i++ (start just above the given element and work up)
|
||||
* end = 4 = top = filled-1
|
||||
* ```
|
||||
*/
|
||||
static uint8_t _shift_elements(uint8_t offset, bool up) {
|
||||
// TODO: maybe we want this function to be the one that calls
|
||||
// _resize_stack()?
|
||||
uint8_t margin = _allocated - _filled;
|
||||
if ( offset < 0 || offset > _filled-1 || (up && (margin==0)) )
|
||||
return 1; // failure
|
||||
|
||||
// TODO: arguments:
|
||||
// - offset: the element we want open, or the element we want to cover by
|
||||
// shifting down
|
||||
// - up: whether to shift the elements up or down
|
||||
uint8_t start = (up) ? _filled-1 : _filled-offset ;
|
||||
uint8_t increment = (up) ? -1 : 1 ;
|
||||
uint8_t end = (up) ? _filled-1-offset : _filled-1 ;
|
||||
|
||||
// TODO: should we be able to shift by more than one element at a time?
|
||||
// probably not, but should consider it
|
||||
for(uint8_t i=start; i!=(end+increment); i+=increment) {
|
||||
_stack[i-increment].id = _stack[i].id;
|
||||
_stack[i-increment].number = _stack[i].number;
|
||||
}
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
uint8_t layer_stack__peek (uint8_t offset) {
|
||||
if ( offset < 0 || offset > _filled-1 )
|
||||
return 0; // default
|
||||
|
||||
return _stack[filled-1-offset].number;
|
||||
}
|
||||
|
||||
// note: must resize before shifting up, otherwise there may not be enough room
|
||||
// for the new element
|
||||
uint8_t layer_stack__push (uint8_t layer_id, uint8_t layer_number) {
|
||||
// TODO: resize first, push after
|
||||
// need to add `offset` as an argument; see '.h'
|
||||
}
|
||||
|
||||
// note: should resize after shifting down, so as to only leave `MARGIN`
|
||||
// elements free in the stack
|
||||
uint8_t layer_stack__pop_id (uint8_t layer_id) {
|
||||
// TODO: remove first, resize after
|
||||
// will use find_id(), which isn't written yet; see '.h'
|
||||
}
|
||||
|
||||
uint8_t layer_stack__size (void) {
|
||||
|
|
Loading…
Reference in New Issue