Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make more use of stb_ds #1096

Merged
merged 4 commits into from
Nov 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions scripts/tests/study.lua
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,7 @@ function test_unit_spells()
u:add_spell("toast")
assert_equal(nil, u.spells)
u:add_spell("fireball", 2)
local sp = u.spells()
assert_equal("fireball", sp.name)
assert_equal(2, sp.level)
assert_equal(2, u:get_spell("fireball"))
end

local function make_teacher(student, f, skill)
Expand Down
36 changes: 22 additions & 14 deletions src/bind_unit.c
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,27 @@ static int tolua_unit_castspell(lua_State * L)
return 0;
}

static int tolua_unit_getspell(lua_State *L)
{
unit *u = (unit *)tolua_tousertype(L, 1, NULL);
const char *str = tolua_tostring(L, 2, NULL);
spellbook *sb;
spellbook_entry *sbe = NULL;

sb = unit_get_spellbook(u);
if (sb) {
spell *sp = find_spell(str);
if (!sp) {
log_warning("spell %s could not be found\n", str);
}
else {
sbe = spellbook_get(sb, sp);
}
}
lua_pushinteger(L, sbe->level);
return 1;
}

static int tolua_unit_addspell(lua_State * L)
{
unit *u = (unit *)tolua_tousertype(L, 1, NULL);
Expand Down Expand Up @@ -800,19 +821,6 @@ static int tolua_unit_get_items(lua_State * L)
return 1;
}

static int tolua_unit_get_spells(lua_State * L)
{
unit *u = (unit *) tolua_tousertype(L, 1, NULL);
struct sc_mage *mage = u ? get_mage(u) : NULL;
spellbook *sb = mage_get_spellbook(mage);
selist *slist = NULL;
if (sb) {
selist **slist_ptr = &sb->spells;
slist = *slist_ptr;
}
return tolua_selist_push(L, "spellbook", "spell_entry", slist);
}

