/* Copyright 1989, 1990 by James Aspnes, David Applegate, and Bennet Yee */
/* See the file COPYING for distribution information */
#ifndef _DB_H
#define _DB_H

#include "os.h"
#include "alist.h"
#include "set.h"

/* this must appear at the beginning of all database files */
#define DB_HEADER "### TinyMUD 2.4 database format ###\n"

typedef datum object_flag_type;

#define F_OPEN 0x1              /* anything can be moved here */
#define F_CONNECTED 0x2         /* this object is connected to somebody */
#define F_PARANOID 0x4          /* annotate tells with the sender */

#define F_PLAYER 0x10           /* this object is a player */
#define F_BUILDER 0x20          /* this object may create objects */
#define F_PROGRAMMER 0x40       /* this object may set code fields */
#define F_WIZARD 0x80           /* this object controls everything */
#define F_ADMIN 0x100           /* this object can shut th system down */

/* names for above */
#define isflagname(name) ((name) >= MIN_FLAGNAME && (name) < MAX_FLAGNAME)
#define name2flag(name) (1 << ((name) - MIN_FLAGNAME))

/* for struct object *'s */
#define oflag_set(o, flag) ((o)->flags & flag)

struct object {
  alist vars;                   /* values are datum's, different types */
  alist sets;                   /* values are pointers to sets of objects */
  alist actions;                /* values are reified code objects */
  datum owner;                  /* what object owns this one */
  datum parent;                 /* object we inherit from */
  datum location;               /* where we are */
  object_flag_type flags;       /* various useful bits */
};

/* String stuff */
extern datum intern (const char *);     /* intern a string into the string table */
extern datum intern_soft (const char *);        /* won't put a new entry in */
extern const char *string (datum);      /* returns the print name of the string */

/* compiled strings */
extern void set_compiled_string (datum s, datum * code);
extern datum *get_compiled_string (datum s);

/* alias expansions */
extern void set_expansion (datum s, alist);
extern alist get_expansion (datum s);

/* Objects */
/* every object has an owner */
extern datum new_object (datum owner);
extern void free_object (datum);
extern struct object *object (datum);   /* get the struct */

/* use this to read fields off of an object */
#define safe_get(obj, field) \
 ((_safe_get_TMP = object(obj)) ? _safe_get_TMP->field : NOTHING)
extern struct object *_safe_get_TMP;

/* Garbage collector */
extern void gc_mark_string (datum);
extern void full_gc (void);
extern void incremental_gc (void);

/* I/O */
extern int db_write (FILE *);
extern int db_read (FILE *);

/* Iteration */
extern int foreach_object (void (*func) (datum));

#endif /* _DB_H */