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 emu {
|
||||||
struct window *window;
|
struct window *window;
|
||||||
struct window_listener *listener;
|
struct window_listener listener;
|
||||||
struct dreamcast *dc;
|
struct dreamcast *dc;
|
||||||
atomic_int running;
|
atomic_int running;
|
||||||
int throttled;
|
int throttled;
|
||||||
|
@ -225,20 +225,21 @@ void emu_run(struct emu *emu, const char *path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct emu *emu_create(struct window *window) {
|
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));
|
struct emu *emu = calloc(1, sizeof(struct emu));
|
||||||
|
|
||||||
emu->window = window;
|
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);
|
emu->running = ATOMIC_VAR_INIT(0);
|
||||||
|
|
||||||
|
win_add_listener(emu->window, &emu->listener);
|
||||||
|
|
||||||
return emu;
|
return emu;
|
||||||
}
|
}
|
||||||
|
|
||||||
void emu_destroy(struct emu *emu) {
|
void emu_destroy(struct emu *emu) {
|
||||||
win_remove_listener(emu->window, emu->listener);
|
win_remove_listener(emu->window, &emu->listener);
|
||||||
|
|
||||||
if (emu->dc) {
|
if (emu->dc) {
|
||||||
dc_destroy(emu->dc);
|
dc_destroy(emu->dc);
|
||||||
|
|
|
@ -66,7 +66,7 @@ struct tracer_texture_entry {
|
||||||
|
|
||||||
struct tracer {
|
struct tracer {
|
||||||
struct window *window;
|
struct window *window;
|
||||||
struct window_listener *listener;
|
struct window_listener listener;
|
||||||
struct texture_provider provider;
|
struct texture_provider provider;
|
||||||
struct rb *rb;
|
struct rb *rb;
|
||||||
struct tr *tr;
|
struct tr *tr;
|
||||||
|
@ -851,21 +851,22 @@ void tracer_run(struct tracer *tracer, const char *path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tracer *tracer_create(struct window *window) {
|
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
|
// ensure param / poly / vertex size LUTs are generated
|
||||||
ta_build_tables();
|
ta_build_tables();
|
||||||
|
|
||||||
struct tracer *tracer = calloc(1, sizeof(struct tracer));
|
struct tracer *tracer = calloc(1, sizeof(struct tracer));
|
||||||
|
|
||||||
tracer->window = window;
|
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 =
|
tracer->provider =
|
||||||
(struct texture_provider){tracer, &tracer_texture_provider_find_texture};
|
(struct texture_provider){tracer, &tracer_texture_provider_find_texture};
|
||||||
tracer->rb = window->rb;
|
tracer->rb = window->rb;
|
||||||
tracer->tr = tr_create(tracer->rb, &tracer->provider);
|
tracer->tr = tr_create(tracer->rb, &tracer->provider);
|
||||||
|
|
||||||
|
win_add_listener(tracer->window, &tracer->listener);
|
||||||
|
|
||||||
// setup tile context buffers
|
// setup tile context buffers
|
||||||
tracer->ctx.params = tracer->params;
|
tracer->ctx.params = tracer->params;
|
||||||
|
|
||||||
|
@ -902,7 +903,7 @@ void tracer_destroy(struct tracer *tracer) {
|
||||||
if (tracer->trace) {
|
if (tracer->trace) {
|
||||||
trace_destroy(tracer->trace);
|
trace_destroy(tracer->trace);
|
||||||
}
|
}
|
||||||
win_remove_listener(tracer->window, tracer->listener);
|
win_remove_listener(tracer->window, &tracer->listener);
|
||||||
tr_destroy(tracer->tr);
|
tr_destroy(tracer->tr);
|
||||||
free(tracer);
|
free(tracer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ struct shader_program {
|
||||||
|
|
||||||
struct rb {
|
struct rb {
|
||||||
struct window *window;
|
struct window *window;
|
||||||
struct window_listener *listener;
|
struct window_listener listener;
|
||||||
|
|
||||||
SDL_GLContext ctx;
|
SDL_GLContext ctx;
|
||||||
int debug_wireframe;
|
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) {
|
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));
|
struct rb *rb = (struct rb *)calloc(1, sizeof(struct rb));
|
||||||
rb->window = window;
|
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)) {
|
if (!rb_init_context(rb)) {
|
||||||
rb_destroy(rb);
|
rb_destroy(rb);
|
||||||
|
@ -723,6 +723,6 @@ void rb_destroy(struct rb *rb) {
|
||||||
rb_destroy_shaders(rb);
|
rb_destroy_shaders(rb);
|
||||||
rb_destroy_textures(rb);
|
rb_destroy_textures(rb);
|
||||||
rb_destroy_context(rb);
|
rb_destroy_context(rb);
|
||||||
win_remove_listener(rb->window, rb->listener);
|
win_remove_listener(rb->window, &rb->listener);
|
||||||
free(rb);
|
free(rb);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ static const int MAX_2D_SURFACES = 256;
|
||||||
|
|
||||||
struct microprofile {
|
struct microprofile {
|
||||||
struct window *window;
|
struct window *window;
|
||||||
struct window_listener *listener;
|
struct window_listener listener;
|
||||||
texture_handle_t font_texture;
|
texture_handle_t font_texture;
|
||||||
struct surface2d surfs[MAX_2D_SURFACES];
|
struct surface2d surfs[MAX_2D_SURFACES];
|
||||||
int num_surfs;
|
int num_surfs;
|
||||||
|
@ -259,14 +259,14 @@ void mp_end_frame(struct microprofile *mp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct microprofile *mp_create(struct window *window) {
|
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 *>(
|
struct microprofile *mp = reinterpret_cast<struct microprofile *>(
|
||||||
calloc(1, sizeof(struct microprofile)));
|
calloc(1, sizeof(struct microprofile)));
|
||||||
|
|
||||||
mp->window = window;
|
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
|
// init microprofile
|
||||||
struct rb *rb = mp->window->rb;
|
struct rb *rb = mp->window->rb;
|
||||||
|
@ -294,7 +294,7 @@ struct microprofile *mp_create(struct window *window) {
|
||||||
void mp_destroy(struct microprofile *mp) {
|
void mp_destroy(struct microprofile *mp) {
|
||||||
rb_destroy_texture(mp->window->rb, mp->font_texture);
|
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);
|
free(mp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,12 +129,12 @@ void nk_end_frame(struct nuklear *nk) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct nuklear *nk_create(struct window *window) {
|
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));
|
struct nuklear *nk = calloc(1, sizeof(struct nuklear));
|
||||||
nk->window = window;
|
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
|
// create default font texture
|
||||||
nk_font_atlas_init_default(&nk->atlas);
|
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);
|
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);
|
free(nk);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,16 +12,14 @@
|
||||||
#include <nuklear.h>
|
#include <nuklear.h>
|
||||||
|
|
||||||
#include "renderer/backend.h"
|
#include "renderer/backend.h"
|
||||||
|
#include "ui/window.h"
|
||||||
struct window;
|
|
||||||
struct window_listener;
|
|
||||||
|
|
||||||
#define NK_MAX_VERTICES 4096
|
#define NK_MAX_VERTICES 4096
|
||||||
#define NK_MAX_ELEMENTS 16384
|
#define NK_MAX_ELEMENTS 16384
|
||||||
|
|
||||||
struct nuklear {
|
struct nuklear {
|
||||||
struct window *window;
|
struct window *window;
|
||||||
struct window_listener *listener;
|
struct window_listener listener;
|
||||||
|
|
||||||
//
|
//
|
||||||
struct nk_context ctx;
|
struct nk_context ctx;
|
||||||
|
|
|
@ -39,10 +39,9 @@ static void win_handle_paint(struct window *win) {
|
||||||
nk_begin_frame(win->nk);
|
nk_begin_frame(win->nk);
|
||||||
mp_begin_frame(win->mp);
|
mp_begin_frame(win->mp);
|
||||||
|
|
||||||
list_for_each_entry(listener, &win->live_listeners, struct window_listener,
|
list_for_each_entry(listener, &win->listeners, struct window_listener, it) {
|
||||||
it) {
|
if (listener->paint) {
|
||||||
if (listener->cb.paint) {
|
listener->paint(listener->data);
|
||||||
listener->cb.paint(listener->data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,10 +53,10 @@ static void win_handle_paint(struct window *win) {
|
||||||
if (nk_begin(ctx, &layout, "debug menu", bounds,
|
if (nk_begin(ctx, &layout, "debug menu", bounds,
|
||||||
NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE |
|
NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE |
|
||||||
NK_WINDOW_TITLE)) {
|
NK_WINDOW_TITLE)) {
|
||||||
list_for_each_entry(listener, &win->live_listeners,
|
list_for_each_entry(listener, &win->listeners, struct window_listener,
|
||||||
struct window_listener, it) {
|
it) {
|
||||||
if (listener->cb.paint_debug_menu) {
|
if (listener->paint_debug_menu) {
|
||||||
listener->cb.paint_debug_menu(listener->data, ctx);
|
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,
|
static void win_handle_keydown(struct window *win, enum keycode code,
|
||||||
int16_t value) {
|
int16_t value) {
|
||||||
list_for_each_entry(listener, &win->live_listeners, struct window_listener,
|
list_for_each_entry(listener, &win->listeners, struct window_listener, it) {
|
||||||
it) {
|
if (listener->keydown) {
|
||||||
if (listener->cb.keydown) {
|
listener->keydown(listener->data, code, value);
|
||||||
listener->cb.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) {
|
static void win_handle_textinput(struct window *win, const char *text) {
|
||||||
list_for_each_entry(listener, &win->live_listeners, struct window_listener,
|
list_for_each_entry(listener, &win->listeners, struct window_listener, it) {
|
||||||
it) {
|
if (listener->textinput) {
|
||||||
if (listener->cb.textinput) {
|
listener->textinput(listener->data, text);
|
||||||
listener->cb.textinput(listener->data, text);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void win_handle_mousemove(struct window *win, int x, int y) {
|
static void win_handle_mousemove(struct window *win, int x, int y) {
|
||||||
list_for_each_entry(listener, &win->live_listeners, struct window_listener,
|
list_for_each_entry(listener, &win->listeners, struct window_listener, it) {
|
||||||
it) {
|
if (listener->mousemove) {
|
||||||
if (listener->cb.mousemove) {
|
listener->mousemove(listener->data, x, y);
|
||||||
listener->cb.mousemove(listener->data, x, y);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void win_handle_close(struct window *win) {
|
static void win_handle_close(struct window *win) {
|
||||||
list_for_each_entry(listener, &win->live_listeners, struct window_listener,
|
list_for_each_entry(listener, &win->listeners, struct window_listener, it) {
|
||||||
it) {
|
if (listener->close) {
|
||||||
if (listener->cb.close) {
|
listener->close(listener->data);
|
||||||
listener->cb.close(listener->data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -829,25 +824,12 @@ void win_pump_events(struct window *win) {
|
||||||
win_handle_paint(win);
|
win_handle_paint(win);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct window_listener *win_add_listener(struct window *win,
|
void win_add_listener(struct window *win, struct window_listener *listener) {
|
||||||
const struct window_callbacks *cb,
|
list_add(&win->listeners, &listener->it);
|
||||||
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_remove_listener(struct window *win, struct window_listener *listener) {
|
void win_remove_listener(struct window *win, struct window_listener *listener) {
|
||||||
list_remove(&win->live_listeners, &listener->it);
|
list_remove(&win->listeners, &listener->it);
|
||||||
|
|
||||||
list_add(&win->free_listeners, &listener->it);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct window *win_create() {
|
struct window *win_create() {
|
||||||
|
@ -856,11 +838,6 @@ struct window *win_create() {
|
||||||
win->width = DEFAULT_WIDTH;
|
win->width = DEFAULT_WIDTH;
|
||||||
win->height = DEFAULT_HEIGHT;
|
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
|
// initialize window
|
||||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
|
||||||
LOG_WARNING("SDL initialization failed: %s", SDL_GetError());
|
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_KEYS ((K_JOY31 - K_JOY0) + 1)
|
||||||
#define NUM_JOYSTICK_HATS (((K_HAT15 - K_HAT0) + 1) / 4) /* 4 keys per hat */
|
#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)(void *data);
|
||||||
void (*paint_debug_menu)(void *data, struct nk_context *ctx);
|
void (*paint_debug_menu)(void *data, struct nk_context *ctx);
|
||||||
void (*keydown)(void *data, enum keycode code, int16_t value);
|
void (*keydown)(void *data, enum keycode code, int16_t value);
|
||||||
void (*textinput)(void *data, const char *text);
|
void (*textinput)(void *data, const char *text);
|
||||||
void (*mousemove)(void *data, int x, int y);
|
void (*mousemove)(void *data, int x, int y);
|
||||||
void (*close)(void *data);
|
void (*close)(void *data);
|
||||||
};
|
|
||||||
|
|
||||||
struct window_listener {
|
|
||||||
struct window_callbacks cb;
|
|
||||||
void *data;
|
|
||||||
struct list_node it;
|
struct list_node it;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,9 +47,7 @@ struct window {
|
||||||
bool text_input;
|
bool text_input;
|
||||||
|
|
||||||
// private state
|
// private state
|
||||||
struct window_listener listeners[MAX_WINDOW_LISTENERS];
|
struct list listeners;
|
||||||
struct list free_listeners;
|
|
||||||
struct list live_listeners;
|
|
||||||
|
|
||||||
struct _SDL_Joystick *joystick;
|
struct _SDL_Joystick *joystick;
|
||||||
uint8_t hat_state[NUM_JOYSTICK_HATS];
|
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_debug_menu(struct window *win, bool active);
|
||||||
void win_enable_text_input(struct window *win, bool active);
|
void win_enable_text_input(struct window *win, bool active);
|
||||||
void win_pump_events(struct window *win);
|
void win_pump_events(struct window *win);
|
||||||
struct window_listener *win_add_listener(struct window *win,
|
void win_add_listener(struct window *win, struct window_listener *listener);
|
||||||
const struct window_callbacks *cb,
|
|
||||||
void *data);
|
|
||||||
void win_remove_listener(struct window *win, struct window_listener *listener);
|
void win_remove_listener(struct window *win, struct window_listener *listener);
|
||||||
struct window *win_create();
|
struct window *win_create();
|
||||||
void win_destroy(struct window *win);
|
void win_destroy(struct window *win);
|
||||||
|
|
Loading…
Reference in New Issue