9 #define NULL (null_entity)
16 #define make_pure(e) \
19 (e).pure_data = true; \
22 #define make_impure(e) \
25 (e).pure_data = false; \
28 #define is_pure(e) ((e).pure_data)
31 /** Location entity was spawned from in source */
32 .string sourceLocFile;
35 entity __spawn(string _classname, string _sourceFile, int _sourceLine, bool pure)
37 entity this = _spawn();
38 this.classname = _classname;
39 this.sourceLocFile = _sourceFile;
40 this.sourceLocLine = _sourceLine;
41 if (pure) make_pure(this);
46 #define entityclass(...) EVAL(OVERLOAD(entityclass, __VA_ARGS__))
47 #define entityclass_1(name) entityclass_2(name, Object)
48 #ifndef QCC_SUPPORT_ENTITYCLASS
49 #define entityclass_2(name, base) typedef entity name
51 #define new(class) __spawn( #class, __FILE__, __LINE__, false)
53 #define entityclass_2(name, base) entityclass name : base {}
54 #define class(name) [[class(name)]]
55 #define new(class) ((class) __spawn( #class, __FILE__, __LINE__, false))
57 #define spawn() __spawn("entity", __FILE__, __LINE__, false)
59 entity _clearentity_ent;
60 STATIC_INIT(clearentity)
62 _clearentity_ent = new(clearentity);
63 make_pure(_clearentity_ent);
65 void clearentity(entity e)
70 bool was_pure = is_pure(e);
71 copyentity(_clearentity_ent, e);
72 if (!was_pure) make_impure(e);
78 // Classes have a `spawn##cname(entity)` constructor
79 // The parameter is used across [[accumulate]] functions
81 // Macros to hide this implementation detail:
83 #define NEW(cname, ...) \
84 OVERLOAD(spawn##cname, new(cname),##__VA_ARGS__)
86 #define CONSTRUCT(cname, ...) \
87 OVERLOAD(spawn##cname, this,##__VA_ARGS__)
89 #define NEW_(cname, ...) \
90 OVERLOAD_(spawn##cname, __VA_ARGS__)
91 #define NEW(cname, ...) \
92 NEW_(cname, new(cname),##__VA_ARGS__)(new(cname),##__VA_ARGS__)
94 #define CONSTRUCT_(cname, ...) \
95 OVERLOAD_(spawn##cname, __VA_ARGS__)
96 #define CONSTRUCT(cname, ...) \
97 CONSTRUCT_(cname, this,##__VA_ARGS__)(this,##__VA_ARGS__)
100 #define CONSTRUCTOR(cname, ...) \
101 cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__) \
105 [[accumulate]] cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__)
110 void RegisterClasses() {}
111 STATIC_INIT(RegisterClasses)
116 #define VTBL(cname, base) \
117 INIT_STATIC(cname); \
118 entity cname##_vtbl; \
119 void cname##_vtbl_init() \
121 cname e = new(vtbl); \
123 spawn##cname##_static(e); \
124 e.vtblname = #cname; \
125 /* Top level objects refer to themselves */ \
126 e.vtblbase = base##_vtbl ? base##_vtbl : e; \
129 ACCUMULATE_FUNCTION(RegisterClasses, cname##_vtbl_init)
131 #define INIT_STATIC(cname) [[accumulate]] void spawn##cname##_static(cname this)
132 #define INIT(cname) [[accumulate]] cname spawn##cname##_1(cname this)
134 #define CLASS(cname, base) \
135 entityclass(cname, base); \
136 class(cname).bool instanceOf##cname; \
142 copyentity(cname##_vtbl, this); \
145 spawn##base##_static(this); \
146 this.instanceOf##cname = true; \
150 /* Only statically initialize the current class, it contains everything it inherits */ \
151 if (cname##_vtbl.vtblname == this.classname) \
153 spawn##cname##_static(this); \
154 this.classname = #cname; \
155 this.vtblname = string_null; \
156 this.vtblbase = cname##_vtbl; \
158 spawn##base##_1(this); \
161 #define METHOD(cname, name, prototype) \
162 class(cname).prototype name; \
163 prototype cname##_##name; \
166 this.name = cname##_##name; \
168 prototype cname##_##name
170 #define ATTRIB(cname, name, type, val) \
171 class(cname).type name; \
174 noref bool strzone; /* Error on strzone() calls. */ \
178 #define ATTRIB_STRZONE(cname, name, type, val) \
179 class(cname).type name; \
183 strunzone(this.name); \
184 this.name = strzone(val); \
187 #define ATTRIBARRAY(cname, name, type, cnt) \
188 class(cname).type name[cnt];
190 #define ENDCLASS(cname) \
196 #define SUPER(cname) (cname##_vtbl.vtblbase)
198 #define spawn_static(this)
199 #define spawn_1(this)
202 METHOD(Object, describe, string(entity this))
204 string s = _("No description");
205 if (cvar("developer"))
207 for (int i = 0, n = numentityfields(); i < n; ++i)
209 string value = getentityfieldstring(i, this);
210 if (value != "") s = sprintf("%s\n%s = %s", s, entityfieldname(i), value);
215 METHOD(Object, display, void(entity this, void(string name, string icon) returns))
217 returns(sprintf("entity %i", this), "nopreview_map");