Refactor the animation api to allow for pre- and post-frame hooks
This commit is contained in:
parent
2dfec75038
commit
cc70d75238
4 changed files with 62 additions and 46 deletions
|
@ -9,6 +9,7 @@
|
||||||
#include <zephyr/types.h>
|
#include <zephyr/types.h>
|
||||||
#include <device.h>
|
#include <device.h>
|
||||||
#include <drivers/led_strip.h>
|
#include <drivers/led_strip.h>
|
||||||
|
|
||||||
#include <zmk/animation.h>
|
#include <zmk/animation.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,17 +20,33 @@
|
||||||
* for various types of 2D animations.
|
* for various types of 2D animations.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct animation_pixel {
|
||||||
|
const size_t id;
|
||||||
|
const uint8_t position_x;
|
||||||
|
const uint8_t position_y;
|
||||||
|
|
||||||
|
const struct device *animation;
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef animation_api_prep_next_frame
|
* @typedef animation_api_prep_next_frame
|
||||||
* @brief Callback API for generating the next animation frame
|
* @brief Callback run before every frame is rendered.
|
||||||
*
|
*
|
||||||
* @see animation_prep_next_frame() for argument descriptions.
|
* @see animation_api_before_frame() for argument descriptions.
|
||||||
*/
|
*/
|
||||||
typedef void (*animation_api_prep_next_frame)(const struct device *dev);
|
typedef void (*animation_api_on_before_frame)(const struct device *dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef animation_api_prep_next_frame
|
||||||
|
* @brief Callback run after every frame is rendered.
|
||||||
|
*
|
||||||
|
* @see animation_api_before_frame() for argument descriptions.
|
||||||
|
*/
|
||||||
|
typedef void (*animation_api_on_after_frame)(const struct device *dev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef animation_api_prep_next_frame
|
* @typedef animation_api_prep_next_frame
|
||||||
|
@ -37,36 +54,42 @@ typedef void (*animation_api_prep_next_frame)(const struct device *dev);
|
||||||
*
|
*
|
||||||
* @see animation_prep_next_frame() for argument descriptions.
|
* @see animation_prep_next_frame() for argument descriptions.
|
||||||
*/
|
*/
|
||||||
typedef void (*animation_api_get_pixel)(const struct device *dev,
|
typedef void (*animation_api_render_pixel)(const struct device *dev,
|
||||||
const struct animation_pixel_position *pixel_position,
|
const struct animation_pixel *pixel,
|
||||||
struct zmk_color_rgb *value);
|
struct zmk_color_rgb *value);
|
||||||
|
|
||||||
struct animation_api {
|
struct animation_api {
|
||||||
animation_api_prep_next_frame prep_next_frame;
|
animation_api_on_before_frame on_before_frame;
|
||||||
animation_api_get_pixel get_pixel;
|
animation_api_on_after_frame on_after_frame;
|
||||||
|
animation_api_render_pixel render_pixel;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
static inline void animation_on_before_frame(const struct device *dev) {
|
||||||
* [animation_prep_next_frame description]
|
|
||||||
* @param dev [description]
|
|
||||||
*/
|
|
||||||
static inline void animation_prep_next_frame(const struct device *dev) {
|
|
||||||
const struct animation_api *api = (const struct animation_api *)dev->api;
|
const struct animation_api *api = (const struct animation_api *)dev->api;
|
||||||
|
|
||||||
return api->prep_next_frame(dev);
|
if (api->on_before_frame == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
api->on_before_frame(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static inline void animation_on_after_frame(const struct device *dev) {
|
||||||
* [animation_get_pixel description]
|
const struct animation_api *api = (const struct animation_api *)dev->api;
|
||||||
* @param dev [description]
|
|
||||||
* @param pixel [description]
|
if (api->on_after_frame == NULL) {
|
||||||
*/
|
return;
|
||||||
static inline void animation_get_pixel(const struct device *dev,
|
}
|
||||||
const struct animation_pixel_position *pixel_position,
|
|
||||||
|
api->on_after_frame(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void animation_render_pixel(const struct device *dev,
|
||||||
|
const struct animation_pixel *pixel,
|
||||||
struct zmk_color_rgb *value) {
|
struct zmk_color_rgb *value) {
|
||||||
const struct animation_api *api = (const struct animation_api *)dev->api;
|
const struct animation_api *api = (const struct animation_api *)dev->api;
|
||||||
|
|
||||||
return api->get_pixel(dev, pixel_position, value);
|
return api->render_pixel(dev, pixel, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -9,16 +9,6 @@
|
||||||
#include <device.h>
|
#include <device.h>
|
||||||
#include <drivers/led_strip.h>
|
#include <drivers/led_strip.h>
|
||||||
|
|
||||||
struct animation_pixel_position {
|
|
||||||
const uint8_t x;
|
|
||||||
const uint8_t y;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct animation_pixel {
|
|
||||||
const struct device *animation;
|
|
||||||
const struct animation_pixel_position position;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct zmk_color_rgb {
|
struct zmk_color_rgb {
|
||||||
float r;
|
float r;
|
||||||
float g;
|
float g;
|
||||||
|
|
|
@ -32,12 +32,10 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
#define PHANDLE_TO_PIXEL(idx, node_id, prop) \
|
#define PHANDLE_TO_PIXEL(idx, node_id, prop) \
|
||||||
{ \
|
{ \
|
||||||
|
.id = idx, \
|
||||||
|
.position_x = DT_PHA_BY_IDX(node_id, prop, idx, position_x), \
|
||||||
|
.position_y = DT_PHA_BY_IDX(node_id, prop, idx, position_y), \
|
||||||
.animation = DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx)), \
|
.animation = DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx)), \
|
||||||
.position = \
|
|
||||||
{ \
|
|
||||||
.x = DT_PHA_BY_IDX(node_id, prop, idx, position_x), \
|
|
||||||
.y = DT_PHA_BY_IDX(node_id, prop, idx, position_y), \
|
|
||||||
}, \
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,7 +84,7 @@ static struct led_rgb px_buffer[DT_INST_PROP_LEN(0, pixels)];
|
||||||
|
|
||||||
static void zmk_animation_tick(struct k_work *work) {
|
static void zmk_animation_tick(struct k_work *work) {
|
||||||
for (size_t i = 0; i < animations_size; ++i) {
|
for (size_t i = 0; i < animations_size; ++i) {
|
||||||
animation_prep_next_frame(animations[i]);
|
animation_on_before_frame(animations[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < pixels_size; ++i) {
|
for (size_t i = 0; i < pixels_size; ++i) {
|
||||||
|
@ -96,7 +94,7 @@ static void zmk_animation_tick(struct k_work *work) {
|
||||||
.b = 0,
|
.b = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
animation_get_pixel(pixels[i].animation, &pixels[i].position, &rgb);
|
animation_render_pixel(pixels[i].animation, &pixels[i], &rgb);
|
||||||
|
|
||||||
zmk_rgb_to_led_rgb(&rgb, &px_buffer[i]);
|
zmk_rgb_to_led_rgb(&rgb, &px_buffer[i]);
|
||||||
}
|
}
|
||||||
|
@ -108,6 +106,10 @@ static void zmk_animation_tick(struct k_work *work) {
|
||||||
|
|
||||||
pixels_updated += (size_t)pixels_per_driver;
|
pixels_updated += (size_t)pixels_per_driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < animations_size; ++i) {
|
||||||
|
animation_on_after_frame(animations[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
K_WORK_DEFINE(animation_work, zmk_animation_tick);
|
K_WORK_DEFINE(animation_work, zmk_animation_tick);
|
||||||
|
|
|
@ -31,7 +31,7 @@ struct animation_solid_data {
|
||||||
struct zmk_color_rgb current_rgb;
|
struct zmk_color_rgb current_rgb;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void animation_solid_prep_next_frame(const struct device *dev) {
|
static void animation_solid_on_before_frame(const struct device *dev) {
|
||||||
const struct animation_solid_config *config = dev->config;
|
const struct animation_solid_config *config = dev->config;
|
||||||
struct animation_solid_data *data = dev->data;
|
struct animation_solid_data *data = dev->data;
|
||||||
|
|
||||||
|
@ -57,8 +57,8 @@ static void animation_solid_prep_next_frame(const struct device *dev) {
|
||||||
data->counter = (data->counter + 1) % config->duration;
|
data->counter = (data->counter + 1) % config->duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void animation_solid_get_pixel(const struct device *dev,
|
static void animation_solid_render_pixel(const struct device *dev,
|
||||||
const struct animation_pixel_position *position,
|
const struct animation_pixel *pixel,
|
||||||
struct zmk_color_rgb *value) {
|
struct zmk_color_rgb *value) {
|
||||||
const struct animation_solid_data *data = dev->data;
|
const struct animation_solid_data *data = dev->data;
|
||||||
|
|
||||||
|
@ -80,8 +80,9 @@ static int animation_solid_init(const struct device *dev) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct animation_api animation_solid_api = {
|
static const struct animation_api animation_solid_api = {
|
||||||
.prep_next_frame = animation_solid_prep_next_frame,
|
.on_before_frame = animation_solid_on_before_frame,
|
||||||
.get_pixel = animation_solid_get_pixel,
|
.on_after_frame = NULL,
|
||||||
|
.render_pixel = animation_solid_render_pixel,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ANIMATION_SOLID_DEVICE(idx) \
|
#define ANIMATION_SOLID_DEVICE(idx) \
|
||||||
|
|
Loading…
Add table
Reference in a new issue