don't create new window_listener instances during registration

This commit is contained in:
Anthony Pesch 2016-07-08 00:00:55 -07:00
parent b54ac3be06
commit 0907a66cd5
8 changed files with 59 additions and 90 deletions

View File

@ -16,7 +16,7 @@ DEFINE_OPTION_STRING(flash, "dc_flash.bin", "Path to flash ROM");
struct emu {
struct window *window;
struct window_listener *listener;
struct window_listener listener;
struct dreamcast *dc;
atomic_int running;
int throttled;
@ -225,20 +225,21 @@ void emu_run(struct emu *emu, const char *path) {
}
struct emu *emu_create(struct window *window) {
static const struct window_callbacks callbacks = {
&emu_paint, &emu_paint_debug_menu, &emu_keydown, NULL, NULL, &emu_close};
struct emu *emu = calloc(1, sizeof(struct emu));
emu->window = window;
emu->listener = win_add_listener(emu->window, &callbacks, emu);
emu->listener = (struct window_listener){
emu, &emu_paint, &emu_paint_debug_menu, &emu_keydown, NULL, NULL,
&emu_close, {}};
emu->running = ATOMIC_VAR_INIT(0);
win_add_listener(emu->window, &emu->listener);
return emu;
}
void emu_destroy(struct emu *emu) {
win_remove_listener(emu->window, emu->listener);
win_remove_listener(emu->window, &emu->listener);
if (emu->dc) {
dc_destroy(emu->dc);

View File

@ -66,7 +66,7 @@ struct tracer_texture_entry {
struct tracer {
struct window *window;
struct window_listener *listener;
struct window_listener listener;
struct texture_provider provider;
struct rb *rb;
struct tr *tr;
@ -851,21 +851,22 @@ void tracer_run(struct tracer *tracer, const char *path) {
}
struct tracer *tracer_create(struct window *window) {
static const struct window_callbacks callbacks = {
&tracer_paint, NULL, &tracer_keydown, NULL, NULL, &tracer_close};
// ensure param / poly / vertex size LUTs are generated
ta_build_tables();
struct tracer *tracer = calloc(1, sizeof(struct tracer));
tracer->window = window;
tracer->listener = win_add_listener(window, &callbacks, tracer);
tracer->listener = (struct window_listener){
tracer, &tracer_paint, NULL, &tracer_keydown,
NULL, NULL, &tracer_close, {}};
tracer->provider =
(struct texture_provider){tracer, &tracer_texture_provider_find_texture};
tracer->rb = window->rb;
tracer->tr = tr_create(tracer->rb, &tracer->provider);
win_add_listener(tracer->window, &tracer->listener);
// setup tile context buffers
tracer->ctx.params = tracer->params;
@ -902,7 +903,7 @@ void tracer_destroy(struct tracer *tracer) {
if (tracer->trace) {
trace_destroy(tracer->trace);
}
win_remove_listener(tracer->window, tracer->listener);
win_remove_listener(tracer->window, &tracer->listener);
tr_destroy(tracer->tr);
free(tracer);
}

View File

@ -29,7 +29,7 @@ struct shader_program {
struct rb {
struct window *window;
struct window_listener *listener;
struct window_listener listener;
SDL_GLContext ctx;
int debug_wireframe;
@ -698,12 +698,12 @@ void rb_destroy_texture(struct rb *rb, texture_handle_t handle) {
}
struct rb *rb_create(struct window *window) {
static const struct window_callbacks callbacks = {
NULL, &rb_paint_debug_menu, NULL, NULL, NULL, NULL};
struct rb *rb = (struct rb *)calloc(1, sizeof(struct rb));
rb->window = window;
rb->listener = win_add_listener(rb->window, &callbacks, rb);
rb->listener = (struct window_listener){
rb, NULL, &rb_paint_debug_menu, NULL, NULL, NULL, NULL, {}};
win_add_listener(rb->window, &rb->listener);
if (!rb_init_context(rb)) {
rb_destroy(rb);
@ -723,6 +723,6 @@ void rb_destroy(struct rb *rb) {
rb_destroy_shaders(rb);
rb_destroy_textures(rb);
rb_destroy_context(rb);
win_remove_listener(rb->window, rb->listener);
win_remove_listener(rb->window, &rb->listener);
free(rb);
}

View File

@ -26,7 +26,7 @@ static const int MAX_2D_SURFACES = 256;
struct microprofile {
struct window *window;
struct window_listener *listener;
struct window_listener listener;
texture_handle_t font_texture;
struct surface2d surfs[MAX_2D_SURFACES];
int num_surfs;
@ -259,14 +259,14 @@ void mp_end_frame(struct microprofile *mp) {
}
struct microprofile *mp_create(struct window *window) {
static const struct window_callbacks callbacks = {
NULL, NULL, &mp_keydown, NULL, &mp_mousemove, NULL};
struct microprofile *mp = reinterpret_cast<struct microprofile *>(
calloc(1, sizeof(struct microprofile)));
mp->window = window;
mp->listener = win_add_listener(mp->window, &callbacks, mp);
mp->listener = (struct window_listener){
mp, NULL, NULL, &mp_keydown, NULL, &mp_mousemove, NULL, {}};
win_add_listener(mp->window, &mp->listener);
// init microprofile
struct rb *rb = mp->window->rb;
@ -294,7 +294,7 @@ struct microprofile *mp_create(struct window *window) {
void mp_destroy(struct microprofile *mp) {
rb_destroy_texture(mp->window->rb, mp->font_texture);
win_remove_listener(mp->window, mp->listener);
win_remove_listener(mp->window, &mp->listener);
free(mp);
}

View File

@ -129,12 +129,12 @@ void nk_end_frame(struct nuklear *nk) {
}
struct nuklear *nk_create(struct window *window) {
static const struct window_callbacks callbacks = {
NULL, NULL, &nk_keydown, &nk_textinput, &nk_mousemove, NULL};
struct nuklear *nk = calloc(1, sizeof(struct nuklear));
nk->window = window;
nk->listener = win_add_listener(nk->window, &callbacks, nk);
nk->listener = (struct window_listener){
nk, NULL, NULL, &nk_keydown, &nk_textinput, &nk_mousemove, NULL, {}};
win_add_listener(nk->window, &nk->listener);
// create default font texture
nk_font_atlas_init_default(&nk->atlas);
@ -162,7 +162,7 @@ void nk_destroy(struct nuklear *nk) {
rb_destroy_texture(nk->window->rb, nk->font_texture);
win_remove_listener(nk->window, nk->listener);
win_remove_listener(nk->window, &nk->listener);
free(nk);
}

View File

@ -12,16 +12,14 @@
#include <nuklear.h>
#include "renderer/backend.h"
struct window;
struct window_listener;
#include "ui/window.h"
#define NK_MAX_VERTICES 4096
#define NK_MAX_ELEMENTS 16384
struct nuklear {
struct window *window;
struct window_listener *listener;
struct window_listener listener;
//
struct nk_context ctx;

View File

@ -39,10 +39,9 @@ static void win_handle_paint(struct window *win) {
nk_begin_frame(win->nk);
mp_begin_frame(win->mp);
list_for_each_entry(listener, &win->live_listeners, struct window_listener,
it) {
if (listener->cb.paint) {
listener->cb.paint(listener->data);
list_for_each_entry(listener, &win->listeners, struct window_listener, it) {
if (listener->paint) {
listener->paint(listener->data);
}
}
@ -54,10 +53,10 @@ static void win_handle_paint(struct window *win) {
if (nk_begin(ctx, &layout, "debug menu", bounds,
NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE |
NK_WINDOW_TITLE)) {
list_for_each_entry(listener, &win->live_listeners,
struct window_listener, it) {
if (listener->cb.paint_debug_menu) {
listener->cb.paint_debug_menu(listener->data, ctx);
list_for_each_entry(listener, &win->listeners, struct window_listener,
it) {
if (listener->paint_debug_menu) {
listener->paint_debug_menu(listener->data, ctx);
}
}
}
@ -72,10 +71,9 @@ static void win_handle_paint(struct window *win) {
static void win_handle_keydown(struct window *win, enum keycode code,
int16_t value) {
list_for_each_entry(listener, &win->live_listeners, struct window_listener,
it) {
if (listener->cb.keydown) {
listener->cb.keydown(listener->data, code, value);
list_for_each_entry(listener, &win->listeners, struct window_listener, it) {
if (listener->keydown) {
listener->keydown(listener->data, code, value);
}
}
}
@ -122,28 +120,25 @@ static void win_handle_hatdown(struct window *win, int hat, uint8_t state,
}
static void win_handle_textinput(struct window *win, const char *text) {
list_for_each_entry(listener, &win->live_listeners, struct window_listener,
it) {
if (listener->cb.textinput) {
listener->cb.textinput(listener->data, text);
list_for_each_entry(listener, &win->listeners, struct window_listener, it) {
if (listener->textinput) {
listener->textinput(listener->data, text);
}
}
}
static void win_handle_mousemove(struct window *win, int x, int y) {
list_for_each_entry(listener, &win->live_listeners, struct window_listener,
it) {
if (listener->cb.mousemove) {
listener->cb.mousemove(listener->data, x, y);
list_for_each_entry(listener, &win->listeners, struct window_listener, it) {
if (listener->mousemove) {
listener->mousemove(listener->data, x, y);
}
}
}
static void win_handle_close(struct window *win) {
list_for_each_entry(listener, &win->live_listeners, struct window_listener,
it) {
if (listener->cb.close) {
listener->cb.close(listener->data);
list_for_each_entry(listener, &win->listeners, struct window_listener, it) {
if (listener->close) {
listener->close(listener->data);
}
}
}
@ -829,25 +824,12 @@ void win_pump_events(struct window *win) {
win_handle_paint(win);
}
struct window_listener *win_add_listener(struct window *win,
const struct window_callbacks *cb,
void *data) {
struct window_listener *listener =
list_first_entry(&win->free_listeners, struct window_listener, it);
CHECK_NOTNULL(listener);
list_remove(&win->free_listeners, &listener->it);
listener->cb = *cb;
listener->data = data;
list_add(&win->live_listeners, &listener->it);
return listener;
void win_add_listener(struct window *win, struct window_listener *listener) {
list_add(&win->listeners, &listener->it);
}
void win_remove_listener(struct window *win, struct window_listener *listener) {
list_remove(&win->live_listeners, &listener->it);
list_add(&win->free_listeners, &listener->it);
list_remove(&win->listeners, &listener->it);
}
struct window *win_create() {
@ -856,11 +838,6 @@ struct window *win_create() {
win->width = DEFAULT_WIDTH;
win->height = DEFAULT_HEIGHT;
for (int i = 0; i < MAX_WINDOW_LISTENERS; i++) {
struct window_listener *listener = &win->listeners[i];
list_add(&win->free_listeners, &listener->it);
}
// initialize window
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
LOG_WARNING("SDL initialization failed: %s", SDL_GetError());

View File

@ -22,18 +22,14 @@ struct SDL_Window;
#define NUM_JOYSTICK_KEYS ((K_JOY31 - K_JOY0) + 1)
#define NUM_JOYSTICK_HATS (((K_HAT15 - K_HAT0) + 1) / 4) /* 4 keys per hat */
struct window_callbacks {
struct window_listener {
void *data;
void (*paint)(void *data);
void (*paint_debug_menu)(void *data, struct nk_context *ctx);
void (*keydown)(void *data, enum keycode code, int16_t value);
void (*textinput)(void *data, const char *text);
void (*mousemove)(void *data, int x, int y);
void (*close)(void *data);
};
struct window_listener {
struct window_callbacks cb;
void *data;
struct list_node it;
};
@ -51,9 +47,7 @@ struct window {
bool text_input;
// private state
struct window_listener listeners[MAX_WINDOW_LISTENERS];
struct list free_listeners;
struct list live_listeners;
struct list listeners;
struct _SDL_Joystick *joystick;
uint8_t hat_state[NUM_JOYSTICK_HATS];
@ -62,9 +56,7 @@ struct window {
void win_enable_debug_menu(struct window *win, bool active);
void win_enable_text_input(struct window *win, bool active);
void win_pump_events(struct window *win);
struct window_listener *win_add_listener(struct window *win,
const struct window_callbacks *cb,
void *data);
void win_add_listener(struct window *win, struct window_listener *listener);
void win_remove_listener(struct window *win, struct window_listener *listener);
struct window *win_create();
void win_destroy(struct window *win);