X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Flib%2Foo.qh;h=a0d6f35db34b9ba8e76ba2af2c1aa3457779d1bb;hb=e9f30b97435c6afe3d6911f21e1f4fd1b97e93da;hp=0615282c3e1a7f7031aa1571eb8e51f5d9ce8e53;hpb=70b84d37e2cf1d5336c327cb43593024de2a2c6c;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/lib/oo.qh b/qcsrc/lib/oo.qh index 0615282c3..a0d6f35db 100644 --- a/qcsrc/lib/oo.qh +++ b/qcsrc/lib/oo.qh @@ -3,148 +3,200 @@ #include "misc.qh" #include "nil.qh" +#include "static.qh" #ifdef MENUQC - #define NULL (null_entity) + #define NULL (null_entity) #else - #define NULL (world) + #define NULL (world) #endif +.vector origin; +.bool pure_data; +#define make_pure(e) \ + do \ + { \ + (e).pure_data = true; \ + } \ + while (0) +#define is_pure(e) ((e).pure_data) + .string classname; /** Location entity was spawned from in source */ .string sourceLocFile; .int sourceLocLine; entity _spawn(); -entity __spawn(string _classname, string _sourceFile, int _sourceLine) { - entity this = _spawn(); - this.classname = _classname; - this.sourceLocFile = _sourceFile; - this.sourceLocLine = _sourceLine; - return this; +entity __spawn(string _classname, string _sourceFile, int _sourceLine, bool pure) +{ + entity this = _spawn(); + this.classname = _classname; + this.sourceLocFile = _sourceFile; + this.sourceLocLine = _sourceLine; + if (pure) make_pure(this); + return this; } - #define entityclass(...) EVAL(OVERLOAD(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) __spawn(#class, __FILE__, __LINE__) + #define entityclass_2(name, base) typedef entity name + #define class(name) + #define new(class) __spawn( #class, __FILE__, __LINE__, false) #else - #define entityclass_2(name, base) entityclass name : base {} - #define class(name) [[class(name)]] - #define new(class) ((class) __spawn(#class, __FILE__, __LINE__)) + #define entityclass_2(name, base) entityclass name : base {} + #define class(name) [[class(name)]] + #define new(class) ((class) __spawn( #class, __FILE__, __LINE__, false)) +#endif +#define spawn() __spawn("entity", __FILE__, __LINE__, false) + +entity _clearentity_ent; +STATIC_INIT(clearentity) +{ + _clearentity_ent = new(clearentity); +} +void clearentity(entity e) +{ +#ifdef CSQC + int n = e.entnum; +#endif + copyentity(_clearentity_ent, e); +#ifdef CSQC + e.entnum = n; #endif -#define spawn() new(entity) +} // Classes have a `spawn##cname(entity)` constructor // The parameter is used across [[accumulate]] functions // Macros to hide this implementation detail: #ifdef GMQCC -#define NEW(cname, ...) \ - OVERLOAD(spawn##cname, new(cname), ##__VA_ARGS__) + #define NEW(cname, ...) \ + OVERLOAD(spawn##cname, new(cname),##__VA_ARGS__) -#define CONSTRUCT(cname, ...) \ - OVERLOAD(spawn##cname, this, ##__VA_ARGS__) + #define CONSTRUCT(cname, ...) \ + OVERLOAD(spawn##cname, this,##__VA_ARGS__) #else -#define NEW_(cname, ...) \ - OVERLOAD_(spawn##cname, __VA_ARGS__) -#define NEW(cname, ...) \ - NEW_(cname, new(cname), ##__VA_ARGS__)(new(cname), ##__VA_ARGS__) - -#define CONSTRUCT_(cname, ...) \ - OVERLOAD_(spawn##cname, __VA_ARGS__) -#define CONSTRUCT(cname, ...) \ - CONSTRUCT_(cname, this, ##__VA_ARGS__)(this, ##__VA_ARGS__) + #define NEW_(cname, ...) \ + OVERLOAD_(spawn##cname, __VA_ARGS__) + #define NEW(cname, ...) \ + NEW_(cname, new(cname),##__VA_ARGS__)(new(cname),##__VA_ARGS__) + + #define CONSTRUCT_(cname, ...) \ + OVERLOAD_(spawn##cname, __VA_ARGS__) + #define CONSTRUCT(cname, ...) \ + CONSTRUCT_(cname, this,##__VA_ARGS__)(this,##__VA_ARGS__) #endif #define CONSTRUCTOR(cname, ...) \ - cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__) { return = this; } \ - [[accumulate]] cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__) + cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__) \ + { \ + return = this; \ + } \ + [[accumulate]] cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__) .string vtblname; .entity vtblbase; -void RegisterClasses() { } -STATIC_INIT(RegisterClasses) { RegisterClasses(); } +void RegisterClasses() {} +STATIC_INIT(RegisterClasses) +{ + RegisterClasses(); +} #define VTBL(cname, base) \ - INIT_STATIC(cname); \ - entity cname##_vtbl; \ - void cname##_vtbl_init() { \ - cname e = new(vtbl); \ - spawn##cname##_static(e); \ - e.vtblname = #cname; \ - /* Top level objects refer to themselves */ \ - e.vtblbase = base##_vtbl ? base##_vtbl : e; \ - cname##_vtbl = e; \ - } \ - ACCUMULATE_FUNCTION(RegisterClasses, cname##_vtbl_init) + INIT_STATIC(cname); \ + entity cname##_vtbl; \ + void cname##_vtbl_init() \ + { \ + cname e = new(vtbl); \ + make_pure(e); \ + spawn##cname##_static(e); \ + e.vtblname = #cname; \ + /* Top level objects refer to themselves */ \ + e.vtblbase = base##_vtbl ? base##_vtbl : e; \ + cname##_vtbl = e; \ + } \ + ACCUMULATE_FUNCTION(RegisterClasses, cname##_vtbl_init) #define INIT_STATIC(cname) [[accumulate]] void spawn##cname##_static(cname this) #define INIT(cname) [[accumulate]] cname spawn##cname##_1(cname this) #define CLASS(cname, base) \ - entityclass(cname, base); \ - class(cname) .bool instanceOf##cname; \ - VTBL(cname, base) \ - INIT_STATIC(cname) { \ - if (cname##_vtbl) { \ - copyentity(cname##_vtbl, this); \ - return; \ - } \ - spawn##base##_static(this); \ - this.instanceOf##cname = true; \ - } \ - INIT(cname) { \ - /* Only statically initialize the current class, it contains everything it inherits */ \ - if (cname##_vtbl.vtblname == this.classname) { \ - spawn##cname##_static(this); \ - this.classname = #cname; \ - this.vtblname = string_null; \ - this.vtblbase = cname##_vtbl; \ - } \ - spawn##base##_1(this); \ - } + entityclass(cname, base); \ + class(cname).bool instanceOf##cname; \ + VTBL(cname, base) \ + INIT_STATIC(cname) \ + { \ + if (cname##_vtbl) \ + { \ + copyentity(cname##_vtbl, this); \ + return; \ + } \ + spawn##base##_static(this); \ + this.instanceOf##cname = true; \ + } \ + INIT(cname) \ + { \ + /* Only statically initialize the current class, it contains everything it inherits */ \ + if (cname##_vtbl.vtblname == this.classname) \ + { \ + spawn##cname##_static(this); \ + this.classname = #cname; \ + this.vtblname = string_null; \ + this.vtblbase = cname##_vtbl; \ + } \ + spawn##base##_1(this); \ + } #define METHOD(cname, name, prototype) \ - class(cname) .prototype name; \ - prototype cname##_##name; \ - INIT_STATIC(cname) { this.name = cname##_##name; } \ - prototype cname##_##name + class(cname).prototype name; \ + prototype cname##_##name; \ + INIT_STATIC(cname) \ + { \ + this.name = cname##_##name; \ + } \ + prototype cname##_##name #define ATTRIB(cname, name, type, val) \ - class(cname) .type name; \ - INIT(cname) { this.name = val; } + class(cname).type name; \ + INIT(cname) \ + { \ + this.name = val; \ + } #define ATTRIBARRAY(cname, name, type, cnt) \ - class(cname) .type name[cnt]; + class(cname).type name[cnt]; #define ENDCLASS(cname) \ - [[last]] INIT(cname) { return this; } + INIT(cname) \ + { \ + return this; \ + } #define SUPER(cname) (cname##_vtbl.vtblbase) -#define super (this.vtblbase.vtblbase) #define spawn_static(this) #define spawn_1(this) #define _vtbl NULL CLASS(Object, ); - METHOD(Object, describe, string(entity this)) { - string s = _("No description"); - if (cvar("developer")) { - for (int i = 0, n = numentityfields(); i < n; ++i) { - string value = getentityfieldstring(i, this); - if (value != "") s = sprintf("%s\n%s = %s", s, entityfieldname(i), value); - } - } - return s; - } - METHOD(Object, display, void(entity this, void(string name, string icon) returns)) { - returns(sprintf("entity %i", this), "nopreview_map"); - } + METHOD(Object, describe, string(entity this)) + { + string s = _("No description"); + if (cvar("developer")) + { + for (int i = 0, n = numentityfields(); i < n; ++i) + { + string value = getentityfieldstring(i, this); + if (value != "") s = sprintf("%s\n%s = %s", s, entityfieldname(i), value); + } + } + return s; + } + METHOD(Object, display, void(entity this, void(string name, string icon) returns)) + { + returns(sprintf("entity %i", this), "nopreview_map"); + } ENDCLASS(Object) #undef spawn_static #undef spawn_1