changeset 14514:38960c0add73 draft

(svn r19085) -Codechange: simplify hooking of console commands
author smatz <smatz@openttd.org>
date Wed, 10 Feb 2010 18:18:08 +0000
parents e99a75a10e29
children 884a959395d7
files src/console.cpp src/console_cmds.cpp src/console_internal.h
diffstat 3 files changed, 34 insertions(+), 157 deletions(-) [+]
line wrap: on
line diff
--- a/src/console.cpp
+++ b/src/console.cpp
@@ -191,76 +191,6 @@
 	return arg != endptr;
 }
 
-/*  * *************************
-    * hooking code            *
-    * *************************/
-
-/**
- * General internal hooking code
- * @param hooks IConsoleHooks structure that will be set according to
- * @param type type access trigger
- * @param proc function called when the hook criteria is met
- */
-static void IConsoleHookAdd(IConsoleHooks *hooks, IConsoleHookTypes type, IConsoleHook *proc)
-{
-	if (hooks == NULL || proc == NULL) return;
-
-	switch (type) {
-		case ICONSOLE_HOOK_ACCESS:
-			hooks->access = proc;
-			break;
-		case ICONSOLE_HOOK_PRE_ACTION:
-			hooks->pre = proc;
-			break;
-		case ICONSOLE_HOOK_POST_ACTION:
-			hooks->post = proc;
-			break;
-		default: NOT_REACHED();
-	}
-}
-
-/**
- * Handle any special hook triggers. If the hook type is met check if
- * there is a function associated with that and if so, execute it
- * @param hooks IConsoleHooks structure that will be checked
- * @param type type of hook, trigger that needs to be activated
- * @return true on a successful execution of the hook command or if there
- * is no hook/trigger present at all. False otherwise
- */
-static bool IConsoleHookHandle(const IConsoleHooks *hooks, IConsoleHookTypes type)
-{
-	IConsoleHook *proc = NULL;
-	if (hooks == NULL) return false;
-
-	switch (type) {
-		case ICONSOLE_HOOK_ACCESS:
-			proc = hooks->access;
-			break;
-		case ICONSOLE_HOOK_PRE_ACTION:
-			proc = hooks->pre;
-			break;
-		case ICONSOLE_HOOK_POST_ACTION:
-			proc = hooks->post;
-			break;
-		default: NOT_REACHED();
-	}
-
-	return (proc == NULL) ? true : proc();
-}
-
-/**
- * Add a hook to a command that will be triggered at certain points
- * @param name name of the command that the hook is added to
- * @param type type of hook that is added (ACCESS, BEFORE and AFTER change)
- * @param proc function called when the hook criteria is met
- */
-void IConsoleCmdHookAdd(const char *name, IConsoleHookTypes type, IConsoleHook *proc)
-{
-	IConsoleCmd *cmd = IConsoleCmdGet(name);
-	if (cmd == NULL) return;
-	IConsoleHookAdd(&cmd->hook, type, proc);
-}
-
 /**
  * Perhaps ugly macro, but this saves us the trouble of writing the same function
  * twice, just with different variables. Yes, templates would be handy. It was
@@ -308,18 +238,13 @@
  * @param name name of the command that will be used
  * @param proc function that will be called upon execution of command
  */
-void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc)
+void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc, IConsoleHook *hook)
 {
-	char *new_cmd = strdup(name);
 	IConsoleCmd *item_new = MallocT<IConsoleCmd>(1);
-
+	item_new->name = strdup(name);
 	item_new->next = NULL;
 	item_new->proc = proc;
-	item_new->name = new_cmd;
-
-	item_new->hook.access = NULL;
-	item_new->hook.pre = NULL;
-	item_new->hook.post = NULL;
+	item_new->hook = hook;
 
 	IConsoleAddSorted(_iconsole_cmds, item_new, IConsoleCmd, "a command");
 }
