/** * @brief Saves configuration file and shuts the client systems down * @todo this is a callback from @c Sys_Quit and @c Com_Error. It would be better * to run quit through here before the final handoff to the sys code. * @sa Sys_Quit * @sa CL_Init */ void CL_Shutdown (void) { if (isdown) { printf("recursive shutdown\n"); return; } isdown = true; /* remove cvar feedback */ for (const cvar_t* var = Cvar_GetFirst(); var; var = var->next) { if (var->flags & CVAR_R_CONTEXT) Cvar_UnRegisterChangeListener(var->name, CL_RContextCvarChange); if (var->flags & CVAR_R_IMAGES) Cvar_UnRegisterChangeListener(var->name, CL_RImagesCvarChange); } GAME_SetMode(nullptr); GAME_UnloadGame(); CL_HTTP_Cleanup(); Irc_Shutdown(); Con_SaveConsoleHistory(); Key_WriteBindings("keys.cfg"); S_Shutdown(); R_Shutdown(); UI_Shutdown(); CIN_Shutdown(); SEQ_Shutdown(); GAME_Shutdown(); CL_LanguageShutdown(); TOTD_Shutdown(); SCR_Shutdown(); }
/** * @brief Callback every time the parent window is closed (pop from the active window stack) */ void uiCvarNode::onWindowClosed (uiNode_t* node) { cvar_t* var; var = Cvar_FindVar(node->name); if (var == nullptr) return; cvarChangeListener_t* l = var->changeListener; while (l) { if (l->exec == UI_CvarListenerNodeCallback) { LIST_Remove(reinterpret_cast<linkedList_t**>(&l->data), node); if (LIST_IsEmpty(static_cast<linkedList_t*>(l->data))) { Cvar_UnRegisterChangeListener(node->name, UI_CvarListenerNodeCallback); } break; } l = l->next; } }