Browse Source

Add logging abstraction

Come up with our own logging system.
master
TheoryOfNekomata 1 year ago
parent
commit
bdbdbec1ce
26 changed files with 332 additions and 36 deletions
  1. +8
    -6
      CMakeLists.txt
  2. +4
    -1
      src/packages/config/IZ_config.c
  3. +1
    -0
      src/packages/config/IZ_config.h
  4. +5
    -2
      src/packages/game/IZ_app.c
  5. +2
    -0
      src/packages/game/IZ_app.h
  6. +8
    -1
      src/packages/game/input/IZ_input.c
  7. +3
    -1
      src/packages/game/memory/IZ_pool.c
  8. +2
    -0
      src/packages/game/memory/IZ_pool.h
  9. +3
    -1
      src/packages/game/output/video/IZ_video.c
  10. +8
    -0
      src/packages/io/IZ_io.c
  11. +2
    -0
      src/packages/io/IZ_io.h
  12. +24
    -0
      src/packages/log/IZ_intercept.c
  13. +10
    -0
      src/packages/log/IZ_intercept.h
  14. +83
    -15
      src/packages/log/IZ_log.c
  15. +44
    -4
      src/packages/log/IZ_log.h
  16. +2
    -0
      src/packages/net/IZ_net_client.c
  17. +1
    -1
      src/packages/net/svc/IZ_wsclient.c
  18. +1
    -0
      src/packages/net/svc/IZ_wsclient.h
  19. +1
    -1
      src/packages/net/svc/IZ_wsserver.c
  20. +1
    -0
      src/packages/net/svc/IZ_wsserver.h
  21. +1
    -1
      src/packages/server/IZ_app.c
  22. +1
    -1
      src/packages/server/IZ_app.h
  23. +4
    -1
      src/packages/string/IZ_string.c
  24. +2
    -0
      src/packages/string/IZ_string.h
  25. +69
    -0
      src/packages/timer/IZ_timer.c
  26. +42
    -0
      src/packages/timer/IZ_timer.h

+ 8
- 6
CMakeLists.txt View File

@@ -39,6 +39,8 @@ add_definitions(
-DIZ_APP_DESCRIPTION="Run and gun game"
-DIZ_APP_SERVER_DESCRIPTION="Dedicated server"
-DIZ_PLAYERS=1
#-DIZ_LOG_DATE_FUNCTION=IZ_TimerElapsed
-DIZ_LOG_DATE_FUNCTION=IZ_TimerNow
)

