393 lines
12 KiB
C
393 lines
12 KiB
C
/* source/include/sgl_anim.h
|
|
*
|
|
* MIT License
|
|
*
|
|
* Copyright(c) 2023-present All contributors of SGL
|
|
* Document reference link: https://sgl-docs.readthedocs.io
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*/
|
|
|
|
#ifndef __SGL_ANIM_H__
|
|
#define __SGL_ANIM_H__
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
|
|
#include <sgl_cfgfix.h>
|
|
#include <stddef.h>
|
|
#include <sgl_list.h>
|
|
#include <sgl_types.h>
|
|
#include <sgl_mm.h>
|
|
|
|
#if (CONFIG_SGL_ANIMATION)
|
|
|
|
/* Forward declaration of sgl_pos sgl_anim structures */
|
|
struct sgl_pos;
|
|
struct sgl_anim;
|
|
|
|
|
|
/* Anim path callback */
|
|
typedef void (*sgl_anim_path_cb_t)(struct sgl_anim *anim, int32_t value);
|
|
typedef int32_t (*sgl_anim_path_algo_t)(uint32_t elaps, uint32_t duration, int32_t start, int32_t end);
|
|
|
|
|
|
/**
|
|
* @brief Animation object structure used to manage a single animation instance.
|
|
*
|
|
* This structure holds all the necessary state and configuration for an animation,
|
|
* including timing parameters, value interpolation, callbacks, and linkage in a list.
|
|
* All time values (act_delay, act_duration) are in milliseconds.
|
|
*
|
|
* @data: Pointer to user-defined private data associated with this animation.
|
|
* Not used internally by the animation engine; intended for application use.
|
|
*
|
|
* @next: Pointer to the next animation in a singly-linked list.
|
|
* Used internally by the animation scheduler to chain active animations.
|
|
*
|
|
* @act_delay: Delay time (in ms) before the animation starts after being added to the system.
|
|
* The animation will not progress until this delay has elapsed.
|
|
*
|
|
* @act_duration: Total duration (in ms) of the animation from start_value to end_value.
|
|
*
|
|
* @start_value: The initial value at the beginning of the animation (after delay).
|
|
*
|
|
* @end_value: The target value at the end of the animation.
|
|
*
|
|
* @path_cb: Optional custom callback function to compute intermediate animation values.
|
|
* If set, it overrides the built-in path algorithm (`path_algo`).
|
|
*
|
|
* @path_algo: Predefined interpolation algorithm (e.g., linear, ease-in, ease-out).
|
|
* Used only if `path_cb` is NULL.
|
|
*
|
|
* @finish_cb: Callback function invoked when the animation completes (including repeats).
|
|
* May be NULL if no cleanup or notification is needed.
|
|
*
|
|
* @repeat_cnt: Number of times the animation should repeat.
|
|
* - -1: play indefinitely, you can use SGL_ANIM_REPEAT_LOOP
|
|
* - 1: play once (no repeat), you can use SGL_ANIM_REPEAT_ONCE
|
|
* - n: repeat n times (total plays = n)
|
|
* @note Only 30 bits are allocated; max value is 0x3FFFFFFE.
|
|
*
|
|
* @finished: Flag indicating whether the animation has completed (including all repeats).
|
|
* Set to 1 when the animation ends naturally or is stopped.
|
|
*
|
|
* @auto_free: If set to 1, the animation object will be automatically freed after completion.
|
|
* Useful for fire-and-forget animations; ensure memory was allocated dynamically.
|
|
*/
|
|
typedef struct sgl_anim {
|
|
void *data;
|
|
struct sgl_anim *next;
|
|
uint32_t act_delay;
|
|
uint32_t act_duration;
|
|
int32_t start_value;
|
|
int32_t end_value;
|
|
sgl_anim_path_cb_t path_cb;
|
|
sgl_anim_path_algo_t path_algo;
|
|
void (*finish_cb)(struct sgl_anim *anim);
|
|
uint32_t repeat_cnt : 30;
|
|
uint32_t finished : 1;
|
|
uint32_t auto_free : 1;
|
|
} sgl_anim_t;
|
|
|
|
|
|
/**
|
|
* @brief animation context, it will be used to store status of animation
|
|
* @anim_list_head: animation list head
|
|
* @anim_list_tail: animation list tail
|
|
*/
|
|
typedef struct sgl_anim_ctx {
|
|
sgl_anim_t *anim_list_head;
|
|
sgl_anim_t *anim_list_tail;
|
|
} sgl_anim_ctx_t;
|
|
|
|
|
|
#define sgl_anim_for_each(anim, head) for ((anim) = (head)->anim_list_head; (anim) != NULL; (anim) = (anim)->next)
|
|
#define sgl_anim_for_each_safe(anim, n, head) for (anim = (head)->anim_list_head, n = (anim) ? (anim)->next : NULL; anim != NULL; anim = n, n = (anim) ? (anim)->next : NULL)
|
|
|
|
#define SGL_ANIM_REPEAT_LOOP (0x3FFFFFFF)
|
|
#define SGL_ANIM_REPEAT_ONCE (1)
|
|
|
|
|
|
/* Animation context it will be used internally */
|
|
extern sgl_anim_ctx_t sgl_anim_ctx;
|
|
|
|
|
|
/**
|
|
* @brief Animation static initialization
|
|
* @param anim - Animation object
|
|
* @return none
|
|
*/
|
|
void sgl_anim_init(sgl_anim_t *anim);
|
|
|
|
|
|
/**
|
|
* @brief dynamic alloc animation object with initialization
|
|
* @param none
|
|
* @return animation object
|
|
*/
|
|
sgl_anim_t* sgl_anim_create(void);
|
|
|
|
|
|
/**
|
|
* @brief start animation
|
|
* @param anim animation object
|
|
* @para repeat_cnt repeat count of animation
|
|
* @return none
|
|
*/
|
|
void sgl_anim_start(sgl_anim_t *anim, uint32_t repeat_cnt);
|
|
|
|
|
|
/**
|
|
* @brief stop animation
|
|
* @param anim animation object
|
|
* @return none
|
|
*/
|
|
void sgl_anim_stop(sgl_anim_t *anim);
|
|
|
|
|
|
/**
|
|
* @brief delete animation object
|
|
* @param anim animation object
|
|
* @return none
|
|
*/
|
|
void sgl_anim_delete(sgl_anim_t *anim);
|
|
|
|
|
|
/**
|
|
* @brief set animation private data
|
|
* @param anim animation object
|
|
* @param data pointer to private data
|
|
* @return none
|
|
*/
|
|
static inline void sgl_anim_set_data(sgl_anim_t *anim, void *data)
|
|
{
|
|
SGL_ASSERT(anim != NULL);
|
|
anim->data = data;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief set animation path callback function
|
|
* @param anim animation object
|
|
* @param path_cb path callback function
|
|
* @param path_algo path algo callback function
|
|
* @return none
|
|
*/
|
|
static inline void sgl_anim_set_path(sgl_anim_t *anim, sgl_anim_path_cb_t path_cb, sgl_anim_path_algo_t path_algo)
|
|
{
|
|
SGL_ASSERT(anim != NULL && path_cb != NULL && path_algo != NULL);
|
|
anim->path_cb = path_cb;
|
|
anim->path_algo = path_algo;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief set animation start value
|
|
* @param anim animation object
|
|
* @param value start value
|
|
* @return none
|
|
*/
|
|
static inline void sgl_anim_set_start_value(sgl_anim_t *anim, int32_t value)
|
|
{
|
|
SGL_ASSERT(anim != NULL);
|
|
anim->start_value = value;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief set animation end value
|
|
* @param anim animation object
|
|
* @param value end value
|
|
* @return none
|
|
*/
|
|
static inline void sgl_anim_set_end_value(sgl_anim_t *anim, int32_t value)
|
|
{
|
|
SGL_ASSERT(anim != NULL);
|
|
anim->end_value = value;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief set animation active delay time, ms
|
|
* @param anim animation object
|
|
* @param delay active delay time, ms
|
|
* @return none
|
|
*/
|
|
static inline void sgl_anim_set_act_delay(sgl_anim_t *anim, uint32_t delay_ms)
|
|
{
|
|
SGL_ASSERT(anim != NULL);
|
|
anim->act_delay = delay_ms;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief set animation active duration time, ms
|
|
* @param anim animation object
|
|
* @param duration active duration time, ms
|
|
* @return none
|
|
*/
|
|
static inline void sgl_anim_set_act_duration(sgl_anim_t *anim, uint32_t duration_ms)
|
|
{
|
|
SGL_ASSERT(anim != NULL);
|
|
anim->act_duration = duration_ms;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief set finish callback for animation
|
|
* @param anim animation object
|
|
* @param finish_cb finish callback
|
|
* @return none
|
|
*/
|
|
static inline void sgl_anim_set_finish_cb(sgl_anim_t *anim, void (*finish_cb)(sgl_anim_t *anim))
|
|
{
|
|
SGL_ASSERT(anim != NULL);
|
|
anim->finish_cb = finish_cb;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief check animation is finished or not
|
|
* @param anim animation object
|
|
* @return true or false
|
|
*/
|
|
static inline bool sgl_anim_is_finished(sgl_anim_t *anim)
|
|
{
|
|
SGL_ASSERT(anim != NULL);
|
|
return (bool)anim->finished;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief set auto free flag for animation
|
|
* @param anim animation
|
|
* @return none
|
|
*/
|
|
static inline void sgl_anim_set_auto_free(sgl_anim_t *anim)
|
|
{
|
|
SGL_ASSERT(anim != NULL);
|
|
anim->auto_free = 1;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief animation task, it will foreach all animation
|
|
* @param none
|
|
* @return none
|
|
* @note this function should be called in sgl_task()
|
|
*/
|
|
void sgl_anim_task(void);
|
|
|
|
|
|
/**
|
|
* Linear animation path calculation function
|
|
*
|
|
* Calculates the current interpolated value based on elapsed time and total duration
|
|
* using linear interpolation.
|
|
*
|
|
* @param elaps Elapsed time in milliseconds
|
|
* @param duration Total animation duration in milliseconds
|
|
* @param start Start value
|
|
* @param end End value
|
|
*
|
|
* @return The interpolated value for the current time
|
|
*
|
|
* @note Returns 'end' if elaps >= duration (animation finished)
|
|
* Returns 'start' if elaps == 0 (animation just started)
|
|
* Uses 32-bit integer arithmetic to avoid floating-point operations
|
|
* for better performance on embedded systems
|
|
*/
|
|
int32_t sgl_anim_path_linear(uint32_t elaps, uint32_t duration, int32_t start, int32_t end);
|
|
#define SGL_ANIM_PATH_LINEAR sgl_anim_path_linear
|
|
|
|
|
|
/**
|
|
* sgl_anim_path_ease_in_out - Cubic ease-in-out animation path
|
|
*
|
|
* This function creates a smooth animation curve that starts slow,
|
|
* accelerates in the middle, and decelerates at the end.
|
|
*
|
|
* @param elaps Elapsed time (ms)
|
|
* @param duration Total animation duration (ms)
|
|
* @param start Start value
|
|
* @param end End value
|
|
* @return Interpolated value at current time
|
|
*/
|
|
int32_t sgl_anim_path_ease_in_out(uint32_t elaps, uint32_t duration, int32_t start, int32_t end);
|
|
#define SGL_ANIM_PATH_EASE_IN_OUT sgl_anim_path_ease_in_out
|
|
|
|
|
|
/**
|
|
* sgl_anim_path_ease_in - Cubic ease-in animation path
|
|
*
|
|
* This function creates a smooth animation curve that starts slow,
|
|
* accelerates in the after
|
|
*
|
|
* @param elaps Elapsed time (ms)
|
|
* @param duration Total animation duration (ms)
|
|
* @param start Start value
|
|
* @param end End value
|
|
* @return Interpolated value at current time
|
|
*/
|
|
int32_t sgl_anim_path_ease_out(uint32_t elaps, uint32_t duration, int32_t start, int32_t end);
|
|
#define SGL_ANIM_PATH_EASE_OUT sgl_anim_path_ease_out
|
|
|
|
|
|
/**
|
|
* sgl_anim_path_ease_in - Cubic ease-in animation path
|
|
*
|
|
* This function creates a smooth animation curve that starts accelerates,
|
|
* accelerates in the after
|
|
*
|
|
* @param elaps Elapsed time (ms)
|
|
* @param duration Total animation duration (ms)
|
|
* @param start Start value
|
|
* @param end End value
|
|
* @return Interpolated value at current time
|
|
*/
|
|
int32_t sgl_anim_path_ease_in(uint32_t elaps, uint32_t duration, int32_t start, int32_t end);
|
|
#define SGL_ANIM_PATH_EASE_IN sgl_anim_path_ease_in
|
|
|
|
|
|
/**
|
|
* sgl_anim_path_overshoot - Overshoot animation path
|
|
*
|
|
* This function creates an animation curve that overshoots the target end value
|
|
* slightly before settling back to it, creating a natural "bounce" or "spring-like"
|
|
* effect for a more dynamic and realistic animation.
|
|
*
|
|
* @param elaps Elapsed time (ms) since the animation started
|
|
* @param duration Total animation duration (ms)
|
|
* @param start Initial value of the animated property at the start of the animation
|
|
* @param end Target end value of the animated property
|
|
* @return Interpolated value of the animated property at the current elapsed time
|
|
*/
|
|
int32_t sgl_anim_path_overshoot(uint32_t elaps, uint32_t duration, int32_t start, int32_t end);
|
|
#define SGL_ANIM_PATH_OVERSHOOT sgl_anim_path_overshoot
|
|
|
|
|
|
#endif // ! CONFIG_SGL_ANIMATION
|
|
|
|
#ifdef __cplusplus
|
|
} /*extern "C"*/
|
|
#endif
|
|
|
|
#endif // ! __SGL_ANIM_H__
|