From: TimePath <andrew.hardaker1995@gmail.com>
Date: Tue, 22 Mar 2016 04:15:34 +0000 (+1100)
Subject: Type check macros
X-Git-Tag: xonotic-v0.8.2~1059
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=0b9cb8f9cc92a3da16661c358fbc6f0f32e627fa;p=xonotic%2Fxonotic-data.pk3dir.git

Type check macros
---

diff --git a/qcsrc/common/state.qh b/qcsrc/common/state.qh
index 64ae3e7fe..90c7029e3 100644
--- a/qcsrc/common/state.qh
+++ b/qcsrc/common/state.qh
@@ -24,11 +24,7 @@ CLASS(PlayerState, Object)
 ENDCLASS(PlayerState)
 
 .PlayerState _ps;
-#if NDEBUG
-	#define PS(this) (this._ps)
-#else
-	PlayerState PS(entity this) { assert(IS_CLIENT(this)); return this._ps; }
-#endif
+#define PS(this) (this._ps)
 
 // TODO: renew on death
 void PlayerState_attach(entity this);
diff --git a/qcsrc/lib/_all.inc b/qcsrc/lib/_all.inc
index 9aaf52449..212ba4a5d 100644
--- a/qcsrc/lib/_all.inc
+++ b/qcsrc/lib/_all.inc
@@ -25,15 +25,28 @@
 	#include <dpdefs/keycodes.qh>
 #endif
 
+#include "bool.qh"
+#include "int.qh"
+
 #include "macro.qh"
 
+#ifndef NDEBUG
+    #define TC(T, sym) MACRO_BEGIN \
+        if (!is_##T(sym)) LOG_WARNINGF("Type check failed: " #sym " :: " #T); \
+    MACRO_END
+#else
+    #define TC(T, sym) MACRO_BEGIN MACRO_END
+#endif
+
+bool is_int(float f) { return f == f | 0; }
+bool is_bool(float f) { return f == true || f == false; }
+
 #include "warpzone/mathlib.qc"
 
 #include "accumulate.qh"
 #include "angle.qc"
 #include "arraylist.qh"
 #include "bits.qh"
-#include "bool.qh"
 #include "color.qh"
 #include "counting.qh"
 #include "cvar.qh"
@@ -43,7 +56,6 @@
 #include "file.qh"
 #include "functional.qh"
 #include "i18n.qh"
-#include "int.qh"
 #include "iter.qh"
 #include "lazy.qh"
 #include "linkedlist.qh"
diff --git a/qcsrc/lib/oo.qh b/qcsrc/lib/oo.qh
index 0638c932b..637dbe924 100644
--- a/qcsrc/lib/oo.qh
+++ b/qcsrc/lib/oo.qh
@@ -155,6 +155,7 @@ STATIC_INIT(RegisterClasses)
 #define CLASS(cname, base)                  \
 	entityclass(cname, base);               \
 	class(cname).bool instanceOf##cname;   \
+    bool is_##cname(entity e) { return e.instanceOf##cname; } \
 	VTBL(cname, base)                       \
 	INIT_STATIC(cname) \
 	{                    \
diff --git a/qcsrc/server/_all.qh b/qcsrc/server/_all.qh
index c43605435..f12a715aa 100644
--- a/qcsrc/server/_all.qh
+++ b/qcsrc/server/_all.qh
@@ -11,6 +11,7 @@ const string STR_OBSERVER = "observer";
 #define IS_OBSERVER(v) ((v).classname == STR_OBSERVER)
 
 #define IS_CLIENT(v) (v.flags & FL_CLIENT)
+#define is_client IS_CLIENT
 #define IS_BOT_CLIENT(v) (clienttype(v) == CLIENTTYPE_BOT)
 #define IS_REAL_CLIENT(v) (clienttype(v) == CLIENTTYPE_REAL)
 #define IS_NOT_A_CLIENT(v) (clienttype(v) == CLIENTTYPE_NOTACLIENT)
diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc
index 34800eaff..532868884 100644
--- a/qcsrc/server/cl_client.qc
+++ b/qcsrc/server/cl_client.qc
@@ -1540,6 +1540,8 @@ spectate mode routines
 
 void SpectateCopy(entity this, entity spectatee)
 {
+    TC(Client, this); TC(Client, spectatee);
+
 	MUTATOR_CALLHOOK(SpectateCopy, spectatee, this);
 	PS(this) = PS(spectatee);
 	this.armortype = spectatee.armortype;