]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/lib/oo.qh
Fix a couple of setorigin pains
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / oo.qh
index e7d9a13b101b068f370d7eaf71c93550b7a6da83..2f871ccf17a3a6d73191dda69ea7d50f5fdfc7bc 100644 (file)
 
 .vector origin;
 .bool pure_data;
+/** deprecated, use new_pure or NEW(class) */
 #define make_pure(e) \
-       do \
+       MACRO_BEGIN \
        { \
                (e).pure_data = true; \
-       } \
-       while (0)
+       } MACRO_END
+#define make_impure(e) \
+       MACRO_BEGIN \
+       { \
+               (e).pure_data = false; \
+       } MACRO_END
 #define is_pure(e) ((e).pure_data)
 
 .string classname;
@@ -32,7 +37,12 @@ entity __spawn(string _classname, string _sourceFile, int _sourceLine, bool pure
        this.classname = _classname;
        this.sourceLocFile = _sourceFile;
        this.sourceLocLine = _sourceLine;
-       if (pure) make_pure(this);
+       if (pure) {
+               make_pure(this);
+               #ifdef CSQC
+               setorigin(this, '0 0 10000');
+               #endif
+       }
        return this;
 }
 
@@ -42,25 +52,32 @@ entity __spawn(string _classname, string _sourceFile, int _sourceLine, bool pure
 #ifndef QCC_SUPPORT_ENTITYCLASS
        #define entityclass_2(name, base) typedef entity name
        #define class(name)
-       #define new(class) __spawn( #class, __FILE__, __LINE__, false)
+       #define _new(class, pure) __spawn( #class, __FILE__, __LINE__, pure)
 #else
        #define entityclass_2(name, base) entityclass name : base {}
        #define class(name) [[class(name)]]
-       #define new(class) ((class) __spawn( #class, __FILE__, __LINE__, false))
+       #define _new(class, pure) ((class) __spawn( #class, __FILE__, __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)
 
 entity _clearentity_ent;
 STATIC_INIT(clearentity)
 {
-       _clearentity_ent = new(clearentity);
+       _clearentity_ent = new_pure(clearentity);
+       make_pure(_clearentity_ent);
 }
 void clearentity(entity e)
 {
 #ifdef CSQC
                int n = e.entnum;
 #endif
+       bool was_pure = is_pure(e);
        copyentity(_clearentity_ent, e);
+       if (!was_pure) make_impure(e);
 #ifdef CSQC
                e.entnum = n;
 #endif
@@ -72,7 +89,7 @@ void clearentity(entity e)
 // Macros to hide this implementation detail:
 #ifdef GMQCC
        #define NEW(cname, ...) \
-               OVERLOAD(spawn##cname, new(cname),##__VA_ARGS__)
+               OVERLOAD(spawn##cname, new_pure(cname),##__VA_ARGS__)
 
        #define CONSTRUCT(cname, ...) \
                OVERLOAD(spawn##cname, this,##__VA_ARGS__)
@@ -80,7 +97,7 @@ void clearentity(entity e)
        #define NEW_(cname, ...) \
                OVERLOAD_(spawn##cname, __VA_ARGS__)
        #define NEW(cname, ...) \
-               NEW_(cname, new(cname),##__VA_ARGS__)(new(cname),##__VA_ARGS__)
+               NEW_(cname, new_pure(cname),##__VA_ARGS__)(new_pure(cname),##__VA_ARGS__)
 
        #define CONSTRUCT_(cname, ...) \
                OVERLOAD_(spawn##cname, __VA_ARGS__)
@@ -109,8 +126,7 @@ STATIC_INIT(RegisterClasses)
        entity cname##_vtbl; \
        void cname##_vtbl_init() \
        { \
-               cname e = new(vtbl); \
-               make_pure(e); \
+               cname e = new_pure(vtbl); \
                spawn##cname##_static(e); \
                e.vtblname = #cname; \
                /* Top level objects refer to themselves */ \
@@ -149,14 +165,20 @@ STATIC_INIT(RegisterClasses)
                spawn##base##_1(this);              \
        }
 
-#define METHOD(cname, name, prototype)      \
-       class(cname).prototype name;           \
-       prototype cname##_##name;               \
+#define METHOD_REFERENCE(cname, name) \
+       cname##_##name
+
+#define STATIC_METHOD(cname, name, prototype) \
+       prototype METHOD_REFERENCE(cname, name)
+
+#define METHOD(cname, name, prototype) \
+       STATIC_METHOD(cname, name, prototype); \
+       class(cname) .prototype name; \
        INIT_STATIC(cname) \
        { \
-               this.name = cname##_##name; \
+               this.name = METHOD_REFERENCE(cname, name); \
        } \
-       prototype cname##_##name
+       STATIC_METHOD(cname, name, prototype)
 
 #define ATTRIB(cname, name, type, val)      \
        class(cname).type name;                \