Add custom enums for making sense of returned values from config and game app code.feature/data-structs
@@ -23,6 +23,11 @@ const char* IZ_ConfigGetCommandlineOption(u8 argc, const char* argv[], const cha | |||
return NULL; | |||
} | |||
typedef enum { | |||
IZ_CONFIG_SAVE_ITEM_ERROR = -1, | |||
IZ_CONFIG_SAVE_ITEM_OK, | |||
} IZ_ConfigSaveItemResult; | |||
#define IZ_CONFIG_REGISTER_INT_TYPE(ID, T) \ | |||
typedef bool IZ_ConfigValidate##ID(T); \ | |||
\ | |||
@@ -64,7 +69,7 @@ void IZ_ConfigLoad##ID(IZ_ConfigItem* item, const char* config_path) { \ | |||
IZ_ConfigEnsureValid##ID(item, raw_value, default_value); \ | |||
} \ | |||
\ | |||
IZ_ProcedureResult IZ_ConfigSave##ID(IZ_ConfigItem* item, const char* config_path) { \ | |||
IZ_ConfigSaveItemResult IZ_ConfigSave##ID(IZ_ConfigItem* item, const char* config_path) { \ | |||
T dest = *((T*) item->dest); \ | |||
if (item->validator) { \ | |||
IZ_ConfigValidate##ID* validate = item->validator; \ | |||
@@ -133,7 +138,7 @@ void IZ_ConfigLoadString(IZ_ConfigItem* item, const char* config_path) { | |||
IZ_ConfigEnsureValidString(item, buffer); | |||
} | |||
IZ_ProcedureResult IZ_ConfigSaveString(IZ_ConfigItem* item, const char* config_path) { | |||
IZ_ConfigSaveItemResult IZ_ConfigSaveString(IZ_ConfigItem* item, const char* config_path) { | |||
const char* dest = (const char*) item->dest; | |||
if (item->validator) { | |||
IZ_ConfigLoadParamsStringValidator* validator = item->validator; | |||
@@ -143,10 +148,10 @@ IZ_ProcedureResult IZ_ConfigSaveString(IZ_ConfigItem* item, const char* config_p | |||
} | |||
if (!ini_puts(item->section, item->key, dest, config_path)) { | |||
return -1; | |||
return IZ_CONFIG_SAVE_ITEM_ERROR; | |||
} | |||
return 0; | |||
return IZ_CONFIG_SAVE_ITEM_OK; | |||
} | |||
void IZ_ConfigOverrideString(IZ_ConfigItem* item, u8 argc, const char* argv[]) { | |||
@@ -180,25 +185,30 @@ void IZ_ConfigLoad(IZ_ConfigItem item[], const char* config_path) { | |||
} | |||
} | |||
IZ_ProcedureResult IZ_ConfigSave(IZ_ConfigItem item[], const char* config_path) { | |||
IZ_ConfigSaveResult IZ_ConfigSave(IZ_ConfigItem item[], const char* config_path) { | |||
u8 i; | |||
u16 problems = 0; | |||
i64 problems = 0; | |||
for (i = 0; item[i].type != IZ_CONFIG_TYPE_VOID; i += 1) { | |||
i8 result = 0; | |||
switch (item[i].type) { | |||
case IZ_CONFIG_TYPE_STRING: | |||
IZ_ConfigSaveString(&item[i], config_path); | |||
result = IZ_ConfigSaveString(&item[i], config_path); | |||
break; | |||
case IZ_CONFIG_TYPE_U8: | |||
IZ_ConfigSaveU8(&item[i], config_path); | |||
result = IZ_ConfigSaveU8(&item[i], config_path); | |||
break; | |||
case IZ_CONFIG_TYPE_U16: | |||
IZ_ConfigSaveU16(&item[i], config_path); | |||
result = IZ_ConfigSaveU16(&item[i], config_path); | |||
break; | |||
case IZ_CONFIG_TYPE_I32: | |||
IZ_ConfigSaveI32(&item[i], config_path); | |||
result = IZ_ConfigSaveI32(&item[i], config_path); | |||
default: | |||
break; | |||
} | |||
if (result < 0) { | |||
problems |= (1u << (i64) i); | |||
} | |||
} | |||
return -problems; | |||
@@ -226,12 +236,15 @@ void IZ_ConfigOverride(IZ_ConfigItem item[], u8 argc, const char* argv[]) { | |||
} | |||
} | |||
IZ_ProcedureResult IZ_ConfigInitialize(IZ_ConfigItem item[], const char* config_path, u8 argc, const char* argv[]) { | |||
IZ_ConfigInitializeResult IZ_ConfigInitialize(IZ_ConfigItem item[], const char* config_path, u8 argc, const char* argv[]) { | |||
IZ_ConfigLoad(item, config_path); | |||
i32 save_result = IZ_ConfigSave(item, config_path); | |||
IZ_ConfigSaveResult save_result = IZ_ConfigSave(item, config_path); | |||
if (save_result < 0) { | |||
return -1; | |||
return IZ_CONFIG_INITIALIZE_RESULT_ERROR; | |||
} | |||
IZ_ConfigOverride(item, argc, argv); | |||
return save_result > 0 ? 1 : 0; | |||
if (save_result > 0) { | |||
return IZ_CONFIG_INITIALIZE_RESULT_WARNING; | |||
} | |||
return IZ_CONFIG_INITIALIZE_RESULT_OK; | |||
} |
@@ -35,9 +35,17 @@ void IZ_ConfigGetDefaultPath(const char*, size_t); | |||
const char* IZ_ConfigGetCommandlineOption(u8, const char*[], const char*); | |||
IZ_ProcedureResult IZ_ConfigInitialize(IZ_ConfigItem[], const char*, u8, const char*[]); | |||
typedef enum { | |||
IZ_CONFIG_INITIALIZE_RESULT_ERROR = -1, | |||
IZ_CONFIG_INITIALIZE_RESULT_OK, | |||
IZ_CONFIG_INITIALIZE_RESULT_WARNING | |||
} IZ_ConfigInitializeResult; | |||
IZ_ConfigInitializeResult IZ_ConfigInitialize(IZ_ConfigItem[], const char*, u8, const char*[]); | |||
typedef i64 IZ_ConfigSaveResult; | |||
IZ_ProcedureResult IZ_ConfigSave(IZ_ConfigItem[], const char*); | |||
IZ_ConfigSaveResult IZ_ConfigSave(IZ_ConfigItem[], const char*); | |||
#define IZ_CONFIG_ITEM_NULL (IZ_ConfigItem) { \ | |||
IZ_CONFIG_TYPE_VOID, \ | |||
@@ -16,7 +16,16 @@ IZ_InputState* IZ_AppGetInputState(struct IZ_App* app) { | |||
return &app->input_state; | |||
} | |||
IZ_ProcedureResult IZ_AppInitialize(struct IZ_App* app, u8 argc, const char* argv[]) { | |||
typedef enum { | |||
IZ_APP_INITIALIZE_RESULT_NETWORKING_ERROR = -5, | |||
IZ_APP_INITIALIZE_RESULT_POOL_ERROR, | |||
IZ_APP_INITIALIZE_RESULT_INPUT_ERROR, | |||
IZ_APP_INITIALIZE_RESULT_VIDEO_ERROR, | |||
IZ_APP_INITIALIZE_RESULT_SDL_ERROR, | |||
IZ_APP_INITIALIZE_RESULT_OK, | |||
} IZ_AppInitializeResult; | |||
IZ_AppInitializeResult IZ_AppInitialize(struct IZ_App* app, u8 argc, const char* argv[]) { | |||
memset(app, 0, sizeof(struct IZ_App)); | |||
const char* cmdline_buffer; | |||
@@ -36,25 +45,25 @@ IZ_ProcedureResult IZ_AppInitialize(struct IZ_App* app, u8 argc, const char* arg | |||
if (SDL_Init(flags) < 0) { | |||
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SDL could not initialize! SDL_Error: %s\n", SDL_GetError()); | |||
return IZ_APP_RUN_SDL_INIT_ERROR; | |||
return IZ_APP_INITIALIZE_RESULT_SDL_ERROR; | |||
} | |||
if (IZ_VideoInitialize(&app->video_state, app, config_path, argc, argv)) { | |||
return IZ_APP_RUN_VIDEO_INIT_ERROR; | |||
return IZ_APP_INITIALIZE_RESULT_VIDEO_ERROR; | |||
} | |||
if (IZ_InputInitialize(&app->input_state, config_path, argc, argv)) { | |||
return IZ_APP_RUN_INPUT_INIT_ERROR; | |||
return IZ_APP_INITIALIZE_RESULT_INPUT_ERROR; | |||
} | |||
if (IZ_NetClientInitialize(&app->net_state, app, IZ_AppRunNetworkingThread, config_path, argc, argv)) { | |||
return IZ_APP_RUN_NETWORKING_ERROR; | |||
return IZ_APP_INITIALIZE_RESULT_NETWORKING_ERROR; | |||
} | |||
IZ_PoolInitialize(&app->pool, POOL_MAX_SIZE); | |||
app->ticks = 0; | |||
return IZ_APP_RUN_RESULT_OK; | |||
return IZ_APP_INITIALIZE_RESULT_OK; | |||
} | |||
void IZ_AppTeardown(struct IZ_App* app) { | |||
@@ -99,16 +108,14 @@ void IZ_AppPrintHelp() { | |||
IZ_AppPrintHelpOptions(); | |||
} | |||
IZ_ProcedureResult IZ_AppRun(struct IZ_App* app, u8 argc, const char* argv[]) { | |||
// TODO have a config subsystem that handles these. | |||
IZ_AppResult IZ_AppRun(struct IZ_App* app, u8 argc, const char* argv[]) { | |||
if (IZ_ConfigGetCommandlineOption(argc, argv, "-h")) { | |||
IZ_AppPrintHelp(); | |||
return IZ_APP_RUN_RESULT_OK; | |||
return IZ_APP_RESULT_OK; | |||
} | |||
IZ_ProcedureResult init_result = IZ_AppInitialize(app, argc, argv); | |||
if (init_result) { | |||
return init_result; | |||
if (IZ_AppInitialize(app, argc, argv) < 0) { | |||
return IZ_APP_RESULT_INITIALIZATION_ERROR; | |||
} | |||
while (true) { | |||
@@ -126,5 +133,5 @@ IZ_ProcedureResult IZ_AppRun(struct IZ_App* app, u8 argc, const char* argv[]) { | |||
} | |||
IZ_AppTeardown(app); | |||
return IZ_APP_RUN_RESULT_OK; | |||
return IZ_APP_RESULT_OK; | |||
} |
@@ -10,13 +10,9 @@ | |||
#include "IZ_app_video.h" | |||
typedef enum { | |||
IZ_APP_RUN_RESULT_OK, | |||
IZ_APP_RUN_SDL_INIT_ERROR, | |||
IZ_APP_RUN_VIDEO_INIT_ERROR, | |||
IZ_APP_RUN_INPUT_INIT_ERROR, | |||
IZ_APP_RUN_POOL_INIT_ERROR, | |||
IZ_APP_RUN_NETWORKING_ERROR, | |||
} IZ_AppRunResult; | |||
IZ_APP_RESULT_INITIALIZATION_ERROR = -1, | |||
IZ_APP_RESULT_OK, | |||
} IZ_AppResult; | |||
typedef struct IZ_App { | |||
IZ_InputState input_state; | |||
@@ -27,6 +23,6 @@ typedef struct IZ_App { | |||
IZ_NetClientState net_state; | |||
} IZ_App; | |||
IZ_ProcedureResult IZ_AppRun(struct IZ_App*, u8, const char*[]); | |||
IZ_AppResult IZ_AppRun(struct IZ_App*, u8, const char*[]); | |||
#endif |