if (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
@@ -126,8 +128,8 @@ add_executable(
src/packages/game/data/IZ_list.h
src/packages/net/svc/IZ_wsclient.c
src/packages/net/svc/IZ_wsclient.h
src/packages/log/IZ_log.c
src/packages/log/IZ_log.h
src/packages/log/IZ_intercept.c
src/packages/log/IZ_intercept.h
src/packages/midi/IZ_midi.c
src/packages/midi/IZ_midi.h
src/packages/net/core/IZ_websocket.h
@@ -149,7 +151,7 @@ add_executable(
src/packages/string/IZ_string.h
src/packages/io/IZ_io.c
src/packages/io/IZ_io.h
)
src/packages/log/IZ_log.c src/packages/log/IZ_log.h src/packages/timer/IZ_timer.c src/packages/timer/IZ_timer.h)

if (WIN32)
target_link_libraries(
@@ -263,8 +265,8 @@ add_executable(
dependencies/sqlite/sqlite3.c
dependencies/minIni/dev/minIni.h
dependencies/minIni/dev/minIni.c
src/packages/log/IZ_log.h
src/packages/log/IZ_log.c
src/packages/log/IZ_intercept.h
src/packages/log/IZ_intercept.c
src/packages/server/main.c
src/packages/server/IZ_app.c
src/packages/server/IZ_app.h
@@ -285,7 +287,7 @@ add_executable(
src/packages/string/IZ_string.h
src/packages/io/IZ_io.c
src/packages/io/IZ_io.h
)
src/packages/log/IZ_log.c src/packages/log/IZ_log.h src/packages/timer/IZ_timer.c src/packages/timer/IZ_timer.h)

target_link_libraries(
server


+ 4
- 1
src/packages/config/IZ_config.c View File

@@ -260,7 +260,7 @@ IZ_ConfigSaveItemResult IZ_ConfigSaveGuid(IZ_ConfigItem* item, const char* confi
}

char guid_str[33];
memset(guid_str, 0, 33);
IZ_memset(guid_str, 0, 33);
SDL_GUIDToString(dest, guid_str, 33);
if (!ini_puts(item->section, item->key, guid_str, config_path)) {
return -1;
@@ -344,11 +344,14 @@ IZ_ConfigInitializeResult IZ_ConfigInitialize(IZ_ConfigItem item[], const char*
IZ_ConfigLoad(item, config_path);
IZ_ConfigSaveResult save_result = IZ_ConfigSave(item, config_path);
if (save_result < 0) {
IZ_LogError("Config sync failed! Result: %u", save_result);
return IZ_CONFIG_INITIALIZE_RESULT_ERROR;
}
IZ_ConfigOverride(item, argc, argv);
if (save_result > 0) {
IZ_LogWarn(false, "Config sync encountered issues. Result: %u", save_result);
return IZ_CONFIG_INITIALIZE_RESULT_WARNING;
}
IZ_LogInfo(IZ_LOG_CATEGORY_GLOBAL, "Config sync successful.");
return IZ_CONFIG_INITIALIZE_RESULT_OK;
}

+ 1
- 0
src/packages/config/IZ_config.h View File

@@ -5,6 +5,7 @@
#include <string.h>
#include <minIni.h>
#include "../common/IZ_common.h"
#include "../log/IZ_log.h"
#include "../string/IZ_string.h"

typedef enum {


+ 5
- 2
src/packages/game/IZ_app.c View File

@@ -26,7 +26,8 @@ typedef enum {
} IZ_AppInitializeResult;

IZ_AppInitializeResult IZ_AppInitialize(struct IZ_App* app, u8 argc, const char* argv[]) {
memset(app, 0, sizeof(struct IZ_App));
IZ_LogInfo(IZ_LOG_CATEGORY_GLOBAL, "Starting %s...", IZ_APP_NAME);
IZ_memset(app, 0, sizeof(struct IZ_App));

const char* cmdline_buffer;
char config_path[128];
@@ -44,7 +45,7 @@ IZ_AppInitializeResult IZ_AppInitialize(struct IZ_App* app, u8 argc, const char*
);

if (SDL_Init(flags) < 0) {
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
IZ_LogError("Framework initialization failed! Reason: %s", SDL_GetError());
return IZ_APP_INITIALIZE_RESULT_SDL_ERROR;
}

@@ -71,6 +72,7 @@ void IZ_AppTeardown(struct IZ_App* app) {
IZ_PoolTeardown(&app->pool);
IZ_InputTeardown(&app->input_state);
IZ_VideoTeardown(&app->video_state);
IZ_LogInfo(IZ_LOG_CATEGORY_GLOBAL, "Stopping %s...", IZ_APP_NAME);
SDL_Quit();
}

@@ -109,6 +111,7 @@ void IZ_AppPrintHelp() {
}

IZ_AppResult IZ_AppRun(struct IZ_App* app, u8 argc, const char* argv[]) {
IZ_TimerStart();
if (IZ_ConfigGetCommandlineOption(argc, argv, "-h")) {
IZ_AppPrintHelp();
return IZ_APP_RESULT_OK;


+ 2
- 0
src/packages/game/IZ_app.h View File

@@ -9,7 +9,9 @@
#include "IZ_app_input.h"
#include "IZ_app_net.h"
#include "IZ_app_video.h"
#include "../log/IZ_log.h"
#include "../string/IZ_string.h"
#include "../timer/IZ_timer.h"

typedef enum {
IZ_APP_RESULT_INITIALIZATION_ERROR = -1,


+ 8
- 1
src/packages/game/input/IZ_input.c View File

@@ -10,6 +10,8 @@ void IZ_InputHandlePortMIDIEvents(IZ_InputState* state, PmEvent e) {
}

IZ_ProcedureResult IZ_InputInitialize(IZ_InputState* state, const char* config_path, u8 argc, const char* argv[]) {
IZ_LogInfo(IZ_LOG_CATEGORY_GLOBAL, "Setting up input...");

*state = (IZ_InputState) {
.action = {},
.joystick_state = {},
@@ -36,10 +38,15 @@ IZ_ProcedureResult IZ_InputInitialize(IZ_InputState* state, const char* config_p
state->action[player_index] = 0;
}

return -result;
IZ_ProcedureResult final_result = -result;

IZ_LogInfo(IZ_LOG_CATEGORY_GLOBAL, "Input setup complete. Result: %d", final_result);

return final_result;
}

void IZ_InputTeardown(IZ_InputState* state) {
IZ_LogInfo(IZ_LOG_CATEGORY_GLOBAL, "Shutting down input...");
IZ_JoystickTeardown(&state->joystick_state);
IZ_MIDIInputTeardown(&state->midi_input_state);
}

+ 3
- 1
src/packages/game/memory/IZ_pool.c View File

@@ -1,9 +1,10 @@
#include "IZ_pool.h"

void IZ_PoolInitialize(IZ_Pool* pool, size_t size) {
IZ_LogInfo(IZ_LOG_CATEGORY_GLOBAL, "Setting up memory pools...");
IZ_ListInitialize(&pool->items);
pool->memory = SDL_malloc(size);
SDL_memset(pool->memory, 0, size);
IZ_memset(pool->memory, 0, size);
pool->allocated_memory = 0;
pool->next_address = 0;
pool->max_size = size;
@@ -46,6 +47,7 @@ void IZ_PoolDeallocate(IZ_PoolItem* item) {
}

void IZ_PoolTeardown(IZ_Pool* pool) {
IZ_LogInfo(IZ_LOG_CATEGORY_GLOBAL, "Shutting down memory pools...");
SDL_free(pool->memory);
pool->memory = NULL;
}

+ 2
- 0
src/packages/game/memory/IZ_pool.h View File

@@ -3,6 +3,8 @@

#include <SDL_stdinc.h>
#include "../../common/IZ_common.h"
#include "../../log/IZ_log.h"
#include "../../string/IZ_string.h"
#include "../data/IZ_list.h"

#define POOL_MAX_SIZE (1llu << 26) // 64MB


+ 3
- 1
src/packages/game/output/video/IZ_video.c View File

@@ -65,8 +65,9 @@ IZ_ProcedureResult IZ_VideoInitializeConfig(IZ_VideoState* state, const char* c
}

IZ_ProcedureResult IZ_VideoInitialize(IZ_VideoState* state, void* user_data, const char* config_path, u8 argc, const char* argv[]) {
IZ_LogInfo(IZ_LOG_CATEGORY_GLOBAL, "Setting up video...");
IZ_memcpy(state, sizeof(IZ_VideoState), &IZ_VIDEO_DEFAULT_STATE, sizeof(IZ_VideoState));
memset(state->active_sprites, 0, sizeof(IZ_SpriteSlot) * IZ_MAX_ACTIVE_SPRITES);
IZ_memset(state->active_sprites, 0, sizeof(IZ_SpriteSlot) * IZ_MAX_ACTIVE_SPRITES);
if (IZ_VideoInitializeConfig(state, config_path, argc, argv) < 0) {
return -2;
}
@@ -92,6 +93,7 @@ IZ_ProcedureResult IZ_VideoInitialize(IZ_VideoState* state, void* user_data, con
}

void IZ_VideoTeardown(IZ_VideoState* state) {
IZ_LogInfo(IZ_LOG_CATEGORY_GLOBAL, "Shutting down video...");
for (u16 i = 0; i < IZ_MAX_ACTIVE_SPRITES; i += 1) {
if (state->active_sprites[i].sprite.texture) {
SDL_DestroyTexture(state->active_sprites[i].sprite.texture);


+ 8
- 0
src/packages/io/IZ_io.c View File

@@ -24,3 +24,11 @@ errno_t IZ_fopen(struct _iobuf** file, const char* filename, const char* mode) {
return *file == NULL ? 1 : 0;
#endif
}

errno_t IZ_vsprintf(char* buffer, size_t buffer_size, const char* format, va_list args) {
#if defined IZ_WIN64
return vsprintf_s(buffer, buffer_size, format, args);
#else
return vsprintf(buffer, format, args);
#endif
}

+ 2
- 0
src/packages/io/IZ_io.h View File

@@ -8,4 +8,6 @@ int IZ_sprintf(char*, size_t, const char*, ...);

errno_t IZ_fopen(struct _iobuf**, const char*, const char*);

errno_t IZ_vsprintf(char* buffer, size_t buffer_size, const char* format, va_list);

#endif

+ 24
- 0
src/packages/log/IZ_intercept.c View File

@@ -0,0 +1,24 @@
#include "IZ_intercept.h"

void IZ_LogInterceptHandleFromWS(i32 level, const char* line) {
switch (level) {
case LLL_ERR:
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "%s", line);
return;
case LLL_WARN:
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "%s", line);
return;
case LLL_NOTICE:
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "%s", line);
return;
case LLL_USER:
default:
break;
}

SDL_Log("%s", line);
}

void IZ_LogInterceptWSMessages(i32 level) {
lws_set_log_level(level, IZ_LogInterceptHandleFromWS);
}

+ 10
- 0
src/packages/log/IZ_intercept.h View File

@@ -0,0 +1,10 @@
#ifndef IZ_INTERCEPT_H
#define IZ_INTERCEPT_H

#include "SDL_log.h"
#include "libwebsockets.h"
#include "../common/IZ_common.h"

void IZ_LogInterceptWSMessages(i32);

#endif

+ 83
- 15
src/packages/log/IZ_log.c View File

@@ -1,24 +1,92 @@
#include "IZ_log.h"

void IZ_LogHandleFromWS(i32 level, const char* line) {
switch (level) {
case LLL_ERR:
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "%s", line);
return;
case LLL_WARN:
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "%s", line);
return;
case LLL_NOTICE:
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "%s", line);
return;
case LLL_USER:
void IZ_LogError(const char* fmt, ...) {
#ifdef IZ_LOG_LEVEL_FLAG_ERROR
char buffer[4096];
va_list args;
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
#if IZ_LOG_DATE_FUNCTION == IZ_TimerElapsed
fprintf(stderr, RED "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer);
#elif IZ_LOG_DATE_FUNCTION == IZ_TimerNow
fprintf(stderr, RED "%24s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer);
#endif
#endif
}

void IZ_LogInfo(IZ_LogCategory category, const char* fmt, ...) {
#ifdef IZ_LOG_LEVEL_FLAG_INFO
char buffer[4096];
va_list args;
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
#if IZ_LOG_DATE_FUNCTION == IZ_TimerElapsed
switch (category) {
default:
case IZ_LOG_CATEGORY_GENERIC:
fprintf(stdout, CYN "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer);
break;
case IZ_LOG_CATEGORY_GLOBAL:
fprintf(stdout, MAG "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer);
break;
case IZ_LOG_CATEGORY_INPUT:
fprintf(stdout, GRN "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer);
break;
}

SDL_Log("%s", line);
#elif IZ_LOG_DATE_FUNCTION == IZ_TimerNow
switch (category) {
default:
case IZ_LOG_CATEGORY_GENERIC:
fprintf(stdout, CYN "%24s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer);
break;
case IZ_LOG_CATEGORY_GLOBAL:
fprintf(stdout, MAG "%24s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer);
break;
case IZ_LOG_CATEGORY_INPUT:
fprintf(stdout, GRN "%24s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer);
break;
}
#endif
#endif
}

void IZ_LogWarn(bool is_critical, const char* fmt, ...) {
#ifdef IZ_LOG_LEVEL_FLAG_WARN
char buffer[4096];
va_list args;
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
#if IZ_LOG_DATE_FUNCTION == IZ_TimerElapsed
if (is_critical) {
fprintf(stdout, WHT "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer);
} else {
fprintf(stdout, YEL "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer);
}
#elif IZ_LOG_DATE_FUNCTION == IZ_TimerNow
if (is_critical) {
fprintf(stdout, WHT "%24s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer);
} else {
fprintf(stdout, YEL "%24s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer);
}
#endif
#endif
}

void IZ_LogInterceptWSMessages(i32 level) {
lws_set_log_level(level, IZ_LogHandleFromWS);
void IZ_Log(const char* fmt, ...) {
#ifdef IZ_LOG_LEVEL_FLAG_DEBUG
char buffer[4096];
va_list args;
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
#if IZ_LOG_DATE_FUNCTION == IZ_TimerElapsed
fprintf(stdout, BLU "%12s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer);
#elif IZ_LOG_DATE_FUNCTION == IZ_TimerNow
fprintf(stdout, BLU "%24s" RESET " %s\n", IZ_LOG_DATE_FUNCTION(), buffer);
#endif
#endif
}

+ 44
- 4
src/packages/log/IZ_log.h View File

@@ -1,10 +1,50 @@
#ifndef IZ_LOG_H
#define IZ_LOG_H

#include "SDL_log.h"
#include "libwebsockets.h"
#include "../common/IZ_common.h"
#ifdef IZ_WIN64

void IZ_LogInterceptWSMessages(i32);
#define RED ""
#define GRN ""
#define YEL ""
#define BLU ""
#define MAG ""
#define CYN ""
#define WHT ""
#define RESET ""

#else

#define RED "\x1B[31m"
#define GRN "\x1B[32m"
#define YEL "\x1B[33m"
#define BLU "\x1B[34m"
#define MAG "\x1B[35m"
#define CYN "\x1B[36m"
#define WHT "\x1B[37m"
#define RESET "\x1B[0m"

#endif

#define IZ_LOG_LEVEL_FLAG_DEBUG
#define IZ_LOG_LEVEL_FLAG_INFO
#define IZ_LOG_LEVEL_FLAG_WARN
#define IZ_LOG_LEVEL_FLAG_ERROR

#include <stdbool.h>
#include <stdarg.h>
#include <stdio.h>
#include <time.h>
#include "../timer/IZ_timer.h"

typedef enum {
IZ_LOG_CATEGORY_INPUT,
IZ_LOG_CATEGORY_GLOBAL,
IZ_LOG_CATEGORY_GENERIC,
} IZ_LogCategory;

void IZ_LogError(const char* fmt, ...);
void IZ_LogInfo(IZ_LogCategory category, const char* fmt, ...);
void IZ_LogWarn(bool is_critical, const char* fmt, ...);
void IZ_Log(const char* fmt, ...);

#endif

+ 2
- 0
src/packages/net/IZ_net_client.c View File

@@ -106,6 +106,7 @@ IZ_ProcedureResult IZ_NetClientInitialize(
if (!user_data) {
return -1;
}
IZ_LogInfo(IZ_LOG_CATEGORY_GLOBAL, "Setting up networking...");
IZ_memcpy(state, sizeof(IZ_NetClientState), &IZ_NET_CLIENT_DEFAULT_STATE, sizeof(IZ_NetClientState));
if (IZ_NetClientInitializeConfig(state, config_path, argc, argv) < 0) {
return -2;
@@ -145,6 +146,7 @@ void IZ_NetClientConnect(IZ_NetClientState* state, IZ_WSClientInitializeParams p
}

void IZ_NetClientDisconnect(IZ_NetClientState* state) {
IZ_LogInfo(IZ_LOG_CATEGORY_GLOBAL, "Shutting down networking...");
if (state->status == IZ_NET_CLIENT_STATUS_PRISTINE) {
return;
}


+ 1
- 1
src/packages/net/svc/IZ_wsclient.c View File

@@ -34,7 +34,7 @@ IZ_ProcedureResult IZ_WSClientCallback(

IZ_ProcedureResult IZ_WSClientInitialize(IZ_Websocket* state, IZ_WSClientInitializeParams params) {
struct lws_context_creation_info info;
memset(&info, 0, sizeof info);
IZ_memset(&info, 0, sizeof info);
info.port = CONTEXT_PORT_NO_LISTEN;

static const struct lws_protocols protocols[] = {


+ 1
- 0
src/packages/net/svc/IZ_wsclient.h View File

@@ -2,6 +2,7 @@
#define IZ_WSCLIENT_H

#include "../../common/IZ_common.h"
#include "../../string/IZ_string.h"
#include "../core/IZ_websocket.h"

typedef struct {


+ 1
- 1
src/packages/net/svc/IZ_wsserver.c View File

@@ -43,7 +43,7 @@ const char* IZ_WSServerTestPath(const char* base_dir, const char* file) {

IZ_ProcedureResult IZ_WSServerInitialize(IZ_Websocket* state, IZ_WSServerInitializeParams params) {
struct lws_context_creation_info info;
memset(&info, 0, sizeof info);
IZ_memset(&info, 0, sizeof info);
info.port = params.port;

const char* origin = "./public";


+ 1
- 0
src/packages/net/svc/IZ_wsserver.h View File

@@ -5,6 +5,7 @@
#include <string.h>
#include "../../common/IZ_common.h"
#include "../../io/IZ_io.h"
#include "../../string/IZ_string.h"
#include "../core/IZ_websocket.h"

#ifndef S_ISDIR


+ 1
- 1
src/packages/server/IZ_app.c View File

@@ -9,7 +9,7 @@ void IZ_AppHandleSignal(i32 _signal) {

IZ_ProcedureResult IZ_AppInitialize(IZ_App *app, u8 argc, const char **argv) {
global_app = app;
memset(app, 0, sizeof(IZ_App));
IZ_memset(app, 0, sizeof(IZ_App));
signal(SIGINT, IZ_AppHandleSignal);

// IZ_LogInterceptWSMessages(app->config.log_level);


+ 1
- 1
src/packages/server/IZ_app.h View File

@@ -5,7 +5,7 @@
#include <stdbool.h>
#include "../common/IZ_common.h"
#include "../net/IZ_net_server.h"
#include "../log/IZ_log.h"
#include "../log/IZ_intercept.h"
#include "../string/IZ_string.h"
#include "db/IZ_repo.h"
#include "IZ_app_config.h"


+ 4
- 1
src/packages/string/IZ_string.c View File

@@ -2,7 +2,6 @@

errno_t IZ_memcpy(void* const dest, const rsize_t dest_size, const void* const source, const rsize_t source_size) {
#if defined IZ_WIN64

return memcpy_s(dest, dest_size, source, source_size);
#else
return memcpy(dest, source, dest_size - 1);
@@ -24,3 +23,7 @@ errno_t IZ_strlwr(char* str, rsize_t str_size) {
return _strlwr(str);
#endif
}

void* IZ_memset(void* dest, int value, rsize_t dest_size) {
return memset(dest, value, dest_size);
}

+ 2
- 0
src/packages/string/IZ_string.h View File

@@ -9,4 +9,6 @@ errno_t IZ_strcat(char*, rsize_t, const char*);

errno_t IZ_strlwr(char*, rsize_t);

void* IZ_memset(void*, int, rsize_t);

#endif

+ 69
- 0
src/packages/timer/IZ_timer.c View File

@@ -0,0 +1,69 @@
#include "IZ_timer.h"

#ifdef IZ_WIN64
typedef enum {
_CLOCK_REALTIME = 0,
#define CLOCK_REALTIME _CLOCK_REALTIME
_CLOCK_MONOTONIC = 6,
#define CLOCK_MONOTONIC _CLOCK_MONOTONIC
} clockid_t;

int clock_gettime(clockid_t __clock_id, struct timespec *__tp) {
return timespec_get(__tp, TIME_UTC);
}
#endif

/**
* Gets the start timestamp.
* @sa IZ_TIMER_START_TIMESTAMP
*/
void IZ_TimerStart() {
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
IZ_TIMER_START_TIMESTAMP = t.tv_sec;
}

/**
* Gets the number of microseconds since the application timer has been started.
* @return The number of microseconds.
* @sa IZ_TimerElapsed()
*/
unsigned int IZ_TimerElapsedRaw() {
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
return (t.tv_sec - IZ_TIMER_START_TIMESTAMP) * 1000000 + (t.tv_nsec / 1000);
}

/**
* Gets the formatted elapsed time since the application timer has been started.
* @return The formatted elapsed time.
* @sa IZ_TimerElapsedRaw()
*/
char* IZ_TimerElapsed() {
static char buffer[32];
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
unsigned int seconds = t.tv_sec - IZ_TIMER_START_TIMESTAMP;
unsigned int milliseconds = t.tv_nsec / 1000000;
unsigned int minutes = seconds / 60;
unsigned int hours = seconds / 60 / 60;
sprintf(buffer, "%02d:%02d:%02d.%03d", hours, minutes % 60, seconds % 60, milliseconds % 1000);
return buffer;
}

/**
* Gets the formatted time in the current instant.
* @return The formatted time in the current instant.
*/
char* IZ_TimerNow() {
struct timespec t;
clock_gettime(CLOCK_REALTIME, &t);
static char buffer[32];
unsigned int seconds = t.tv_sec;
unsigned int milliseconds = t.tv_nsec / 1000000;
static char formatted[32];
time_t current_time = seconds;
strftime(formatted, sizeof(formatted), "%Y-%m-%dT%H:%M:%S", gmtime(&current_time));
sprintf(buffer, "%s.%03dZ", formatted, milliseconds < 0 ? 0 : milliseconds % 1000);
return buffer;
}

+ 42
- 0
src/packages/timer/IZ_timer.h View File

@@ -0,0 +1,42 @@
#ifndef IZ_TIMER_H
#define IZ_TIMER_H

//#define IZ_LOG_DATE_FRIENDLY
#define IZ_LOG_DATE_ELAPSED_FRIENDLY

#include <stdio.h>
#include <time.h>

/**
* The start timestamp.
* @sa IZ_TimerStart
*/
static time_t IZ_TIMER_START_TIMESTAMP = 0;

/**
* Gets the start timestamp.
* @sa IZ_TIMER_START_TIMESTAMP
*/
void IZ_TimerStart();

/**
* Gets the number of microseconds since the application timer has been started.
* @return The number of microseconds.
* @sa IZ_TimerElapsed()
*/
unsigned int IZ_TimerElapsedRaw();

/**
* Gets the formatted elapsed time since the application timer has been started.
* @return The formatted elapsed time.
* @sa IZ_TimerElapsedRaw()
*/
char* IZ_TimerElapsed();

/**
* Gets the formatted time in the current instant.
* @return The formatted time in the current instant.
*/
char* IZ_TimerNow();

#endif

Loading…
Cancel
Save