forked from github/server
remove order de-duplication for short and study orders.
This commit is contained in:
parent
828ca5f5f6
commit
97ff152f17
|
@ -31,21 +31,13 @@
|
||||||
#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 OD_LOCALE(odata) locale_array[(odata)->_lindex]->lang
|
# define OD_LOCALE(odata) ((odata) ? (odata)->lang : NULL)
|
||||||
# define OD_STRING(odata) (odata)->_str
|
# define OD_STRING(odata) ((odata) ? (odata)->_str : NULL)
|
||||||
|
|
||||||
typedef struct locale_data {
|
|
||||||
struct order_data *short_orders;
|
|
||||||
struct order_data *study_orders[MAXSKILLS];
|
|
||||||
const struct locale *lang;
|
|
||||||
} locale_data;
|
|
||||||
|
|
||||||
static struct locale_data *locale_array[MAXLOCALES];
|
|
||||||
|
|
||||||
typedef struct order_data {
|
typedef struct order_data {
|
||||||
const char *_str;
|
const char *_str;
|
||||||
int _refcount;
|
int _refcount;
|
||||||
int _lindex;
|
const struct locale *lang;
|
||||||
} order_data;
|
} order_data;
|
||||||
|
|
||||||
#include <selist.h>
|
#include <selist.h>
|
||||||
|
@ -53,15 +45,21 @@ typedef struct order_data {
|
||||||
static selist * orders;
|
static selist * orders;
|
||||||
|
|
||||||
order_data *load_data(int id) {
|
order_data *load_data(int id) {
|
||||||
|
if (id > 0) {
|
||||||
order_data * od = (order_data *)selist_get(orders, id - 1);
|
order_data * od = (order_data *)selist_get(orders, id - 1);
|
||||||
++od->_refcount;
|
++od->_refcount;
|
||||||
return od;
|
return od;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int add_data(order_data *od) {
|
int add_data(order_data *od) {
|
||||||
|
if (od->_str) {
|
||||||
++od->_refcount;
|
++od->_refcount;
|
||||||
selist_push(&orders, od);
|
selist_push(&orders, od);
|
||||||
return selist_length(orders);
|
return selist_length(orders);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void release_data(order_data * data)
|
static void release_data(order_data * data)
|
||||||
|
@ -219,103 +217,42 @@ void free_orders(order ** olist)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *mkdata(order_data **pdata, size_t len, int lindex, const char *str)
|
static char *mkdata(order_data **pdata, size_t len, const struct locale *lang, const char *str)
|
||||||
{
|
{
|
||||||
order_data *data;
|
order_data *data;
|
||||||
char *result;
|
char *result;
|
||||||
data = malloc(sizeof(order_data) + len + 1);
|
data = malloc(sizeof(order_data) + len + 1);
|
||||||
result = (char *)(data + 1);
|
result = (char *)(data + 1);
|
||||||
data->_lindex = lindex;
|
data->lang = lang;
|
||||||
data->_refcount = 0;
|
data->_refcount = 0;
|
||||||
data->_str = 0;
|
data->_str = (len > 0) ? result : NULL;
|
||||||
data->_str = (len > 0) ? result : 0;
|
|
||||||
if (str) strcpy(result, str);
|
if (str) strcpy(result, str);
|
||||||
if (pdata) *pdata = data;
|
if (pdata) *pdata = data;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static order_data *create_data(keyword_t kwd, const char *sptr, int lindex)
|
static order_data *create_data(keyword_t kwd, const char *sptr, const struct locale *lang)
|
||||||
{
|
{
|
||||||
const char *s = sptr;
|
const char *s = sptr;
|
||||||
order_data *data;
|
order_data *data;
|
||||||
const struct locale *lang = locale_array[lindex]->lang;
|
|
||||||
|
|
||||||
if (kwd != NOKEYWORD)
|
if (kwd != NOKEYWORD)
|
||||||
s = (*sptr) ? sptr : NULL;
|
s = (*sptr) ? sptr : NULL;
|
||||||
|
|
||||||
/* learning, only one order_data per skill required */
|
|
||||||
if (kwd == K_STUDY) {
|
|
||||||
skill_t sk = get_skill(parse_token_depr(&sptr), lang);
|
|
||||||
switch (sk) {
|
|
||||||
case NOSKILL: /* fehler */
|
|
||||||
break;
|
|
||||||
case SK_MAGIC: /* kann parameter haben */
|
|
||||||
if (*sptr != 0)
|
|
||||||
break;
|
|
||||||
default: /* nur skill als Parameter, keine extras */
|
|
||||||
data = locale_array[lindex]->study_orders[sk];
|
|
||||||
if (data == NULL) {
|
|
||||||
const char *skname = skillname(sk, lang);
|
|
||||||
const char *spc = strchr(skname, ' ');
|
|
||||||
size_t len = strlen(skname);
|
|
||||||
char *dst = mkdata(&data, len + (spc ? 3 : 0), lindex, spc ? 0 : skname);
|
|
||||||
locale_array[lindex]->study_orders[sk] = data;
|
|
||||||
if (spc) {
|
|
||||||
dst[0] = '\"';
|
|
||||||
memcpy(dst + 1, skname, len);
|
|
||||||
dst[len + 1] = '\"';
|
|
||||||
dst[len + 2] = '\0';
|
|
||||||
}
|
|
||||||
data->_refcount = 1;
|
|
||||||
}
|
|
||||||
++data->_refcount;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* orders with no parameter, only one order_data per order required */
|
/* orders with no parameter, only one order_data per order required */
|
||||||
else if (kwd != NOKEYWORD && *sptr == 0) {
|
if (kwd != NOKEYWORD && *sptr == 0) {
|
||||||
data = locale_array[lindex]->short_orders;
|
mkdata(&data, 0, lang, NULL);
|
||||||
if (data == NULL) {
|
|
||||||
mkdata(&data, 0, lindex, 0);
|
|
||||||
data->_refcount = 1;
|
|
||||||
locale_array[lindex]->short_orders = data;
|
|
||||||
}
|
|
||||||
++data->_refcount;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
mkdata(&data, s ? strlen(s) : 0, lindex, s);
|
|
||||||
data->_refcount = 1;
|
data->_refcount = 1;
|
||||||
return data;
|
return data;
|
||||||
}
|
|
||||||
|
|
||||||
static void clear_localedata(int lindex) {
|
|
||||||
int i;
|
|
||||||
release_data(locale_array[lindex]->short_orders);
|
|
||||||
locale_array[lindex]->short_orders = NULL;
|
|
||||||
for (i = 0; i != MAXSKILLS; ++i) {
|
|
||||||
release_data(locale_array[lindex]->study_orders[i]);
|
|
||||||
locale_array[lindex]->study_orders[i] = 0;
|
|
||||||
}
|
}
|
||||||
locale_array[lindex]->lang = 0;
|
mkdata(&data, s ? strlen(s) : 0, lang, s);
|
||||||
}
|
data->_refcount = 1;
|
||||||
|
return data;
|
||||||
void close_orders(void) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i != MAXLOCALES; ++i) {
|
|
||||||
if (locale_array[i]){
|
|
||||||
clear_localedata(i);
|
|
||||||
free(locale_array[i]);
|
|
||||||
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;
|
|
||||||
order_data *od;
|
order_data *od;
|
||||||
|
|
||||||
assert(ord);
|
assert(ord);
|
||||||
|
@ -335,16 +272,6 @@ static order *create_order_i(order *ord, keyword_t kwd, const char *sptr, bool p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lindex = locale_index(lang);
|
|
||||||
assert(lindex < MAXLOCALES);
|
|
||||||
if (!locale_array[lindex]) {
|
|
||||||
locale_array[lindex] = (locale_data *)calloc(1, sizeof(locale_data));
|
|
||||||
}
|
|
||||||
else if (locale_array[lindex]->lang != lang) {
|
|
||||||
clear_localedata(lindex);
|
|
||||||
}
|
|
||||||
locale_array[lindex]->lang = lang;
|
|
||||||
|
|
||||||
ord->command = (int)kwd;
|
ord->command = (int)kwd;
|
||||||
if (persistent) ord->command |= CMD_PERSIST;
|
if (persistent) ord->command |= CMD_PERSIST;
|
||||||
if (noerror) ord->command |= CMD_QUIET;
|
if (noerror) ord->command |= CMD_QUIET;
|
||||||
|
@ -352,7 +279,7 @@ static order *create_order_i(order *ord, keyword_t kwd, const char *sptr, bool p
|
||||||
|
|
||||||
while (isspace(*(unsigned char *)sptr)) ++sptr;
|
while (isspace(*(unsigned char *)sptr)) ++sptr;
|
||||||
|
|
||||||
od = create_data(kwd, sptr, lindex);
|
od = create_data(kwd, sptr, lang);
|
||||||
ord->id = add_data(od);
|
ord->id = add_data(od);
|
||||||
release_data(od);
|
release_data(od);
|
||||||
|
|
||||||
|
@ -630,21 +557,30 @@ void push_order(order ** ordp, order * ord)
|
||||||
*ordp = ord;
|
*ordp = ord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static order_data *parser_od;
|
||||||
|
|
||||||
keyword_t init_order(const struct order *ord)
|
keyword_t init_order(const struct order *ord)
|
||||||
{
|
{
|
||||||
static order_data *od;
|
|
||||||
|
|
||||||
if (!ord) {
|
if (!ord) {
|
||||||
release_data(od);
|
release_data(parser_od);
|
||||||
|
parser_od = NULL;
|
||||||
return NOKEYWORD;
|
return NOKEYWORD;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (od) {
|
if (parser_od) {
|
||||||
// TODO: warning
|
// TODO: warning
|
||||||
release_data(od);
|
release_data(parser_od);
|
||||||
}
|
}
|
||||||
od = load_data(ord->id);
|
parser_od = load_data(ord->id);
|
||||||
init_tokens_str(od->_str);
|
init_tokens_str(OD_STRING(parser_od));
|
||||||
return ORD_KEYWORD(ord);
|
return ORD_KEYWORD(ord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void close_orders(void) {
|
||||||
|
if (parser_od) {
|
||||||
|
init_order(NULL);
|
||||||
|
}
|
||||||
|
free_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -496,8 +496,8 @@ int sabotage_cmd(unit * u, struct order *ord)
|
||||||
|
|
||||||
init_order(ord);
|
init_order(ord);
|
||||||
s = getstrtoken();
|
s = getstrtoken();
|
||||||
|
|
||||||
p = findparam(s, u->faction->locale);
|
p = findparam(s, u->faction->locale);
|
||||||
|
init_order(NULL);
|
||||||
|
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case P_SHIP:
|
case P_SHIP:
|
||||||
|
|
|
@ -448,6 +448,7 @@ int teach_cmd(unit * teacher, struct order *ord)
|
||||||
if (academy_students > 0 && sk_academy!=NOSKILL) {
|
if (academy_students > 0 && sk_academy!=NOSKILL) {
|
||||||
academy_teaching_bonus(teacher, sk_academy, academy_students);
|
academy_teaching_bonus(teacher, sk_academy, academy_students);
|
||||||
}
|
}
|
||||||
|
init_order(NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -784,7 +785,7 @@ int study_cmd(unit * u, order * ord)
|
||||||
mage = create_mage(u, u->faction->magiegebiet);
|
mage = create_mage(u, u->faction->magiegebiet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
init_order(NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue