t/gui: Add scene manager

This commit is contained in:
Jakob Bornecrantz 2019-09-02 13:15:51 +01:00 committed by Jakob Bornecrantz
parent c474112782
commit 71b3de9c46
3 changed files with 149 additions and 0 deletions

View file

@ -18,6 +18,7 @@ set(SOURCE_FILES
gui_main.c
gui_ogl.c
gui_prober.c
gui_scene.cpp
gui_sdl2.c
../../../external/glad/gl.h
../../../external/glad/gl.c

View file

@ -28,6 +28,7 @@ extern "C" {
struct xrt_device;
struct xrt_prober;
struct time_state;
struct gui_scene_manager;
/*!
* Common struct holding state for the GUI interface.
@ -42,6 +43,8 @@ struct program
bool stopped;
bool initialized;
struct gui_scene_manager *gsm;
struct
{
SDL_Surface *sf;
@ -59,6 +62,15 @@ struct program
struct gui_ogl_texture *texs[256];
};
/*!
* A single currently running scene.
*/
struct gui_scene
{
void (*render)(struct gui_scene *, struct program *);
void (*destroy)(struct gui_scene *);
};
/*!
* A OpenGL texture.
*
@ -156,6 +168,46 @@ gui_ogl_sink_create(const char *name,
void
gui_ogl_sink_update(struct gui_ogl_texture *);
/*!
* Push the scene to the top of the lists.
*
* @ingroup gui
*/
void
gui_scene_push_front(struct program *p, struct gui_scene *me);
/*!
* Put a scene on the delete list, also removes it from any other list.
*
* @ingroup gui
*/
void
gui_scene_delete_me(struct program *p, struct gui_scene *me);
/*!
* Render the scenes.
*
* @ingroup gui
*/
void
gui_scene_manager_render(struct program *p);
/*!
* Initialize the scene manager.
*
* @ingroup gui
*/
void
gui_scene_manager_init(struct program *p);
/*!
* Destroy the scene manager.
*
* @ingroup gui
*/
void
gui_scene_manager_destroy(struct program *p);
#ifdef __cplusplus
}

View file

@ -0,0 +1,96 @@
// Copyright 2019, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief SDL2 functions to drive the GUI.
* @author Jakob Bornecrantz <jakob@collabora.com>
* @ingroup gui
*/
#include "gui_common.h"
#include <vector>
struct gui_scene_manager
{
public:
std::vector<gui_scene *> scenes = {};
std::vector<gui_scene *> del = {};
};
extern "C" void
gui_scene_push_front(struct program *p, struct gui_scene *me)
{
auto &gsm = *p->gsm;
// Need to remove the scene if it is already on the list.
auto index = gsm.scenes.begin();
for (auto scene : gsm.scenes) {
if (scene != me) {
index++;
continue;
}
gsm.scenes.erase(index);
break;
}
// Now push it to the front.
gsm.scenes.push_back(me);
}
extern "C" void
gui_scene_delete_me(struct program *p, struct gui_scene *me)
{
auto &gsm = *p->gsm;
auto index = gsm.scenes.begin();
for (auto scene : gsm.scenes) {
if (scene != me) {
index++;
continue;
}
gsm.scenes.erase(index);
break;
}
gsm.del.push_back(me);
}
extern "C" void
gui_scene_manager_render(struct program *p)
{
auto &gsm = *p->gsm;
auto copy = gsm.scenes;
for (auto scene : copy) {
scene->render(scene, p);
}
copy = gsm.del;
gsm.del.clear();
for (auto scene : copy) {
scene->destroy(scene);
}
// If there are no scenes left stop the program.
if (gsm.scenes.size() == 0) {
p->stopped = true;
}
}
extern "C" void
gui_scene_manager_init(struct program *p)
{
p->gsm = new gui_scene_manager;
}
extern "C" void
gui_scene_manager_destroy(struct program *p)
{
delete p->gsm;
p->gsm = NULL;
}