From 4cf74ec0f32a862cd379d4677b66ab921e77729a Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak <dos@dosowisko.net> Date: Sat, 30 Jun 2018 01:27:28 +0200 Subject: [PATCH] timeline: delta eating Untested. Great reason to write unit tests :) --- src/internal.c | 2 +- src/timeline.c | 37 +++++++++++++++++++++---------------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/internal.c b/src/internal.c index ec5585a..dc25779 100644 --- a/src/internal.c +++ b/src/internal.c @@ -462,7 +462,7 @@ static void DrawQueue(struct Game* game, struct TM_Action* queue, int clipX, int al_draw_text(game->_priv.font_console, pom->started ? al_map_rgb(0, 0, 0) : al_map_rgb(255, 255, 255), pos, clipY, ALLEGRO_ALIGN_LEFT, pom->name); if (pom->delay) { - al_draw_textf(game->_priv.font_console, al_map_rgb(255, 255, 255), pos, clipY - (50 / 1800.0) * al_get_display_height(game->display), ALLEGRO_ALIGN_LEFT, "%d", (int)pom->delay); + al_draw_textf(game->_priv.font_console, al_map_rgb(255, 255, 255), pos, clipY - (50 / 1800.0) * al_get_display_height(game->display), ALLEGRO_ALIGN_LEFT, "%d", (int)(pom->delay * 1000)); } if (strncmp(pom->name, "TM_BackgroundAction", 19) == 0) { diff --git a/src/timeline.c b/src/timeline.c index b17c903..9c7e001 100644 --- a/src/timeline.c +++ b/src/timeline.c @@ -45,19 +45,22 @@ SYMBOL_EXPORT struct Timeline* TM_Init(struct Game* game, struct GamestateResour } SYMBOL_EXPORT void TM_Process(struct Timeline* timeline, double delta) { - // NOTICE: current implementation has no way to know how much time - // an action has "eaten". This means that if you pass a huge delta - // that spans across multiple actions, the end result will most likely - // differ from what you would get from calling TM_Process repeatively - // with smaller deltas that sum up to the first value. Be aware! + // NOTICE: if you create background actions from running action, + // newly created ones have no way to know how much time has been + // "eaten" by the one that created it, which may result in incorrect + // result when calling TM_Process with huge delta. This behaviour + // may change in the future. + + // TODO: make sure new action STARTS in the same tick as the old one + // DESTROYS, but make it RUNNING only in the next tick (or when there's + // some remaining delta). /* process first element from queue. if returns true, delete it and repeat for the next one */ - delta *= 1000; - bool next = true; - while (next) { + double origDelta = delta; + while (delta > 0.0) { if (timeline->queue) { - timeline->queue->delta = delta / 1000.0; + timeline->queue->delta = delta; if (timeline->queue->active && timeline->queue->delay > 0.0) { timeline->queue->delay -= delta; @@ -84,6 +87,7 @@ SYMBOL_EXPORT void TM_Process(struct Timeline* timeline, double delta) { timeline->queue->state = TM_ACTIONSTATE_RUNNING; if ((*timeline->queue->function)(timeline->game, timeline->data, timeline->queue)) { PrintConsole(timeline->game, "Timeline Manager[%s]: queue: destroy action (%d - %s)", timeline->name, timeline->queue->id, timeline->queue->name); + delta -= timeline->queue->delta; struct TM_Action* tmp = timeline->queue; timeline->queue = timeline->queue->next; tmp->state = TM_ACTIONSTATE_DESTROY; @@ -92,7 +96,7 @@ SYMBOL_EXPORT void TM_Process(struct Timeline* timeline, double delta) { free(tmp->name); free(tmp); } else { - next = false; + delta = 0.0; } } else { /* delay handling */ @@ -103,23 +107,24 @@ SYMBOL_EXPORT void TM_Process(struct Timeline* timeline, double delta) { free(tmp); } else { if (!timeline->queue->active) { - PrintConsole(timeline->game, "Timeline Manager[%s]: queue: delay started %d ms (%d - %s)", timeline->name, (int)timeline->queue->delay, timeline->queue->id, timeline->queue->name); + PrintConsole(timeline->game, "Timeline Manager[%s]: queue: delay started %d ms (%d - %s)", timeline->name, (int)(timeline->queue->delay * 1000), timeline->queue->id, timeline->queue->name); timeline->queue->active = true; } - next = false; + delta = 0.0; } } } else { - next = false; + delta = 0.0; } } + delta = origDelta; /* process all elements from background queue */ struct TM_Action *tmp, *tmp2, *pom = timeline->background; tmp = NULL; while (pom != NULL) { bool destroy = false; - pom->delta = delta / 1000.0; + pom->delta = delta; if (pom->started) { if (pom->function) { pom->state = TM_ACTIONSTATE_RUNNING; @@ -221,7 +226,7 @@ SYMBOL_EXPORT struct TM_Action* TM_AddBackgroundAction(struct Timeline* timeline action->function = func; action->arguments = args; action->name = strdup(name); - action->delay = delay; + action->delay = delay / 1000.0; action->id = ++timeline->lastid; action->active = true; action->started = false; @@ -263,7 +268,7 @@ SYMBOL_EXPORT struct TM_Action* TM_AddQueuedBackgroundAction(struct Timeline* ti SYMBOL_EXPORT void TM_AddDelay(struct Timeline* timeline, int delay) { struct TM_Action* tmp = TM_AddAction(timeline, NULL, NULL, "TM_Delay"); PrintConsole(timeline->game, "Timeline Manager[%s]: queue: adding delay %d ms (%d)", timeline->name, delay, tmp->id); - tmp->delay = delay; + tmp->delay = delay / 1000.0; } SYMBOL_EXPORT void TM_CleanQueue(struct Timeline* timeline) {