aboutsummaryrefslogtreecommitdiff
path: root/src/room.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/room.c')
-rw-r--r--src/room.c111
1 files changed, 19 insertions, 92 deletions
diff --git a/src/room.c b/src/room.c
index d3f306a..df819a6 100644
--- a/src/room.c
+++ b/src/room.c
@@ -61,40 +61,6 @@ bool room_user_del(room_id id, struct child_data *child)
return false;
}
-void write_roomid(int fd, room_id *id)
-{
- write(fd, id, sizeof(*id));
-}
-
-void write_string(int fd, const char *str)
-{
- size_t len = strlen(str);
- write(fd, &len, sizeof(len));
- write(fd, str, len);
-}
-
-room_id read_roomid(int fd)
-{
- room_id ret;
- if(read(fd, &ret, sizeof(ret)) < 0)
- return ROOM_NONE;
- return ret;
-}
-
-char *read_string(int fd)
-{
- size_t sz;
- read(fd, &sz, sizeof(sz));
- char *ret = malloc(sz + 1);
- if(read(fd, ret, sz) < 0)
- {
- free(ret);
- return NULL;
- }
- ret[sz] = '\0';
- return ret;
-}
-
void world_save(const char *fname)
{
int fd = open(fname, O_CREAT | O_WRONLY, 0644);
@@ -129,13 +95,6 @@ void world_save(const char *fname)
break;
id = ROOM_NONE;
- write_string(fd, obj->class->class_name);
- write_string(fd, obj->name);
- write(fd, &obj->can_take, sizeof(obj->can_take));
- write(fd, &obj->list, sizeof(obj->list));
-
- if(obj->class->hook_serialize)
- obj->class->hook_serialize(fd, obj);
}
}
close(fd);
@@ -166,59 +125,28 @@ void world_free(void)
}
}
-/* map of class names -> object classes */
-static void *obj_class_map = NULL;
-
-struct object_t *obj_new(const char *class_name)
-{
- if(!obj_class_map)
- {
- extern const struct obj_class_t netcosm_obj_classes[];
- extern const size_t netcosm_obj_classes_sz;
- obj_class_map = hash_init(netcosm_obj_classes_sz / 2 + 1,
- hash_djb,
- compare_strings);
- for(unsigned i = 0; i < netcosm_obj_classes_sz; ++i)
- {
- if(hash_insert(obj_class_map,
- netcosm_obj_classes[i].class_name,
- netcosm_obj_classes + i))
- error("duplicate object class name");
- }
- }
-
- struct object_t *obj = calloc(1, sizeof(struct object_t));
-
- obj->class = hash_lookup(obj_class_map, class_name);
- if(!obj->class)
- {
- free(obj);
- error("unknown object class '%s'", class_name);
- }
- else
- return obj;
-}
-
-bool obj_add(room_id room, struct object_t *obj)
+bool room_obj_add(room_id room, struct object_t *obj)
{
return !hash_insert(room_get(room)->objects, obj->name, obj);
}
#define OBJMAP_SIZE 8
+static void free_obj(void *ptr)
+{
+ struct object_t *obj = ptr;
+ if(obj->class->hook_destroy)
+ obj->class->hook_destroy(obj);
+ free(obj);
+}
+
/* initialize the room's hash tables */
static void room_init_maps(struct room_t *room)
{
room->users = hash_init((userdb_size() / 2) + 1, hash_djb, compare_strings);
- room->objects = hash_init(OBJMAP_SIZE, hash_djb, compare_strings);
-}
-bool read_bool(int fd)
-{
- bool ret;
- if(read(fd, &ret, sizeof(ret)) != sizeof(ret))
- error("unexpected EOF");
- return ret;
+ room->objects = hash_init(OBJMAP_SIZE, hash_djb, compare_strings);
+ hash_setfreedata_cb(room->objects, free_obj);
}
/**
@@ -273,15 +201,9 @@ bool world_load(const char *fname, const struct roomdata_t *data, size_t data_sz
for(unsigned j = 0; j < n_objects; ++j)
{
- const char *class_name = read_string(fd);
- struct object_t *obj = obj_new(class_name);
- obj->name = read_string(fd);
- obj->can_take = read_bool(fd);
- obj->list = read_bool(fd);
- if(obj->class->hook_deserialize)
- obj->class->hook_deserialize(fd, obj);
-
- if(!obj_add(i, obj))
+ struct object_t *obj = obj_read(fd);
+
+ if(!room_obj_add(i, obj))
error("duplicate object name in room '%s'", world[i].data.name);
}
}
@@ -416,3 +338,8 @@ size_t room_obj_count(room_id room)
{
return hash_size(room_get(room)->objects);
}
+
+bool room_obj_del(room_id room, const char *name)
+{
+ return hash_remove(room_get(room)->objects, name);
+}