diff --git a/examples/core/core_custom_logging.c b/examples/core/core_custom_logging.c new file mode 100644 index 000000000..95bfd727b --- /dev/null +++ b/examples/core/core_custom_logging.c @@ -0,0 +1,90 @@ +/******************************************************************************************* +* +* raylib [core] example - Custom logging +* +* Welcome to raylib! +* +* To test examples, just press F6 and execute raylib_compile_execute script +* Note that compiled executable is placed in the same folder as .c file +* +* You can find all basic examples on C:\raylib\raylib\examples folder or +* raylib official webpage: www.raylib.com +* +* Enjoy using raylib. :) +* +* This example has been created using raylib 2.0 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2018 Ramon Santamaria (@raysan5) and Pablo Marcos Oltra (@pamarcos) +* +********************************************************************************************/ + +#include "raylib.h" + +#include // Required for: fopen(), fclose(), fputc(), fwrite(), printf(), fprintf(), funopen() +#include // Required for: time_t, tm, time(), localtime(), strftime() + +void logCustom(int msgType, const char *text, va_list args) +{ + char timeStr[64]; + time_t now = time(NULL); + struct tm *tm_info = localtime(&now); + + strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", tm_info); + printf("[%s] ", timeStr); + + switch (msgType) + { + case LOG_INFO: printf("[INFO] : "); break; + case LOG_ERROR: printf("[ERROR]: "); break; + case LOG_WARNING: printf("[WARN] : "); break; + case LOG_DEBUG: printf("[DEBUG]: "); break; + default: break; + } + vprintf(text, args); + printf("\n"); +} + +int main(int argc, char* argv[]) +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + // First thing we do is setting our custom logger to ensure everything raylib logs + // will use our own logger instead of its internal one + SetTraceLogCallback(logCustom); + + InitWindow(screenWidth, screenHeight, "raylib [core] example - custom logging"); + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + // TODO: Update your variables here + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawText("Check out the console output to see the custom logger in action!", 60, 200, 20, LIGHTGRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/examples/core/core_custom_logging.png b/examples/core/core_custom_logging.png new file mode 100644 index 000000000..478fef741 Binary files /dev/null and b/examples/core/core_custom_logging.png differ diff --git a/src/raylib.h b/src/raylib.h index 251dd0208..4e64cdee0 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -71,6 +71,8 @@ #ifndef RAYLIB_H #define RAYLIB_H +#include // Required for va_list + #if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED) #define RLAPI __declspec(dllexport) // We are building raylib as a Win32 shared library (.dll) #elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED) @@ -727,6 +729,9 @@ typedef enum { HMD_SONY_PSVR } VrDeviceType; +// Callbacks to be implemented by users +typedef void (*TraceLogCallback)(int msgType, const char *text, va_list args); + #ifdef __cplusplus extern "C" { // Prevents name mangling of functions #endif @@ -796,6 +801,7 @@ RLAPI Color Fade(Color color, float alpha); // Color fade- RLAPI void ShowLogo(void); // Activate raylib logo at startup (can be done with flags) RLAPI void SetConfigFlags(unsigned char flags); // Setup window configuration flags (view FLAGS) RLAPI void SetTraceLog(unsigned char types); // Enable trace log message types (bit flags based) +RLAPI void SetTraceLogCallback(TraceLogCallback callback); // Set a trace log callback to enable custom logging bypassing raylib's one RLAPI void TraceLog(int logType, const char *text, ...); // Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG) RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (saved a .png) RLAPI int GetRandomValue(int min, int max); // Returns a random value between min and max (both included) diff --git a/src/utils.c b/src/utils.c index 74780680d..f7c19afb4 100644 --- a/src/utils.c +++ b/src/utils.c @@ -74,6 +74,7 @@ FILE *funopen(const void *cookie, int (*readfn)(void *, char *, int), // Log types messages supported flags (bit based) static unsigned char logTypeFlags = LOG_INFO | LOG_WARNING | LOG_ERROR; +static TraceLogCallback logCallback = NULL; #if defined(PLATFORM_ANDROID) AAssetManager *assetManager; @@ -99,11 +100,26 @@ void SetTraceLog(unsigned char types) logTypeFlags = types; } +// Set a trace log callback to enable custom logging bypassing raylib's one +void SetTraceLogCallback(TraceLogCallback callback) +{ + logCallback = callback; +} + // Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG) void TraceLog(int msgType, const char *text, ...) { #if defined(SUPPORT_TRACELOG) static char buffer[128]; + va_list args; + va_start(args, text); + + if (logCallback) + { + logCallback(msgType, text, args); + va_end(args); + return; + } switch(msgType) { @@ -117,9 +133,6 @@ void TraceLog(int msgType, const char *text, ...) strcat(buffer, text); strcat(buffer, "\n"); - va_list args; - va_start(args, text); - #if defined(PLATFORM_ANDROID) switch(msgType) {