forked from github/server
Reference-counting in Befehlen. Derzeit nur für Befehle ohne Parameter.
This commit is contained in:
parent
43f7c7413c
commit
c755cf39f2
|
@ -3450,7 +3450,7 @@ setdefaults (void)
|
||||||
}
|
}
|
||||||
#ifdef LASTORDER
|
#ifdef LASTORDER
|
||||||
/* by default the default long order becomes the new long order. */
|
/* by default the default long order becomes the new long order. */
|
||||||
u->thisorder = duplicate_order(u->lastorder);
|
u->thisorder = copy_order(u->lastorder);
|
||||||
#endif
|
#endif
|
||||||
/* check all orders for a potential new long order this round: */
|
/* check all orders for a potential new long order this round: */
|
||||||
for (ord = u->orders; ord; ord = ord->next) {
|
for (ord = u->orders; ord; ord = ord->next) {
|
||||||
|
|
|
@ -3780,7 +3780,7 @@ report_init(void)
|
||||||
add_function("spell", &eval_spell);
|
add_function("spell", &eval_spell);
|
||||||
|
|
||||||
register_argtype("string", free, (void*(*)(void*))strdup);
|
register_argtype("string", free, (void*(*)(void*))strdup);
|
||||||
register_argtype("order", (void(*)(void*))free_order, (void*(*)(void*))duplicate_order);
|
register_argtype("order", (void(*)(void*))free_order, (void*(*)(void*))copy_order);
|
||||||
register_function((pf_generic)view_neighbours, "view_neighbours");
|
register_function((pf_generic)view_neighbours, "view_neighbours");
|
||||||
register_function((pf_generic)view_regatta, "view_regatta");
|
register_function((pf_generic)view_regatta, "view_regatta");
|
||||||
}
|
}
|
||||||
|
|
|
@ -427,7 +427,7 @@ teach(unit * u, struct order * ord)
|
||||||
#ifdef LASTORDER
|
#ifdef LASTORDER
|
||||||
set_order(&u->lastorder, new_order);
|
set_order(&u->lastorder, new_order);
|
||||||
#else
|
#else
|
||||||
copy_order(ord, new_order);
|
replace_order(ord, new_order);
|
||||||
#endif
|
#endif
|
||||||
free_order(new_order); /* parse_order & set_order have each increased the refcount */
|
free_order(new_order); /* parse_order & set_order have each increased the refcount */
|
||||||
}
|
}
|
||||||
|
|
|
@ -934,7 +934,7 @@ build_building(unit * u, const building_type * btype, int want, order * ord)
|
||||||
#ifdef LASTORDER
|
#ifdef LASTORDER
|
||||||
set_order(&u->lastorder, new_order);
|
set_order(&u->lastorder, new_order);
|
||||||
#else
|
#else
|
||||||
copy_order(ord, new_order);
|
replace_order(ord, new_order);
|
||||||
#endif
|
#endif
|
||||||
free_order(new_order);
|
free_order(new_order);
|
||||||
|
|
||||||
|
@ -1028,7 +1028,7 @@ create_ship(region * r, unit * u, const struct ship_type * newtype, int want, or
|
||||||
#ifdef LASTORDER
|
#ifdef LASTORDER
|
||||||
set_order(&u->lastorder, new_order);
|
set_order(&u->lastorder, new_order);
|
||||||
#else
|
#else
|
||||||
copy_order(ord, new_order);
|
replace_order(ord, new_order);
|
||||||
#endif
|
#endif
|
||||||
free_order(new_order);
|
free_order(new_order);
|
||||||
|
|
||||||
|
|
|
@ -2004,7 +2004,7 @@ new_castorder(void *u, unit *u2, spell *sp, region *r, int lev,
|
||||||
corder->force = force;
|
corder->force = force;
|
||||||
corder->rt = r;
|
corder->rt = r;
|
||||||
corder->distance = range;
|
corder->distance = range;
|
||||||
corder->order = duplicate_order(ord);
|
corder->order = copy_order(ord);
|
||||||
corder->par = p;
|
corder->par = p;
|
||||||
|
|
||||||
return corder;
|
return corder;
|
||||||
|
|
|
@ -332,7 +332,7 @@ mistake(const unit * u, struct order * ord, const char *comment, int mtype)
|
||||||
if (u->faction->no != MONSTER_FACTION) {
|
if (u->faction->no != MONSTER_FACTION) {
|
||||||
char * cmt = strdup(comment);
|
char * cmt = strdup(comment);
|
||||||
ADDMSG(&u->faction->msgs, msg_message("mistake",
|
ADDMSG(&u->faction->msgs, msg_message("mistake",
|
||||||
"command error unit region", duplicate_order(ord), cmt, u, u->region));
|
"command error unit region", copy_order(ord), cmt, u, u->region));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +345,7 @@ cmistake(const unit * u, struct order *ord, int mno, int mtype)
|
||||||
if (u->faction->no == MONSTER_FACTION) return;
|
if (u->faction->no == MONSTER_FACTION) return;
|
||||||
sprintf(ebuf, "error%d", mno);
|
sprintf(ebuf, "error%d", mno);
|
||||||
ADDMSG(&u->faction->msgs, msg_message(ebuf,
|
ADDMSG(&u->faction->msgs, msg_message(ebuf,
|
||||||
"command unit region", duplicate_order(ord), u, u->region));
|
"command unit region", copy_order(ord), u, u->region));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern unsigned int new_hashstring(const char* s);
|
extern unsigned int new_hashstring(const char* s);
|
||||||
|
|
|
@ -914,7 +914,7 @@ cycle_route(order * ord, unit *u, int gereist)
|
||||||
#ifdef LASTORDER
|
#ifdef LASTORDER
|
||||||
set_order(&u->lastorder, norder);
|
set_order(&u->lastorder, norder);
|
||||||
#else
|
#else
|
||||||
copy_order(ord, norder);
|
replace_order(ord, norder);
|
||||||
#endif
|
#endif
|
||||||
free_order(norder);
|
free_order(norder);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,19 +21,40 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static const struct locale * locale_array[16];
|
typedef struct locale_data {
|
||||||
|
struct order_data * short_orders[MAXKEYWORDS];
|
||||||
|
const struct locale * lang;
|
||||||
|
} locale_data;
|
||||||
|
|
||||||
|
static struct locale_data * locale_array[16];
|
||||||
static int nlocales = 0;
|
static int nlocales = 0;
|
||||||
|
|
||||||
#undef SHORT_STRINGS
|
#undef SHORT_STRINGS
|
||||||
|
|
||||||
void
|
typedef struct order_data {
|
||||||
copy_order(order * dst, const order * src)
|
char * _str;
|
||||||
|
keyword_t _keyword;
|
||||||
|
int _lindex : 7;
|
||||||
|
int _refcount : 16;
|
||||||
|
} order_data;
|
||||||
|
|
||||||
|
static void
|
||||||
|
release_data(order_data * data)
|
||||||
{
|
{
|
||||||
if (dst->_str) free(dst->_str);
|
if (data) {
|
||||||
if (src->_str) dst->_str = strdup(src->_str);
|
if (--data->_refcount == 0) {
|
||||||
else dst->_str = NULL;
|
if (data->_str) free(data->_str);
|
||||||
dst->_keyword = src->_keyword;
|
free(data);
|
||||||
dst->_lindex = src->_lindex;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
replace_order(order * dst, const order * src)
|
||||||
|
{
|
||||||
|
release_data(dst->data);
|
||||||
|
dst->data = src->data;
|
||||||
|
++src->data->_refcount;
|
||||||
dst->_persistent = src->_persistent;
|
dst->_persistent = src->_persistent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +64,7 @@ get_keyword(const order * ord)
|
||||||
if (ord==NULL) {
|
if (ord==NULL) {
|
||||||
return NOKEYWORD;
|
return NOKEYWORD;
|
||||||
}
|
}
|
||||||
return ord->_keyword;
|
return ord->data->_keyword;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
|
@ -52,39 +73,45 @@ getcommand(const order * ord)
|
||||||
char sbuffer[DISPLAYSIZE*2];
|
char sbuffer[DISPLAYSIZE*2];
|
||||||
char * str = sbuffer;
|
char * str = sbuffer;
|
||||||
|
|
||||||
assert(ord->_lindex<nlocales);
|
assert(ord->data->_lindex<nlocales);
|
||||||
if (ord->_persistent) *str++ = '@';
|
if (ord->_persistent) *str++ = '@';
|
||||||
#ifdef SHORT_STRINGS
|
#ifdef SHORT_STRINGS
|
||||||
if (ord->_keyword!=NOKEYWORD) {
|
if (ord->data->_keyword!=NOKEYWORD) {
|
||||||
const struct locale * lang = locale_array[ord->_lindex];
|
const struct locale * lang = locale_array[ord->data->_lindex]->lang;
|
||||||
|
|
||||||
strcpy(str, LOC(lang, keywords[ord->_keyword]));
|
strcpy(str, LOC(lang, keywords[ord->data->_keyword]));
|
||||||
str += strlen(str);
|
str += strlen(str);
|
||||||
if (ord->_str) {
|
if (ord->data->_str) {
|
||||||
*str++ = ' ';
|
*str++ = ' ';
|
||||||
*str = 0;
|
*str = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (ord->_str) strcpy(str, ord->_str);
|
if (ord->data->_str) strcpy(str, ord->data->_str);
|
||||||
return strdup(sbuffer);
|
return strdup(sbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
free_order(order * ord)
|
free_order(order * ord)
|
||||||
{
|
{
|
||||||
if (ord!=NULL && --ord->_refcount==0) {
|
if (ord!=NULL) {
|
||||||
assert(ord->next==NULL);
|
release_data(ord->data);
|
||||||
if (ord->_str!=NULL) free(ord->_str);
|
|
||||||
free(ord);
|
free(ord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
order *
|
order *
|
||||||
duplicate_order(order * ord)
|
copy_order(order * src)
|
||||||
{
|
{
|
||||||
if (ord!=NULL) ++ord->_refcount;
|
if (src!=NULL) {
|
||||||
return ord;
|
order * ord = (order*)malloc(sizeof(order));
|
||||||
|
ord->next = NULL;
|
||||||
|
ord->_persistent = src->_persistent;
|
||||||
|
ord->data = src->data;
|
||||||
|
++ord->data->_refcount;
|
||||||
|
return ord;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -92,7 +119,7 @@ set_order(struct order ** destp, struct order * src)
|
||||||
{
|
{
|
||||||
if (*destp==src) return;
|
if (*destp==src) return;
|
||||||
free_order(*destp);
|
free_order(*destp);
|
||||||
*destp = duplicate_order(src);
|
*destp = copy_order(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -126,6 +153,7 @@ parse_order(const char * s, const struct locale * lang)
|
||||||
#endif
|
#endif
|
||||||
sptr = s;
|
sptr = s;
|
||||||
kwd = findkeyword(parse_token(&sptr), lang);
|
kwd = findkeyword(parse_token(&sptr), lang);
|
||||||
|
while (isspace(*(unsigned char*)sptr)) ++sptr;
|
||||||
|
|
||||||
/* if this is just nonsense, then we skip it. */
|
/* if this is just nonsense, then we skip it. */
|
||||||
if (lomem) {
|
if (lomem) {
|
||||||
|
@ -138,30 +166,50 @@ parse_order(const char * s, const struct locale * lang)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ord = (order*)malloc(sizeof(order));
|
|
||||||
for (i=0;i!=nlocales;++i) {
|
for (i=0;i!=nlocales;++i) {
|
||||||
if (locale_array[i]==lang) break;
|
if (locale_array[i]->lang==lang) break;
|
||||||
}
|
}
|
||||||
if (i==nlocales) locale_array[nlocales++] = lang;
|
if (i==nlocales) {
|
||||||
ord->_lindex = (unsigned char)i;
|
locale_array[nlocales] = (locale_data*)calloc(1, sizeof(locale_data));
|
||||||
ord->_str = NULL;
|
locale_array[nlocales]->lang = lang;
|
||||||
|
++nlocales;
|
||||||
|
}
|
||||||
|
|
||||||
|
ord = (order*)malloc(sizeof(order));
|
||||||
ord->_persistent = persistent;
|
ord->_persistent = persistent;
|
||||||
ord->_refcount = 1;
|
|
||||||
ord->next = NULL;
|
ord->next = NULL;
|
||||||
|
|
||||||
ord->_keyword = kwd;
|
if (kwd!=NOKEYWORD && *sptr == 0) {
|
||||||
#ifdef SHORT_STRINGS
|
ord->data = locale_array[i]->short_orders[kwd];
|
||||||
if (ord->_keyword==NOKEYWORD) {
|
if (ord->data != NULL) {
|
||||||
ord->_str = strdup(s);
|
++ord->data->_refcount;
|
||||||
} else {
|
|
||||||
while (isspace(*(unsigned char*)sptr)) ++sptr;
|
|
||||||
if (*sptr) {
|
|
||||||
ord->_str = strdup(sptr);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
ord->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ord->data==NULL) {
|
||||||
|
ord->data = (order_data*)malloc(sizeof(order_data));
|
||||||
|
ord->data->_lindex = (unsigned char)i;
|
||||||
|
ord->data->_str = NULL;
|
||||||
|
ord->data->_refcount = 1;
|
||||||
|
ord->data->_keyword = kwd;
|
||||||
|
if (kwd!=NOKEYWORD && *sptr == 0) {
|
||||||
|
locale_array[i]->short_orders[kwd] = ord->data;
|
||||||
|
++ord->data->_refcount;
|
||||||
|
}
|
||||||
|
#ifdef SHORT_STRINGS
|
||||||
|
if (ord->data->_keyword==NOKEYWORD) {
|
||||||
|
ord->data->_str = strdup(s);
|
||||||
|
} else {
|
||||||
|
if (*sptr) {
|
||||||
|
ord->data->_str = strdup(sptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
ord->_str = strdup(s);
|
ord->data->_str = strdup(s);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
return ord;
|
return ord;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,10 +217,10 @@ parse_order(const char * s, const struct locale * lang)
|
||||||
boolean
|
boolean
|
||||||
is_repeated(const order * ord)
|
is_repeated(const order * ord)
|
||||||
{
|
{
|
||||||
const struct locale * lang = locale_array[ord->_lindex];
|
const struct locale * lang = locale_array[ord->data->_lindex]->lang;
|
||||||
param_t param;
|
param_t param;
|
||||||
|
|
||||||
switch (ord->_keyword) {
|
switch (ord->data->_keyword) {
|
||||||
case K_CAST:
|
case K_CAST:
|
||||||
case K_BUY:
|
case K_BUY:
|
||||||
case K_SELL:
|
case K_SELL:
|
||||||
|
@ -229,10 +277,10 @@ is_repeated(const order * ord)
|
||||||
boolean
|
boolean
|
||||||
is_exclusive(const order * ord)
|
is_exclusive(const order * ord)
|
||||||
{
|
{
|
||||||
const struct locale * lang = locale_array[ord->_lindex];
|
const struct locale * lang = locale_array[ord->data->_lindex]->lang;
|
||||||
param_t param;
|
param_t param;
|
||||||
|
|
||||||
switch (ord->_keyword) {
|
switch (ord->data->_keyword) {
|
||||||
case K_MOVE:
|
case K_MOVE:
|
||||||
case K_WEREWOLF:
|
case K_WEREWOLF:
|
||||||
/* these should not become persistent */
|
/* these should not become persistent */
|
||||||
|
@ -290,7 +338,7 @@ boolean
|
||||||
is_persistent(const order * ord)
|
is_persistent(const order * ord)
|
||||||
{
|
{
|
||||||
boolean persist = ord->_persistent!=0;
|
boolean persist = ord->_persistent!=0;
|
||||||
switch (ord->_keyword) {
|
switch (ord->data->_keyword) {
|
||||||
case K_MOVE:
|
case K_MOVE:
|
||||||
case K_WEREWOLF:
|
case K_WEREWOLF:
|
||||||
case NOKEYWORD:
|
case NOKEYWORD:
|
||||||
|
@ -308,7 +356,7 @@ is_persistent(const order * ord)
|
||||||
char *
|
char *
|
||||||
write_order(const order * ord, const struct locale * lang, char * buffer, size_t size)
|
write_order(const order * ord, const struct locale * lang, char * buffer, size_t size)
|
||||||
{
|
{
|
||||||
if (ord==0 || ord->_keyword==NOKEYWORD) {
|
if (ord==0 || ord->data->_keyword==NOKEYWORD) {
|
||||||
buffer[0]=0;
|
buffer[0]=0;
|
||||||
} else {
|
} else {
|
||||||
char * s = getcommand(ord);
|
char * s = getcommand(ord);
|
||||||
|
|
|
@ -25,22 +25,21 @@ extern "C" {
|
||||||
* implemented yet) saving approx. 50% of all string-related memory.
|
* implemented yet) saving approx. 50% of all string-related memory.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct order_data;
|
||||||
|
|
||||||
typedef struct order {
|
typedef struct order {
|
||||||
struct order * next;
|
struct order * next;
|
||||||
/* do not access this data: */
|
/* do not access this data: */
|
||||||
char * _str;
|
struct order_data * data;
|
||||||
keyword_t _keyword;
|
|
||||||
int _lindex : 7;
|
|
||||||
int _persistent : 1;
|
int _persistent : 1;
|
||||||
int _refcount : 16;
|
|
||||||
} order;
|
} order;
|
||||||
|
|
||||||
/* constructor */
|
/* constructor */
|
||||||
extern struct order * parse_order(const char * s, const struct locale * lang);
|
extern struct order * parse_order(const char * s, const struct locale * lang);
|
||||||
extern void copy_order(order * dst, const order * src);
|
extern void replace_order(order * dst, const order * src);
|
||||||
|
|
||||||
/* reference counted copies of orders: */
|
/* reference counted copies of orders: */
|
||||||
extern struct order * duplicate_order(struct order * ord);
|
extern struct order * copy_order(struct order * ord);
|
||||||
extern void free_order(struct order * ord);
|
extern void free_order(struct order * ord);
|
||||||
extern void free_orders(struct order ** olist);
|
extern void free_orders(struct order ** olist);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue