Difference between revisions of "Get led code"
From Just in Time
(Created page with "<source lang='cpp'> template<uint8_t buffer_size, uint8_t led_string_size> rgb & get( sparse_leds<buffer_size, led_string_size> &leds, uint8_t position) { uint8_t *buffer_it...") |
|||
Line 1: | Line 1: | ||
<source lang='cpp'> | <source lang='cpp'> | ||
+ | /** | ||
+ | * A data structure for a sparse representation of values in a LED string. | ||
+ | * | ||
+ | * A non-sparse representation of an LED string holds 3 bytes for every | ||
+ | * LED in the string. For a 60 LED string this means that at least 180 bytes | ||
+ | * of memory are required. | ||
+ | */ | ||
+ | template<uint8_t buffer_size, uint8_t led_string_size> | ||
+ | struct sparse_leds | ||
+ | { | ||
+ | uint8_t buffer[buffer_size]; | ||
+ | }; | ||
+ | |||
+ | |||
+ | template< uint8_t buffer_size, uint8_t led_string_size> | ||
+ | struct led_buffer_traits<sparse_leds<buffer_size, led_string_size> > | ||
+ | { | ||
+ | static const uint8_t count = led_string_size; | ||
+ | static const uint8_t size = buffer_size; | ||
+ | }; | ||
+ | |||
+ | template<uint8_t buffer_size, uint8_t led_string_size> | ||
+ | inline void clear( sparse_leds<buffer_size, led_string_size> &leds) | ||
+ | { | ||
+ | leds.buffer[0] = led_string_size; | ||
+ | leds.buffer[1] = 0; | ||
+ | } | ||
+ | |||
+ | |||
+ | void move_right( uint8_t *begin, uint8_t *end, uint8_t *buffer_end) | ||
+ | { | ||
+ | while (begin < end) *(--buffer_end) = *(--end); | ||
+ | while( begin < buffer_end) *(--buffer_end) = 0; | ||
+ | } | ||
+ | |||
template<uint8_t buffer_size, uint8_t led_string_size> | template<uint8_t buffer_size, uint8_t led_string_size> | ||
rgb & get( sparse_leds<buffer_size, led_string_size> &leds, uint8_t position) | rgb & get( sparse_leds<buffer_size, led_string_size> &leds, uint8_t position) |
Revision as of 14:50, 9 March 2014
<source lang='cpp'> /**
* A data structure for a sparse representation of values in a LED string. * * A non-sparse representation of an LED string holds 3 bytes for every * LED in the string. For a 60 LED string this means that at least 180 bytes * of memory are required. */
template<uint8_t buffer_size, uint8_t led_string_size> struct sparse_leds { uint8_t buffer[buffer_size]; };
template< uint8_t buffer_size, uint8_t led_string_size>
struct led_buffer_traits<sparse_leds<buffer_size, led_string_size> >
{
static const uint8_t count = led_string_size;
static const uint8_t size = buffer_size;
};
template<uint8_t buffer_size, uint8_t led_string_size> inline void clear( sparse_leds<buffer_size, led_string_size> &leds) { leds.buffer[0] = led_string_size; leds.buffer[1] = 0; }
void move_right( uint8_t *begin, uint8_t *end, uint8_t *buffer_end)
{
while (begin < end) *(--buffer_end) = *(--end);
while( begin < buffer_end) *(--buffer_end) = 0;
}
template<uint8_t buffer_size, uint8_t led_string_size> rgb & get( sparse_leds<buffer_size, led_string_size> &leds, uint8_t position) {
uint8_t *buffer_iterator = &leds.buffer[0]; uint8_t * const end = buffer_iterator + buffer_size; uint8_t current_pos = 0; while (buffer_iterator < end) { // current_pos pointing one past the previous block // buffer_iterator pointing at a 'jump'
uint8_t jump_pos = current_pos + *buffer_iterator; if (jump_pos > position + 1) { // need to add a new block before the one we're pointing at. *buffer_iterator = (jump_pos - position - 1); move_right( buffer_iterator, end - 5, end); *buffer_iterator++ = position - current_pos; *buffer_iterator++=1; break; } current_pos = jump_pos; // current_pos now pointing at the location of the first led in the block if (current_pos == position + 1) { // prepend the new led to the current block of leds --(*buffer_iterator); ++buffer_iterator; ++*buffer_iterator; ++buffer_iterator; move_right( buffer_iterator, end-3, end); break; } ++buffer_iterator; // pointing at the led block size jump_pos = position - current_pos; if ( jump_pos < *buffer_iterator) { // we're actually pointing to a led that is inside the current block buffer_iterator += (1 + 3 * jump_pos); break; } current_pos += *buffer_iterator; // pointing one past the last led in the string. jump_pos = 3 * (*buffer_iterator) + 1; //buffer_iterator += 3 * (*buffer_iterator); if (position == current_pos) { // decrease distance between this block and the next by one if (--(*(buffer_iterator+jump_pos)) == 0) { // distance is zero, concatenate two blocks.
// new size is the old size plus the size of the next block plus // 1 for the new led. *buffer_iterator += *(buffer_iterator + jump_pos + 1)+1; buffer_iterator += jump_pos; move_right( buffer_iterator, end - 1, end); } else { // distance is non-zero, just enlarge the current block ++*buffer_iterator; buffer_iterator += jump_pos; move_right( buffer_iterator, end - 3, end); } break; } buffer_iterator+=jump_pos; }
return *(reinterpret_cast<rgb *>(buffer_iterator));
} </source>