1 #ifndef OBJECT_H__ 2 #define OBJECT_H__ 1 3 4 #include "driver.h" 5 #include "typedefs.h" 6 7 #include "sent.h" /* O_GET_* */ 8 9 #ifdef DEBUG 10 #include <stdio.h> /* printf() for refcount tracing */ 11 #endif 12 13 /* --- Types --- */ 14 15 /* --- struct object: the base structure of every object 16 */ 17 18 struct object_s 19 { 20 unsigned short flags; /* Bits or'ed together, see below */ 21 p_int ref; /* Reference count. */ 22 #ifdef USE_SET_LIGHT 23 short total_light; /* Total light */ 24 #endif 25 mp_int time_reset; /* Time of next reset, or 0 if none */ 26 mp_int time_of_ref; /* Time when last referenced. Used by swap */ 27 mp_int time_cleanup; /* Time when the next variable cleanup is due. */ 28 mp_int load_time; /* Time when the object was created. */ 29 p_int load_id; /* Load-ID within the time the object was created */ 30 #ifdef DEBUG 31 p_int extra_ref; /* Used to check ref count. */ 32 #endif 33 program_t *prog; /* Program code for this object */ 34 string_t *name; 35 /* name of the object (untabled), always w/o leading '/' */ 36 string_t *load_name; 37 /* name of the object's blueprint (tabled), in compat 38 * mode without leading '/' 39 */ 40 object_t *next_all; /* Next object in global list */ 41 object_t *prev_all; /* Previous object in global list */ 42 object_t *next_hash; /* Next object in chain in the otable */ 43 object_t *next_inv; /* Next object in the current environment */ 44 object_t *contains; /* First contained object */ 45 object_t *super; /* Current environment */ 46 sentence_t *sent; /* Sentences, shadows, interactive data */ 47 wiz_list_t *user; /* What wizard defined this object */ 48 wiz_list_t *eff_user; /* Effective user */ 49 #ifdef DEBUG 50 int extra_num_variables; 51 /* amylaar : used to determine where to check ref counts at all... */ 52 #endif 53 #ifdef USE_SQLITE 54 Bool open_sqlite_db; /* does this object have an open sqlite db? */ 55 #endif 56 svalue_t *variables; 57 /* All variables to this object: an array of svalues, allocated 58 * in a separate block. 59 */ 60 unsigned long ticks, gigaticks; 61 /* Evalcost used by this object. The total cost 62 * is computed with gigaticks*1E9+ticks. 63 */ 64 }; 65 66 67 /* Values of object_t.flags: */ 68 69 #define O_HEART_BEAT 0x01 /* Does it have an heart beat? */ 70 #ifdef USE_SET_IS_WIZARD 71 #define O_IS_WIZARD 0x02 /* Is it a wizard player.c? */ 72 #endif 73 #define O_ENABLE_COMMANDS 0x04 /* Can it execute commands? */ 74 #define O_CLONE 0x08 /* Is it cloned from a master copy? */ 75 #define O_DESTRUCTED 0x10 /* Is it destructed ? */ 76 #define O_SWAPPED 0x20 /* Is it swapped to file */ 77 #define O_ONCE_INTERACTIVE 0x40 /* Has it ever been interactive? */ 78 #define O_UNUSED_80 0x80 79 #define O_RESET_STATE 0x100 /* Object in a 'reset':ed state ? */ 80 #define O_WILL_CLEAN_UP 0x200 /* clean_up will be called next time */ 81 #define O_LAMBDA_REFERENCED 0x400 /* be careful with replace_program() */ 82 #define O_SHADOW 0x800 /* Is the object shadowed/shadowing? */ 83 #define O_REPLACED 0x1000 /* Was the program replaced? */ 84 85 86 /* If an object's program or variables are swapped out, the values 87 * of .prog resp. .variables are replaced with the associated (even) 88 * swap number assigned by the swapper, and the lowest bit of the number 89 * is set. The swap number '-1' means 'not swapped'. 90 * TODO: This assumes that pointers are always even. 91 */ 92 93 #define P_PROG_SWAPPED(p) ((p_int)(p) & 1) 94 /* Is the program <p> swapped out? 95 */ 96 97 #define O_PROG_SWAPPED(ob) ((p_int)(ob)->prog & 1) 98 /* Is the program of <ob> swapped out? 99 */ 100 101 #define O_VAR_SWAPPED(ob) ((p_int)(ob)->variables & 1) 102 /* Are the variables of <ob> swapped out? 103 */ 104 105 #define O_SWAP_NUM(ob) \ 106 (O_PROG_SWAPPED(ob) ? (p_int)(ob)->prog & ~1 : (ob)->prog->swap_num) 107 /* The swap number for the program of <ob>. 108 */ 109 110 #define O_IS_INTERACTIVE(o) \ 111 (((o)->flags & O_SHADOW) && (NULL != O_GET_INTERACTIVE(o)) ) 112 113 /* Bool O_IS_INTERACTIVE(object_t *o) 114 * Return TRUE if ob is an interactive object. 115 */ 116 117 #define O_SET_INTERACTIVE(ip,o) \ 118 ( ( ((o)->flags & O_SHADOW) && (NULL != (ip = O_GET_INTERACTIVE(o))) ) \ 119 || ( (ip = NULL), MY_FALSE ) ) 120 121 /* Bool O_SET_INTERACTIVE(interactive_t *ip, object_t *o) 122 * Return TRUE if ob is an interactive object and set ip to the interactive 123 * structure. Return FALSE is not and clear ip. 124 */ 125 126 127 /* --- struct replace_ob_s: one scheduled program replacement 128 * 129 * A list of this structure (obj_list_replace) keeps track of all 130 * requested replace_program()s during one backend round. 131 * 132 * It is possible, though not very useful, to replace an object's 133 * program by the very same program. 134 */ 135 136 struct replace_ob_s 137 { 138 object_t *ob; /* Object requesting the new program */ 139 program_t *new_prog; /* Requested new program */ 140 int var_offset; /* Variable offset of .new_prog */ 141 int fun_offset; /* Function offset of .new_prog */ 142 replace_ob_t *next; /* Link pointer for list */ 143 struct lambda_replace_program_protector *lambda_rpp; 144 /* Additional information about lambdas bound to the program 145 * after the replacement was scheduled. The exact information 146 * is private to closure.c. 147 */ 148 }; 149 150 151 /* --- Macros --- */ 152 153 /* object_t *ref_object(object_t *o, char *from) 154 * Add another ref to object <o> from function <from> 155 * and return the object <o>. 156 */ 157 158 #ifndef DEBUG 159 160 # define ref_object(o,from) ((o)->ref++, (o)) 161 162 #else 163 164 # define ref_object(o,from) (\ 165 (o)->ref++,\ 166 d_flag > 1 ? printf("Add ref to object %s: %"PRIdPINT" (%s) %s %d\n" \ 167 , get_txt((o)->name), (o)->ref, from, __FILE__, __LINE__) : 0, \ 168 (o)) 169 170 #endif 171 172 /* object_t *ref_valid_object(object_t *o, char *from) 173 * Add another ref to object <o> from function <from> if <o> 174 * is not a destructed object or the NULL pointer. 175 * Return <o>, or NULL if <o> is destructed. 176 */ 177 178 #define ref_valid_object(o,from) \ 179 ( ((o) && !((o)->flags & O_DESTRUCTED)) \ 180 ? ref_object(o,from) : NULL) 181 182 /* void free_object(object_t *o, char *) 183 * Subtract one ref from object <o> from function <o>, and free the 184 * object fully if the refcount reaches zero. 185 */ 186 187 #ifndef DEBUG 188 189 #ifndef CHECK_OBJECT_REF 190 # define free_object(o,from) MACRO( \ 191 object_t * tmp_ = o; \ 192 if (tmp_->ref == 2) dest_last_ref_gone = MY_TRUE; \ 193 if (--(tmp_->ref) <= 0) dealloc_object(tmp_);\ 194 ) 195 #else 196 # define free_object(o,from) MACRO( \ 197 object_t * tmp_ = o; \ 198 if (tmp_->ref == 2) dest_last_ref_gone = MY_TRUE; \ 199 if (--(tmp_->ref) <= 0) dealloc_object(tmp_, __FILE__, __LINE__); \ 200 ) 201 #endif 202 203 #else 204 205 #ifndef CHECK_OBJECT_REF 206 # define free_object(o,from) MACRO(\ 207 object_t * tmp_ = o; \ 208 if (tmp_->ref == 2) dest_last_ref_gone = MY_TRUE; \ 209 tmp_->ref--;\ 210 if (d_flag > 1) printf("Sub ref from object %s: %"PRIdPINT" (%s) %s %d\n"\ 211 , get_txt(tmp_->name), tmp_->ref, from, __FILE__, __LINE__);\ 212 if (tmp_->ref <= 0) dealloc_object(tmp_); \ 213 ) 214 #else 215 # define free_object(o,from) MACRO(\ 216 object_t * tmp_ = o; \ 217 if (tmp_->ref == 2) dest_last_ref_gone = MY_TRUE; \ 218 tmp_->ref--;\ 219 if (d_flag > 1) printf("Sub ref from object %s: %"PRIdPINT" (%s) %s %d\n"\ 220 , get_txt(tmp_->name), tmp_->ref, from, __FILE__, __LINE__);\ 221 if (tmp_->ref <= 0) dealloc_object(tmp_, __FILE__, __LINE__); \ 222 ) 223 #endif 224 225 #endif 226 227 /* void deref_object(object_t *o, char *from) 228 * Subtract one ref from object <o> from function <from>, but don't 229 * check if it needs to be freed. 230 */ 231 232 #ifndef DEBUG 233 234 # define deref_object(o, from) (--(o)->ref) 235 236 #else 237 238 # define deref_object(o,from) (--(o)->ref, \ 239 d_flag > 1 ? printf("Sub ref from object %s: %"PRIdPINT" (%s)\n" \ 240 , get_txt((o)->name), (o)->ref, from) : 0) 241 242 #endif 243 244 245 #define check_object(o) ((o)&&((o)->flags&O_DESTRUCTED) ? NULL :(o)) 246 247 /* Return NULL, if object <o> is NULL or destructed, 248 * return <o> else. 249 */ 250 251 #ifdef CHECK_OBJECT_REF 252 #define free_prog(p,f) _free_prog(p,f, __FILE__, __LINE__) 253 #endif 254 255 /* --- Variables --- */ 256 257 extern replace_ob_t *obj_list_replace; 258 extern long tot_alloc_object; 259 extern long tot_alloc_object_size; 260 extern object_t NULL_object; 261 extern Bool dest_last_ref_gone; 262 263 264 /* --- Prototypes --- */ 265 266 extern int32 renumber_programs(void); 267 extern void tell_object(object_t *, string_t *); 268 extern void tell_object_str(object_t *, const char *); 269 extern void tell_npc(object_t *, string_t *); 270 extern void tell_npc_str(object_t *, const char *); 271 extern void reference_prog(program_t *, char *); 272 #ifdef DEALLOCATE_MEMORY_AT_SHUTDOWN 273 extern void remove_all_objects(void); 274 #endif 275 extern void do_free_sub_strings(int num_strings, string_t ** strings 276 , int num_variables, variable_t *variables 277 , int num_includes, include_t *includes 278 #ifdef USE_STRUCTS 279 ,int num_structs, struct_def_t *struct_defs 280 #endif /* USE_STRUCTS */ 281 ); 282 #ifndef CHECK_OBJECT_REF 283 extern void free_prog(program_t *progp, Bool free_all); 284 #else 285 extern void _free_prog(program_t *progp, Bool free_all, const char * file, int line); 286 #endif 287 extern void reset_object(object_t *ob, int arg); 288 extern void logon_object (object_t *ob); 289 extern void replace_programs(void); 290 extern Bool shadow_catch_message(object_t *ob, const char *str); 291 292 #ifndef CHECK_OBJECT_REF 293 extern void dealloc_object(object_t *); 294 #else 295 extern void dealloc_object(object_t *, const char * file, int line); 296 #endif 297 extern object_t *get_empty_object(int num_var); 298 extern void init_object_variables (object_t *ob, object_t *templ); 299 300 extern svalue_t *v_function_exists(svalue_t *sp, int num_arg); 301 extern svalue_t *f_functionlist(svalue_t *sp); 302 extern svalue_t *v_variable_exists (svalue_t *sp, int num_arg); 303 extern svalue_t *f_variable_list (svalue_t *sp); 304 extern svalue_t *v_include_list (svalue_t *sp, int num_arg); 305 extern svalue_t *v_inherit_list(svalue_t *sp, int num_arg); 306 extern svalue_t *f_load_name(svalue_t *sp); 307 extern svalue_t *f_object_name(svalue_t *sp); 308 extern svalue_t *f_object_time(svalue_t *sp); 309 extern svalue_t *f_program_name(svalue_t *sp); 310 extern svalue_t *f_program_time(svalue_t *sp); 311 extern svalue_t *f_query_once_interactive(svalue_t *sp); 312 extern svalue_t *f_rename_object(svalue_t *sp); 313 extern svalue_t *v_replace_program(svalue_t *sp, int num_arg); 314 extern svalue_t *f_tell_object(svalue_t *sp); 315 extern svalue_t *f_set_next_reset(svalue_t *sp); 316 317 extern svalue_t *f_export_uid(svalue_t *sp); 318 extern svalue_t *f_geteuid(svalue_t *sp); 319 extern svalue_t *f_seteuid(svalue_t *sp); 320 extern svalue_t *f_getuid(svalue_t *sp); 321 322 extern svalue_t *v_all_environment(svalue_t *sp, int num_arg); 323 extern svalue_t *f_all_inventory(svalue_t *sp); 324 #if defined(USE_PARSE_COMMAND) 325 extern vector_t *deep_inventory(object_t *ob, Bool take_top, p_int depth); 326 /* needed by parse.c */ 327 #endif 328 extern svalue_t *v_deep_inventory(svalue_t *sp, int num_arg); 329 extern svalue_t *v_environment(svalue_t *sp, int num_arg); 330 extern svalue_t *f_first_inventory(svalue_t *sp); 331 extern svalue_t *f_next_inventory(svalue_t *sp); 332 extern svalue_t *f_move_object (svalue_t *sp); 333 extern svalue_t *v_present(svalue_t *sp, int num_arg); 334 extern svalue_t *v_say(svalue_t *sp, int num_arg); 335 extern svalue_t *v_tell_room(svalue_t *sp, int num_arg); 336 extern svalue_t *f_set_environment(svalue_t *sp); 337 #ifdef USE_DEPRECATED 338 extern svalue_t *f_transfer(svalue_t *svp); 339 #endif 340 341 #ifdef USE_SET_LIGHT 342 extern void add_light(object_t *p, int n); 343 extern svalue_t *f_set_light(svalue_t *sp); 344 #endif 345 346 extern svalue_t *v_save_object(svalue_t *sp, int numarg); 347 extern svalue_t *v_save_value(svalue_t *sp, int numarg); 348 extern svalue_t *f_restore_object(svalue_t *sp); 349 extern svalue_t *f_restore_value(svalue_t *sp); 350 351 extern void free_save_object_buffers(void); 352 353 #endif /* OBJECT_H__ */ 354