mirror of https://github.com/inolen/redream.git
don't create new window_listener instances during registration
This commit is contained in:
parent
b54ac3be06
commit
0907a66cd5
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue