Skip to content
Permalink
Browse files

Merge pull request #8194 from lioncash/common-msg

Common/MsgHandler: Tidy up interface and namespace code
  • Loading branch information...
leoetlino committed Jun 20, 2019
2 parents baf0219 + 4f1f550 commit 4885130799a357eee8e279ed68dac60d6bcd78ca
@@ -151,7 +151,7 @@ void Host_TitleChanged()
{
}

static bool MsgAlert(const char* caption, const char* text, bool yes_no, MsgType /*style*/)
static bool MsgAlert(const char* caption, const char* text, bool yes_no, Common::MsgType /*style*/)
{
JNIEnv* env = IDCache::GetEnvForThread();

@@ -630,7 +630,7 @@ static void Run(JNIEnv* env, const std::vector<std::string>& paths, bool first_o
ASSERT(!paths.empty());
__android_log_print(ANDROID_LOG_INFO, DOLPHIN_TAG, "Running : %s", paths[0].c_str());

RegisterMsgAlertHandler(&MsgAlert);
Common::RegisterMsgAlertHandler(&MsgAlert);
Common::AndroidSetReportHandler(&ReportSend);
DolphinAnalytics::AndroidSetGetValFunc(&GetAnalyticValue);

@@ -2,49 +2,80 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.

#include "Common/MsgHandler.h"

#include <cstdarg>
#include <cstdio>
#include <string>

#ifdef _WIN32
#include <windows.h>
#else
#include <cstdio>
#include <fmt/format.h>
#endif

#include "Common/Common.h"
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
#include "Common/MsgHandler.h"
#include "Common/StringUtil.h"

namespace Common
{
namespace
{
// Default non library dependent panic alert
bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, MsgType style)
{
#ifdef _WIN32
#include <windows.h>
int window_style = MB_ICONINFORMATION;
if (style == MsgType::Question)
window_style = MB_ICONQUESTION;
if (style == MsgType::Warning)
window_style = MB_ICONWARNING;

return IDYES == MessageBox(0, UTF8ToTStr(text).c_str(), UTF8ToTStr(caption).c_str(),
window_style | (yes_no ? MB_YESNO : MB_OK));
#else
fmt::print(stderr, "{}\n", text);

// Return no to any question (which will in general crash the emulator)
return false;
#endif
}

bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, MsgType style);
static MsgAlertHandler msg_handler = DefaultMsgHandler;
static bool AlertEnabled = true;
// Default (non) translator
std::string DefaultStringTranslator(const char* text)
{
return text;
}

std::string DefaultStringTranslator(const char* text);
static StringTranslator str_translator = DefaultStringTranslator;
MsgAlertHandler s_msg_handler = DefaultMsgHandler;
StringTranslator s_str_translator = DefaultStringTranslator;
bool s_alert_enabled = true;
} // Anonymous namespace

// Select which of these functions that are used for message boxes. If
// Qt is enabled we will use QtMsgAlertHandler() that is defined in Main.cpp
void RegisterMsgAlertHandler(MsgAlertHandler handler)
{
msg_handler = handler;
s_msg_handler = handler;
}

// Select translation function.
void RegisterStringTranslator(StringTranslator translator)
{
str_translator = translator;
s_str_translator = translator;
}

// enable/disable the alert handler
void SetEnableAlert(bool enable)
{
AlertEnabled = enable;
s_alert_enabled = enable;
}

std::string GetStringT(const char* string)
{
return str_translator(string);
return s_str_translator(string);
}

// This is the first stop for gui alerts where the log is updated and the
@@ -60,12 +91,12 @@ bool MsgAlert(bool yes_no, MsgType style, const char* format, ...)
static std::string ques_caption;
static std::string crit_caption;

if (!info_caption.length())
if (info_caption.empty())
{
info_caption = str_translator(_trans("Information"));
ques_caption = str_translator(_trans("Question"));
warn_caption = str_translator(_trans("Warning"));
crit_caption = str_translator(_trans("Critical"));
info_caption = s_str_translator(_trans("Information"));
ques_caption = s_str_translator(_trans("Question"));
warn_caption = s_str_translator(_trans("Warning"));
crit_caption = s_str_translator(_trans("Critical"));
}

switch (style)
@@ -86,40 +117,18 @@ bool MsgAlert(bool yes_no, MsgType style, const char* format, ...)

va_list args;
va_start(args, format);
CharArrayFromFormatV(buffer, sizeof(buffer) - 1, str_translator(format).c_str(), args);
CharArrayFromFormatV(buffer, sizeof(buffer) - 1, s_str_translator(format).c_str(), args);
va_end(args);

ERROR_LOG(MASTER_LOG, "%s: %s", caption.c_str(), buffer);

// Don't ignore questions, especially AskYesNo, PanicYesNo could be ignored
if (msg_handler && (AlertEnabled || style == MsgType::Question || style == MsgType::Critical))
return msg_handler(caption.c_str(), buffer, yes_no, style);
if (s_msg_handler != nullptr &&
(s_alert_enabled || style == MsgType::Question || style == MsgType::Critical))
{
return s_msg_handler(caption.c_str(), buffer, yes_no, style);
}

return true;
}

