[client] overlay: move keybinds and config into the overlays

This adds a new `earlyInit` call which allows the overlay to register
options before actually being intialized. Also the keybind handling and
state tracking for each overlay has been moved internal to the overlay
itself.
This commit is contained in:
Geoffrey McRae 2021-08-05 06:40:06 +10:00
parent d90e658e3b
commit 6c84c0eca6
12 changed files with 83 additions and 56 deletions

View File

@ -83,7 +83,8 @@ void app_glSwapBuffers(void);
#endif #endif
#define MAX_OVERLAY_RECTS 10 #define MAX_OVERLAY_RECTS 10
void app_registerOverlay(const struct LG_OverlayOps * ops, void * params); void app_registerOverlay(const struct LG_OverlayOps * ops, const void * params);
void app_initOverlays(void);
void app_setOverlay(bool enable); void app_setOverlay(bool enable);
bool app_overlayNeedsRender(void); bool app_overlayNeedsRender(void);
/** /**

View File

@ -31,8 +31,11 @@ struct LG_OverlayOps
/* internal name of the overlay for debugging */ /* internal name of the overlay for debugging */
const char * name; const char * name;
/* called very early to allow for option registration, optional */
void (*earlyInit)(void);
/* called when the overlay is registered */ /* called when the overlay is registered */
bool (*init)(void ** udata, void * params); bool (*init)(void ** udata, const void * params);
/* final free */ /* final free */
void (*free)(void * udata); void (*free)(void * udata);

View File

@ -671,27 +671,39 @@ void app_unregisterGraph(GraphHandle handle)
struct Overlay struct Overlay
{ {
const struct LG_OverlayOps * ops; const struct LG_OverlayOps * ops;
const void * params;
void * udata; void * udata;
int lastRectCount; int lastRectCount;
struct Rect lastRects[MAX_OVERLAY_RECTS]; struct Rect lastRects[MAX_OVERLAY_RECTS];
}; };
void app_registerOverlay(const struct LG_OverlayOps * ops, void * params) void app_registerOverlay(const struct LG_OverlayOps * ops, const void * params)
{ {
ASSERT_LG_OVERLAY_VALID(ops); ASSERT_LG_OVERLAY_VALID(ops);
void * udata;
if (!ops->init(&udata, params))
{
DEBUG_ERROR("Overlay `%s` failed to initialize", ops->name);
return;
}
struct Overlay * overlay = malloc(sizeof(struct Overlay)); struct Overlay * overlay = malloc(sizeof(struct Overlay));
overlay->ops = ops; overlay->ops = ops;
overlay->udata = udata; overlay->params = params;
overlay->udata = NULL;
overlay->lastRectCount = 0; overlay->lastRectCount = 0;
ll_push(g_state.overlays, overlay); ll_push(g_state.overlays, overlay);
if (ops->earlyInit)
ops->earlyInit();
}
void app_initOverlays(void)
{
struct Overlay * overlay;
for (ll_reset(g_state.overlays);
ll_walk(g_state.overlays, (void **)&overlay); )
{
if (!overlay->ops->init(&overlay->udata, overlay->params))
{
DEBUG_ERROR("Overlay `%s` failed to initialize", overlay->ops->name);
overlay->ops = NULL;
}
}
} }
static inline void mergeRect(struct Rect * dest, const struct Rect * a, const struct Rect * b) static inline void mergeRect(struct Rect * dest, const struct Rect * a, const struct Rect * b)

View File