static int tolua_unit_get_curse(lua_State *L) {
unit *u = (unit *)tolua_tousertype(L, 1, NULL);
const char *name = tolua_tostring(L, 2, NULL);
Expand Down Expand Up @@ -1118,7 +1126,7 @@ void tolua_unit_open(lua_State * L)
tolua_variable(L, "race_name", tolua_unit_get_racename,
tolua_unit_set_racename);
tolua_function(L, "add_spell", tolua_unit_addspell);
tolua_variable(L, "spells", tolua_unit_get_spells, 0);
tolua_function(L, "get_spell", tolua_unit_getspell);
tolua_function(L, "cast_spell", tolua_unit_castspell);
tolua_function(L, "effect", bind_unit_effect);

Expand Down
3 changes: 1 addition & 2 deletions src/bindings.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,8 +405,7 @@ static int tolua_turn_begin(lua_State * L)
UNUSED_ARG(L);
for (f = factions; f; f = f->next) {
if (f->msgs) {
free_messagelist(f->msgs->begin);
free(f->msgs);
free_messagelist(f->msgs);
f->msgs = NULL;
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/creport.c
Original file line number Diff line number Diff line change
Expand Up @@ -727,11 +727,11 @@ static void cr_output_spells(stream *out, const unit * u, int maxlevel)

if (book) {
const faction * f = u->faction;
selist *ql;
int qi, header = 0;
int header = 0;
ptrdiff_t qi, ql = arrlen(book->spells);

for (ql = book->spells, qi = 0; ql; selist_advance(&ql, &qi, 1)) {
spellbook_entry * sbe = (spellbook_entry *)selist_get(ql, qi);
for (qi = 0; qi != ql; ++qi) {
spellbook_entry *sbe = (spellbook_entry *)book->spells + qi;
if (sbe->level <= maxlevel) {
const spell *sp = spellref_get(&sbe->spref);
const char * spname = mkname("spell", sp->sname);
Expand Down
70 changes: 35 additions & 35 deletions src/kernel/attrib.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <storage.h>
#include <strings.h>

#include <stb_ds.h>

#include <assert.h>
#include <string.h>
#include <stdlib.h>
Expand Down Expand Up @@ -112,8 +114,10 @@ void a_finalizestring(variant * var)
free(var->v);
}

#define MAXATHASH 61
static attrib_type *at_hash[MAXATHASH];
static struct at_hash_t {
unsigned int key;
attrib_type *value;
} *at_hash;

static unsigned int __at_hashkey(const char *s)
{
Expand All @@ -128,46 +132,42 @@ static unsigned int __at_hashkey(const char *s)

void at_register(attrib_type * at)
{
attrib_type *find;

if (at->read == NULL) {
log_warning("registering non-persistent attribute %s.\n", at->name);
}
at->hashkey = __at_hashkey(at->name);
find = at_hash[at->hashkey % MAXATHASH];
while (find && at->hashkey != find->hashkey) {
find = find->nexthash;
}
if (find && find == at) {
log_warning("attribute '%s' was registered more than once\n", at->name);
return;
unsigned int hash = __at_hashkey(at->name);
#ifndef NDEBUG
ptrdiff_t i = hmgeti(at_hash, hash);
if (i >= 0) {
if (at == at_hash[i].value) {
log_error("attribute %s is already registered", at->name);
return;
}
else {
log_fatal("attributes %s and %s hash to the same key", at->name, at_hash[i].value->name);
}
}
else {
assert(!find || !"hashkey is already in use");
#endif
if (at->read == NULL) {
log_error("registering non-persistent attribute %s.\n", at->name);
}
at->nexthash = at_hash[at->hashkey % MAXATHASH];
at_hash[at->hashkey % MAXATHASH] = at;
hmput(at_hash, hash, at);
}

static attrib_type *at_find_key(unsigned int hk)
{
attrib_type *find = at_hash[hk % MAXATHASH];
while (find && hk != find->hashkey)
find = find->nexthash;
if (!find) {
const char *translate[3][2] = {
{ "zielregion", "targetregion" }, /* remapping: from 'zielregion, heute targetregion */
{ "verzaubert", "curse" }, /* remapping: frueher verzaubert, jetzt curse */
ptrdiff_t i = hmgeti(at_hash, hk);
if (i < 0) {
int k;
const char *aliases[3][2] = {
{ "zielregion", "targetregion" }, /* remapping: from 'zielregion, heute targetregion */
{ "verzaubert", "curse" }, /* remapping: frueher verzaubert, jetzt curse */
{ NULL, NULL }
};
int i = 0;
while (translate[i][0]) {
if (__at_hashkey(translate[i][0]) == hk)
return at_find_key(__at_hashkey(translate[i][1]));
++i;
for (k = 0; aliases[k][0]; ++k) {
if (__at_hashkey(aliases[k][0]) == hk)
return at_find_key(__at_hashkey(aliases[k][1]));
}
return NULL;
}
return find;
return at_hash[i].value;
}

struct attrib_type *at_find(const char *name) {
Expand Down Expand Up @@ -482,8 +482,8 @@ void a_write(struct storage *store, const attrib * attribs, const void *owner) {

while (na) {
if (na->type->write) {
assert(na->type->hashkey || !"attribute not registered");
WRITE_INT(store, na->type->hashkey);
unsigned int hashkey = __at_hashkey(na->type->name);
WRITE_INT(store, hashkey);
na->type->write(&na->data, owner, store);
na = na->next;
}
Expand All @@ -496,5 +496,5 @@ void a_write(struct storage *store, const attrib * attribs, const void *owner) {

void attrib_done(void) {
cb_clear(&cb_deprecated);
memset(at_hash, 0, sizeof(at_hash[0]) * MAXATHASH);
hmfree(at_hash);
}
4 changes: 0 additions & 4 deletions src/kernel/attrib.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ extern "C" {
int(*read) (union variant *, void *owner, struct gamedata *); /* return AT_READ_OK on success, AT_READ_FAIL if attrib needs removal */
void(*upgrade) (struct attrib **alist, struct attrib *a);
unsigned int flags;
/* ---- internal data, do not modify: ---- */
struct attrib_type *nexthash;
unsigned int hashkey;
} attrib_type;

void at_register(attrib_type * at);
Expand All @@ -48,7 +45,6 @@ extern "C" {

attrib *a_select(attrib * a, const void *data, bool(*compare) (const attrib *, const void *));
attrib *a_find(attrib * a, const attrib_type * at);
attrib** a_find_it(attrib** ap, const attrib_type* at);
attrib *a_add(attrib ** pa, attrib * at);
int a_remove(attrib ** pa, attrib * at);
void a_removeall(attrib ** a, const attrib_type * at);
Expand Down
13 changes: 4 additions & 9 deletions src/kernel/faction.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,23 +59,19 @@
faction *factions;

/** remove the faction from memory.
* this frees all memory that's only accessible through the faction,
* but you should still call funhash and remove the faction from the
* global list.
* this frees all memory that's only accessible through the faction.
*/
static void free_faction(faction * f)
{
funhash(f);
if (f->msgs) {
free_messagelist(f->msgs->begin);
free(f->msgs);
free_messagelist(f->msgs);
}
while (f->battles) {
struct bmsg *bm = f->battles;
f->battles = bm->next;
if (bm->msgs) {
free_messagelist(bm->msgs->begin);
free(bm->msgs);
free_messagelist(bm->msgs);
}
free(bm);
}
Expand All @@ -95,7 +91,6 @@ static void free_faction(faction * f)
free(f->name);
if (f->seen_factions) {
selist_free(f->seen_factions);
f->seen_factions = 0;
}

while (f->attribs) {
Expand All @@ -105,6 +100,7 @@ static void free_faction(faction * f)
i_freeall(&f->items);

freelist(f->origin);
free(f);
}

#define FMAXHASH 2039
Expand Down Expand Up @@ -335,7 +331,6 @@ void free_flist(faction **fp) {
faction *f = flist;
flist = f->next;
free_faction(f);
free(f);
}
*fp = NULL;
}
Expand Down
10 changes: 9 additions & 1 deletion src/kernel/messages.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ void syntax_error(const struct unit *u, struct order *ord)
}
}

void free_messagelist(mlist *msgs)
void free_mlist(mlist *msgs)
{
struct mlist **mlistptr;
for (mlistptr = &msgs; *mlistptr;) {
Expand All @@ -292,6 +292,14 @@ void free_messagelist(mlist *msgs)
}
}

void free_messagelist(message_list *msgs)
{
free_mlist(msgs->begin);
msgs->begin = NULL;
msgs->end = NULL;
free(msgs);
}

message *add_message(message_list ** pm, message * m)
{
if (m != NULL) {
Expand Down
3 changes: 2 additions & 1 deletion src/kernel/messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ struct message;
enum msg_t;

void message_handle_missing(int mode);
void free_messagelist(struct mlist *msgs);
void free_mlist(struct mlist *msgs);
void free_messagelist(struct message_list *msgs);

struct message *msg_message(const char *name, const char *sig, ...);
struct message *msg_feedback(const struct unit *, struct order *cmd,
Expand Down
8 changes: 3 additions & 5 deletions src/kernel/messages.test.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,9 @@ static void test_merge_split(CuTest *tc) {
CuAssertPtrEquals(tc, append->begin, mlist->begin->next);
split_messages(mlist, split);
CuAssertPtrEquals(tc, NULL, mlist->begin->next);
free_messagelist(*split);
free_messagelist(mlist->begin);
free(mlist);
free_messagelist(append->begin);
free(append);
free_mlist(*split);
free_messagelist(mlist);
free_messagelist(append);
test_teardown();
}

Expand Down
Loading