#pragma once #include "../util/allocator.h" #include "../util/vector.h" #include "../util/fnv.h" typedef void ( *OBJECT_DEINIT_FN )( struct OBJECT* obj ); inline const char* obj_classid_to_name( U32 classid ); inline LIST* obj_proplist( U32 classid ); enum ObjectClass_t { OBJCLASS_NONE = 0, OBJCLASS_WORLD, OBJCLASS_TRIGGER, OBJCLASS_PLAYER, OBJCLASS_BASENPC, OBJCLASS_LAST }; static const char* OBJCLASS_NAMES[] = { "none (invalid - FIXME)", "world", "trigger", "player", "base_npc", }; // todo: come up with a good way to make these static struct OBJECT_PROP { OBJECT_PROP( const char* name, U32 size, U32 classid, U32 offset ) { this->name = name; this->size = size; this->hash = fnv1a( name ); this->offset = offset; LIST* l = obj_proplist( classid ); l->push( this ); } const char* name; FNV1A hash; U32 offset; U32 size; }; inline LIST* obj_proplist( U32 classid ) { static struct LIST prop_lists[OBJCLASS_LAST]; if( classid >= OBJCLASS_LAST ) { dlog( "obj_classid_to_name() : invalid classid passed (%d)", classid ); return 0; } return &prop_lists[classid]; } #define OBJVAR( type, name ) \ type name; \ constexpr static U32 __##name##_offset() { OBJ_SELF_TYPE t; return (U32)( (U64)&t.name - (U64)&t ); } \ static inline OBJECT_PROP __##name##_props{ #name, sizeof(type), OBJ_SELF_TYPE::CLASSID, (U32)( __##name##_offset() ) } #define OBJVARV( type, name, val ) \ type name{ type( val ) }; \ constexpr static U32 __##name##_offset() { OBJ_SELF_TYPE t; return (U32)( (U64)&t.name - (U64)&t ); } \ static inline OBJECT_PROP __##name##_props{ #name, sizeof(type), OBJ_SELF_TYPE::CLASSID, (U32)( __##name##_offset() ) } #define OBJVAR_STR( name, len ) \ char name##[len]; \ constexpr static U32 __##name##_offset() { OBJ_SELF_TYPE t; return (U32)( (U64)&t.name - (U64)&t ); } \ static inline OBJECT_PROP __##name##_props{ #name, sizeof(type), OBJ_SELF_TYPE::CLASSID, (U32)( __##name##_offset() ) } struct OBJECT { static const U32 CLASSID = OBJCLASS_NONE; using OBJ_SELF_TYPE = OBJECT; U32 classid; U8 keeponlevel{}; char name[64]; OBJECT* parent; LIST children{}; OBJECT_DEINIT_FN deinit_fn{}; OBJVAR( VEC3, pos ); OBJVAR( VEC3, rot ); OBJVAR( I32, idx ); OBJVAR( VEC3, velocity ); OBJVAR( VEC3, mins ); OBJVAR( VEC3, maxs ); }; inline const char* obj_classid_to_name( U32 classid ) { if( classid > (sizeof(OBJCLASS_NAMES) / sizeof(OBJCLASS_NAMES[0])) ) { dlog( "obj_classid_to_name() : invalid classid passed (%d)", classid ); return "INVALIDCLASSID"; } return OBJCLASS_NAMES[classid]; }