#ifndef TOBJECT_H #define TOBJECT_H #include "pso/forward.h" #include "pso/macros.h" #include #include #define o(name) extern const char *name##_name; OBJECT_NAMES #undef o extern TMainTask main_task; extern TObject global_obj1; extern TObject global_obj2; enum object_flags { NONE = 0, QUEUE_DESTRUCTION = 1, CHILD_QUEUE_DESTRUCTION = 2, BIT_2 = 4, BIT_3 = 8, DISALLOW_UPDATE = 0x0F, DISALLOW_RENDER = 0x10, DISALLOW_DESTRUCTION = 0x20, DISALLOW_RENDER_SHADOWS = 0x100, BIT_9 = 0x200, BIT_10 = 0x400, BIT_11 = 0x800, BIT_12 = 0x1000, BIT_13 = 0x2000, BIT_14 = 0x4000, BIT_15 = 0x8000, ALL_BITS = 0xFFFF }; static inline object_flags operator^(object_flags a, object_flags b) { return static_cast(static_cast(a) ^ static_cast(b)); }; static inline object_flags operator&(object_flags a, object_flags b) { return static_cast(static_cast(a) & static_cast(b)); }; static inline object_flags operator|(object_flags a, object_flags b) { return static_cast(static_cast(a) | static_cast(b)); }; static inline object_flags operator~(object_flags a) { return static_cast(~static_cast(a)); } static inline void operator^=(object_flags &a, object_flags b) { a = a ^ b; }; static inline void operator&=(object_flags &a, object_flags b) { a = a & b; }; static inline void operator|=(object_flags &a, object_flags b) { a = a | b; }; class TObject { private: void _delete_children() { while (m_down != NULL) { delete m_down; } }; void add_parent(TObject *parent, bool set_parent) { if (set_parent) { m_up = parent; } TObject *child; if (parent == NULL) { m_prev = this; m_next = NULL; return; } child = parent->m_down; if (child != NULL) { m_prev = child->m_next; m_next = NULL; child->m_prev->m_next = this; child->m_prev = this; } else { m_prev = this; parent->m_down = this; m_next = NULL; } }; void remove_parent() { if (m_up != NULL) { if (m_prev == this) { m_up->m_down = NULL; } else if (m_up->m_down == this) { m_up->m_down = m_next; m_prev->m_next = NULL; if (m_next != NULL) { m_next->m_prev = m_prev; } } else { m_prev->m_next = m_next; if (m_next != NULL) { m_next->m_prev = m_prev; } else { m_up->m_down->m_prev = m_prev; } } } }; void set_flags(object_flags flags) { m_flags |= flags; } void clear_flags(object_flags flags) { m_flags_u16 &= ~static_cast(flags); } void toggle_flags(object_flags flags) { m_flags ^= flags; } u32 get_flags(object_flags flags) { return m_flags & flags; }; protected: const char *m_name; private: union { object_flags m_flags; u16 m_flags_u16; }; u16 m_id; TObject *m_prev; TObject *m_next; TObject *m_up; TObject *m_down; public: void disallow_rendering_shadows(); void allow_rendering_shadows(); void disallow_rendering(); void allow_rendering(); void toggle_flag_3(); void set_flag_3(); void clear_flag_3(); void queue_destruction(); void set_flag_9(); u32 get_flag_9(); void clear_flag_9(); TObject(TObject *parent = NULL); virtual ~TObject(); void *operator new (size_t size) { return alloc(size); }; void operator delete(void *ptr) { free(ptr); }; const char *name() { return m_name; }; object_flags flags() { return m_flags; }; u16 flags_u16() { return m_flags_u16; }; u16 id() { return m_id; }; TObject *prev() { return m_prev; }; TObject *next() { return m_next; }; TObject *up() { return m_up; }; TObject *down() { return m_down; }; void set_name(const char *name) { m_name = name; }; void set_obj_flags(object_flags flags) { m_flags = flags; }; void set_flags_u16(u16 flags) { m_flags_u16 = flags; }; void set_id(u16 id) { m_id = id; }; void set_prev(TObject *node) { m_prev = node; }; void set_next(TObject *node) { m_next = node; }; void set_up(TObject *node) { m_up = node; }; void set_down(TObject *node) { m_down = node; }; void delete_children(); void queue_destruction_for_each_node(); void run_tasks(); void render_nodes(); void render_shadows_for_each_node(); void render_nodes2(); void empty_func(); void set_parent(TObject *parent); virtual void run_task(); virtual void render(); virtual void render_shadows(); void empty_func2(); void log(const char *str); int get_node_count(); int all_parents_unqueued_for_destruction(); static void *alloc(size_t size); static void free(void *ptr); bool toggle_flag_9_if_flag_10_is_clear(); }; #endif