Core: Migrate SDL logging enhancements into core

This commit is contained in:
Vicki Pfau 2022-07-09 02:17:03 -07:00
parent f4f5521b9b
commit 8997055fc0
7 changed files with 111 additions and 100 deletions

View File

@ -36,6 +36,12 @@ struct mLogger {
struct mLogFilter* filter;
};
struct mStandardLogger {
struct mLogger d;
bool logToStdout;
struct VFile* logFile;
};
struct mLogger* mLogGetContext(void);
void mLogSetDefaultLogger(struct mLogger*);
int mLogGenerateCategory(const char*, const char*);
@ -44,6 +50,10 @@ const char* mLogCategoryId(int);
int mLogCategoryById(const char*);
struct mCoreConfig;
void mStandardLoggerInit(struct mStandardLogger*);
void mStandardLoggerDeinit(struct mStandardLogger*);
void mStandardLoggerConfig(struct mStandardLogger*, struct mCoreConfig* config);
void mLogFilterInit(struct mLogFilter*);
void mLogFilterDeinit(struct mLogFilter*);
void mLogFilterLoad(struct mLogFilter*, const struct mCoreConfig*);

View File

@ -21,6 +21,7 @@ struct mCoreThread;
struct mThreadLogger {
struct mLogger d;
struct mCoreThread* p;
struct mLogger* logger;
};
#ifdef ENABLE_SCRIPTING

View File

@ -7,8 +7,10 @@
#include <mgba/core/config.h>
#include <mgba/core/thread.h>
#include <mgba-util/vfs.h>
#define MAX_CATEGORY 64
#define MAX_LOG_BUF 1024
static struct mLogger* _defaultLogger = NULL;
@ -183,4 +185,63 @@ int mLogFilterLevels(const struct mLogFilter* filter , int category) {
return value;
}
void _mCoreStandardLog(struct mLogger* logger, int category, enum mLogLevel level, const char* format, va_list args) {
struct mStandardLogger* stdlog = (struct mStandardLogger*) logger;
if (!mLogFilterTest(logger->filter, category, level)) {
return;
}
char buffer[MAX_LOG_BUF];
// Prepare the string
size_t length = snprintf(buffer, sizeof(buffer), "%s: ", mLogCategoryName(category));
if (length < sizeof(buffer)) {
length += vsnprintf(buffer + length, sizeof(buffer) - length, format, args);
}
if (length < sizeof(buffer)) {
length += snprintf(buffer + length, sizeof(buffer) - length, "\n");
}
// Make sure the length doesn't exceed the size of the buffer when actually writing
if (length > sizeof(buffer)) {
length = sizeof(buffer);
}
if (stdlog->logToStdout) {
printf("%s", buffer);
}
if (stdlog->logFile) {
stdlog->logFile->write(stdlog->logFile, buffer, length);
}
}
void mStandardLoggerInit(struct mStandardLogger* logger) {
logger->d.log = _mCoreStandardLog;
logger->d.filter = malloc(sizeof(struct mLogFilter));
mLogFilterInit(logger->d.filter);
}
void mStandardLoggerDeinit(struct mStandardLogger* logger) {
if (logger->d.filter) {
mLogFilterDeinit(logger->d.filter);
free(logger->d.filter);
logger->d.filter = NULL;
}
}
void mStandardLoggerConfig(struct mStandardLogger* logger, struct mCoreConfig* config) {
bool logToFile = false;
const char* logFile = mCoreConfigGetValue(config, "logFile");
mCoreConfigGetBoolValue(config, "logToStdout", &logger->logToStdout);
mCoreConfigGetBoolValue(config, "logToFile", &logToFile);
if (logToFile && logFile) {
logger->logFile = VFileOpen(logFile, O_WRONLY | O_CREAT | O_APPEND);
}
mLogFilterLoad(logger->d.filter, config);
}
mLOG_DEFINE_CATEGORY(STATUS, "Status", "core.status")

View File

