/** * Copyright (c) 2021 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "timeline.h" void timelineInit(timeline_t *timeline) { timeline->current = 0; timeline->diff = 0; timeline->previous = 0; timeline->user = 0; timeline->actionCount = 0; } void timelineUpdate(timeline_t *timeline, float delta) { uint8_t i; timelineaction_t *action; float full; timeline->diff = delta; timeline->previous = timeline->current; timeline->current = timeline->current + delta; // Find all actions that would have started or ended in this timespan. for(i = 0; i < timeline->actionCount; i++) { action = timeline->actions +i; // Has the action started yet? if(action->start > timeline->current) continue; // Did we start this frame? if(action->start > timeline->previous && action->onStart != NULL) { action->onStart(timeline, action, i); } // Durations of 0 only fire starts, never ends or durations. if(action->duration == 0) continue; // Is the end still in the future? Durations in negatives go forever full = action->start+action->duration; if(action->duration < 0 || full > timeline->current) { if(action->onDuration != NULL) action->onDuration(timeline, action, i); } else if(full > timeline->previous) {// Did we end this frame? if(action->onEnd != NULL) action->onEnd(timeline, action, i); if(action->loop) action->start = timeline->current; } } } bool timelineIsFinished(timeline_t *timeline) { uint8_t i; timelineaction_t *action; for(i = 0; i < timeline->actionCount; i++) { action = timeline->actions +i; if(action->start > timeline->current) return false; if(action->duration < 0) return false; if(action->duration == 0) continue; if(action->start+action->duration > timeline->current) return false; } return true; } timelineaction_t * timelineAddAction(timeline_t *timeline, float start, float duration ) { if(timeline->actionCount == TIMELINE_ACTION_COUNT_MAX) return NULL; timelineaction_t *action = timeline->actions + (timeline->actionCount++); action->loop = false; action->start = start, action->duration = duration; action->onStart = action->onEnd = action->onDuration = NULL; return action; }