// Default non library dependent panic alert
bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, MsgType style)
{
#ifdef _WIN32
int window_style = MB_ICONINFORMATION;
if (style == MsgType::Question)
window_style = MB_ICONQUESTION;
if (style == MsgType::Warning)
window_style = MB_ICONWARNING;

return IDYES == MessageBox(0, UTF8ToTStr(text).c_str(), UTF8ToTStr(caption).c_str(),
window_style | (yes_no ? MB_YESNO : MB_OK));
#else
fprintf(stderr, "%s\n", text);

// Return no to any question (which will in general crash the emulator)
return false;
#endif
}

// Default (non) translator
std::string DefaultStringTranslator(const char* text)
{
return text;
}
} // namespace Common
@@ -6,6 +6,8 @@

#include <string>

namespace Common
{
// Message alerts
enum class MsgType
{
@@ -15,8 +17,8 @@ enum class MsgType
Critical
};

typedef bool (*MsgAlertHandler)(const char* caption, const char* text, bool yes_no, MsgType style);
typedef std::string (*StringTranslator)(const char* text);
using MsgAlertHandler = bool (*)(const char* caption, const char* text, bool yes_no, MsgType style);
using StringTranslator = std::string (*)(const char* text);

void RegisterMsgAlertHandler(MsgAlertHandler handler);
void RegisterStringTranslator(StringTranslator translator);
@@ -28,30 +30,69 @@ bool MsgAlert(bool yes_no, MsgType style, const char* format, ...)
#endif
;
void SetEnableAlert(bool enable);
} // namespace Common

#ifdef _WIN32
#define SuccessAlert(format, ...) MsgAlert(false, MsgType::Information, format, __VA_ARGS__)
#define PanicAlert(format, ...) MsgAlert(false, MsgType::Warning, format, __VA_ARGS__)
#define PanicYesNo(format, ...) MsgAlert(true, MsgType::Warning, format, __VA_ARGS__)
#define AskYesNo(format, ...) MsgAlert(true, MsgType::Question, format, __VA_ARGS__)
#define CriticalAlert(format, ...) MsgAlert(false, MsgType::Critical, format, __VA_ARGS__)
#define SuccessAlert(format, ...) \
Common::MsgAlert(false, Common::MsgType::Information, format, __VA_ARGS__)

#define PanicAlert(format, ...) \
Common::MsgAlert(false, Common::MsgType::Warning, format, __VA_ARGS__)

#define PanicYesNo(format, ...) \
Common::MsgAlert(true, Common::MsgType::Warning, format, __VA_ARGS__)

#define AskYesNo(format, ...) Common::MsgAlert(true, Common::MsgType::Question, format, __VA_ARGS__)

#define CriticalAlert(format, ...) \
Common::MsgAlert(false, Common::MsgType::Critical, format, __VA_ARGS__)

// Use these macros (that do the same thing) if the message should be translated.
#define SuccessAlertT(format, ...) MsgAlert(false, MsgType::Information, format, __VA_ARGS__)
#define PanicAlertT(format, ...) MsgAlert(false, MsgType::Warning, format, __VA_ARGS__)
#define PanicYesNoT(format, ...) MsgAlert(true, MsgType::Warning, format, __VA_ARGS__)
#define AskYesNoT(format, ...) MsgAlert(true, MsgType::Question, format, __VA_ARGS__)
#define CriticalAlertT(format, ...) MsgAlert(false, MsgType::Critical, format, __VA_ARGS__)

