]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/lib/replicate.qh
Merge branch 'master' into Mario/stats_eloranking
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / replicate.qh
index 6ff77139f83e76f05f089edd397d137592535c10..a88bde462934134f3585707eff76e81303e8d6c2 100644 (file)
@@ -1,49 +1,95 @@
-#ifndef REPLICATE_H
-#define REPLICATE_H
-#ifndef MENUQC
-
-#define REPLICATE(...) EVAL(OVERLOAD(REPLICATE, __VA_ARGS__))
-
-[[accumulate]] void ReplicateVars(entity this, string thisname, int i) { }
-
-#define REPLICATE_3(fld, type, var)         REPLICATE_4(fld, type, var, )
-#define REPLICATE_4(fld, type, var, func)   REPLICATE_##type(fld, var, func)
-#define REPLICATE_string(fld, var, func)    REPLICATE_7(fld, string, var, , \
-    { if (field) strunzone(field); field = strzone(it); }, \
-    { if (field) strunzone(field); field = string_null; }, \
-    { \
-        /* also initialize to the default value of func when requesting cvars */ \
-        string s = func(field); \
-        if (s != field) { \
-            strunzone(field); \
-            field = strzone(s); \
-        } \
-    })
-#define REPLICATE_float(fld, var, func)     REPLICATE_7(fld, float, var, func,  { field = stof(it); },          , )
-#define REPLICATE_bool(fld, var, func)      REPLICATE_7(fld, bool, var, func,   { field = boolean(stoi(it)); }, , )
-#define REPLICATE_int(fld, var, func)       REPLICATE_7(fld, int, var, func,    { field = stoi(it); },          , )
-
-#if defined(SVQC)
-    #define REPLICATE_7(fld, type, var, func, create, destroy, after) \
-        void ReplicateVars(entity this, string thisname, int i) { \
-            type field = this.fld; \
-            if (i < 0) { destroy } \
-            else { \
-                string it = func(argv(i + 1)); \
-                bool current = thisname == var; \
-                if (i > 0) { \
-                    if (current) { create } \
-                } else { \
-                    stuffcmd(this, "cl_cmd sendcvar " var "\n"); \
-                } \
-                if (current) { after } \
-            } \
-            this.fld = field; \
-        }
-#elif defined(CSQC)
-    // TODO
-    #define REPLICATE_7(fld, type, var, func, create, destroy, after)
-#endif
+#pragma once
+
+#ifdef GAMEQC
+
+    /**
+     * Replicate a client cvar into a server field
+     *
+     * @param fld   The field to replicate into
+     * @param type  The field type
+     * @param cvar  The cvar name
+     */
+       #define REPLICATE(...) EVAL_REPLICATE(OVERLOAD(REPLICATE, __VA_ARGS__))
+       #define EVAL_REPLICATE(...) __VA_ARGS__
+
+       #if defined(SVQC)
+       ACCUMULATE void ReplicateVars(entity this, entity store, string thisname, int i) {}
+       #elif defined(CSQC)
+       ACCUMULATE void ReplicateVars(bool would_destroy) {}
+       #endif
+
+       #define REPLICATE_3(fld, type, var) REPLICATE_4(fld, type, var, )
+       #define REPLICATE_4(fld, type, var, func) REPLICATE_##type(fld, var, func)
+       #if defined(SVQC)
+               #define REPLICATE_string(fld, var, func) \
+                       REPLICATE_7(fld, string, var, , \
+               { strcpy(field, it); }, \
+               { strfree(field); }, \
+               { \
+                       /* also initialize to the default value of func when requesting cvars */ \
+                       string s = func(field); \
+                       if (s != field) \
+                       { \
+                               strcpy(field, s); \
+                       } \
+               })
+               #define REPLICATE_float(fld, var, func) REPLICATE_7(fld, float, var, func,  { field = stof(it); },          , )
+               #define REPLICATE_bool(fld, var, func) REPLICATE_7(fld, bool, var, func,   { field = boolean(stoi(it)); }, , )
+               #define REPLICATE_int(fld, var, func) REPLICATE_7(fld, int, var, func,    { field = stoi(it); },          , )
+
+               #define REPLICATE_7(fld, type, var, func, create, destroy, after) \
+                       void ReplicateVars(entity this, entity store, string thisname, int i) \
+                       { \
+                               type field = store.fld; \
+                               if (i < 0) { destroy } \
+                               else \
+                               { \
+                                       string it = func(argv(i + 1)); \
+                                       bool current = thisname == var; \
+                                       if (i > 0) \
+                                       { \
+                                               if (current) { create } \
+                                       } \
+                                       else \
+                                       { \
+                                               stuffcmd(this, strcat("cl_cmd sendcvar ", var, "\n")); \
+                                       } \
+                                       if (current) { after } \
+                               } \
+                               store.fld = field; \
+                       }
+       #elif defined(CSQC)
+               float ReplicateVars_time;
+               #define ReplicateVars_NOT_SENDING() (time > ReplicateVars_time)
+               #define ReplicateVars_DELAY(t) ReplicateVars_time = time + t
+               #define ReplicateVars_DELAY_1FRAME() ReplicateVars_time = time
+               #define REPLICATE_string(fld, var, func) REPLICATE_7(fld, float, var, func, (fld != cvar_string(var)), { strcpy(fld, cvar_string(var)); }, { strfree(fld); })
+               #define REPLICATE_float(fld, var, func) REPLICATE_7(fld, float, var, func, (fld != cvar(var)), { fld = cvar(var); }, )
+               #define REPLICATE_bool(fld, var, func) REPLICATE_7(fld, bool, var, func, (fld != cvar(var)), { fld = cvar(var); }, )
+               #define REPLICATE_int(fld, var, func) REPLICATE_7(fld, int, var, func, (fld != cvar(var)), { fld = cvar(var); }, )
+
+               #define REPLICATE_7(fld, type, var, func, check, update, destroy) \
+                       void ReplicateVars(bool would_destroy) \
+                       { \
+                               if (would_destroy) { destroy } \
+                               else if (ReplicateVars_NOT_SENDING() && check) \
+                               { \
+                                       localcmd(strcat("cl_cmd sendcvar ", var, "\n")); \
+                                       ReplicateVars_DELAY_1FRAME(); \
+                                       update \
+                                       return; \
+                               } \
+                       }
+
+               #define REPLICATE_SIMPLE(field, cvarname) MACRO_BEGIN \
+                       if (ReplicateVars_NOT_SENDING() && field != cvar(cvarname)) \
+                       { \
+                               localcmd(strcat("cl_cmd sendcvar ", cvarname, "\n")); \
+                               ReplicateVars_DELAY_1FRAME(); \
+                               field = cvar(cvarname); \
+                               return; \
+                       } \
+               MACRO_END
+       #endif
 
-#endif
 #endif