forked from github/server
refactor: split order_data from order, force use of ids (to be replaced with db backend).
This commit is contained in:
parent
0ffb4e3ca9
commit
828ca5f5f6
|
@ -31,8 +31,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
# define ORD_KEYWORD(ord) (keyword_t)((ord)->command & 0xFFFF)
|
# define ORD_KEYWORD(ord) (keyword_t)((ord)->command & 0xFFFF)
|
||||||
# define ORD_LOCALE(ord) locale_array[(ord)->data->_lindex]->lang
|
# define OD_LOCALE(odata) locale_array[(odata)->_lindex]->lang
|
||||||
# define ORD_STRING(ord) (ord)->data->_str
|
# define OD_STRING(odata) (odata)->_str
|
||||||
|
|
||||||
typedef struct locale_data {
|
typedef struct locale_data {
|
||||||
struct order_data *short_orders;
|
struct order_data *short_orders;
|
||||||
|
@ -48,6 +48,22 @@ typedef struct order_data {
|
||||||
int _lindex;
|
int _lindex;
|
||||||
} order_data;
|
} order_data;
|
||||||
|
|
||||||
|
#include <selist.h>
|
||||||
|
|
||||||
|
static selist * orders;
|
||||||
|
|
||||||
|
order_data *load_data(int id) {
|
||||||
|
order_data * od = (order_data *)selist_get(orders, id - 1);
|
||||||
|
++od->_refcount;
|
||||||
|
return od;
|
||||||
|
}
|
||||||
|
|
||||||
|
int add_data(order_data *od) {
|
||||||
|
++od->_refcount;
|
||||||
|
selist_push(&orders, od);
|
||||||
|
return selist_length(orders);
|
||||||
|
}
|
||||||
|
|
||||||
static void release_data(order_data * data)
|
static void release_data(order_data * data)
|
||||||
{
|
{
|
||||||
if (data) {
|
if (data) {
|
||||||
|
@ -57,6 +73,20 @@ static void release_data(order_data * data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_data_cb(void *entry) {
|
||||||
|
order_data *od = (order_data *)entry;
|
||||||
|
if (od->_refcount > 1) {
|
||||||
|
log_error("refcount=%d for order %s", od->_refcount, od->_str);
|
||||||
|
}
|
||||||
|
release_data(od);
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_data(void) {
|
||||||
|
selist_foreach(orders, free_data_cb);
|
||||||
|
selist_free(orders);
|
||||||
|
orders = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void replace_order(order ** dlist, order * orig, const order * src)
|
void replace_order(order ** dlist, order * orig, const order * src)
|
||||||
{
|
{
|
||||||
assert(src);
|
assert(src);
|
||||||
|
@ -64,7 +94,7 @@ void replace_order(order ** dlist, order * orig, const order * src)
|
||||||
assert(dlist);
|
assert(dlist);
|
||||||
while (*dlist != NULL) {
|
while (*dlist != NULL) {
|
||||||
order *dst = *dlist;
|
order *dst = *dlist;
|
||||||
if (dst->data == orig->data) {
|
if (dst->id == orig->id) {
|
||||||
order *cpy = copy_order(src);
|
order *cpy = copy_order(src);
|
||||||
*dlist = cpy;
|
*dlist = cpy;
|
||||||
cpy->next = dst->next;
|
cpy->next = dst->next;
|
||||||
|
@ -89,7 +119,8 @@ keyword_t getkeyword(const order * ord)
|
||||||
*/
|
*/
|
||||||
char* get_command(const order *ord, char *sbuffer, size_t size) {
|
char* get_command(const order *ord, char *sbuffer, size_t size) {
|
||||||
char *bufp = sbuffer;
|
char *bufp = sbuffer;
|
||||||
const char *text = ORD_STRING(ord);
|
order_data *od;
|
||||||
|
const char * text;
|
||||||
keyword_t kwd = ORD_KEYWORD(ord);
|
keyword_t kwd = ORD_KEYWORD(ord);
|
||||||
int bytes;
|
int bytes;
|
||||||
|
|
||||||
|
@ -111,8 +142,11 @@ char* get_command(const order *ord, char *sbuffer, size_t size) {
|
||||||
WARN_STATIC_BUFFER();
|
WARN_STATIC_BUFFER();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
od = load_data(ord->id);
|
||||||
|
text = OD_STRING(od);
|
||||||
if (kwd != NOKEYWORD) {
|
if (kwd != NOKEYWORD) {
|
||||||
const struct locale *lang = ORD_LOCALE(ord);
|
const struct locale *lang = OD_LOCALE(od);
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
const char *str = (const char *)LOC(lang, keyword(kwd));
|
const char *str = (const char *)LOC(lang, keyword(kwd));
|
||||||
assert(str);
|
assert(str);
|
||||||
|
@ -142,6 +176,7 @@ char* get_command(const order *ord, char *sbuffer, size_t size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
release_data(od);
|
||||||
if (size > 0) *bufp = 0;
|
if (size > 0) *bufp = 0;
|
||||||
return sbuffer;
|
return sbuffer;
|
||||||
}
|
}
|
||||||
|
@ -150,8 +185,6 @@ void free_order(order * ord)
|
||||||
{
|
{
|
||||||
if (ord != NULL) {
|
if (ord != NULL) {
|
||||||
assert(ord->next == 0);
|
assert(ord->next == 0);
|
||||||
|
|
||||||
release_data(ord->data);
|
|
||||||
free(ord);
|
free(ord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -162,8 +195,7 @@ order *copy_order(const order * src)
|
||||||
order *ord = (order *)malloc(sizeof(order));
|
order *ord = (order *)malloc(sizeof(order));
|
||||||
ord->next = NULL;
|
ord->next = NULL;
|
||||||
ord->command = src->command;
|
ord->command = src->command;
|
||||||
ord->data = src->data;
|
ord->id = src->id;
|
||||||
++ord->data->_refcount;
|
|
||||||
return ord;
|
return ord;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -277,12 +309,14 @@ void close_orders(void) {
|
||||||
locale_array[i] = 0;
|
locale_array[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free_data();
|
||||||
}
|
}
|
||||||
|
|
||||||
static order *create_order_i(order *ord, keyword_t kwd, const char *sptr, bool persistent,
|
static order *create_order_i(order *ord, keyword_t kwd, const char *sptr, bool persistent,
|
||||||
bool noerror, const struct locale *lang)
|
bool noerror, const struct locale *lang)
|
||||||
{
|
{
|
||||||
int lindex;
|
int lindex;
|
||||||
|
order_data *od;
|
||||||
|
|
||||||
assert(ord);
|
assert(ord);
|
||||||
if (kwd == NOKEYWORD || keyword_disabled(kwd)) {
|
if (kwd == NOKEYWORD || keyword_disabled(kwd)) {
|
||||||
|
@ -317,7 +351,10 @@ static order *create_order_i(order *ord, keyword_t kwd, const char *sptr, bool p
|
||||||
ord->next = NULL;
|
ord->next = NULL;
|
||||||
|
|
||||||
while (isspace(*(unsigned char *)sptr)) ++sptr;
|
while (isspace(*(unsigned char *)sptr)) ++sptr;
|
||||||
ord->data = create_data(kwd, sptr, lindex);
|
|
||||||
|
od = create_data(kwd, sptr, lindex);
|
||||||
|
ord->id = add_data(od);
|
||||||
|
release_data(od);
|
||||||
|
|
||||||
return ord;
|
return ord;
|
||||||
}
|
}
|
||||||
|
@ -573,9 +610,11 @@ char *write_order(const order * ord, char *buffer, size_t size)
|
||||||
else {
|
else {
|
||||||
keyword_t kwd = ORD_KEYWORD(ord);
|
keyword_t kwd = ORD_KEYWORD(ord);
|
||||||
if (kwd == NOKEYWORD) {
|
if (kwd == NOKEYWORD) {
|
||||||
const char *text = ORD_STRING(ord);
|
order_data *od = load_data(ord->id);
|
||||||
|
const char *text = OD_STRING(od);
|
||||||
if (text) strlcpy(buffer, (const char *)text, size);
|
if (text) strlcpy(buffer, (const char *)text, size);
|
||||||
else buffer[0] = 0;
|
else buffer[0] = 0;
|
||||||
|
release_data(od);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
get_command(ord, buffer, size);
|
get_command(ord, buffer, size);
|
||||||
|
@ -593,7 +632,19 @@ void push_order(order ** ordp, order * ord)
|
||||||
|
|
||||||
keyword_t init_order(const struct order *ord)
|
keyword_t init_order(const struct order *ord)
|
||||||
{
|
{
|
||||||
assert(ord && ord->data);
|
static order_data *od;
|
||||||
init_tokens_str(ord->data->_str);
|
|
||||||
return ORD_KEYWORD(ord);
|
if (!ord) {
|
||||||
|
release_data(od);
|
||||||
|
return NOKEYWORD;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (od) {
|
||||||
|
// TODO: warning
|
||||||
|
release_data(od);
|
||||||
|
}
|
||||||
|
od = load_data(ord->id);
|
||||||
|
init_tokens_str(od->_str);
|
||||||
|
return ORD_KEYWORD(ord);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,6 @@ 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;
|
|
||||||
|
|
||||||
#define CMD_QUIET 0x010000
|
#define CMD_QUIET 0x010000
|
||||||
#define CMD_PERSIST 0x020000
|
#define CMD_PERSIST 0x020000
|
||||||
#define CMD_DEFAULT 0x040000
|
#define CMD_DEFAULT 0x040000
|
||||||
|
@ -39,7 +37,7 @@ extern "C" {
|
||||||
typedef struct order {
|
typedef struct order {
|
||||||
struct order *next;
|
struct order *next;
|
||||||
/* do not access this data: */
|
/* do not access this data: */
|
||||||
struct order_data *data;
|
int id;
|
||||||
int command;
|
int command;
|
||||||
} order;
|
} order;
|
||||||
|
|
||||||
|
|
|
@ -48,35 +48,35 @@ static void test_parse_order(CuTest *tc) {
|
||||||
|
|
||||||
ord = parse_order("!MOVE NORTH", lang);
|
ord = parse_order("!MOVE NORTH", lang);
|
||||||
CuAssertPtrNotNull(tc, ord);
|
CuAssertPtrNotNull(tc, ord);
|
||||||
CuAssertPtrNotNull(tc, ord->data);
|
CuAssertTrue(tc, ord->id > 0);
|
||||||
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
||||||
CuAssertIntEquals(tc, K_MOVE | CMD_QUIET, ord->command);
|
CuAssertIntEquals(tc, K_MOVE | CMD_QUIET, ord->command);
|
||||||
free_order(ord);
|
free_order(ord);
|
||||||
|
|
||||||
ord = parse_order("@MOVE NORTH", lang);
|
ord = parse_order("@MOVE NORTH", lang);
|
||||||
CuAssertPtrNotNull(tc, ord);
|
CuAssertPtrNotNull(tc, ord);
|
||||||
CuAssertPtrNotNull(tc, ord->data);
|
CuAssertTrue(tc, ord->id > 0);
|
||||||
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
||||||
CuAssertIntEquals(tc, K_MOVE | CMD_PERSIST, ord->command);
|
CuAssertIntEquals(tc, K_MOVE | CMD_PERSIST, ord->command);
|
||||||
free_order(ord);
|
free_order(ord);
|
||||||
|
|
||||||
ord = parse_order("!@MOVE NORTH", lang);
|
ord = parse_order("!@MOVE NORTH", lang);
|
||||||
CuAssertPtrNotNull(tc, ord);
|
CuAssertPtrNotNull(tc, ord);
|
||||||
CuAssertPtrNotNull(tc, ord->data);
|
CuAssertTrue(tc, ord->id > 0);
|
||||||
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
||||||
CuAssertIntEquals(tc, K_MOVE | CMD_PERSIST | CMD_QUIET, ord->command);
|
CuAssertIntEquals(tc, K_MOVE | CMD_PERSIST | CMD_QUIET, ord->command);
|
||||||
free_order(ord);
|
free_order(ord);
|
||||||
|
|
||||||
ord = parse_order("@!MOVE NORTH", lang);
|
ord = parse_order("@!MOVE NORTH", lang);
|
||||||
CuAssertPtrNotNull(tc, ord);
|
CuAssertPtrNotNull(tc, ord);
|
||||||
CuAssertPtrNotNull(tc, ord->data);
|
CuAssertTrue(tc, ord->id > 0);
|
||||||
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
||||||
CuAssertIntEquals(tc, K_MOVE | CMD_PERSIST | CMD_QUIET, ord->command);
|
CuAssertIntEquals(tc, K_MOVE | CMD_PERSIST | CMD_QUIET, ord->command);
|
||||||
free_order(ord);
|
free_order(ord);
|
||||||
|
|
||||||
ord = parse_order(" !@MOVE NORTH", lang);
|
ord = parse_order(" !@MOVE NORTH", lang);
|
||||||
CuAssertPtrNotNull(tc, ord);
|
CuAssertPtrNotNull(tc, ord);
|
||||||
CuAssertPtrNotNull(tc, ord->data);
|
CuAssertTrue(tc, ord->id > 0);
|
||||||
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
||||||
CuAssertIntEquals(tc, K_MOVE | CMD_PERSIST | CMD_QUIET, ord->command);
|
CuAssertIntEquals(tc, K_MOVE | CMD_PERSIST | CMD_QUIET, ord->command);
|
||||||
free_order(ord);
|
free_order(ord);
|
||||||
|
|
|
@ -1005,7 +1005,7 @@ static void test_long_order_normal(CuTest *tc) {
|
||||||
fset(u, UFL_LONGACTION);
|
fset(u, UFL_LONGACTION);
|
||||||
unit_addorder(u, ord = create_order(K_MOVE, u->faction->locale, 0));
|
unit_addorder(u, ord = create_order(K_MOVE, u->faction->locale, 0));
|
||||||
update_long_order(u);
|
update_long_order(u);
|
||||||
CuAssertPtrEquals(tc, ord->data, u->thisorder->data);
|
CuAssertIntEquals(tc, ord->id, u->thisorder->id);
|
||||||
CuAssertIntEquals(tc, 0, fval(u, UFL_MOVED));
|
CuAssertIntEquals(tc, 0, fval(u, UFL_MOVED));
|
||||||
CuAssertIntEquals(tc, 0, fval(u, UFL_LONGACTION));
|
CuAssertIntEquals(tc, 0, fval(u, UFL_LONGACTION));
|
||||||
CuAssertPtrNotNull(tc, u->orders);
|
CuAssertPtrNotNull(tc, u->orders);
|
||||||
|
|
Loading…
Reference in New Issue