]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Commands: use registry
authorTimePath <andrew.hardaker1995@gmail.com>
Fri, 9 Oct 2015 11:03:03 +0000 (22:03 +1100)
committerTimePath <andrew.hardaker1995@gmail.com>
Fri, 9 Oct 2015 11:03:03 +0000 (22:03 +1100)
qcsrc/common/command/all.qh
qcsrc/common/command/command.qh
qcsrc/common/command/generic.qc
qcsrc/lib/registry.qh

index 7eeb5c3233a5e77ea532206c948d7b4630c29e21..253dc857b598cc8f2d9f77e6282b99fccf0ac193 100644 (file)
@@ -1,6 +1,19 @@
 #ifndef COMMON_COMMANDS_ALL_H
 #define COMMON_COMMANDS_ALL_H
 
+#include "command.qh"
+REGISTRY(GENERIC_COMMANDS, 50)
+REGISTER_REGISTRY(RegisterGENERIC_COMMANDS)
+REGISTRY_SORT(GENERIC_COMMANDS, m_name, 0)
+
+#define GENERIC_COMMAND(id, description) \
+       CLASS(genericcommand_##id, Command) \
+               ATTRIB(genericcommand_##id, m_name, string, #id); \
+       ATTRIB(genericcommand_##id, m_description, string, description); \
+       ENDCLASS(genericcommand_##id) \
+    REGISTER(RegisterGENERIC_COMMANDS, CMD_G, GENERIC_COMMANDS, id, m_id, NEW(genericcommand_##id)); \
+       METHOD(genericcommand_##id, m_invokecmd, void(int request, int arguments, string command))
+
 #include "generic.qh"
 #include "markup.qh"
 #include "rpn.qh"
index fa310fdfc56ca780ff989965d708ff8c8d7739d3..31909549a68f82d1d39bfc348601961ab1ca8a48 100644 (file)
@@ -1,12 +1,13 @@
 #ifndef COMMAND_H
 #define COMMAND_H
 
-// =========================================================
-//  Shared declarations for all commands, written by Samual
-//  Last updated: December 13th, 2011
-// =========================================================
-
-// identifiers for subfunction requests by the command code structure
 const int CMD_REQUEST_COMMAND = 1;
 const int CMD_REQUEST_USAGE = 2;
+
+CLASS(Command, Object)
+       ATTRIB(Command, m_name, string, string_null);
+       ATTRIB(Command, m_description, string, string_null);
+       METHOD(Command, m_invokecmd, void(int request, int arguments, string command)) { }
+ENDCLASS(Command)
+
 #endif
index 20826f64e21f74853743cd7e757da8a3f4031552..0c6380cfa18567e61d3273aaefcc335051ee1dad 100644 (file)
@@ -1,5 +1,4 @@
-#include "command.qh"
-#include "generic.qh"
+#include "all.qh"
 
 #include "markup.qh"
 #include "rpn.qh"
@@ -757,72 +756,52 @@ void GenericCommand_(float request)
 }
 */
 
-// ==================================
-//  Macro system for server commands
-// ==================================
-
 // Do not hard code aliases for these, instead create them in commands.cfg... also: keep in alphabetical order, please ;)
-#define GENERIC_COMMANDS(request,arguments,command) \
-       GENERIC_COMMAND("addtolist", GenericCommand_addtolist(request, arguments), "Add a string to a cvar") \
-       GENERIC_COMMAND("dumpcommands", GenericCommand_dumpcommands(request), "Dump all commands on the program to *_cmd_dump.txt") \
-       GENERIC_COMMAND("dumpeffectinfo", GenericCommand_dumpeffectinfo(request), "Dump all effectinfo to effectinfo_dump.txt") \
-       GENERIC_COMMAND("dumpitems", GenericCommand_dumpitems(request), "Dump all items to the console") \
-       GENERIC_COMMAND("dumpnotifs", GenericCommand_dumpnotifs(request), "Dump all notifications into notifications_dump.txt") \
-       GENERIC_COMMAND("dumpturrets", GenericCommand_dumpturrets(request), "Dump all turrets into turrets_dump.txt") \
-       GENERIC_COMMAND("dumpweapons", GenericCommand_dumpweapons(request), "Dump all weapons into weapons_dump.txt") \
-       GENERIC_COMMAND("maplist", GenericCommand_maplist(request, arguments), "Automatic control of maplist") \
-       GENERIC_COMMAND("nextframe", GenericCommand_nextframe(request, arguments, command), "Execute the given command next frame of this VM") \
-       GENERIC_COMMAND("qc_curl", GenericCommand_qc_curl(request, arguments), "Queries a URL") \
-       GENERIC_COMMAND("removefromlist", GenericCommand_removefromlist(request, arguments), "Remove a string from a cvar") \
-       GENERIC_COMMAND("restartnotifs", GenericCommand_restartnotifs(request), "Re-initialize all notifications") \
-       GENERIC_COMMAND("rpn", GenericCommand_rpn(request, arguments, command), "RPN calculator") \
-       GENERIC_COMMAND("settemp", GenericCommand_settemp(request, arguments), "Temporarily set a value to a cvar which is restored later") \
-       GENERIC_COMMAND("settemp_restore", GenericCommand_settemp_restore(request, arguments), "Restore all cvars set by settemp command") \
-       GENERIC_COMMAND("runtest", GenericCommand_runtest(request, arguments), "Run unit tests") \
-       /* nothing */
+GENERIC_COMMAND(addtolist, "Add a string to a cvar") { GenericCommand_addtolist(request, arguments); }
+GENERIC_COMMAND(dumpcommands, "Dump all commands on the program to *_cmd_dump.txt") { GenericCommand_dumpcommands(request); }
+GENERIC_COMMAND(dumpeffectinfo, "Dump all effectinfo to effectinfo_dump.txt") { GenericCommand_dumpeffectinfo(request); }
+GENERIC_COMMAND(dumpitems, "Dump all items to the console") { GenericCommand_dumpitems(request); }
+GENERIC_COMMAND(dumpnotifs, "Dump all notifications into notifications_dump.txt") { GenericCommand_dumpnotifs(request); }
+GENERIC_COMMAND(dumpturrets, "Dump all turrets into turrets_dump.txt") { GenericCommand_dumpturrets(request); }
+GENERIC_COMMAND(dumpweapons, "Dump all weapons into weapons_dump.txt") { GenericCommand_dumpweapons(request); }
+GENERIC_COMMAND(maplist, "Automatic control of maplist") { GenericCommand_maplist(request, arguments); }
+GENERIC_COMMAND(nextframe, "Execute the given command next frame of this VM") { GenericCommand_nextframe(request, arguments, command); }
+GENERIC_COMMAND(qc_curl, "Queries a URL") { GenericCommand_qc_curl(request, arguments); }
+GENERIC_COMMAND(removefromlist, "Remove a string from a cvar") { GenericCommand_removefromlist(request, arguments); }
+GENERIC_COMMAND(restartnotifs, "Re-initialize all notifications") { GenericCommand_restartnotifs(request); }
+GENERIC_COMMAND(rpn, "RPN calculator") { GenericCommand_rpn(request, arguments, command); }
+GENERIC_COMMAND(settemp, "Temporarily set a value to a cvar which is restored later") { GenericCommand_settemp(request, arguments); }
+GENERIC_COMMAND(settemp_restore, "Restore all cvars set by settemp command") { GenericCommand_settemp_restore(request, arguments); }
+GENERIC_COMMAND(runtest, "Run unit tests") { GenericCommand_runtest(request, arguments); }
 
 void GenericCommand_macro_help()
 {
-       #define GENERIC_COMMAND(name,function,description) \
-               { LOG_INFO("  ^2", name, "^7: ", description, "\n"); }
-
-       GENERIC_COMMANDS(0, 0, "");
-       #undef GENERIC_COMMAND
-
-       return;
+       FOREACH(GENERIC_COMMANDS, true, LAMBDA(LOG_INFOF("  ^2%s^7: %s\n", it.m_name, it.m_description)));
 }
 
 float GenericCommand_macro_command(float argc, string command)
 {
-       #define GENERIC_COMMAND(name,function,description) \
-               { if(name == strtolower(argv(0))) { function; return true; } }
-
-       GENERIC_COMMANDS(CMD_REQUEST_COMMAND, argc, command);
-       #undef GENERIC_COMMAND
-
+       string c = strtolower(argv(0));
+       FOREACH(GENERIC_COMMANDS, it.m_name == c, LAMBDA(
+               it.m_invokecmd(CMD_REQUEST_COMMAND, argc, command);
+               return true;
+       ));
        return false;
 }
 
 float GenericCommand_macro_usage(float argc)
 {
-       #define GENERIC_COMMAND(name,function,description) \
-               { if(name == strtolower(argv(1))) { function; return true; } }
-
-       GENERIC_COMMANDS(CMD_REQUEST_USAGE, argc, "");
-       #undef GENERIC_COMMAND
-
+       string c = strtolower(argv(1));
+       FOREACH(GENERIC_COMMANDS, it.m_name == c, LAMBDA(
+               it.m_invokecmd(CMD_REQUEST_USAGE, argc, "");
+               return true;
+       ));
        return false;
 }
 
 void GenericCommand_macro_write_aliases(float fh)
 {
-       #define GENERIC_COMMAND(name,function,description) \
-               { CMD_Write_Alias("qc_cmd_svmenu", name, description); }
-
-       GENERIC_COMMANDS(0, 0, "");
-       #undef GENERIC_COMMAND
-
-       return;
+       FOREACH(GENERIC_COMMANDS, true, LAMBDA(CMD_Write_Alias("qc_cmd_svmenu", it.m_name, it.m_description)));
 }
 
 
index 688a711912cd1e43694b1856d03a0493b09c10b5..4c39a9dec6e59379f719e24b865857e9503c5ebe 100644 (file)
  * @param fld       The field to store the current count into
  * @param inst      An expression to create a new instance, invoked for every registration
  */
-#define REGISTER(initfunc, ns, array, id, fld, inst)            \
-    entity ns##_##id;                                           \
-    REGISTER_INIT(ns, id) { }                                   \
-    REGISTER_INIT_POST(ns, id) { }                              \
-    .entity enemy; /* internal next pointer */                  \
-    void Register_##ns##_##id() {                               \
+#define REGISTER(initfunc, ns, array, id, fld, inst)                \
+    entity ns##_##id;                                               \
+    REGISTER_INIT(ns, id) { }                                       \
+    REGISTER_INIT_POST(ns, id) { }                                  \
+    void Register_##ns##_##id() {                                   \
         if (array##_COUNT >= array##_MAX) LOG_FATALF("Registry capacity exceeded (%s)", ftos(array##_MAX)); \
-        entity this = inst;                                     \
-        ns##_##id = this;                                       \
-        this.fld = array##_COUNT;                               \
-        array[array##_COUNT++] = this;                          \
-        if (!array##_first)    array##_first = this;            \
-        if ( array##_last)     array##_last.enemy = this;       \
-        array##_last = this;                                    \
-        Register_##ns##_##id##_init(this);                      \
-        Register_##ns##_##id##_init_post(this);                 \
-    }                                                           \
-    ACCUMULATE_FUNCTION(initfunc, Register_##ns##_##id)         \
+        entity this = inst;                                         \
+        ns##_##id = this;                                           \
+        this.fld = array##_COUNT;                                   \
+        array[array##_COUNT++] = this;                              \
+        if (!array##_first)    array##_first = this;                \
+        if ( array##_last)     array##_last.REGISTRY_NEXT = this;   \
+        array##_last = this;                                        \
+        Register_##ns##_##id##_init(this);                          \
+        Register_##ns##_##id##_init_post(this);                     \
+    }                                                               \
+    ACCUMULATE_FUNCTION(initfunc, Register_##ns##_##id)             \
     REGISTER_INIT(ns, id)
 
-#define REGISTRY_SORT(id, field, skip)                          \
-    void _REGISTRY_SWAP_##id(int i, int j, entity pass) {       \
-        i += skip; j += skip;                                   \
-        entity e = id[i];                                       \
-        id[i] = id[j];                                          \
-        id[j] = e;                                              \
-    }                                                           \
-    float _REGISTRY_CMP_##id(int i, int j, entity pass) {       \
-        i += skip; j += skip;                                   \
-        string a = id[i].field;                                 \
-        string b = id[j].field;                                 \
-        return strcasecmp(a, b);                                \
-    }                                                           \
-    STATIC_INIT(Registry_sort_##id) {                           \
+/** internal next pointer */
+#define REGISTRY_NEXT enemy
+.entity REGISTRY_NEXT;
+
+#define REGISTRY_SORT(id, field, skip)                              \
+    void _REGISTRY_SWAP_##id(int i, int j, entity pass) {           \
+        i += skip; j += skip;                                       \
+                                                                    \
+        entity a = id[i], b = id[j];                                \
+        id[i] = b;                                                  \
+        id[j] = a;                                                  \
+                                                                    \
+        entity a_next = a.REGISTRY_NEXT, b_next = b.REGISTRY_NEXT;  \
+        a.REGISTRY_NEXT = b_next;                                   \
+        b.REGISTRY_NEXT = a_next;                                   \
+                                                                    \
+        if (i == 0) id##_first = b;                                 \
+        else id[i - 1].REGISTRY_NEXT = b;                           \
+                                                                    \
+        if (j == 0) id##_first = a;                                 \
+        else id[j - 1].REGISTRY_NEXT = a;                           \
+    }                                                               \
+    float _REGISTRY_CMP_##id(int i, int j, entity pass) {           \
+        i += skip; j += skip;                                       \
+        string a = id[i].field;                                     \
+        string b = id[j].field;                                     \
+        return strcasecmp(a, b);                                    \
+    }                                                               \
+    STATIC_INIT(Registry_sort_##id) {                               \
         heapsort(id##_COUNT - (skip), _REGISTRY_SWAP_##id, _REGISTRY_CMP_##id, NULL); \
     }