Skip to content

Commit

Permalink
Merge pull request #5198 from wesnoth/thread_safe_logging
Browse files Browse the repository at this point in the history
Thread-safe logging

Closes #5209
  • Loading branch information
CelticMinstrel committed Oct 15, 2020
2 parents 5cab8f2 + 8b1c6cf commit 988bf97
Show file tree
Hide file tree
Showing 11 changed files with 305 additions and 151 deletions.
2 changes: 1 addition & 1 deletion src/deprecation.cpp
Expand Up @@ -77,7 +77,7 @@ std::string deprecated_message(

if(log_ptr && !log_ptr->dont_log(log_deprecate)) {
const lg::logger& out_log = *log_ptr;
out_log(log_deprecate) << message << '\n';
FORCE_LOG_TO(out_log, log_deprecate) << message << '\n';

if(preferences::get("show_deprecation", false)) {
lg::wml_error() << message << '\n';
Expand Down
4 changes: 0 additions & 4 deletions src/font/pango/stream_ops.hpp
Expand Up @@ -17,12 +17,8 @@
#include <pango/pango.h>
#include <ostream>

namespace font {

inline std::ostream& operator<<(std::ostream& s, const PangoRectangle &rect)
{
s << rect.x << ',' << rect.y << " x " << rect.width << ',' << rect.height;
return s;
}

} // end namespace font
25 changes: 25 additions & 0 deletions src/formatter.hpp
Expand Up @@ -67,6 +67,31 @@ class formatter
{
return stream_.str();
}

// Support manipulators
formatter& operator<<(std::ostream&(*fn)(std::ostream&)) &
{
fn(stream_);
return *this;
}

formatter&& operator<<(std::ostream&(*fn)(std::ostream&)) &&
{
fn(stream_);
return std::move(*this);
}

formatter& operator<<(std::ios_base&(*fn)(std::ios_base&)) &
{
fn(stream_);
return *this;
}

formatter&& operator<<(std::ios_base&(*fn)(std::ios_base&)) &&
{
fn(stream_);
return std::move(*this);
}

private:
std::ostringstream stream_;
Expand Down
5 changes: 3 additions & 2 deletions src/game_config_manager.cpp
Expand Up @@ -134,7 +134,7 @@ void game_config_manager::load_game_config_with_loadscreen(FORCE_RELOAD_CONFIG f
boost::optional<std::set<std::string>> active_addons)
{
if (!lg::info().dont_log(log_config)) {
auto& out = lg::info()(log_config);
auto out = formatter();
out << "load_game_config: defines:";
for(const auto& pair : cache_.get_preproc_map()) {
out << pair.first << ",";
Expand All @@ -149,7 +149,8 @@ void game_config_manager::load_game_config_with_loadscreen(FORCE_RELOAD_CONFIG f
out << "\n Everything:";
}
out << "\n";
}
FORCE_LOG_TO(lg::info(), log_config) << out.str();
}


game_config::scoped_preproc_define debug_mode("DEBUG_MODE",
Expand Down
2 changes: 1 addition & 1 deletion src/game_events/pump.cpp
Expand Up @@ -402,7 +402,7 @@ void wml_event_pump::show_wml_messages()
void wml_event_pump::put_wml_message(
lg::logger& logger, const std::string& prefix, const std::string& message, bool in_chat)
{
logger(log_wml) << message << std::endl;
FORCE_LOG_TO(logger, log_wml) << message << std::endl;
if(in_chat) {
impl_->wml_messages_stream << prefix << message << std::endl;
}
Expand Down
181 changes: 131 additions & 50 deletions src/gui/core/event/distributor.cpp
Expand Up @@ -357,47 +357,92 @@ void mouse_motion::stop_hover_timer()

#undef LOG_HEADER
#define LOG_HEADER \
"distributor mouse button " << name_ << " [" << owner_.id() << "]: "
"distributor mouse button " << events_.name << " [" << owner_.id() << "]: "

template<typename T>
mouse_button<T>::mouse_button(const std::string& name_, widget& owner,
mouse_button::mouse_button(const mouse_button_event_types& events, widget& owner,
const dispatcher::queue_position queue_position)
: mouse_motion(owner, queue_position)
, last_click_stamp_(0)
, last_clicked_widget_(nullptr)
, focus_(nullptr)
, name_(name_)
, events_(events)
, is_down_(false)
, signal_handler_sdl_button_down_entered_(false)
, signal_handler_sdl_button_up_entered_(false)
{
owner_.connect_signal<T::sdl_button_down_event>(
std::bind(&mouse_button<T>::signal_handler_sdl_button_down,
this,
_2,
_3,
_5),
queue_position);
owner_.connect_signal<T::sdl_button_up_event>(
std::bind(&mouse_button<T>::signal_handler_sdl_button_up,
this,
_2,
_3,
_5),
queue_position);
// The connect_signal framework is currently using SFINAE checking to ensure that we only
// register mouse button signal handlers for mouse buttons. That causes us to need this
// hardcoded (either directly or by making mouse_button a templated class), the manual handling
// of the three cases here is the current progress on refactoring.
switch(events_.sdl_button_down_event) {
case event::SDL_LEFT_BUTTON_DOWN: {
owner_.connect_signal<event::SDL_LEFT_BUTTON_DOWN>(
std::bind(&mouse_button::signal_handler_sdl_button_down,
this,
_2,
_3,
_5),
queue_position);
owner_.connect_signal<event::SDL_LEFT_BUTTON_UP>(
std::bind(&mouse_button::signal_handler_sdl_button_up,
this,
_2,
_3,
_5),
queue_position);
break;
}
case event::SDL_MIDDLE_BUTTON_DOWN: {
owner_.connect_signal<event::SDL_MIDDLE_BUTTON_DOWN>(
std::bind(&mouse_button::signal_handler_sdl_button_down,
this,
_2,
_3,
_5),
queue_position);
owner_.connect_signal<event::SDL_MIDDLE_BUTTON_UP>(
std::bind(&mouse_button::signal_handler_sdl_button_up,
this,
_2,
_3,
_5),
queue_position);
break;
}
case event::SDL_RIGHT_BUTTON_DOWN: {
owner_.connect_signal<event::SDL_RIGHT_BUTTON_DOWN>(
std::bind(&mouse_button::signal_handler_sdl_button_down,
this,
_2,
_3,
_5),
queue_position);
owner_.connect_signal<event::SDL_RIGHT_BUTTON_UP>(
std::bind(&mouse_button::signal_handler_sdl_button_up,
this,
_2,
_3,
_5),
queue_position);
break;
}
default: {
// There's exactly three instances of this class per instance of distributor, so this assert
// will be caught during the build-time-tests.
assert(!"Hardcoded assumption about button being LEFT / MIDDLE / RIGHT failed");
}
}
}

template<typename T>
void mouse_button<T>::initialize_state(const bool is_down)
void mouse_button::initialize_state(int32_t button_state)
{
last_click_stamp_ = 0;
last_clicked_widget_ = nullptr;
focus_ = 0;
is_down_ = is_down;
is_down_ = button_state & events_.mask;
}

template<typename T>
void mouse_button<T>::signal_handler_sdl_button_down(const event::ui_event event, bool& handled,
void mouse_button::signal_handler_sdl_button_down(const event::ui_event event, bool& handled,
const point& coordinate)
{
if(signal_handler_sdl_button_down_entered_) {
Expand All @@ -420,10 +465,10 @@ void mouse_button<T>::signal_handler_sdl_button_down(const event::ui_event event
if(mouse_captured_) {
assert(mouse_focus_);
focus_ = mouse_focus_;
DBG_GUI_E << LOG_HEADER << "Firing: " << T::sdl_button_down_event << ".\n";
if(!owner_.fire(T::sdl_button_down_event, *focus_, coordinate)) {
DBG_GUI_E << LOG_HEADER << "Firing: " << T::button_down_event << ".\n";
owner_.fire(T::button_down_event, *mouse_focus_);
DBG_GUI_E << LOG_HEADER << "Firing: " << events_.sdl_button_down_event << ".\n";
if(!owner_.fire(events_.sdl_button_down_event, *focus_, coordinate)) {
DBG_GUI_E << LOG_HEADER << "Firing: " << events_.button_down_event << ".\n";
owner_.fire(events_.button_down_event, *mouse_focus_);
}
} else {
widget* mouse_over = owner_.find_at(coordinate, true);
Expand All @@ -440,17 +485,16 @@ void mouse_button<T>::signal_handler_sdl_button_down(const event::ui_event event
}

focus_ = mouse_over;
DBG_GUI_E << LOG_HEADER << "Firing: " << T::sdl_button_down_event << ".\n";
if(!owner_.fire(T::sdl_button_down_event, *focus_, coordinate)) {
DBG_GUI_E << LOG_HEADER << "Firing: " << T::button_down_event << ".\n";
owner_.fire(T::button_down_event, *focus_);
DBG_GUI_E << LOG_HEADER << "Firing: " << events_.sdl_button_down_event << ".\n";
if(!owner_.fire(events_.sdl_button_down_event, *focus_, coordinate)) {
DBG_GUI_E << LOG_HEADER << "Firing: " << events_.button_down_event << ".\n";
owner_.fire(events_.button_down_event, *focus_);
}
}
handled = true;
}

template<typename T>
void mouse_button<T>::signal_handler_sdl_button_up(const event::ui_event event, bool& handled,
void mouse_button::signal_handler_sdl_button_up(const event::ui_event event, bool& handled,
const point& coordinate)
{
if(signal_handler_sdl_button_up_entered_) {
Expand All @@ -470,13 +514,17 @@ void mouse_button<T>::signal_handler_sdl_button_up(const event::ui_event event,
is_down_ = false;

if(focus_) {
DBG_GUI_E << LOG_HEADER << "Firing: " << T::sdl_button_up_event << ".\n";
if(!owner_.fire(T::sdl_button_up_event, *focus_, coordinate)) {
DBG_GUI_E << LOG_HEADER << "Firing: " << T::button_up_event << ".\n";
owner_.fire(T::button_up_event, *focus_);
DBG_GUI_E << LOG_HEADER << "Firing: " << events_.sdl_button_up_event << ".\n";
if(!owner_.fire(events_.sdl_button_up_event, *focus_, coordinate)) {
DBG_GUI_E << LOG_HEADER << "Firing: " << events_.button_up_event << ".\n";
owner_.fire(events_.button_up_event, *focus_);
}
}

// FIXME: The block below is strange diamond inheritance - it's code that could be in
// mouse_motion which applies to all three buttons, but it will be run in one of the
// three mouse_button<T> subclasses, and then the other two mouse_button<T> subclasses
// will reach here with mouse_captured_ == false.
widget* mouse_over = owner_.find_at(coordinate, true);
if(mouse_captured_) {
const unsigned mask = SDL_BUTTON_LMASK | SDL_BUTTON_MMASK
Expand All @@ -503,23 +551,22 @@ void mouse_button<T>::signal_handler_sdl_button_up(const event::ui_event event,
handled = true;
}

template<typename T>
void mouse_button<T>::mouse_button_click(widget* widget)
void mouse_button::mouse_button_click(widget* widget)
{
uint32_t stamp = SDL_GetTicks();
if(last_click_stamp_ + settings::double_click_time >= stamp
&& last_clicked_widget_ == widget) {

DBG_GUI_E << LOG_HEADER << "Firing: " << T::button_double_click_event << ".\n";
DBG_GUI_E << LOG_HEADER << "Firing: " << events_.button_double_click_event << ".\n";

owner_.fire(T::button_double_click_event, *widget);
owner_.fire(events_.button_double_click_event, *widget);
last_click_stamp_ = 0;
last_clicked_widget_ = nullptr;

} else {

DBG_GUI_E << LOG_HEADER << "Firing: " << T::button_click_event << ".\n";
owner_.fire(T::button_click_event, *widget);
DBG_GUI_E << LOG_HEADER << "Firing: " << events_.button_click_event << ".\n";
owner_.fire(events_.button_click_event, *widget);
last_click_stamp_ = stamp;
last_clicked_widget_ = widget;
}
Expand All @@ -530,16 +577,50 @@ void mouse_button<T>::mouse_button_click(widget* widget)
#undef LOG_HEADER
#define LOG_HEADER "distributor mouse motion [" << owner_.id() << "]: "

namespace
{

const auto mouse_button_left_events = mouse_button_event_types {
SDL_LEFT_BUTTON_DOWN,
SDL_LEFT_BUTTON_UP,
LEFT_BUTTON_DOWN,
LEFT_BUTTON_UP,
LEFT_BUTTON_CLICK,
LEFT_BUTTON_DOUBLE_CLICK,
SDL_BUTTON_LMASK,
"left"};

const auto mouse_button_middle_events = mouse_button_event_types {
SDL_MIDDLE_BUTTON_DOWN,
SDL_MIDDLE_BUTTON_UP,
MIDDLE_BUTTON_DOWN,
MIDDLE_BUTTON_UP,
MIDDLE_BUTTON_CLICK,
MIDDLE_BUTTON_DOUBLE_CLICK,
SDL_BUTTON_MMASK,
"middle"};

const auto mouse_button_right_events = mouse_button_event_types {
SDL_RIGHT_BUTTON_DOWN,
SDL_RIGHT_BUTTON_UP,
RIGHT_BUTTON_DOWN,
RIGHT_BUTTON_UP,
RIGHT_BUTTON_CLICK,
RIGHT_BUTTON_DOUBLE_CLICK,
SDL_BUTTON_RMASK,
"right"};
} // anonymous namespace

/**
* @todo Test whether the state is properly tracked when an input blocker is
* used.
*/
distributor::distributor(widget& owner,
const dispatcher::queue_position queue_position)
: mouse_motion(owner, queue_position)
, mouse_button_left("left", owner, queue_position)
, mouse_button_middle("middle", owner, queue_position)
, mouse_button_right("right", owner, queue_position)
, mouse_button_left(mouse_button_left_events, owner, queue_position)
, mouse_button_middle(mouse_button_middle_events, owner, queue_position)
, mouse_button_right(mouse_button_right_events, owner, queue_position)
, keyboard_focus_(nullptr)
, keyboard_focus_chain_()
{
Expand Down Expand Up @@ -581,11 +662,11 @@ distributor::~distributor()

void distributor::initialize_state()
{
const uint8_t button_state = SDL_GetMouseState(nullptr, nullptr);
const uint32_t button_state = SDL_GetMouseState(nullptr, nullptr);

mouse_button_left::initialize_state((button_state & SDL_BUTTON(1)) != 0);
mouse_button_middle::initialize_state((button_state & SDL_BUTTON(2)) != 0);
mouse_button_right::initialize_state((button_state & SDL_BUTTON(3)) != 0);
mouse_button_left::initialize_state(button_state);
mouse_button_middle::initialize_state(button_state);
mouse_button_right::initialize_state(button_state);

init_mouse_location();
}
Expand Down

0 comments on commit 988bf97

Please sign in to comment.