#define SuccessAlertT(format, ...) \
Common::MsgAlert(false, Common::MsgType::Information, format, __VA_ARGS__)

#define PanicAlertT(format, ...) \
Common::MsgAlert(false, Common::MsgType::Warning, format, __VA_ARGS__)

#define PanicYesNoT(format, ...) \
Common::MsgAlert(true, Common::MsgType::Warning, format, __VA_ARGS__)

#define AskYesNoT(format, ...) \
Common::MsgAlert(true, Common::MsgType::Question, format, __VA_ARGS__)

#define CriticalAlertT(format, ...) \
Common::MsgAlert(false, Common::MsgType::Critical, format, __VA_ARGS__)

#else
#define SuccessAlert(format, ...) MsgAlert(false, MsgType::Information, format, ##__VA_ARGS__)
#define PanicAlert(format, ...) MsgAlert(false, MsgType::Warning, format, ##__VA_ARGS__)
#define PanicYesNo(format, ...) MsgAlert(true, MsgType::Warning, format, ##__VA_ARGS__)
#define AskYesNo(format, ...) MsgAlert(true, MsgType::Question, format, ##__VA_ARGS__)
#define CriticalAlert(format, ...) MsgAlert(false, MsgType::Critical, format, ##__VA_ARGS__)
#define SuccessAlert(format, ...) \
Common::MsgAlert(false, Common::MsgType::Information, format, ##__VA_ARGS__)

#define PanicAlert(format, ...) \
Common::MsgAlert(false, Common::MsgType::Warning, format, ##__VA_ARGS__)

#define PanicYesNo(format, ...) \
Common::MsgAlert(true, Common::MsgType::Warning, format, ##__VA_ARGS__)

#define AskYesNo(format, ...) \
Common::MsgAlert(true, Common::MsgType::Question, format, ##__VA_ARGS__)

#define CriticalAlert(format, ...) \
Common::MsgAlert(false, Common::MsgType::Critical, format, ##__VA_ARGS__)

// Use these macros (that do the same thing) if the message should be translated.
#define SuccessAlertT(format, ...) MsgAlert(false, MsgType::Information, format, ##__VA_ARGS__)
#define PanicAlertT(format, ...) MsgAlert(false, MsgType::Warning, format, ##__VA_ARGS__)
#define PanicYesNoT(format, ...) MsgAlert(true, MsgType::Warning, format, ##__VA_ARGS__)
#define AskYesNoT(format, ...) MsgAlert(true, MsgType::Question, format, ##__VA_ARGS__)
#define CriticalAlertT(format, ...) MsgAlert(false, MsgType::Critical, format, ##__VA_ARGS__)
#define SuccessAlertT(format, ...) \
Common::MsgAlert(false, Common::MsgType::Information, format, ##__VA_ARGS__)

#define PanicAlertT(format, ...) \
Common::MsgAlert(false, Common::MsgType::Warning, format, ##__VA_ARGS__)

#define PanicYesNoT(format, ...) \
Common::MsgAlert(true, Common::MsgType::Warning, format, ##__VA_ARGS__)

#define AskYesNoT(format, ...) \
Common::MsgAlert(true, Common::MsgType::Question, format, ##__VA_ARGS__)

#define CriticalAlertT(format, ...) \
Common::MsgAlert(false, Common::MsgType::Critical, format, ##__VA_ARGS__)
#endif
@@ -805,7 +805,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
if (m_sync_save_data_count == 0)
SyncSaveDataResponse(true);
else
m_dialog->AppendChat(GetStringT("Synchronizing save data..."));
m_dialog->AppendChat(Common::GetStringT("Synchronizing save data..."));
}
break;

@@ -1040,7 +1040,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
SyncCodeResponse(true);
}
else
m_dialog->AppendChat(GetStringT("Synchronizing Gecko codes..."));
m_dialog->AppendChat(Common::GetStringT("Synchronizing Gecko codes..."));
}
break;

@@ -1109,7 +1109,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
SyncCodeResponse(true);
}
else
m_dialog->AppendChat(GetStringT("Synchronizing AR codes..."));
m_dialog->AppendChat(Common::GetStringT("Synchronizing AR codes..."));
}
break;

@@ -1289,9 +1289,14 @@ void NetPlayClient::ThreadFunc()
qos_session = Common::QoSSession(m_server);

if (qos_session.Successful())
m_dialog->AppendChat(GetStringT("Quality of Service (QoS) was successfully enabled."));
{
m_dialog->AppendChat(
Common::GetStringT("Quality of Service (QoS) was successfully enabled."));
}
else
m_dialog->AppendChat(GetStringT("Quality of Service (QoS) couldn't be enabled."));
{
m_dialog->AppendChat(Common::GetStringT("Quality of Service (QoS) couldn't be enabled."));
}
}

while (m_do_loop.IsSet())
@@ -1511,8 +1516,8 @@ bool NetPlayClient::StartGame(const std::string& path)

void NetPlayClient::SyncSaveDataResponse(const bool success)
{
m_dialog->AppendChat(success ? GetStringT("Data received!") :
GetStringT("Error processing data."));
m_dialog->AppendChat(success ? Common::GetStringT("Data received!") :
Common::GetStringT("Error processing data."));

if (success)
{
@@ -1540,7 +1545,7 @@ void NetPlayClient::SyncCodeResponse(const bool success)
// If something failed, immediately report back that code sync failed
if (!success)
{
m_dialog->AppendChat(GetStringT("Error processing codes."));
m_dialog->AppendChat(Common::GetStringT("Error processing codes."));

sf::Packet response_packet;
response_packet << static_cast<MessageId>(NP_MSG_SYNC_CODES);
@@ -1553,7 +1558,7 @@ void NetPlayClient::SyncCodeResponse(const bool success)
// If both gecko and AR codes have completely finished transferring, report back as successful
if (m_sync_gecko_codes_complete && m_sync_ar_codes_complete)
{
m_dialog->AppendChat(GetStringT("Codes received!"));
m_dialog->AppendChat(Common::GetStringT("Codes received!"));

sf::Packet response_packet;
response_packet << static_cast<MessageId>(NP_MSG_SYNC_CODES);
@@ -1049,7 +1049,7 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, Client& player)
m_save_data_synced_players++;
if (m_save_data_synced_players >= m_players.size() - 1)
{
m_dialog->AppendChat(GetStringT("All players' saves synchronized."));
m_dialog->AppendChat(Common::GetStringT("All players' saves synchronized."));

// Saves are synced, check if codes are as well and attempt to start the game
m_saves_synced = true;
@@ -1061,8 +1061,8 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, Client& player)

case SYNC_SAVE_DATA_FAILURE:
{
m_dialog->AppendChat(
StringFromFormat(GetStringT("%s failed to synchronize.").c_str(), player.name.c_str()));
m_dialog->AppendChat(StringFromFormat(Common::GetStringT("%s failed to synchronize.").c_str(),
player.name.c_str()));
m_dialog->OnGameStartAborted();
ChunkedDataAbort();
m_start_pending = false;
@@ -1093,7 +1093,7 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, Client& player)
{
if (++m_codes_synced_players >= m_players.size() - 1)
{
m_dialog->AppendChat(GetStringT("All players' codes synchronized."));
m_dialog->AppendChat(Common::GetStringT("All players' codes synchronized."));

// Codes are synced, check if saves are as well and attempt to start the game
m_codes_synced = true;
@@ -1105,8 +1105,8 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, Client& player)

case SYNC_CODES_FAILURE:
{
m_dialog->AppendChat(StringFromFormat(GetStringT("%s failed to synchronize codes.").c_str(),
player.name.c_str()));
m_dialog->AppendChat(StringFromFormat(
Common::GetStringT("%s failed to synchronize codes.").c_str(), player.name.c_str()));
m_dialog->OnGameStartAborted();
m_start_pending = false;
}

0 comments on commit 4885130

Please sign in to comment.
You can’t perform that action at this time.