Moved GUI2's per-frame drawing trigger to global scope

This is derived from work originally done by @aginor (48bcb277d4). I cherry-picked that commit and made a few alterations.
This commit is contained in:
Charles Dang 2017-06-02 22:51:31 +11:00
parent eaac01c9a2
commit 441ec38adf
7 changed files with 73 additions and 36 deletions

View file

@ -30,7 +30,8 @@ static lg::log_domain log_display("display");
#define ERR_DP LOG_STREAM(err, log_display)
controller_base::controller_base(const config& game_config)
: game_config_(game_config)
: draw_layering(false)
, game_config_(game_config)
, key_()
, scrolling_(false)
, scroll_up_(false)

View file

@ -87,6 +87,8 @@ editor_controller::editor_controller(const config &game_config)
get_current_map_context().set_starting_position_labels(gui());
cursor::set(cursor::NORMAL);
join();
gui().create_buttons();
gui().redraw_everything();
}

View file

@ -403,6 +403,54 @@ static bool remove_on_resize(const SDL_Event& a)
return false;
}
/**
* The interval between draw events.
*
* When the window is shown this value is set, the callback function always
* uses this value instead of the parameter send, that way the window can stop
* drawing when it wants.
*/
static int draw_interval = 0;
SDL_TimerID draw_timer_id;
/**
* SDL_AddTimer() callback for the draw event.
*
* When this callback is called it pushes a new draw event in the event queue.
*
* @returns The new timer interval, 0 to stop.
*/
static Uint32 draw_timer(Uint32, void*)
{
// DBG_GUI_E << "Pushing draw event in queue.\n";
SDL_Event event;
SDL_UserEvent data;
data.type = DRAW_EVENT;
data.code = 0;
data.data1 = NULL;
data.data2 = NULL;
event.type = DRAW_EVENT;
event.user = data;
SDL_PushEvent(&event);
return draw_interval;
}
void initialise()
{
draw_interval = 20;
draw_timer_id = SDL_AddTimer(draw_interval, draw_timer, NULL);
}
void finalize()
{
SDL_RemoveTimer(draw_timer_id);
}
// TODO: I'm uncertain if this is always safe to call at static init; maybe set in main() instead?
static const boost::thread::id main_thread = boost::this_thread::get_id();
@ -607,6 +655,12 @@ void pump()
}
}
const bool is_draw_event = event.type == DRAW_EVENT || event.type == DRAW_ALL_EVENT;
if(is_draw_event) {
CVideo::get_singleton().clear_screen();
}
for(auto global_handler : event_contexts.front().handlers) {
global_handler->handle_event(event);
}
@ -616,6 +670,10 @@ void pump()
handler->handle_event(event);
}
}
if(is_draw_event) {
CVideo::get_singleton().render_screen();
}
}
// Inform the pump monitors that an events::pump() has occurred

View file

@ -151,6 +151,9 @@ public:
virtual void process(pump_info& info) = 0;
};
void initialise();
void finalize();
void raise_process_event();
void raise_resize_event();
void raise_draw_event();

View file

@ -536,13 +536,6 @@ void sdl_event_handler::draw()
return;
}
CVideo& video = dynamic_cast<window&>(*dispatchers_.back()).video();
/**
* Clear the renderer before beginning the draw cycle.
*/
video.clear_screen();
/**
* @todo Need to evaluate which windows really to redraw.
*
@ -552,9 +545,6 @@ void sdl_event_handler::draw()
{
dispatcher->fire(DRAW, dynamic_cast<widget&>(*dispatcher));
}
// Finally, render the screen.
video.render_screen();
}
void sdl_event_handler::draw_everything()

View file

@ -113,33 +113,13 @@ namespace
const unsigned SHOW = debug_layout_graph::SHOW;
const unsigned LAYOUT = debug_layout_graph::LAYOUT;
#else
// values are irrelavant when DEBUG_WINDOW_LAYOUT_GRAPHS is not defined.
// values are irrelevant when DEBUG_WINDOW_LAYOUT_GRAPHS is not defined.
const unsigned SHOW = 0;
const unsigned LAYOUT = 0;
#endif
/**
* Pushes a single draw event to the queue. To be used before calling
* events::pump when drawing windows.
*
* @todo: in the future we should simply call draw functions directly
* from events::pump and do away with the custom drawing events, but
* that's a 1.15 target. For now, this will have to do.
*/
static void push_draw_event()
{
// DBG_GUI_E << "Pushing draw event in queue.\n";
SDL_Event event;
sdl::UserEvent data(DRAW_EVENT);
event.type = DRAW_EVENT;
event.user = data;
SDL_PushEvent(&event);
}
/**
* SDL_AddTimer() callback for delay_event.
*
* @param event The event to push in the event queue.
@ -489,8 +469,6 @@ void window::show_non_modal(/*const unsigned auto_close_timeout*/)
invalidate_layout();
suspend_drawing_ = false;
push_draw_event();
events::pump();
}
@ -538,8 +516,6 @@ int window::show(const unsigned auto_close_timeout)
// Start our loop drawing will happen here as well.
bool mouse_button_state_initialized = false;
for(status_ = SHOWING; status_ != CLOSED;) {
push_draw_event();
// process installed callback if valid, to allow e.g. network
// polling
events::pump();

View file

@ -676,12 +676,17 @@ static int do_gameloop(const std::vector<std::string>& args)
return 1;
}
events::initialise();
events::pump();
res = image::update_from_preferences();
if(res == false) {
std::cerr << "could not initialize image preferences\n";
return 1;
}
events::pump();
if(preferences::joystick_support_enabled()) {
res = game->init_joystick();
if(res == false) {
@ -693,6 +698,8 @@ static int do_gameloop(const std::vector<std::string>& args)
const cursor::manager cursor_manager;
cursor::set(cursor::WAIT);
events::pump();
#if(defined(_X11) && !defined(__APPLE__)) || defined(_WIN32)
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
#endif