@ -209,14 +209,6 @@ static struct Option options[] =
.type = OPTION_TYPE_INT, .type = OPTION_TYPE_INT,
.value.x_int = -1, .value.x_int = -1,
}, },
{
.module = "win",
.name = "showFPS",
.description = "Enable the FPS & UPS display",
.shortopt = 'k',
.type = OPTION_TYPE_BOOL,
.value.x_bool = false,
},
{ {
.module = "win", .module = "win",
.name = "ignoreQuit", .name = "ignoreQuit",
@ -563,7 +555,6 @@ bool config_load(int argc, char * argv[])
g_params.fullscreen = option_get_bool ("win", "fullScreen" ); g_params.fullscreen = option_get_bool ("win", "fullScreen" );
g_params.maximize = option_get_bool ("win", "maximize" ); g_params.maximize = option_get_bool ("win", "maximize" );
g_params.fpsMin = option_get_int ("win", "fpsMin" ); g_params.fpsMin = option_get_int ("win", "fpsMin" );
g_params.showFPS = option_get_bool ("win", "showFPS" );
g_params.ignoreQuit = option_get_bool ("win", "ignoreQuit" ); g_params.ignoreQuit = option_get_bool ("win", "ignoreQuit" );
g_params.noScreensaver = option_get_bool ("win", "noScreensaver" ); g_params.noScreensaver = option_get_bool ("win", "noScreensaver" );
g_params.autoScreensaver = option_get_bool ("win", "autoScreensaver"); g_params.autoScreensaver = option_get_bool ("win", "autoScreensaver");

View File

@ -48,18 +48,6 @@ static void bind_video(int sc, void * opaque)
core_startFrameThread(); core_startFrameThread();
} }
static void bind_showFPS(int sc, void * opaque)
{
g_state.showFPS = !g_state.showFPS;
app_invalidateWindow();
}
static void bind_showTiming(int sc, void * opaque)
{
g_state.showTiming = !g_state.showTiming;
app_invalidateWindow();
}
static void bind_rotate(int sc, void * opaque) static void bind_rotate(int sc, void * opaque)
{ {
if (g_params.winRotate == LG_ROTATE_MAX-1) if (g_params.winRotate == LG_ROTATE_MAX-1)
@ -144,8 +132,6 @@ void keybind_register(void)
{ {
app_registerKeybind(KEY_F, bind_fullscreen , NULL, "Full screen toggle"); app_registerKeybind(KEY_F, bind_fullscreen , NULL, "Full screen toggle");
app_registerKeybind(KEY_V, bind_video , NULL, "Video stream toggle"); app_registerKeybind(KEY_V, bind_video , NULL, "Video stream toggle");
app_registerKeybind(KEY_D, bind_showFPS , NULL, "FPS display toggle");
app_registerKeybind(KEY_T, bind_showTiming , NULL, "Show frame timing information");
app_registerKeybind(KEY_R, bind_rotate , NULL, "Rotate the output clockwise by 90° increments"); app_registerKeybind(KEY_R, bind_rotate , NULL, "Rotate the output clockwise by 90° increments");
app_registerKeybind(KEY_Q, bind_quit , NULL, "Quit"); app_registerKeybind(KEY_Q, bind_quit , NULL, "Quit");
app_registerKeybind(KEY_O, bind_toggleOverlay, NULL, "Toggle overlay"); app_registerKeybind(KEY_O, bind_toggleOverlay, NULL, "Toggle overlay");

View File

@ -70,7 +70,7 @@ static LGThread *t_spice = NULL;
static LGThread *t_render = NULL; static LGThread *t_render = NULL;
static LGThread *t_cursor = NULL; static LGThread *t_cursor = NULL;
struct AppState g_state; struct AppState g_state = { 0 };
struct CursorState g_cursor; struct CursorState g_cursor;
// this structure is initialized in config.c // this structure is initialized in config.c
@ -798,14 +798,10 @@ static bool tryRenderer(const int index, const LG_RendererParams lgrParams,
static int lg_run(void) static int lg_run(void)
{ {
memset(&g_state, 0, sizeof(g_state));
g_cursor.sens = g_params.mouseSens; g_cursor.sens = g_params.mouseSens;
if (g_cursor.sens < -9) g_cursor.sens = -9; if (g_cursor.sens < -9) g_cursor.sens = -9;
else if (g_cursor.sens > 9) g_cursor.sens = 9; else if (g_cursor.sens > 9) g_cursor.sens = 9;
g_state.showFPS = g_params.showFPS;
/* setup imgui */ /* setup imgui */
igCreateContext(NULL); igCreateContext(NULL);
g_state.io = igGetIO(); g_state.io = igGetIO();
@ -819,12 +815,7 @@ static int lg_run(void)
g_state.fontName = util_getUIFont(g_params.uiFont); g_state.fontName = util_getUIFont(g_params.uiFont);
DEBUG_INFO("Using font: %s", g_state.fontName); DEBUG_INFO("Using font: %s", g_state.fontName);
g_state.overlays = ll_new(); app_initOverlays();
app_registerOverlay(&LGOverlayConfig, NULL);
app_registerOverlay(&LGOverlayAlert , NULL);
app_registerOverlay(&LGOverlayFPS , NULL);
app_registerOverlay(&LGOverlayGraphs, NULL);
app_registerOverlay(&LGOverlayHelp , NULL);
// initialize metrics ringbuffers // initialize metrics ringbuffers
g_state.renderTimings = ringbuffer_new(256, sizeof(float)); g_state.renderTimings = ringbuffer_new(256, sizeof(float));
@ -1277,6 +1268,13 @@ int main(int argc, char * argv[])
for(unsigned int i = 0; i < LG_DISPLAYSERVER_COUNT; ++i) for(unsigned int i = 0; i < LG_DISPLAYSERVER_COUNT; ++i)
LG_DisplayServers[i]->setup(); LG_DisplayServers[i]->setup();
g_state.overlays = ll_new();
app_registerOverlay(&LGOverlayConfig, NULL);
app_registerOverlay(&LGOverlayAlert , NULL);
app_registerOverlay(&LGOverlayFPS , NULL);
app_registerOverlay(&LGOverlayGraphs, NULL);
app_registerOverlay(&LGOverlayHelp , NULL);
if (!config_load(argc, argv)) if (!config_load(argc, argv))
return -1; return -1;

View File

@ -68,8 +68,6 @@ struct AppState
bool stopVideo; bool stopVideo;
bool ignoreInput; bool ignoreInput;
bool showFPS;
bool showTiming;
bool escapeActive; bool escapeActive;
uint64_t escapeTime; uint64_t escapeTime;
int escapeAction; int escapeAction;
@ -148,7 +146,6 @@ struct AppParams
int x, y; int x, y;
unsigned int w, h; unsigned int w, h;
int fpsMin; int fpsMin;
bool showFPS;
LG_RendererRotate winRotate; LG_RendererRotate winRotate;
bool useSpiceInput; bool useSpiceInput;
bool useSpiceClipboard; bool useSpiceClipboard;

View File

@ -24,7 +24,7 @@
#include "../main.h" #include "../main.h"
static bool alert_init(void ** udata, void * params) static bool alert_init(void ** udata, const void * params)
{ {
return true; return true;
} }

View File

@ -46,7 +46,7 @@ OverlayConfig;
static OverlayConfig cfg = { 0 }; static OverlayConfig cfg = { 0 };
static bool config_init(void ** udata, void * params) static bool config_init(void ** udata, const void * params)
{ {
cfg.callbacks = ll_new(); cfg.callbacks = ll_new();
if (!cfg.callbacks) if (!cfg.callbacks)

View File

@ -22,10 +22,39 @@
#include "cimgui.h" #include "cimgui.h"
#include "overlay_utils.h" #include "overlay_utils.h"
#include "common/option.h"
#include "../main.h" #include "../main.h"
static bool fps_init(void ** udata, void * params) static bool showFPS;
static void showFPSKeybind(int sc, void * opaque)
{ {
showFPS ^= true;
app_invalidateWindow();
}
static void fps_earlyInit(void)
{
static struct Option options[] =
{
{
.module = "win",
.name = "showFPS",
.description = "Enable the FPS & UPS display",
.shortopt = 'k',
.type = OPTION_TYPE_BOOL,
.value.x_bool = false,
},
{ 0 }
};
option_register(options);
}
static bool fps_init(void ** udata, const void * params)
{
app_registerKeybind(KEY_D, showFPSKeybind, NULL, "FPS display toggle");
showFPS = option_get_bool("win", "showFPS");
return true; return true;
} }
@ -36,7 +65,7 @@ static void fps_free(void * udata)
static int fps_render(void * udata, bool interactive, struct Rect * windowRects, static int fps_render(void * udata, bool interactive, struct Rect * windowRects,
int maxRects) int maxRects)
{ {
if (!g_state.showFPS) if (!showFPS)
return 0; return 0;
ImVec2 pos = {0.0f, 0.0f}; ImVec2 pos = {0.0f, 0.0f};
@ -68,6 +97,7 @@ static int fps_render(void * udata, bool interactive, struct Rect * windowRects,
struct LG_OverlayOps LGOverlayFPS = struct LG_OverlayOps LGOverlayFPS =
{ {
.name = "FPS", .name = "FPS",
.earlyInit = fps_earlyInit,
.init = fps_init, .init = fps_init,
.free = fps_free, .free = fps_free,
.render = fps_render .render = fps_render

View File

@ -29,6 +29,7 @@
struct GraphState struct GraphState
{ {
bool show;
struct ll * graphs; struct ll * graphs;
}; };
@ -46,7 +47,7 @@ struct OverlayGraph
static void configCallback(void * udata) static void configCallback(void * udata)
{ {
igCheckbox("Show Timing Graphs", &g_state.showTiming); igCheckbox("Show Timing Graphs", &gs.show);
igSeparator(); igSeparator();
igBeginTable("split", 2, 0, (ImVec2){}, 0); igBeginTable("split", 2, 0, (ImVec2){}, 0);
@ -61,10 +62,18 @@ static void configCallback(void * udata)
igEndTable(); igEndTable();
} }
static bool graphs_init(void ** udata, void * params) static void showTimingKeybind(int sc, void * opaque)
{
gs.show ^= true;
app_invalidateWindow();
}
static bool graphs_init(void ** udata, const void * params)
{ {
gs.graphs = ll_new(); gs.graphs = ll_new();
app_overlayConfigRegister("Performance Metrics", configCallback, NULL); app_overlayConfigRegister("Performance Metrics", configCallback, NULL);
app_registerKeybind(KEY_T, showTimingKeybind, NULL,
"Show frame timing information");
return true; return true;
} }
@ -111,7 +120,7 @@ static bool rbCalcMetrics(int index, void * value_, void * udata_)
static int graphs_render(void * udata, bool interactive, static int graphs_render(void * udata, bool interactive,
struct Rect * windowRects, int maxRects) struct Rect * windowRects, int maxRects)
{ {
if (!g_state.showTiming) if (!gs.show)
return 0; return 0;
float fontSize = igGetFontSize(); float fontSize = igGetFontSize();

View File

@ -27,7 +27,7 @@
#include "../kb.h" #include "../kb.h"
#include "../main.h" #include "../main.h"
static bool help_init(void ** udata, void * params) static bool help_init(void ** udata, const void * params)
{ {
return true; return true;
} }