@@ -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 | |||
@@ -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; | |||
} |
@@ -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 { | |||
@@ -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; | |||
@@ -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, | |||
@@ -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); | |||
} |
@@ -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; | |||
} |
@@ -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 | |||
@@ -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); | |||
@@ -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 | |||
} |
@@ -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 |
@@ -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); | |||
} |
@@ -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 |
@@ -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 | |||
} |
@@ -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 |
@@ -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; | |||
} | |||
@@ -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[] = { | |||
@@ -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 { | |||
@@ -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"; | |||
@@ -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 | |||
@@ -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); | |||
@@ -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" | |||
@@ -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); | |||
} |
@@ -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 |
@@ -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(¤t_time)); | |||
sprintf(buffer, "%s.%03dZ", formatted, milliseconds < 0 ? 0 : milliseconds % 1000); | |||
return buffer; | |||
} |
@@ -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 |