@ -253,10 +253,13 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) {
core->setSync(core, &threadContext->impl->sync);
struct mLogFilter filter;
if (!threadContext->logger.d.filter) {
threadContext->logger.d.filter = &filter;
mLogFilterInit(threadContext->logger.d.filter);
mLogFilterLoad(threadContext->logger.d.filter, &core->config);
struct mLogger* logger = &threadContext->logger.d;
if (threadContext->logger.logger) {
logger->filter = threadContext->logger.logger->filter;
} else {
logger->filter = &filter;
mLogFilterInit(logger->filter);
mLogFilterLoad(logger->filter, &core->config);
}
#ifdef ENABLE_SCRIPTING
@ -431,10 +434,10 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) {
#endif
core->clearCoreCallbacks(core);
if (threadContext->logger.d.filter == &filter) {
if (logger->filter == &filter) {
mLogFilterDeinit(&filter);
}
threadContext->logger.d.filter = NULL;
logger->filter = NULL;
return 0;
}
@ -444,10 +447,8 @@ bool mCoreThreadStart(struct mCoreThread* threadContext) {
threadContext->impl->state = mTHREAD_INITIALIZED;
threadContext->impl->requested = 0;
threadContext->logger.p = threadContext;
if (!threadContext->logger.d.log) {
threadContext->logger.d.log = _mCoreLog;
threadContext->logger.d.filter = NULL;
}
threadContext->logger.d.log = _mCoreLog;
threadContext->logger.d.filter = NULL;
if (!threadContext->impl->sync.fpsTarget) {
threadContext->impl->sync.fpsTarget = _defaultFPSTarget;
@ -718,14 +719,17 @@ struct mCoreThread* mCoreThreadGet(void) {
}
static void _mCoreLog(struct mLogger* logger, int category, enum mLogLevel level, const char* format, va_list args) {
UNUSED(logger);
UNUSED(level);
printf("%s: ", mLogCategoryName(category));
vprintf(format, args);
printf("\n");
struct mCoreThread* thread = mCoreThreadGet();
if (thread && level == mLOG_FATAL) {
mCoreThreadMarkCrashed(thread);
struct mThreadLogger* threadLogger = (struct mThreadLogger*) logger;
if (level == mLOG_FATAL) {
mCoreThreadMarkCrashed(threadLogger->p);
}
if (!threadLogger->p->logger.logger) {
printf("%s: ", mLogCategoryName(category));
vprintf(format, args);
printf("\n");
} else {
logger = threadLogger->p->logger.logger;
logger->log(logger, category, level, format, args);
}
}
#else

View File

@ -144,19 +144,19 @@ CoreController::CoreController(mCore* core, QObject* parent)
QMetaObject::invokeMethod(controller, "unpaused");
};
m_threadContext.logger.d.log = [](mLogger* logger, int category, enum mLogLevel level, const char* format, va_list args) {
mThreadLogger* logContext = reinterpret_cast<mThreadLogger*>(logger);
mCoreThread* context = logContext->p;
m_logger.self = this;
m_logger.log = [](mLogger* logger, int category, enum mLogLevel level, const char* format, va_list args) {
CoreLogger* logContext = static_cast<CoreLogger*>(logger);
static const char* savestateMessage = "State %i saved";
static const char* loadstateMessage = "State %i loaded";
static const char* savestateFailedMessage = "State %i failed to load";
static int biosCat = -1;
static int statusCat = -1;
if (!context) {
if (!logContext) {
return;
}
CoreController* controller = static_cast<CoreController*>(context->userData);
CoreController* controller = logContext->self;
QString message;
if (biosCat < 0) {
biosCat = mLogCategoryById("gba.bios");
@ -201,10 +201,10 @@ CoreController::CoreController(mCore* core, QObject* parent)
message = QString::vasprintf(format, args);
QMetaObject::invokeMethod(controller, "logPosted", Q_ARG(int, level), Q_ARG(int, category), Q_ARG(const QString&, message));
if (level == mLOG_FATAL) {
mCoreThreadMarkCrashed(controller->thread());
QMetaObject::invokeMethod(controller, "crashed", Q_ARG(const QString&, message));
}
};
m_threadContext.logger.logger = &m_logger;
}
CoreController::~CoreController() {
@ -424,7 +424,7 @@ void CoreController::setInputController(InputController* inputController) {
void CoreController::setLogger(LogController* logger) {
disconnect(m_log);
m_log = logger;
m_threadContext.logger.d.filter = logger->filter();
m_logger.filter = logger->filter();
connect(this, &CoreController::logPosted, m_log, &LogController::postLog);
}

View File

@ -241,6 +241,9 @@ private:
void updateROMInfo();
mCoreThread m_threadContext{};
struct CoreLogger : public mLogger {
CoreController* self;
} m_logger{};
bool m_patched = false;
bool m_preload = false;

View File

@ -38,19 +38,12 @@
#include <signal.h>
#define PORT "sdl"
#define MAX_LOG_BUF 1024
static void mSDLDeinit(struct mSDLRenderer* renderer);
static int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args);
static void _setLogger(struct mCore* core);
static void _mCoreLog(struct mLogger* logger, int category, enum mLogLevel level, const char* format, va_list args);
static bool _logToStdout = true;
static struct VFile* _logFile = NULL;
static struct mLogFilter _filter;
static struct mLogger _logger;
static struct mStandardLogger _logger;
static struct VFile* _state = NULL;
@ -136,6 +129,7 @@ int main(int argc, char** argv) {
mCoreInitConfig(renderer.core, PORT);
mArgumentsApply(&args, &subparser, 1, &renderer.core->config);
mCoreConfigSetDefaultIntValue(&renderer.core->config, "logToStdout", true);
mCoreConfigLoadDefaults(&renderer.core->config, &opts);
mCoreLoadConfig(renderer.core);
@ -188,7 +182,8 @@ int main(int argc, char** argv) {
int ret;
// TODO: Use opts and config
_setLogger(renderer.core);
mStandardLoggerInit(&_logger);
mStandardLoggerConfig(&_logger, &renderer.core->config);
ret = mSDLRun(&renderer, &args);
mSDLDetachPlayer(&renderer.events, &renderer.player);
mInputMapDeinit(&renderer.core->inputMap);
@ -198,6 +193,7 @@ int main(int argc, char** argv) {
}
mSDLDeinit(&renderer);
mStandardLoggerDeinit(&_logger);
mArgumentsDeinit(&args);
mCoreConfigFreeOpts(&opts);
@ -273,12 +269,8 @@ int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args) {
renderer->audio.samples = renderer->core->opts.audioBuffers;
renderer->audio.sampleRate = 44100;
struct mThreadLogger threadLogger;
threadLogger.d = _logger;
threadLogger.p = &thread;
thread.logger = threadLogger;
thread.logger.logger = &_logger.d;
bool didFail = !mCoreThreadStart(&thread);
if (!didFail) {
@ -342,63 +334,3 @@ static void mSDLDeinit(struct mSDLRenderer* renderer) {
SDL_Quit();
}
static void _setLogger(struct mCore* core) {
int fakeBool = 0;
bool logToFile = false;
if (mCoreConfigGetIntValue(&core->config, "logToStdout", &fakeBool)) {
_logToStdout = fakeBool;
}
if (mCoreConfigGetIntValue(&core->config, "logToFile", &fakeBool)) {
logToFile = fakeBool;
}
const char* logFile = mCoreConfigGetValue(&core->config, "logFile");
if (logToFile && logFile) {
_logFile = VFileOpen(logFile, O_WRONLY | O_CREAT | O_APPEND);
}
// Create the filter
mLogFilterInit(&_filter);
mLogFilterLoad(&_filter, &core->config);
// Fill the logger
_logger.log = _mCoreLog;
_logger.filter = &_filter;
}
static void _mCoreLog(struct mLogger* logger, int category, enum mLogLevel level, const char* format, va_list args) {
struct mCoreThread* thread = mCoreThreadGet();
if (thread && level == mLOG_FATAL) {
mCoreThreadMarkCrashed(thread);
}
if (!mLogFilterTest(logger->filter, category, level)) {
return;
}
char buffer[MAX_LOG_BUF];
// Prepare the string
size_t length = snprintf(buffer, sizeof(buffer), "%s: ", mLogCategoryName(category));
if (length < sizeof(buffer)) {
length += vsnprintf(buffer + length, sizeof(buffer) - length, format, args);
}
if (length < sizeof(buffer)) {
length += snprintf(buffer + length, sizeof(buffer) - length, "\n");
}
// Make sure the length doesn't exceed the size of the buffer when actually writing
if (length > sizeof(buffer)) {
length = sizeof(buffer);
}
if (_logToStdout) {
printf("%s", buffer);
}
if (_logFile) {
_logFile->write(_logFile, buffer, length);
}
}