@@ -541,11 +466,8 @@
 	 */
 	cmd = IConsoleCmdGet(tokens[0]);
 	if (cmd != NULL) {
-		if (IConsoleHookHandle(&cmd->hook, ICONSOLE_HOOK_ACCESS)) {
-			IConsoleHookHandle(&cmd->hook, ICONSOLE_HOOK_PRE_ACTION);
-			if (cmd->proc(t_index, tokens)) { // index started with 0
-				IConsoleHookHandle(&cmd->hook, ICONSOLE_HOOK_POST_ACTION);
-			} else {
+		if (cmd->hook == NULL || cmd->hook()) {
+			if (!cmd->proc(t_index, tokens)) { // index started with 0
 				cmd->proc(0, NULL); // if command failed, give help
 			}
 		}
--- a/src/console_cmds.cpp
+++ b/src/console_cmds.cpp
@@ -106,6 +106,8 @@
 	return true;
 }
 
+#else
+#	define ConHookNoNetwork NULL
 #endif /* ENABLE_NETWORK */
 
 static void IConsoleHelp(const char *str)
@@ -1263,9 +1265,7 @@
 	IConsolePrintF(CC_DEFAULT, "command name: %s", cmd->name);
 	IConsolePrintF(CC_DEFAULT, "command proc: %p", cmd->proc);
 
-	if (cmd->hook.access) IConsoleWarning("command is access hooked");
-	if (cmd->hook.pre) IConsoleWarning("command is pre hooked");
-	if (cmd->hook.post) IConsoleWarning("command is post hooked");
+	if (cmd->hook != NULL) IConsoleWarning("command is hooked");
 
 	return true;
 }
@@ -1721,7 +1721,7 @@
 	IConsoleCmdRegister("getseed",      ConGetSeed);
 	IConsoleCmdRegister("getdate",      ConGetDate);
 	IConsoleCmdRegister("quit",         ConExit);
-	IConsoleCmdRegister("resetengines", ConResetEngines);
+	IConsoleCmdRegister("resetengines", ConResetEngines, ConHookNoNetwork);
 	IConsoleCmdRegister("return",       ConReturn);
 	IConsoleCmdRegister("screenshot",   ConScreenShot);
 	IConsoleCmdRegister("script",       ConScript);
@@ -1761,66 +1761,42 @@
 
 	/* networking functions */
 #ifdef ENABLE_NETWORK
-	/* Network hooks; only active in network */
-	IConsoleCmdHookAdd ("resetengines", ICONSOLE_HOOK_ACCESS, ConHookNoNetwork);
-
 /* Content downloading is only available with ZLIB */
 #if defined(WITH_ZLIB)
 	IConsoleCmdRegister("content",         ConContent);
 #endif /* defined(WITH_ZLIB) */
 
 	/*** Networking commands ***/
-	IConsoleCmdRegister("say",             ConSay);
-	IConsoleCmdHookAdd("say",              ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
-	IConsoleCmdRegister("companies",       ConCompanies);
-	IConsoleCmdHookAdd("companies",        ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+	IConsoleCmdRegister("say",             ConSay, ConHookNeedNetwork);
+	IConsoleCmdRegister("companies",       ConCompanies, ConHookServerOnly);
 	IConsoleAliasRegister("players",       "companies");
-	IConsoleCmdRegister("say_company",     ConSayCompany);
-	IConsoleCmdHookAdd("say_company",      ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
+	IConsoleCmdRegister("say_company",     ConSayCompany, ConHookNeedNetwork);
 	IConsoleAliasRegister("say_player",    "say_company %+");
-	IConsoleCmdRegister("say_client",      ConSayClient);
-	IConsoleCmdHookAdd("say_client",       ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
+	IConsoleCmdRegister("say_client",      ConSayClient, ConHookNeedNetwork);
 
-	IConsoleCmdRegister("connect",         ConNetworkConnect);
-	IConsoleCmdHookAdd("connect",          ICONSOLE_HOOK_ACCESS, ConHookClientOnly);
-	IConsoleCmdRegister("clients",         ConNetworkClients);
-	IConsoleCmdHookAdd("clients",          ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
-	IConsoleCmdRegister("status",          ConStatus);
-	IConsoleCmdHookAdd("status",           ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
-	IConsoleCmdRegister("server_info",     ConServerInfo);
-	IConsoleCmdHookAdd("server_info",      ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+	IConsoleCmdRegister("connect",         ConNetworkConnect, ConHookClientOnly);
+	IConsoleCmdRegister("clients",         ConNetworkClients, ConHookNeedNetwork);
+	IConsoleCmdRegister("status",          ConStatus, ConHookServerOnly);
+	IConsoleCmdRegister("server_info",     ConServerInfo, ConHookServerOnly);
 	IConsoleAliasRegister("info",          "server_info");
-	IConsoleCmdRegister("reconnect",       ConNetworkReconnect);
-	IConsoleCmdHookAdd("reconnect",        ICONSOLE_HOOK_ACCESS, ConHookClientOnly);
-	IConsoleCmdRegister("rcon",            ConRcon);
-	IConsoleCmdHookAdd("rcon",             ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
+	IConsoleCmdRegister("reconnect",       ConNetworkReconnect, ConHookClientOnly);
+	IConsoleCmdRegister("rcon",            ConRcon, ConHookNeedNetwork);
 
-	IConsoleCmdRegister("join",            ConJoinCompany);
-	IConsoleCmdHookAdd("join",             ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
+	IConsoleCmdRegister("join",            ConJoinCompany, ConHookNeedNetwork);
 	IConsoleAliasRegister("spectate",      "join 255");
-	IConsoleCmdRegister("move",            ConMoveClient);
-	IConsoleCmdHookAdd("move",             ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
-	IConsoleCmdRegister("reset_company",   ConResetCompany);
-	IConsoleCmdHookAdd("reset_company",    ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+	IConsoleCmdRegister("move",            ConMoveClient, ConHookServerOnly);
+	IConsoleCmdRegister("reset_company",   ConResetCompany, ConHookServerOnly);
 	IConsoleAliasRegister("clean_company", "reset_company %A");
-	IConsoleCmdRegister("client_name",     ConClientNickChange);
-	IConsoleCmdHookAdd("client_name",      ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
-	IConsoleCmdRegister("kick",            ConKick);
-	IConsoleCmdHookAdd("kick",             ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
-	IConsoleCmdRegister("ban",             ConBan);
-	IConsoleCmdHookAdd("ban",              ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
-	IConsoleCmdRegister("unban",           ConUnBan);
-	IConsoleCmdHookAdd("unban",            ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
-	IConsoleCmdRegister("banlist",         ConBanList);
-	IConsoleCmdHookAdd("banlist",          ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+	IConsoleCmdRegister("client_name",     ConClientNickChange, ConHookServerOnly);
+	IConsoleCmdRegister("kick",            ConKick, ConHookServerOnly);
+	IConsoleCmdRegister("ban",             ConBan, ConHookServerOnly);
+	IConsoleCmdRegister("unban",           ConUnBan, ConHookServerOnly);
+	IConsoleCmdRegister("banlist",         ConBanList, ConHookServerOnly);
 
-	IConsoleCmdRegister("pause",           ConPauseGame);
-	IConsoleCmdHookAdd("pause",            ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
-	IConsoleCmdRegister("unpause",         ConUnPauseGame);
-	IConsoleCmdHookAdd("unpause",          ICONSOLE_HOOK_ACCESS, ConHookServerOnly);
+	IConsoleCmdRegister("pause",           ConPauseGame, ConHookServerOnly);
+	IConsoleCmdRegister("unpause",         ConUnPauseGame, ConHookServerOnly);
 
-	IConsoleCmdRegister("company_pw",      ConCompanyPassword);
-	IConsoleCmdHookAdd("company_pw",       ICONSOLE_HOOK_ACCESS, ConHookNeedNetwork);
+	IConsoleCmdRegister("company_pw",      ConCompanyPassword, ConHookNeedNetwork);
 	IConsoleAliasRegister("company_password",      "company_pw %+");
 
 	IConsoleAliasRegister("net_frame_freq",        "setting frame_freq %+");
--- a/src/console_internal.h
+++ b/src/console_internal.h
@@ -19,24 +19,6 @@
 	ICON_MAX_STREAMSIZE = 2048, ///< maximum length of a totally expanded command
 };
 
-enum IConsoleHookTypes {
-	ICONSOLE_HOOK_ACCESS,
-	ICONSOLE_HOOK_PRE_ACTION,
-	ICONSOLE_HOOK_POST_ACTION
-};
-
-/** --Hooks--
- * Hooks are certain triggers that are executed on either
- * access, before execution or after execution. This allows
- * for general flow of permissions or special action needed in some cases
- */
-typedef bool IConsoleHook();
-struct IConsoleHooks {
-	IConsoleHook *access; ///< trigger when accessing the command
-	IConsoleHook *pre;    ///< trigger before the command is executed
-	IConsoleHook *post;   ///< trigger after the command is executed
-};
-
 /** --Commands--
  * Commands are commands, or functions. They get executed once and any
  * effect they produce are carried out. The arguments to the commands
@@ -44,14 +26,14 @@
  * If you want to handle multiple words as one, enclose them in double-quotes
  * eg. 'say "hello sexy boy"'
  */
-typedef bool (IConsoleCmdProc)(byte argc, char *argv[]);
-
+typedef bool IConsoleCmdProc(byte argc, char *argv[]);
+typedef bool IConsoleHook();
 struct IConsoleCmd {
 	char *name;               ///< name of command
 	IConsoleCmd *next;        ///< next command in list
 
 	IConsoleCmdProc *proc;    ///< process executed when command is typed
-	IConsoleHooks hook;       ///< any special trigger action that needs executing
+	IConsoleHook *hook;       ///< any special trigger action that needs executing
 };
 
 /** --Aliases--
@@ -80,7 +62,7 @@
 void IConsoleClearBuffer();
 
 /* Commands */
-void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc);
+void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc, IConsoleHook *hook = NULL);
 void IConsoleAliasRegister(const char *name, const char *cmd);
 IConsoleCmd *IConsoleCmdGet(const char *name);
 IConsoleAlias *IConsoleAliasGet(const char *name);
@@ -88,9 +70,6 @@
 /* console std lib (register ingame commands/aliases) */
 void IConsoleStdLibRegister();
 
-/* Hooking code */
-void IConsoleCmdHookAdd(const char *name, IConsoleHookTypes type, IConsoleHook *proc);
-
 /* Supporting functions */
 bool GetArgumentInteger(uint32 *value, const char *arg);