From bf702c3f433ca7a78d5790bb4b239f5692cfc070 Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Fri, 24 Nov 2017 09:34:54 +0000 Subject: loader: Use SDL event queue to return images --- src/imv.c | 48 ++++++++++++++++++++++++++++++++---------------- src/loader.c | 44 +++++++++++++++++--------------------------- src/loader.h | 11 +++-------- 3 files changed, 52 insertions(+), 51 deletions(-) diff --git a/src/imv.c b/src/imv.c index 7e576e6..ff60d6e 100644 --- a/src/imv.c +++ b/src/imv.c @@ -93,6 +93,13 @@ struct imv { SDL_Texture *background_texture; bool sdl_init; bool ttf_init; + struct { + unsigned int NEW_IMAGE; + } events; + struct { + int width; + int height; + } current_image; }; enum config_section { @@ -469,8 +476,8 @@ int imv_run(struct imv *imv) } /* cache current image's dimensions */ - int iw = 0; - int ih = 0; + imv->current_image.width = 0; + imv->current_image.height = 0; /* time keeping */ unsigned int last_time = SDL_GetTicks(); @@ -532,26 +539,15 @@ int imv_run(struct imv *imv) imv->view->playing = true; } - - /* check if a new image is available to display */ - FIBITMAP *bmp; - int is_new_image; - if(imv_loader_get_image(imv->loader, &bmp, &is_new_image)) { - imv_texture_set_image(imv->texture, bmp); - iw = FreeImage_GetWidth(bmp); - ih = FreeImage_GetHeight(bmp); - FreeImage_Unload(bmp); - imv->need_redraw = true; - imv->need_rescale += is_new_image; - } - if(imv->need_rescale) { int ww, wh; SDL_GetWindowSize(imv->window, &ww, &wh); imv->need_rescale = false; if(imv->scaling_mode == SCALING_NONE || - (imv->scaling_mode == SCALING_DOWN && ww > iw && wh > ih)) { + (imv->scaling_mode == SCALING_DOWN + && ww > imv->current_image.width + && wh > imv->current_image.height)) { imv_viewport_scale_to_actual(imv->view, imv->texture); } else { imv_viewport_scale_to_window(imv->view, imv->texture); @@ -622,6 +618,13 @@ static bool setup_window(struct imv *imv) fprintf(stderr, "SDL Failed to Init: %s\n", SDL_GetError()); return false; } + + /* register custom events */ + imv->events.NEW_IMAGE = SDL_RegisterEvents(1); + + /* tell the loader which event ids it should use */ + imv_loader_set_event_types(imv->loader, imv->events.NEW_IMAGE); + imv->sdl_init = true; /* width and height arbitrarily chosen. Perhaps there's a smarter way to @@ -683,6 +686,19 @@ static bool setup_window(struct imv *imv) static void handle_event(struct imv *imv, SDL_Event *event) { const int command_buffer_len = 1024; + + if(event->type == imv->events.NEW_IMAGE) { + /* new image to display */ + FIBITMAP *bmp = event->user.data1; + imv_texture_set_image(imv->texture, bmp); + imv->current_image.width = FreeImage_GetWidth(bmp); + imv->current_image.height = FreeImage_GetHeight(bmp); + FreeImage_Unload(bmp); + imv->need_redraw = true; + imv->need_rescale |= event->user.code; + return; + } + switch(event->type) { case SDL_QUIT: imv_command_exec(imv->commands, "quit", imv); diff --git a/src/loader.c b/src/loader.c index 3709d5b..4f8550c 100644 --- a/src/loader.c +++ b/src/loader.c @@ -65,9 +65,6 @@ void imv_loader_free(struct imv_loader *ldr) if(ldr->bmp) { FreeImage_Unload(ldr->bmp); } - if(ldr->out_bmp) { - FreeImage_Unload(ldr->out_bmp); - } if(ldr->mbmp) { FreeImage_CloseMultiBitmap(ldr->mbmp, 0); } @@ -104,22 +101,9 @@ void imv_loader_load(struct imv_loader *ldr, const char *path, pthread_mutex_unlock(&ldr->lock); } -int imv_loader_get_image(struct imv_loader *ldr, FIBITMAP **out_bmp, - int *out_is_new_image) +void imv_loader_set_event_types(struct imv_loader *ldr, unsigned int new_image) { - int ret = 0; - pthread_mutex_lock(&ldr->lock); - - if(ldr->out_bmp) { - *out_bmp = ldr->out_bmp; - ldr->out_bmp = NULL; - *out_is_new_image = ldr->out_is_new_image; - ldr->out_is_new_image = 0; - ret = 1; - } - - pthread_mutex_unlock(&ldr->lock); - return ret; + ldr->new_image_event = new_image; } char *imv_loader_get_error(struct imv_loader *ldr) @@ -297,11 +281,7 @@ static void *bg_new_img(void *data) ldr->mbmp = mbmp; ldr->bmp = bmp; - if(ldr->out_bmp) { - FreeImage_Unload(ldr->out_bmp); - } - ldr->out_bmp = FreeImage_Clone(bmp); - ldr->out_is_new_image = 1; + ldr->width = width; ldr->height = height; ldr->cur_frame = 0; @@ -309,6 +289,14 @@ static void *bg_new_img(void *data) ldr->num_frames = num_frames; ldr->frame_time = (double)raw_frame_time * 0.0001; + /* return the image via SDL event queue */ + SDL_Event event; + SDL_zero(event); + event.type = ldr->new_image_event; + event.user.data1 = FreeImage_Clone(bmp); + event.user.code = 1; /* is a new image */ + SDL_PushEvent(&event); + pthread_mutex_unlock(&ldr->lock); return NULL; } @@ -407,10 +395,12 @@ static void *bg_next_frame(void *data) break; } - if(ldr->out_bmp) { - FreeImage_Unload(ldr->out_bmp); - } - ldr->out_bmp = FreeImage_Clone(ldr->bmp); + SDL_Event event; + SDL_zero(event); + event.type = ldr->new_image_event; + event.user.data1 = FreeImage_Clone(ldr->bmp); + event.user.code = 0; /* not a new image */ + SDL_PushEvent(&event); pthread_mutex_unlock(&ldr->lock); return NULL; diff --git a/src/loader.h b/src/loader.h index cbc8178..ad01cb4 100644 --- a/src/loader.h +++ b/src/loader.h @@ -31,8 +31,6 @@ struct imv_loader { BYTE *buffer; size_t buffer_size; FIMEMORY *fi_buffer; - FIBITMAP *out_bmp; - int out_is_new_image; char *out_err; FIMULTIBITMAP *mbmp; FIBITMAP *bmp; @@ -42,6 +40,7 @@ struct imv_loader { int next_frame; int num_frames; double frame_time; + unsigned int new_image_event; }; /* Creates an instance of imv_loader */ @@ -54,12 +53,8 @@ void imv_loader_free(struct imv_loader *ldr); void imv_loader_load(struct imv_loader *ldr, const char *path, const void *buffer, const size_t buffer_size); -/* Returns 1 if image data is available. 0 if not. Caller is responsible for - * cleaning up the data returned. Each image is only returned once. - * out_is_frame indicates whether the returned image is a new image, or just - * a new frame of an existing one. */ -int imv_loader_get_image(struct imv_loader *ldr, FIBITMAP **out_bmp, - int *out_is_frame); +/* Set the custom event types for returning data */ +void imv_loader_set_event_types(struct imv_loader *ldr, unsigned int new_image); /* If a file failed to load, return the path to that file. Otherwise returns * NULL. Only returns the path once. Caller is responsible for cleaning up the -- cgit v1.2.3