8 #define NULL (null_entity)
15 #define make_pure(e) \
18 (e).pure_data = true; \
21 #define is_pure(e) ((e).pure_data)
24 /** Location entity was spawned from in source */
25 .string sourceLocFile;
28 entity __spawn(string _classname, string _sourceFile, int _sourceLine, bool pure)
30 entity this = _spawn();
31 this.classname = _classname;
32 this.sourceLocFile = _sourceFile;
33 this.sourceLocLine = _sourceLine;
34 if (pure) make_pure(this);
39 #define entityclass(...) EVAL(OVERLOAD(entityclass, __VA_ARGS__))
40 #define entityclass_1(name) entityclass_2(name, Object)
41 #ifndef QCC_SUPPORT_ENTITYCLASS
42 #define entityclass_2(name, base) typedef entity name
44 #define new(class) __spawn( #class, __FILE__, __LINE__, false)
46 #define entityclass_2(name, base) entityclass name : base {}
47 #define class(name) [[class(name)]]
48 #define new(class) ((class) __spawn( #class, __FILE__, __LINE__, false))
50 #define spawn() __spawn("entity", __FILE__, __LINE__, false)
52 // Classes have a `spawn##cname(entity)` constructor
53 // The parameter is used across [[accumulate]] functions
55 // Macros to hide this implementation detail:
57 #define NEW(cname, ...) \
58 OVERLOAD(spawn##cname, new(cname),##__VA_ARGS__)
60 #define CONSTRUCT(cname, ...) \
61 OVERLOAD(spawn##cname, this,##__VA_ARGS__)
63 #define NEW_(cname, ...) \
64 OVERLOAD_(spawn##cname, __VA_ARGS__)
65 #define NEW(cname, ...) \
66 NEW_(cname, new(cname),##__VA_ARGS__)(new(cname),##__VA_ARGS__)
68 #define CONSTRUCT_(cname, ...) \
69 OVERLOAD_(spawn##cname, __VA_ARGS__)
70 #define CONSTRUCT(cname, ...) \
71 CONSTRUCT_(cname, this,##__VA_ARGS__)(this,##__VA_ARGS__)
74 #define CONSTRUCTOR(cname, ...) \
75 cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__) \
79 [[accumulate]] cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__)
84 void RegisterClasses() {}
85 STATIC_INIT(RegisterClasses)
90 #define VTBL(cname, base) \
92 entity cname##_vtbl; \
93 void cname##_vtbl_init() \
95 cname e = new(vtbl); \
97 spawn##cname##_static(e); \
98 e.vtblname = #cname; \
99 /* Top level objects refer to themselves */ \
100 e.vtblbase = base##_vtbl ? base##_vtbl : e; \
103 ACCUMULATE_FUNCTION(RegisterClasses, cname##_vtbl_init)
105 #define INIT_STATIC(cname) [[accumulate]] void spawn##cname##_static(cname this)
106 #define INIT(cname) [[accumulate]] cname spawn##cname##_1(cname this)
108 #define CLASS(cname, base) \
109 entityclass(cname, base); \
110 class(cname).bool instanceOf##cname; \
116 copyentity(cname##_vtbl, this); \
119 spawn##base##_static(this); \
120 this.instanceOf##cname = true; \
124 /* Only statically initialize the current class, it contains everything it inherits */ \
125 if (cname##_vtbl.vtblname == this.classname) \
127 spawn##cname##_static(this); \
128 this.classname = #cname; \
129 this.vtblname = string_null; \
130 this.vtblbase = cname##_vtbl; \
132 spawn##base##_1(this); \
135 #define METHOD(cname, name, prototype) \
136 class(cname).prototype name; \
137 prototype cname##_##name; \
140 this.name = cname##_##name; \
142 prototype cname##_##name
144 #define ATTRIB(cname, name, type, val) \
145 class(cname).type name; \
151 #define ATTRIBARRAY(cname, name, type, cnt) \
152 class(cname).type name[cnt];
154 #define ENDCLASS(cname) \
160 #define SUPER(cname) (cname##_vtbl.vtblbase)
162 #define spawn_static(this)
163 #define spawn_1(this)
166 METHOD(Object, describe, string(entity this))
168 string s = _("No description");
169 if (cvar("developer"))
171 for (int i = 0, n = numentityfields(); i < n; ++i)
173 string value = getentityfieldstring(i, this);
174 if (value != "") s = sprintf("%s\n%s = %s", s, entityfieldname(i), value);
179 METHOD(Object, display, void(entity this, void(string name, string icon) returns))
181 returns(sprintf("entity %i", this), "nopreview_map");