mirror of
https://github.com/FelixKratz/SketchyBar
synced 2024-11-10 05:44:16 +00:00
improve animation system
This commit is contained in:
parent
6fbf9edf75
commit
e1afb4e257
7 changed files with 41 additions and 48 deletions
|
@ -2,7 +2,7 @@
|
|||
#include "event.h"
|
||||
|
||||
static CVReturn animation_frame_callback(CVDisplayLinkRef display_link, const CVTimeStamp* now, const CVTimeStamp* output_time, CVOptionFlags flags, CVOptionFlags* flags_out, void* context) {
|
||||
struct event event = { NULL, ANIMATOR_REFRESH };
|
||||
struct event event = { (void*)output_time->hostTime, ANIMATOR_REFRESH };
|
||||
event_post(&event);
|
||||
return kCVReturnSuccess;
|
||||
}
|
||||
|
@ -23,8 +23,9 @@ static void animation_lock(struct animation* animation) {
|
|||
}
|
||||
|
||||
void animation_setup(struct animation* animation, void* target, animator_function* update_function, int initial_value, int final_value, uint32_t duration, char interp_function) {
|
||||
animation->counter = 1;
|
||||
animation->duration = duration;
|
||||
// The animation duration is represented as a frame count equivalent on a
|
||||
// 60Hz display. E.g. 120frames = 2 seconds
|
||||
animation->duration = (double)duration / 60.0;
|
||||
animation->initial_value = initial_value;
|
||||
animation->final_value = final_value;
|
||||
animation->update_function = update_function;
|
||||
|
@ -47,23 +48,30 @@ void animation_setup(struct animation* animation, void* target, animator_functio
|
|||
}
|
||||
}
|
||||
|
||||
static bool animation_update(struct animation* animation, double time_scale) {
|
||||
static bool animation_update(struct animation* animation, uint64_t time, uint64_t clock) {
|
||||
if (!animation->target || !animation->update_function) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double dt = animation->last_time > 0
|
||||
? ((double)(time - animation->last_time) / clock)
|
||||
: 0.0;
|
||||
animation->last_time = time;
|
||||
if (animation->offset > 0) {
|
||||
animation->offset-= time_scale;
|
||||
animation->offset -= dt;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool final_frame = !((animation->duration > 1
|
||||
&& animation->counter < animation->duration));
|
||||
if (!animation->initial_time) animation->initial_time = time;
|
||||
double t = animation->duration > 0
|
||||
? ((double)(time - animation->initial_time)
|
||||
/ (double)(animation->duration * clock))
|
||||
: 1.0;
|
||||
|
||||
double slider = final_frame
|
||||
? 1.0
|
||||
: animation->interp_function(animation->counter
|
||||
/ animation->duration);
|
||||
bool final_frame = t >= 1.0;
|
||||
if (t < 0.0) t = 0.0;
|
||||
if (t > 1.0) t = 1.0;
|
||||
|
||||
double slider = final_frame ? 1.0 : animation->interp_function(t);
|
||||
|
||||
int value;
|
||||
if (animation->separate_bytes) {
|
||||
|
@ -92,7 +100,7 @@ static bool animation_update(struct animation* animation, double time_scale) {
|
|||
needs_update = animation->update_function(animation->target, value);
|
||||
}
|
||||
|
||||
animation->counter += time_scale;
|
||||
animation->counter += dt;
|
||||
|
||||
bool found_item = false;
|
||||
for (int i = 0; i < g_bar_manager.bar_item_count; i++) {
|
||||
|
@ -117,31 +125,21 @@ void animator_init(struct animator* animator) {
|
|||
animator->animation_count = 0;
|
||||
animator->interp_function = 0;
|
||||
animator->duration = 0;
|
||||
animator->time_scale = 1.;
|
||||
animator->display_link = NULL;
|
||||
|
||||
animator_renew_display_link(animator);
|
||||
}
|
||||
|
||||
void animator_renew_display_link(struct animator* animator) {
|
||||
bool running = false;
|
||||
if (animator->display_link) {
|
||||
running = CVDisplayLinkIsRunning(animator->display_link);
|
||||
}
|
||||
|
||||
animator_destroy_display_link(animator);
|
||||
CVDisplayLinkCreateWithActiveCGDisplays(&animator->display_link);
|
||||
|
||||
CVDisplayLinkSetOutputCallback(animator->display_link,
|
||||
animation_frame_callback,
|
||||
animator );
|
||||
|
||||
CVTime refresh_period =
|
||||
CVDisplayLinkGetNominalOutputVideoRefreshPeriod(animator->display_link);
|
||||
|
||||
animator->time_scale = 60.
|
||||
* (double)refresh_period.timeValue / (double)refresh_period.timeScale;
|
||||
|
||||
if (running) CVDisplayLinkStart(animator->display_link);
|
||||
animator->clock = CVGetHostClockFrequency();
|
||||
CVDisplayLinkStart(animator->display_link);
|
||||
}
|
||||
|
||||
void animator_destroy_display_link(struct animator* animator) {
|
||||
|
@ -182,10 +180,7 @@ void animator_add(struct animator* animator, struct animation* animation) {
|
|||
* ++animator->animation_count);
|
||||
animator->animations[animator->animation_count - 1] = animation;
|
||||
|
||||
if (animator->display_link
|
||||
&& !CVDisplayLinkIsRunning(animator->display_link)) {
|
||||
CVDisplayLinkStart(animator->display_link);
|
||||
}
|
||||
if (!animator->display_link) animator_renew_display_link(animator);
|
||||
}
|
||||
|
||||
static void animator_remove(struct animator* animator, struct animation* animation) {
|
||||
|
@ -211,12 +206,6 @@ static void animator_remove(struct animator* animator, struct animation* animati
|
|||
}
|
||||
|
||||
animation_destroy(animation);
|
||||
|
||||
if (animator->animation_count == 0
|
||||
&& animator->display_link
|
||||
&& CVDisplayLinkIsRunning(animator->display_link)) {
|
||||
CVDisplayLinkStop(animator->display_link);
|
||||
}
|
||||
}
|
||||
|
||||
void animator_cancel_locked(struct animator* animator, void* target, animator_function* function) {
|
||||
|
@ -261,7 +250,7 @@ bool animator_cancel(struct animator* animator, void* target, animator_function*
|
|||
return needs_update;
|
||||
}
|
||||
|
||||
bool animator_update(struct animator* animator) {
|
||||
bool animator_update(struct animator* animator, uint64_t time) {
|
||||
bool needs_refresh = false;
|
||||
struct animation* remove[animator->animation_count];
|
||||
memset(remove, 0, animator->animation_count);
|
||||
|
@ -269,7 +258,8 @@ bool animator_update(struct animator* animator) {
|
|||
|
||||
for (uint32_t i = 0; i < animator->animation_count; i++) {
|
||||
needs_refresh |= animation_update(animator->animations[i],
|
||||
animator->time_scale );
|
||||
time,
|
||||
animator->clock );
|
||||
|
||||
if (animator->animations[i]->finished) {
|
||||
remove[remove_count++] = animator->animations[i];
|
||||
|
@ -280,6 +270,7 @@ bool animator_update(struct animator* animator) {
|
|||
animator_remove(animator, remove[i]);
|
||||
}
|
||||
|
||||
if (animator->animation_count == 0) animator_destroy_display_link(animator);
|
||||
return needs_refresh;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#pragma once
|
||||
#include <CoreVideo/CVDisplayLink.h>
|
||||
#include <CoreVideo/CoreVideo.h>
|
||||
#include "misc/helpers.h"
|
||||
|
||||
extern struct bar_manager g_bar_manager;
|
||||
|
@ -87,6 +87,8 @@ struct animation {
|
|||
bool locked;
|
||||
bool finished;
|
||||
|
||||
uint64_t initial_time;
|
||||
uint64_t last_time;
|
||||
double duration;
|
||||
double counter;
|
||||
double offset;
|
||||
|
@ -105,7 +107,7 @@ void animation_setup(struct animation* animation, void* target, animator_functio
|
|||
struct animator {
|
||||
CVDisplayLinkRef display_link;
|
||||
|
||||
double time_scale;
|
||||
double clock;
|
||||
uint32_t interp_function;
|
||||
uint32_t duration;
|
||||
struct animation** animations;
|
||||
|
@ -118,7 +120,7 @@ void animator_add(struct animator* animator, struct animation* animation);
|
|||
bool animator_cancel(struct animator* animator, void* target, animator_function* function);
|
||||
void animator_cancel_locked(struct animator* animator, void* target, animator_function* function);
|
||||
|
||||
bool animator_update(struct animator* animator);
|
||||
bool animator_update(struct animator* animator, uint64_t time);
|
||||
void animator_lock(struct animator* animator);
|
||||
void animator_destroy(struct animator* animator);
|
||||
|
||||
|
|
|
@ -1081,7 +1081,7 @@ void bar_item_parse_set_message(struct bar_item* bar_item, char* message, FILE*
|
|||
(bool (*)(void*, int))&bar_item_set_width,
|
||||
bar_item->custom_width,
|
||||
-1,
|
||||
1,
|
||||
0,
|
||||
INTERP_FUNCTION_LINEAR );
|
||||
animator_add(&g_bar_manager.animator, animation);
|
||||
}
|
||||
|
|
|
@ -509,9 +509,9 @@ void bar_manager_update_space_components(struct bar_manager* bar_manager, bool f
|
|||
}
|
||||
}
|
||||
|
||||
void bar_manager_animator_refresh(struct bar_manager* bar_manager) {
|
||||
void bar_manager_animator_refresh(struct bar_manager* bar_manager, uint64_t time) {
|
||||
bar_manager_freeze(bar_manager);
|
||||
if (animator_update(&bar_manager->animator)) {
|
||||
if (animator_update(&bar_manager->animator, time)) {
|
||||
bar_manager_unfreeze(bar_manager);
|
||||
|
||||
if (bar_manager->bar_needs_resize) bar_manager_resize(bar_manager);
|
||||
|
|
|
@ -61,7 +61,7 @@ void bar_manager_remove_item(struct bar_manager* bar_manager, struct bar_item* b
|
|||
void bar_manager_move_item(struct bar_manager* bar_manager, struct bar_item* item, struct bar_item* reference, bool before);
|
||||
void bar_manager_handle_notification(struct bar_manager* bar_manager, struct notification* notification);
|
||||
|
||||
void bar_manager_animator_refresh(struct bar_manager* bar_manager);
|
||||
void bar_manager_animator_refresh(struct bar_manager* bar_manager, uint64_t time);
|
||||
void bar_manager_update(struct bar_manager* bar_manager, bool forced);
|
||||
void bar_manager_update_space_components(struct bar_manager* bar_manager, bool forced);
|
||||
bool bar_manager_set_margin(struct bar_manager* bar_manager, int margin);
|
||||
|
|
|
@ -59,7 +59,7 @@ static void event_shell_refresh(void* context) {
|
|||
}
|
||||
|
||||
static void event_animator_refresh(void* context) {
|
||||
bar_manager_animator_refresh(&g_bar_manager);
|
||||
bar_manager_animator_refresh(&g_bar_manager, (uint64_t)context);
|
||||
}
|
||||
|
||||
static void event_mach_message(void* context) {
|
||||
|
|
|
@ -495,7 +495,7 @@ bool text_parse_sub_domain(struct text* text, FILE* rsp, struct token property,
|
|||
(bool (*)(void*, int))&text_set_width,
|
||||
text->custom_width,
|
||||
-1,
|
||||
1,
|
||||
0,
|
||||
INTERP_FUNCTION_LINEAR );
|
||||
animator_add(&g_bar_manager.animator, animation);
|
||||
}
|
||||
|
@ -532,7 +532,7 @@ bool text_parse_sub_domain(struct text* text, FILE* rsp, struct token property,
|
|||
(bool (*)(void*, int))&text_set_width,
|
||||
text->custom_width,
|
||||
-1,
|
||||
1,
|
||||
0,
|
||||
INTERP_FUNCTION_LINEAR );
|
||||
animator_add(&g_bar_manager.animator, animation);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue