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