Resolve naming confusion, rename object and bind_hashtable.

They implement a dict-style thing, so let's call it that.
This commit is contained in:
Enno Rehling 2015-01-17 13:22:26 +01:00
parent dadf7734a5
commit 7bfb14b4e6
10 changed files with 490 additions and 485 deletions

View File

@ -116,7 +116,7 @@ set(SERVER_SRC
bind_locale.c
bind_eressea.c
bind_faction.c
bind_hashtable.c
bind_dict.c
bindings.c
bind_message.c
bind_monsters.c

View File

@ -13,7 +13,7 @@ key.c
matmod.c
moved.c
movement.c
object.c
dict.c
orcification.c
otherfaction.c
overrideroads.c

View File

@ -28,7 +28,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "stealth.h"
#include "moved.h"
#include "movement.h"
#include "object.h"
#include "dict.h"
#include "orcification.h"
#include "otherfaction.h"
#include "overrideroads.h"
@ -56,7 +56,7 @@ void register_attributes(void)
{
at_deprecate("gm", a_readint);
at_register(&at_stealth);
at_register(&at_object);
at_register(&at_dict);
at_register(&at_unitdissolve);
at_register(&at_overrideroads);
at_register(&at_raceprefix);

283
src/attributes/dict.c Normal file
View File

@ -0,0 +1,283 @@
/*
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**/
#include <platform.h>
#include <kernel/config.h>
#include "dict.h"
/* kernel includes */
#include <kernel/building.h>
#include <kernel/faction.h>
#include <kernel/region.h>
#include <kernel/save.h>
#include <kernel/ship.h>
#include <kernel/unit.h>
#include <kernel/version.h>
/* util includes */
#include <util/attrib.h>
#include <util/resolve.h>
#include <storage.h>
/* stdc includes */
#include <string.h>
#include <stdlib.h>
#include <assert.h>
typedef struct dict_data {
dict_type type;
char *name;
union {
int i;
char *str;
double real;
struct unit *u;
struct region *r;
struct building *b;
struct ship *sh;
struct faction *f;
} data;
} dict_data;
static void
dict_write(const attrib * a, const void *owner, struct storage *store)
{
const dict_data *data = (dict_data *)a->data.v;
int type = (int)data->type;
WRITE_TOK(store, data->name);
WRITE_INT(store, type);
switch (data->type) {
case TINTEGER:
WRITE_INT(store, data->data.i);
break;
case TREAL:
WRITE_FLT(store, (float)data->data.real);
break;
case TSTRING:
WRITE_STR(store, data->data.str);
break;
case TUNIT:
write_unit_reference(data->data.u, store);
break;
case TFACTION:
write_faction_reference(data->data.f, store);
break;
case TBUILDING:
write_building_reference(data->data.b, store);
break;
case TSHIP:
/* write_ship_reference(data->data.sh, store); */
assert(!"not implemented");
break;
case TREGION:
write_region_reference(data->data.r, store);
break;
case TNONE:
break;
default:
assert(!"illegal type in object-attribute");
}
}
static int dict_read(attrib * a, void *owner, struct storage *store)
{
char name[NAMESIZE];
dict_data *data = (dict_data *)a->data.v;
int result, n;
float flt;
READ_STR(store, name, sizeof(name));
data->name = _strdup(name);
READ_INT(store, &n);
data->type = (dict_type)n;
switch (data->type) {
case TINTEGER:
READ_INT(store, &data->data.i);
break;
case TREAL:
READ_FLT(store, &flt);
if ((int)flt == flt) {
data->type = TINTEGER;
data->data.i = (int)flt;
}
else {
data->data.real = flt;
}
break;
case TSTRING:
READ_STR(store, name, sizeof(name));
data->data.str = _strdup(name);
break;
case TBUILDING:
result =
read_reference(&data->data.b, store, read_building_reference,
resolve_building);
if (result == 0 && !data->data.b) {
return AT_READ_FAIL;
}
break;
case TUNIT:
result =
read_reference(&data->data.u, store, read_unit_reference, resolve_unit);
if (result == 0 && !data->data.u) {
return AT_READ_FAIL;
}
break;
case TFACTION:
result =
read_reference(&data->data.f, store, read_faction_reference,
resolve_faction);
if (result == 0 && !data->data.f) {
return AT_READ_FAIL;
}
break;
case TREGION:
result =
read_reference(&data->data.r, store, read_region_reference,
RESOLVE_REGION(global.data_version));
if (result == 0 && !data->data.r) {
return AT_READ_FAIL;
}
break;
case TSHIP:
/* return read_ship_reference(&data->data.sh, store); */
assert(!"not implemented");
break;
case TNONE:
break;
default:
return AT_READ_FAIL;
}
return AT_READ_OK;
}
static void dict_init(attrib * a)
{
dict_data *data;
a->data.v = malloc(sizeof(dict_data));
data = (dict_data *)a->data.v;
data->type = TNONE;
}
static void dict_done(attrib * a)
{
dict_data *data = (dict_data *)a->data.v;
if (data->type == TSTRING)
free(data->data.str);
free(data->name);
free(a->data.v);
}
attrib_type at_dict = {
"object", dict_init, dict_done, NULL,
dict_write, dict_read
};
const char *dict_name(const attrib * a)
{
dict_data *data = (dict_data *)a->data.v;
return data->name;
}
struct attrib *dict_create(const char *name, dict_type type, variant value)
{
attrib *a = a_new(&at_dict);
dict_data *data = (dict_data *)a->data.v;
data->name = _strdup(name);
dict_set(a, type, value);
return a;
}
void dict_set(attrib * a, dict_type type, variant value)
{
dict_data *data = (dict_data *)a->data.v;
if (data->type == TSTRING)
free(data->data.str);
data->type = type;
switch (type) {
case TSTRING:
data->data.str = value.v ? _strdup(value.v) : NULL;
break;
case TINTEGER:
data->data.i = value.i;
break;
case TREAL:
data->data.real = value.f;
break;
case TREGION:
data->data.r = (region *)value.v;
break;
case TBUILDING:
data->data.b = (building *)value.v;
break;
case TFACTION:
data->data.f = (faction *)value.v;
break;
case TUNIT:
data->data.u = (unit *)value.v;
break;
case TSHIP:
data->data.sh = (ship *)value.v;
break;
case TNONE:
break;
default:
assert(!"invalid object-type");
break;
}
}
void dict_get(const struct attrib *a, dict_type * type, variant * value)
{
dict_data *data = (dict_data *)a->data.v;
*type = data->type;
switch (data->type) {
case TSTRING:
value->v = data->data.str;
break;
case TINTEGER:
value->i = data->data.i;
break;
case TREAL:
value->f = (float)data->data.real;
break;
case TREGION:
value->v = data->data.r;
break;
case TBUILDING:
value->v = data->data.b;
break;
case TFACTION:
value->v = data->data.f;
break;
case TUNIT:
value->v = data->data.u;
break;
case TSHIP:
value->v = data->data.sh;
break;
case TNONE:
break;
default:
assert(!"invalid object-type");
break;
}
}

View File

@ -8,7 +8,7 @@
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
*/
*/
#ifndef H_ATTRIBUTE_OBJECT
#define H_ATTRIBUTE_OBJECT
@ -19,19 +19,19 @@
extern "C" {
#endif
typedef enum {
TNONE = 0, TINTEGER = 1, TREAL = 2, TSTRING = 3,
TUNIT = 10, TFACTION = 11, TREGION = 12, TBUILDING = 13, TSHIP = 14
} object_type;
typedef enum {
TNONE = 0, TINTEGER = 1, TREAL = 2, TSTRING = 3,
TUNIT = 10, TFACTION = 11, TREGION = 12, TBUILDING = 13, TSHIP = 14
} dict_type;
extern struct attrib_type at_object;
extern struct attrib_type at_dict;
extern struct attrib *object_create(const char *name, object_type type,
variant value);
extern void object_get(const struct attrib *a, object_type * type,
variant * value);
extern void object_set(struct attrib *a, object_type type, variant value);
extern const char *object_name(const struct attrib *a);
extern struct attrib *dict_create(const char *name, dict_type type,
variant value);
extern void dict_get(const struct attrib *a, dict_type * type,
variant * value);
extern void dict_set(struct attrib *a, dict_type type, variant value);
extern const char *dict_name(const struct attrib *a);
#ifdef __cplusplus
}

View File

@ -1,283 +0,0 @@
/*
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**/
#include <platform.h>
#include <kernel/config.h>
#include "object.h"
/* kernel includes */
#include <kernel/building.h>
#include <kernel/faction.h>
#include <kernel/region.h>
#include <kernel/save.h>
#include <kernel/ship.h>
#include <kernel/unit.h>
#include <kernel/version.h>
/* util includes */
#include <util/attrib.h>
#include <util/resolve.h>
#include <storage.h>
/* stdc includes */
#include <string.h>
#include <stdlib.h>
#include <assert.h>
typedef struct object_data {
object_type type;
char *name;
union {
int i;
char *str;
double real;
struct unit *u;
struct region *r;
struct building *b;
struct ship *sh;
struct faction *f;
} data;
} object_data;
static void
object_write(const attrib * a, const void *owner, struct storage *store)
{
const object_data *data = (object_data *) a->data.v;
int type = (int)data->type;
WRITE_TOK(store, data->name);
WRITE_INT(store, type);
switch (data->type) {
case TINTEGER:
WRITE_INT(store, data->data.i);
break;
case TREAL:
WRITE_FLT(store, (float)data->data.real);
break;
case TSTRING:
WRITE_STR(store, data->data.str);
break;
case TUNIT:
write_unit_reference(data->data.u, store);
break;
case TFACTION:
write_faction_reference(data->data.f, store);
break;
case TBUILDING:
write_building_reference(data->data.b, store);
break;
case TSHIP:
/* write_ship_reference(data->data.sh, store); */
assert(!"not implemented");
break;
case TREGION:
write_region_reference(data->data.r, store);
break;
case TNONE:
break;
default:
assert(!"illegal type in object-attribute");
}
}
static int object_read(attrib * a, void *owner, struct storage *store)
{
char name[NAMESIZE];
object_data *data = (object_data *) a->data.v;
int result, n;
float flt;
READ_STR(store, name, sizeof(name));
data->name = _strdup(name);
READ_INT(store, &n);
data->type = (object_type)n;
switch (data->type) {
case TINTEGER:
READ_INT(store, &data->data.i);
break;
case TREAL:
READ_FLT(store, &flt);
if ((int)flt == flt) {
data->type = TINTEGER;
data->data.i = (int)flt;
}
else {
data->data.real = flt;
}
break;
case TSTRING:
READ_STR(store, name, sizeof(name));
data->data.str = _strdup(name);
break;
case TBUILDING:
result =
read_reference(&data->data.b, store, read_building_reference,
resolve_building);
if (result == 0 && !data->data.b) {
return AT_READ_FAIL;
}
break;
case TUNIT:
result =
read_reference(&data->data.u, store, read_unit_reference, resolve_unit);
if (result == 0 && !data->data.u) {
return AT_READ_FAIL;
}
break;
case TFACTION:
result =
read_reference(&data->data.f, store, read_faction_reference,
resolve_faction);
if (result == 0 && !data->data.f) {
return AT_READ_FAIL;
}
break;
case TREGION:
result =
read_reference(&data->data.r, store, read_region_reference,
RESOLVE_REGION(global.data_version));
if (result == 0 && !data->data.r) {
return AT_READ_FAIL;
}
break;
case TSHIP:
/* return read_ship_reference(&data->data.sh, store); */
assert(!"not implemented");
break;
case TNONE:
break;
default:
return AT_READ_FAIL;
}
return AT_READ_OK;
}
static void object_init(attrib * a)
{
object_data *data;
a->data.v = malloc(sizeof(object_data));
data = (object_data *) a->data.v;
data->type = TNONE;
}
static void object_done(attrib * a)
{
object_data *data = (object_data *) a->data.v;
if (data->type == TSTRING)
free(data->data.str);
free(data->name);
free(a->data.v);
}
attrib_type at_object = {
"object", object_init, object_done, NULL,
object_write, object_read
};
const char *object_name(const attrib * a)
{
object_data *data = (object_data *) a->data.v;
return data->name;
}
struct attrib *object_create(const char *name, object_type type, variant value)
{
attrib *a = a_new(&at_object);
object_data *data = (object_data *) a->data.v;
data->name = _strdup(name);
object_set(a, type, value);
return a;
}
void object_set(attrib * a, object_type type, variant value)
{
object_data *data = (object_data *) a->data.v;
if (data->type == TSTRING)
free(data->data.str);
data->type = type;
switch (type) {
case TSTRING:
data->data.str = value.v ? _strdup(value.v) : NULL;
break;
case TINTEGER:
data->data.i = value.i;
break;
case TREAL:
data->data.real = value.f;
break;
case TREGION:
data->data.r = (region *) value.v;
break;
case TBUILDING:
data->data.b = (building *) value.v;
break;
case TFACTION:
data->data.f = (faction *) value.v;
break;
case TUNIT:
data->data.u = (unit *) value.v;
break;
case TSHIP:
data->data.sh = (ship *) value.v;
break;
case TNONE:
break;
default:
assert(!"invalid object-type");
break;
}
}
void object_get(const struct attrib *a, object_type * type, variant * value)
{
object_data *data = (object_data *) a->data.v;
*type = data->type;
switch (data->type) {
case TSTRING:
value->v = data->data.str;
break;
case TINTEGER:
value->i = data->data.i;
break;
case TREAL:
value->f = (float)data->data.real;
break;
case TREGION:
value->v = data->data.r;
break;
case TBUILDING:
value->v = data->data.b;
break;
case TFACTION:
value->v = data->data.f;
break;
case TUNIT:
value->v = data->data.u;
break;
case TSHIP:
value->v = data->data.sh;
break;
case TNONE:
break;
default:
assert(!"invalid object-type");
break;
}
}

185
src/bind_dict.c Normal file
View File

@ -0,0 +1,185 @@
/* vi: set ts=2:
+-------------------+
| | Enno Rehling <enno@eressea.de>
| Eressea PBEM host | Christian Schlittchen <corwin@amber.kn-bremen.de>
| (c) 1998 - 2008 | Katja Zedel <katze@felidae.kn-bremen.de>
| | Henning Peters <faroul@beyond.kn-bremen.de>
+-------------------+
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
*/
#include <platform.h>
#include "bind_dict.h"
#include <kernel/building.h>
#include <kernel/unit.h>
#include <kernel/ship.h>
#include <kernel/region.h>
#include <attributes/dict.h>
#include <util/variant.h>
#include <util/attrib.h>
#include <tolua.h>
#include <lua.h>
#include <string.h>
#include <assert.h>
static int tolua_dict_get(lua_State * L)
{
dict self = (dict)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
attrib *a = a_find(*self, &at_dict);
for (; a && a->type == &at_dict; a = a->next) {
const char *obj_name = dict_name(a);
if (obj_name && name && strcmp(obj_name, name) == 0) {
variant val;
dict_type type;
dict_get(a, &type, &val);
switch (type) {
case TNONE:
lua_pushnil(L);
break;
case TINTEGER:
lua_pushnumber(L, (lua_Number)val.i);
break;
case TREAL:
lua_pushnumber(L, (lua_Number)val.f);
break;
case TREGION:
tolua_pushusertype(L, val.v, TOLUA_CAST "region");
break;
case TBUILDING:
tolua_pushusertype(L, val.v, TOLUA_CAST "building");
break;
case TUNIT:
tolua_pushusertype(L, val.v, TOLUA_CAST "unit");
break;
case TSHIP:
tolua_pushusertype(L, val.v, TOLUA_CAST "ship");
break;
case TSTRING:
tolua_pushstring(L, (const char *)val.v);
break;
default:
assert(!"not implemented");
}
return 1;
}
}
lua_pushnil(L);
return 1;
}
static int tolua_dict_set_number(lua_State * L)
{
dict self = (dict)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
lua_Number value = tolua_tonumber(L, 3, 0);
attrib *a = a_find(*self, &at_dict);
variant val;
val.f = (float)value;
for (; a && a->type == &at_dict; a = a->next) {
if (strcmp(dict_name(a), name) == 0) {
dict_set(a, TREAL, val);
return 0;
}
}
a = a_add(self, dict_create(name, TREAL, val));
return 0;
}
static int tolua_dict_set_string(lua_State * L)
{
dict self = (dict)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
const char *value = tolua_tostring(L, 3, 0);
attrib *a = a_find(*self, &at_dict);
variant val;
val.v = _strdup(value);
for (; a && a->type == &at_dict; a = a->next) {
if (strcmp(dict_name(a), name) == 0) {
dict_set(a, TSTRING, val);
return 0;
}
}
a = a_add(self, dict_create(name, TSTRING, val));
return 0;
}
static int tolua_dict_set_usertype(lua_State * L, int type)
{
dict self = (dict)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
unit *value = tolua_tousertype(L, 3, 0);
attrib *a = a_find(*self, &at_dict);
variant val;
val.v = value;
for (; a && a->type == &at_dict; a = a->next) {
if (strcmp(dict_name(a), name) == 0) {
dict_set(a, type, val);
return 0;
}
}
a = a_add(self, dict_create(name, type, val));
return 0;
}
static int tolua_dict_set(lua_State * L)
{
tolua_Error tolua_err;
if (tolua_isnumber(L, 3, 0, &tolua_err)) {
return tolua_dict_set_number(L);
}
else if (tolua_isusertype(L, 3, TOLUA_CAST "unit", 0, &tolua_err)) {
return tolua_dict_set_usertype(L, TUNIT);
}
else if (tolua_isusertype(L, 3, TOLUA_CAST "faction", 0, &tolua_err)) {
return tolua_dict_set_usertype(L, TFACTION);
}
else if (tolua_isusertype(L, 3, TOLUA_CAST "ship", 0, &tolua_err)) {
return tolua_dict_set_usertype(L, TSHIP);
}
else if (tolua_isusertype(L, 3, TOLUA_CAST "building", 0, &tolua_err)) {
return tolua_dict_set_usertype(L, TBUILDING);
}
else if (tolua_isusertype(L, 3, TOLUA_CAST "region", 0, &tolua_err)) {
return tolua_dict_set_usertype(L, TREGION);
}
return tolua_dict_set_string(L);
}
void tolua_dict_open(lua_State * L)
{
/* register user types */
tolua_usertype(L, TOLUA_CAST "dict");
tolua_module(L, NULL, 0);
tolua_beginmodule(L, NULL);
{
tolua_cclass(L, TOLUA_CAST "dict", TOLUA_CAST "dict",
TOLUA_CAST "", NULL);
tolua_beginmodule(L, TOLUA_CAST "dict");
{
tolua_function(L, TOLUA_CAST "get", tolua_dict_get);
tolua_function(L, TOLUA_CAST "set", tolua_dict_set);
}
tolua_endmodule(L);
}
tolua_endmodule(L);
}

View File

@ -14,10 +14,10 @@ without prior permission by the authors of Eressea.
extern "C" {
#endif
struct lua_State;
void tolua_hashtable_open(struct lua_State *L);
struct lua_State;
void tolua_dict_open(struct lua_State *L);
typedef struct attrib **hashtable;
typedef struct attrib **dict;
#ifdef __cplusplus
}

View File

@ -1,180 +0,0 @@
/* vi: set ts=2:
+-------------------+
| | Enno Rehling <enno@eressea.de>
| Eressea PBEM host | Christian Schlittchen <corwin@amber.kn-bremen.de>
| (c) 1998 - 2008 | Katja Zedel <katze@felidae.kn-bremen.de>
| | Henning Peters <faroul@beyond.kn-bremen.de>
+-------------------+
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
*/
#include <platform.h>
#include "bind_hashtable.h"
#include <kernel/building.h>
#include <kernel/unit.h>
#include <kernel/ship.h>
#include <kernel/region.h>
#include <attributes/object.h>
#include <util/variant.h>
#include <util/attrib.h>
#include <tolua.h>
#include <lua.h>
#include <string.h>
#include <assert.h>
static int tolua_hashtable_get(lua_State * L)
{
hashtable self = (hashtable) tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
attrib *a = a_find(*self, &at_object);
for (; a && a->type == &at_object; a = a->next) {
const char *obj_name = object_name(a);
if (obj_name && name && strcmp(obj_name, name) == 0) {
variant val;
object_type type;
object_get(a, &type, &val);
switch (type) {
case TNONE:
lua_pushnil(L);
break;
case TINTEGER:
lua_pushnumber(L, (lua_Number) val.i);
break;
case TREAL:
lua_pushnumber(L, (lua_Number) val.f);
break;
case TREGION:
tolua_pushusertype(L, val.v, TOLUA_CAST "region");
break;
case TBUILDING:
tolua_pushusertype(L, val.v, TOLUA_CAST "building");
break;
case TUNIT:
tolua_pushusertype(L, val.v, TOLUA_CAST "unit");
break;
case TSHIP:
tolua_pushusertype(L, val.v, TOLUA_CAST "ship");
break;
case TSTRING:
tolua_pushstring(L, (const char *)val.v);
break;
default:
assert(!"not implemented");
}
return 1;
}
}
lua_pushnil(L);
return 1;
}
static int tolua_hashtable_set_number(lua_State * L)
{
hashtable self = (hashtable) tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
lua_Number value = tolua_tonumber(L, 3, 0);
attrib *a = a_find(*self, &at_object);
variant val;
val.f = (float)value;
for (; a && a->type == &at_object; a = a->next) {
if (strcmp(object_name(a), name) == 0) {
object_set(a, TREAL, val);
return 0;
}
}
a = a_add(self, object_create(name, TREAL, val));
return 0;
}
static int tolua_hashtable_set_string(lua_State * L)
{
hashtable self = (hashtable) tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
const char *value = tolua_tostring(L, 3, 0);
attrib *a = a_find(*self, &at_object);
variant val;
val.v = _strdup(value);
for (; a && a->type == &at_object; a = a->next) {
if (strcmp(object_name(a), name) == 0) {
object_set(a, TSTRING, val);
return 0;
}
}
a = a_add(self, object_create(name, TSTRING, val));
return 0;
}
static int tolua_hashtable_set_usertype(lua_State * L, int type)
{
hashtable self = (hashtable) tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
unit *value = tolua_tousertype(L, 3, 0);
attrib *a = a_find(*self, &at_object);
variant val;
val.v = value;
for (; a && a->type == &at_object; a = a->next) {
if (strcmp(object_name(a), name) == 0) {
object_set(a, type, val);
return 0;
}
}
a = a_add(self, object_create(name, type, val));
return 0;
}
static int tolua_hashtable_set(lua_State * L)
{
tolua_Error tolua_err;
if (tolua_isnumber(L, 3, 0, &tolua_err)) {
return tolua_hashtable_set_number(L);
} else if (tolua_isusertype(L, 3, TOLUA_CAST "unit", 0, &tolua_err)) {
return tolua_hashtable_set_usertype(L, TUNIT);
} else if (tolua_isusertype(L, 3, TOLUA_CAST "faction", 0, &tolua_err)) {
return tolua_hashtable_set_usertype(L, TFACTION);
} else if (tolua_isusertype(L, 3, TOLUA_CAST "ship", 0, &tolua_err)) {
return tolua_hashtable_set_usertype(L, TSHIP);
} else if (tolua_isusertype(L, 3, TOLUA_CAST "building", 0, &tolua_err)) {
return tolua_hashtable_set_usertype(L, TBUILDING);
} else if (tolua_isusertype(L, 3, TOLUA_CAST "region", 0, &tolua_err)) {
return tolua_hashtable_set_usertype(L, TREGION);
}
return tolua_hashtable_set_string(L);
}
void tolua_hashtable_open(lua_State * L)
{
/* register user types */
tolua_usertype(L, TOLUA_CAST "hashtable");
tolua_module(L, NULL, 0);
tolua_beginmodule(L, NULL);
{
tolua_cclass(L, TOLUA_CAST "hashtable", TOLUA_CAST "hashtable",
TOLUA_CAST "", NULL);
tolua_beginmodule(L, TOLUA_CAST "hashtable");
{
tolua_function(L, TOLUA_CAST "get", tolua_hashtable_get);
tolua_function(L, TOLUA_CAST "set", tolua_hashtable_set);
}
tolua_endmodule(L);
}
tolua_endmodule(L);
}

View File

@ -15,7 +15,7 @@ without prior permission by the authors of Eressea.
#include "bind_unit.h"
#include "bind_storage.h"
#include "bind_building.h"
#include "bind_hashtable.h"
#include "bind_dict.h"
#include "bind_message.h"
#include "bind_building.h"
#include "bind_faction.h"
@ -1211,7 +1211,7 @@ lua_State *lua_init(void) {
tolua_faction_open(L);
tolua_unit_open(L);
tolua_message_open(L);
tolua_hashtable_open(L);
tolua_dict_open(L);
#ifdef USE_CURSES
tolua_gmtool_open(L);
#endif