Freeciv-3.3
Loading...
Searching...
No Matches
global_worklist.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13#ifdef HAVE_CONFIG_H
14#include <fc_config.h>
15#endif
16
17#include <stdarg.h>
18
19/* utility */
20#include "fcintl.h"
21#include "log.h"
22#include "mem.h"
23#include "registry.h"
24#include "shared.h"
25#include "support.h"
26
27/* common */
28#include "fc_types.h"
29#include "requirements.h"
30#include "worklist.h"
31
32/* client */
33#include "client_main.h"
34
35#include "global_worklist.h"
36
38 /* Means we have a list of kind of universal and their name, but we
39 * don't know the id they could have on the server's ruleset. In this
40 * case, we use the unbuilt part and not the worklist one. */
42
43 /* Means this worklist is plainly usable at running time. */
45};
46
47
48/* The global worklist structure. */
50 int id;
53 union {
54 struct {
55 int length;
56 struct uni_name {
57 char *kind;
58 char *name;
62 };
63};
64
65static bool global_worklist_load(struct section_file *file,
66 const char *path, ...)
70 const char *path, ...)
72
73/*******************************************************************/
82
83/*******************************************************************/
96
97/*******************************************************************/
101{
103 if (pgwl->status == STATUS_UNBUILT) {
104 struct worklist worklist;
105 struct uni_name *puni_name;
106 int i;
107
108 /* Build a worklist. */
110 for (i = 0; i < pgwl->unbuilt.length; i++) {
111 struct universal source;
112
113 puni_name = pgwl->unbuilt.entries + i;
115 if (source.kind == universals_n_invalid()) {
116 /* This worklist is not valid on this ruleset.
117 * N.B.: Don't remove it to resave it in client rc file. */
118 break;
119 } else {
121 }
122 }
123
124 if (worklist_length(&worklist) != pgwl->unbuilt.length) {
125 /* Somewhat in this worklist is not supported by the current
126 * ruleset. Don't try to build it, but keep it for later save. */
127 continue;
128 }
129
130 /* Now the worklist is built, change status. */
131 for (i = 0; i < pgwl->unbuilt.length; i++) {
132 puni_name = pgwl->unbuilt.entries + i;
133 free(puni_name->kind);
134 free(puni_name->name);
135 }
136 pgwl->status = STATUS_WORKLIST;
137 worklist_copy(&pgwl->worklist, &worklist);
138 }
140}
141
142/*******************************************************************/
146{
148 if (pgwl->status == STATUS_WORKLIST) {
149 struct worklist worklist;
150 struct uni_name *puni_name;
151 int i;
152
153 /* Copy before over-write. */
154 worklist_copy(&worklist, &pgwl->worklist);
155 pgwl->status = STATUS_UNBUILT;
156
157 pgwl->unbuilt.length = worklist_length(&worklist);
158 for (i = 0; i < worklist_length(&worklist); i++) {
159 puni_name = pgwl->unbuilt.entries + i;
160 puni_name->kind =
162 puni_name->name =
164 }
165 }
167}
168
169/*******************************************************************/
174{
175 int count = 0;
176
178 count++;
180
181 return count;
182}
183
184/*******************************************************************/
187static struct global_worklist *
189{
190 static int last_id = 0;
191 struct global_worklist *pgwl = fc_calloc(1, sizeof(struct global_worklist));
192
193 pgwl->id = ++last_id;
194 pgwl->status = type;
195
196 /* Specific initializer. */
197 switch (pgwl->status) {
198 case STATUS_UNBUILT:
199 /* All members set to 0 by fc_calloc. */
200 break;
201 case STATUS_WORKLIST:
202 worklist_init(&pgwl->worklist);
203 break;
204 }
205
207
208 return pgwl;
209}
210
211/*******************************************************************/
215{
217
219
220 /* Specific destructor. */
221 switch (pgwl->status) {
222 case STATUS_UNBUILT:
223 {
224 struct uni_name *puni_name;
225 int i;
226
227 for (i = 0; i < pgwl->unbuilt.length; i++) {
228 puni_name = pgwl->unbuilt.entries + i;
229 free(puni_name->kind);
230 free(puni_name->name);
231 }
232 }
233 break;
234 case STATUS_WORKLIST:
235 break;
236 }
237
238 free(pgwl);
239}
240
241/*******************************************************************/
251
252/*******************************************************************/
256{
257 return pgwl && pgwl->status == STATUS_WORKLIST;
258}
259
260/*******************************************************************/
264 const struct worklist *pwl)
265{
266 if (pgwl && pgwl->status == STATUS_WORKLIST && pwl) {
267 worklist_copy(&pgwl->worklist, pwl);
268 return TRUE;
269 }
270 return FALSE;
271}
272
273/*******************************************************************/
277{
278 if (pgwl && pgwl->status == STATUS_WORKLIST) {
279 return &pgwl->worklist;
280 } else {
281 return NULL;
282 }
283}
284
285/*******************************************************************/
289{
291 return pgwl->id;
292}
293
294/*******************************************************************/
299{
301 if (pgwl->id == id) {
302 return pgwl;
303 }
305
306 return NULL;
307}
308
309/*******************************************************************/
313 const char *name)
314{
315 if (name) {
316 sz_strlcpy(pgwl->name, name);
317 }
318}
319
320/*******************************************************************/
323const char *global_worklist_name(const struct global_worklist *pgwl)
324{
326 return pgwl->name;
327}
328
329/*******************************************************************/
333static bool global_worklist_load(struct section_file *file,
334 const char *path, ...)
335{
336 struct global_worklist *pgwl;
337 const char *kind;
338 const char *name;
339 char path_str[1024];
340 va_list ap;
341 int i, length;
342
343 /* The first part of the registry path is taken from the varargs to the
344 * function. */
345 va_start(ap, path);
346 fc_vsnprintf(path_str, sizeof(path_str), path, ap);
347 va_end(ap);
348
349 length = secfile_lookup_int_default(file, -1, "%s.wl_length", path_str);
350 if (length == -1) {
351 /* Not set. */
352 return FALSE;
353 }
357 secfile_lookup_str_default(file, _("(noname)"),
358 "%s.wl_name",
359 path_str));
360
361 for (i = 0; i < length; i++) {
362 kind = secfile_lookup_str_default(file, NULL, "%s.wl_kind%d",
363 path_str, i);
364
365 if (!kind) {
366 /* before 2.2.0 unit production was indicated by flag. */
367 bool is_unit = secfile_lookup_bool_default(file, FALSE,
368 "%s.wl_is_unit%d",
369 path_str, i);
371 }
372
373 name = secfile_lookup_str_default(file, NULL, "%s.wl_value%d",
374 path_str, i);
375 if (NULL == kind || '\0' == kind[0] || NULL == name || '\0' == name[0]) {
376 break;
377 } else {
378 pgwl->unbuilt.entries[i].kind = fc_strdup(kind);
379 pgwl->unbuilt.entries[i].name = fc_strdup(name);
380 pgwl->unbuilt.length++;
381 }
382 }
383
384 return TRUE;
385}
386
387/*******************************************************************/
391{
392 int i;
393
394 /* Clear the current global worklists. */
398
399 for (i = 0; global_worklist_load(file, "worklists.worklist%d", i); i++) {
400 /* Nothing to do more. */
401 }
402
403 if (C_S_RUNNING <= client_state()) {
404 /* We need to build the worklists immediately. */
406 }
407}
408
409/*******************************************************************/
412static void global_worklist_save(const struct global_worklist *pgwl,
413 struct section_file *file, int fill_until,
414 const char *path, ...)
415{
416 char path_str[1024];
417 int i = 0;
418 va_list ap;
419
420 /* The first part of the registry path is taken from the varargs to the
421 * function. */
422 va_start(ap, path);
423 fc_vsnprintf(path_str, sizeof(path_str), path, ap);
424 va_end(ap);
425
426 secfile_insert_str(file, pgwl->name, "%s.wl_name", path_str);
427
428 switch (pgwl->status) {
429 case STATUS_UNBUILT:
430 secfile_insert_int(file, pgwl->unbuilt.length,
431 "%s.wl_length", path_str);
432 for (i = 0; i < pgwl->unbuilt.length; i++) {
433 secfile_insert_str(file, pgwl->unbuilt.entries[i].kind,
434 "%s.wl_kind%d", path_str, i);
435 secfile_insert_str(file, pgwl->unbuilt.entries[i].name,
436 "%s.wl_value%d", path_str, i);
437 }
438 break;
439 case STATUS_WORKLIST:
440 secfile_insert_int(file, worklist_length(&pgwl->worklist),
441 "%s.wl_length", path_str);
442 for (i = 0; i < pgwl->unbuilt.length; i++) {
444 universal_type_rule_name(pgwl->worklist.entries + i),
445 "%s.wl_kind%d", path_str, i);
447 universal_rule_name(pgwl->worklist.entries + i),
448 "%s.wl_value%d", path_str, i);
449 }
450 break;
451 }
452
453 /* We want to keep savegame in tabular format, so each line has to be
454 * of equal length. Fill table up to maximum worklist size. */
455 while (i < fill_until) {
456 secfile_insert_str(file, "", "%s.wl_kind%d", path_str, i);
457 secfile_insert_str(file, "", "%s.wl_value%d", path_str, i);
458 i++;
459 }
460}
461
462/*******************************************************************/
466{
467 int max_length = 0;
468 int i = 0;
469
470 /* We want to keep savegame in tabular format, so each line has to be
471 * of equal length. So we need to know about the biggest worklist. */
473 switch (pgwl->status) {
474 case STATUS_UNBUILT:
475 max_length = MAX(max_length, pgwl->unbuilt.length);
476 break;
477 case STATUS_WORKLIST:
479 break;
480 }
482
485 "worklists.worklist%d", i++);
487}
struct civclient client
enum client_states client_state(void)
@ C_S_RUNNING
Definition client_main.h:47
char * incite_cost
Definition comments.c:76
#define MAX_LEN_NAME
Definition fc_types.h:66
#define _(String)
Definition fcintl.h:67
struct global_worklist * global_worklist_by_id(int id)
static struct global_worklist * global_worklist_alloc(enum global_worklist_status type)
bool global_worklist_set(struct global_worklist *pgwl, const struct worklist *pwl)
const char * global_worklist_name(const struct global_worklist *pgwl)
int global_worklist_id(const struct global_worklist *pgwl)
global_worklist_status
@ STATUS_WORKLIST
@ STATUS_UNBUILT
int global_worklists_number(void)
bool global_worklist_is_valid(const struct global_worklist *pgwl)
void global_worklist_destroy(struct global_worklist *pgwl)
static bool static void global_worklist_save(const struct global_worklist *pgwl, struct section_file *file, int fill_until, const char *path,...) fc__attribute((__format__(__printf__
void global_worklists_build(void)
static bool global_worklist_load(struct section_file *file, const char *path,...) fc__attribute((__format__(__printf__
const struct worklist * global_worklist_get(const struct global_worklist *pgwl)
static bool static void void global_worklists_init(void)
void global_worklists_load(struct section_file *file)
void global_worklists_free(void)
struct global_worklist * global_worklist_new(const char *name)
void global_worklists_unbuild(void)
void global_worklists_save(struct section_file *file)
void global_worklist_set_name(struct global_worklist *pgwl, const char *name)
#define global_worklists_iterate_all_end
#define global_worklists_iterate_all(pgwl)
#define global_worklists_iterate(pgwl)
#define global_worklists_iterate_end
static GtkWidget * source
Definition gotodlg.c:58
GType type
Definition repodlgs.c:1313
const char * name
Definition inputfile.c:127
#define fc_assert_ret(condition)
Definition log.h:192
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define fc_calloc(n, esz)
Definition mem.h:38
#define fc_strdup(str)
Definition mem.h:43
bool secfile_lookup_bool_default(const struct section_file *secfile, bool def, const char *path,...)
int secfile_lookup_int_default(const struct section_file *secfile, int def, const char *path,...)
const char * secfile_lookup_str_default(const struct section_file *secfile, const char *def, const char *path,...)
#define secfile_insert_int(secfile, value, path,...)
#define secfile_insert_str(secfile, string, path,...)
const char * universal_rule_name(const struct universal *psource)
const char * universal_type_rule_name(const struct universal *psource)
struct universal universal_by_rule_name(const char *kind, const char *value)
#define MIN(x, y)
Definition shared.h:55
#define MAX(x, y)
Definition shared.h:54
struct global_worklist_list * worklists
Definition client_main.h:97
enum global_worklist_status status
struct global_worklist::@135::@137 unbuilt
char name[MAX_LEN_NAME]
struct global_worklist::@135::@137::uni_name entries[MAX_LEN_WORKLIST]
struct entry_hash * entries
struct universal entries[MAX_LEN_WORKLIST]
Definition worklist.h:30
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
Definition support.c:886
#define sz_strlcpy(dest, src)
Definition support.h:195
#define fc__attribute(x)
Definition support.h:99
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
void worklist_copy(struct worklist *dst, const struct worklist *src)
Definition worklist.c:112
void worklist_init(struct worklist *pwl)
Definition worklist.c:38
bool worklist_append(struct worklist *pwl, const struct universal *prod)
Definition worklist.c:147
int worklist_length(const struct worklist *pwl)
Definition worklist.c:57
#define MAX_LEN_WORKLIST
Definition worklist.h:24