void CSQC_Ent_Update(bool isnew)
{
SELFPARAM();
- this.sourceLocLine = __LINE__;
- this.sourceLocFile = __FILE__;
+ this.sourceLoc = __FILE__ ":" STR(__LINE__);
int t = ReadByte();
// set up the "time" global for received entities to be correct for interpolation purposes
setorigin(this, this.origin);
this.debug = true; // identify server entities by this
this.classname = strzone(ReadString());
- this.sourceLocFile = strzone(ReadString());
- this.sourceLocLine = ReadInt24_t();
+ this.sourceLoc = strzone(ReadString());
return true;
}
#endif
WriteCoord(channel, this.origin.y);
WriteCoord(channel, this.origin.z);
WriteString(channel, this.classname);
- WriteString(channel, this.sourceLocFile);
- WriteInt24_t(channel, this.sourceLocLine);
+ WriteString(channel, this.sourceLoc);
return true;
}
#endif
pos.z = 0;
pos.y += ofs * sz;
drawcolorcodedstring2(pos,
- sprintf("%d: '%s'@%s:%d", (e.debug ? e.sv_entnum : etof(e)),
- e.classname, e.sourceLocFile, e.sourceLocLine),
+ sprintf("%d: '%s'@%s", (e.debug ? e.sv_entnum : etof(e)),
+ e.classname, e.sourceLoc),
sz * '1 1 0', rgb, 0.5, DRAWFLAG_NORMAL);
++ofs;
}
-#define EFFECTINFO_PARSER(on) \
+#define EFFECTINFO_PARSER(on, MY) \
on(type, MY(type) \
,{ demand(n == 1 && "type"); MY(type) = strzone(argv(1)); \
}, sprintf(" %s", (MY(type)) \
#define p(f, type, default) if (this.effectinfo_##f) { s = strcat(s, "\t", "MY("#f") = ", str_##type(this.effectinfo_##f), ";\n"); }
FIELDS(p)
#undef p
- #undef MY
return strcat(s, "}\n");
}
string s = sprintf("effect %s\n", this.effectinfo_name);
#define MY(f) this.effectinfo_##f
#define p(k, isset, parse, unparse) if (isset) { s = strcat(s, "\t", #k, unparse, "\n"); }
- EFFECTINFO_PARSER(p)
+ EFFECTINFO_PARSER(p, MY)
#undef p
#undef MY
return s;
switch (k) {
#define MY(f) info.effectinfo_##f
#define p(k, isset, parse, unparse) case #k: parse break;
- EFFECTINFO_PARSER(p)
+ EFFECTINFO_PARSER(p, MY)
#undef p
#undef MY
default:
return ret; \
} \
[[accumulate]] void RegisterHooks() { HOOK_##id = NEW(CallbackChain, #id); }
-#define MUTATOR_CALLHOOK(id, ...) APPLY(__Mutator_Send_##id, 0, ##__VA_ARGS__)
+#ifdef __STDC__
+ #define MUTATOR_CALLHOOK(id, ...) APPLY(__Mutator_Send_##id, 0 P99_IF_EMPTY(__VA_ARGS__)()(, __VA_ARGS__))
+#else
+ #define MUTATOR_CALLHOOK(id, ...) APPLY(__Mutator_Send_##id, 0, ##__VA_ARGS__)
+#endif
enum {
MUTATOR_REMOVING,
#define EVAL4(...) EVAL5(EVAL5(EVAL5(__VA_ARGS__)))
#define EVAL5(...) __VA_ARGS__
- #define OVERLOAD___(F, _16, _15, _14, _13, _12, _11, _10, _9, _8, _7, _6, _5, _4, _3, _2, _1, n, ...) F##_##n
- #define OVERLOAD__(F, ...) OVERLOAD___(F,##__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
- #define OVERLOAD_(...) DEFER(OVERLOAD__(__VA_ARGS__))
- #define OVERLOAD(F, ...) OVERLOAD_(F,##__VA_ARGS__)(__VA_ARGS__)
+ #include "p99.qh"
+ #define OVERLOAD(F, ...) P99_IF_EMPTY(__VA_ARGS__)(P99_PASTE2(F, _00)())(P99_PASTE3(F, _, P00_NARG(__VA_ARGS__))(__VA_ARGS__))
+ #define OVERLOAD_(F, ...) P99_IF_EMPTY(__VA_ARGS__)(P99_PASTE2(F, _00)())(P99_PASTE3(F, _, P00_NARG(__VA_ARGS__))(__VA_ARGS__))
#else
#define EVAL(...) __VA_ARGS__
[[accumulate]] NET_HANDLE(id, bool isnew) \
{ \
this = self; \
- this.sourceLocFile = __FILE__; \
- this.sourceLocLine = __LINE__; \
+ this.sourceLoc = __FILE__ ":" STR(__LINE__); \
if (!this) isnew = true; \
} \
REGISTER(LinkedEntities, NET, id, m_id, new_pure(net_linked_packet)) \
.string classname;
/** Location entity was spawned from in source */
-.string sourceLocFile;
-.int sourceLocLine;
+.string sourceLoc;
entity _spawn();
#ifndef SPAWN_PURE
#define spawn_pure() _spawn()
#endif
-entity __spawn(string _classname, string _sourceFile, int _sourceLine, bool pure)
+entity __spawn(string _classname, string _sourceLoc, bool pure)
{
entity this = pure ? spawn_pure() : _spawn();
this.classname = _classname;
- this.sourceLocFile = _sourceFile;
- this.sourceLocLine = _sourceLine;
+ this.sourceLoc = _sourceLoc;
if (pure) {
make_pure(this);
#ifdef CSQC
}
-#define entityclass(...) EVAL_entityclass(OVERLOAD(entityclass, __VA_ARGS__))
+#define entityclass(...) EVAL_entityclass(OVERLOAD_(entityclass, __VA_ARGS__))
#define EVAL_entityclass(...) __VA_ARGS__
#define entityclass_1(name) entityclass_2(name, Object)
#ifndef QCC_SUPPORT_ENTITYCLASS
#define entityclass_2(name, base) typedef entity name
#define class(name)
- #define _new(class, pure) __spawn( #class, __FILE__, __LINE__, pure)
+ #define _new(class, pure) __spawn( #class, __FILE__ ":" STR(__LINE__), pure)
#else
#define entityclass_2(name, base) entityclass name : base {}
#define class(name) [[class(name)]]
- #define _new(class, pure) ((class) __spawn( #class, __FILE__, __LINE__, pure))
+ #define _new(class, pure) ((class) __spawn( #class, __FILE__ ":" STR(__LINE__), pure))
#endif
/** entities you care about seeing (.origin works) */
#define new(class) _new(class, false)
/** purely logical entities (.origin doesn't work) */
#define new_pure(class) _new(class, true)
-#define spawn() __spawn("entity", __FILE__, __LINE__, false)
+#define spawn() __spawn("entity", __FILE__ ":" STR(__LINE__), false)
entity _clearentity_ent;
STATIC_INIT(clearentity)
// Macros to hide this implementation detail:
#ifdef __STDC__
- #define NEW_(cname, ...) \
- OVERLOAD_(spawn##cname, __VA_ARGS__)
#define NEW(cname, ...) \
- NEW_(cname, new_pure(cname),##__VA_ARGS__)(new_pure(cname),##__VA_ARGS__)
-
- #define CONSTRUCT_(cname, ...) \
- OVERLOAD_(spawn##cname, __VA_ARGS__)
+ OVERLOAD_(spawn##cname, new_pure(cname) P99_IF_EMPTY(__VA_ARGS__)()(, __VA_ARGS__))
#define CONSTRUCT(cname, ...) \
- CONSTRUCT_(cname, this,##__VA_ARGS__)(this,##__VA_ARGS__)
+ OVERLOAD_(spawn##cname, this P99_IF_EMPTY(__VA_ARGS__)()(, __VA_ARGS__))
#else
#define NEW(cname, ...) \
OVERLOAD(spawn##cname, new_pure(cname),##__VA_ARGS__)
--- /dev/null
+/* This may look like nonsense, but it really is -*- mode: C -*- */
+/* */
+/* Except for parts copied from previous work and as explicitly stated below, */
+/* the authors and copyright holders for this work are as follows: */
+/* (C) copyright 2010-2013 Jens Gustedt, INRIA, France */
+/* (C) copyright 2013 Pierre-Nicolas Clauss */
+/* (C) copyright 2012 William Morris */
+/* */
+/* This file is free software; it is part of the P99 project. */
+/* You can redistribute it and/or modify it under the terms of the QPL as */
+/* given in the file LICENSE. It is distributed without any warranty; */
+/* without even the implied warranty of merchantability or fitness for a */
+/* particular purpose. */
+/* */
+#ifndef P99_H_
+#define P99_H_
+
+#define P99_MAX_NUMBER 16
+#define P00_ARG( \
+ _01, _02, _03, _04, _05, _06, _07, _08, \
+ _09, _10, _11, _12, _13, _14, _15, _16, \
+ _00, ...) _00
+#define P00_NARG(...) P00_ARG(__VA_ARGS__, \
+ 16, 15, 14, 13, 12, 11, 10, 9, \
+ 8, 7, 6, 5, 4, 3, 2, 1, \
+ 0, )
+#define P99_HAS_COMMA(...) P00_ARG(__VA_ARGS__, \
+ 1, 1, 1, 1, 1, 1, 1, 1, \
+ 1, 1, 1, 1, 1, 1, 1, 0, \
+ 0)
+
+#define P99_IF_EMPTY(...) P99_IF_EQ(1, P99_IS_EMPTY(__VA_ARGS__))
+ // P99_HAS_COMMA(__VA_ARGS__), : test if there is just one argument, that might be empty
+ // P99_HAS_COMMA(P00_IS__EQ__ __VA_ARGS__), : test if P99_IS__EQ__ together with the argument adds a comma
+ // P99_HAS_COMMA(__VA_ARGS__ (/*empty*/)), : test if the argument together with a parenthesis adds a comma
+ // P99_HAS_COMMA(P00_IS__EQ__ __VA_ARGS__ (/*empty*/)) : test if placing it between P99_IS__EQ__ and the parenthesis adds a comma
+ #define P99_IS_EMPTY(...) \
+ P00_ISEMPTY( \
+ P99_HAS_COMMA(__VA_ARGS__), \
+ P99_HAS_COMMA(P00_IS__EQ__ __VA_ARGS__), \
+ P99_HAS_COMMA(__VA_ARGS__ (/*empty*/)), \
+ P99_HAS_COMMA(P00_IS__EQ__ __VA_ARGS__ (/*empty*/)) \
+ )
+ #define P00_IS__EQ__(...) ,
+ #define P00_ISEMPTY(_1, _2, _3, _4) P99_HAS_COMMA(P99_PASTE5(P00_IS_EMPTY_CASE_, _1, _2, _3, _4))
+ #define P00_IS_EMPTY_CASE_0000 P00_IS_EMPTY_CASE_0000
+ #define P00_IS_EMPTY_CASE_0001 ,
+ #define P00_IS_EMPTY_CASE_0010 P00_IS_EMPTY_CASE_0010
+ #define P00_IS_EMPTY_CASE_0011 P00_IS_EMPTY_CASE_0011
+ #define P00_IS_EMPTY_CASE_0100 P00_IS_EMPTY_CASE_0100
+ #define P00_IS_EMPTY_CASE_0101 P00_IS_EMPTY_CASE_0101
+ #define P00_IS_EMPTY_CASE_0110 P00_IS_EMPTY_CASE_0110
+ #define P00_IS_EMPTY_CASE_0111 P00_IS_EMPTY_CASE_0111
+ #define P00_IS_EMPTY_CASE_1000 P00_IS_EMPTY_CASE_1000
+ #define P00_IS_EMPTY_CASE_1001 P00_IS_EMPTY_CASE_1001
+ #define P00_IS_EMPTY_CASE_1010 P00_IS_EMPTY_CASE_1010
+ #define P00_IS_EMPTY_CASE_1011 P00_IS_EMPTY_CASE_1011
+ #define P00_IS_EMPTY_CASE_1100 P00_IS_EMPTY_CASE_1100
+ #define P00_IS_EMPTY_CASE_1101 P00_IS_EMPTY_CASE_1101
+ #define P00_IS_EMPTY_CASE_1110 P00_IS_EMPTY_CASE_1110
+ #define P00_IS_EMPTY_CASE_1111 P00_IS_EMPTY_CASE_1111
+
+
+#define P00_IF_CLAUSE(EXP) P00__IF_CLAUSE(EXP, P00_CLAUSE1, P00_CLAUSE2, ~)
+ #define P00__IF_CLAUSE(A, B, C, ...) C
+ #define P00_CLAUSE1(...) __VA_ARGS__ P00_IGNORE
+ #define P00_IGNORE(...)
+ #define P00_CLAUSE2(...) P00_IDENT
+ #define P00_IDENT(...) __VA_ARGS__
+
+
+#define P99_IF_EQ(A, B) P00_IF_CLAUSE(P99_PASTE4(P00_IS_, A, _EQ_, B)())
+ #define P00_IS_0_EQ_0(...) ,
+ #define P00_IS_1_EQ_1(...) ,
+
+
+#define P99_CAT2(_1, _2) _1 ## _2
+#define P99_PASTE2(_1, _2) \
+ P99_CAT2(_1, _2)
+#define P99_PASTE3(_1, _2, _3) \
+ P99_PASTE2(P99_PASTE2(_1, _2), _3)
+#define P99_PASTE4(_1, _2, _3, _4) \
+ P99_PASTE2(P99_PASTE3(_1, _2, _3), _4)
+#define P99_PASTE5(_1, _2, _3, _4, _5) \
+ P99_PASTE2(P99_PASTE4(_1, _2, _3, _4), _5)
+
+#endif /* !P99_H_ */
* @param fld The field to store the locally unique unique entity id
* @param inst An expression to create a new instance, invoked for every registration
*/
-#define REGISTER(...) EVAL_REGISTER(OVERLOAD(REGISTER, __VA_ARGS__))
+#define REGISTER(...) EVAL_REGISTER(OVERLOAD_(REGISTER, __VA_ARGS__))
#define EVAL_REGISTER(...) __VA_ARGS__
#define REGISTER_5(registry, ns, id, fld, inst) REGISTER_4(registry, ns##_##id, fld, inst)
#define REGISTER_4(registry, id, fld, inst) \
REGISTER_INIT_POST(id) {} \
void Register_##id() \
{ \
- if (registry##_COUNT >= registry##_MAX) LOG_FATALF("Registry capacity exceeded (%s)", ftos(registry##_MAX)); \
+ if (registry##_COUNT >= registry##_MAX) LOG_FATALF("Registry capacity exceeded (%d)", registry##_MAX); \
entity this = id = inst; \
this.registered_id = #id; \
REGISTRY_PUSH(registry, fld, this); \
{ \
assert(this); \
} \
- if (!this.sourceLocFile) \
+ if (!this.sourceLoc) \
{ \
- this.sourceLocFile = __FILE__; \
- this.sourceLocLine = __LINE__; \
+ this.sourceLoc = __FILE__ ":" STR(__LINE__); \
} \
if (!this.spawnfunc_checked) \
{ \
#define FIELDS_COMMON(fld) \
FIELD_SCALAR(fld, classname) \
- FIELD_SCALAR(fld, sourceLocFile) \
- FIELD_SCALAR(fld, sourceLocLine) \
+ FIELD_SCALAR(fld, sourceLoc) \
FIELD_SCALAR(fld, spawnfunc_checked) \
FIELD_VEC(fld, origin) \
/**/
#define vec2(v) (_vec2 = (v), _vec2.z = 0, _vec2)
noref vector _vec3;
-#define vec3(x, y, z) (_vec3_x = (x), _vec3_y = (y), _vec3_z = (z), _vec3)
+#define vec3(_x, _y, _z) (_vec3.x = (_x), _vec3.y = (_y), _vec3.z = (_z), _vec3)
vector rotate(vector v, float a)
{