Freeciv21
Develop your civilization from humble roots to a global empire
worklist.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2020 Freeciv21 and Freeciv
3 \_ \ / __/ contributors. This file is part of Freeciv21.
4  _\ \ / /__ Freeciv21 is free software: you can redistribute it
5  \___ \____/ __/ and/or modify it under the terms of the GNU General
6  \_ _/ Public License as published by the Free Software
7  | @ @ \_ Foundation, either version 3 of the License,
8  | or (at your option) any later version.
9  _/ /\ You should have received a copy of the GNU
10  /o) (o/\ \_ General Public License along with Freeciv21.
11  \_____/ / If not, see https://www.gnu.org/licenses/.
12  \____/ ********************************************************/
13 
14 #include <cstring>
15 
16 // utility
17 #include "log.h"
18 #include "support.h"
19 
20 // common
21 #include "city.h"
22 #include "requirements.h"
23 #include "unit.h"
24 
25 #include "worklist.h"
26 
32 void worklist_init(struct worklist *pwl)
33 {
34  int i;
35 
36  pwl->length = 0;
37 
38  for (i = 0; i < MAX_LEN_WORKLIST; i++) {
39  // just setting the entry to zero:
40  pwl->entries[i].kind = VUT_NONE;
41  // all the union pointers should be in the same place:
42  pwl->entries[i].value.building = nullptr;
43  }
44 }
45 
51 int worklist_length(const struct worklist *pwl)
52 {
53  fc_assert_ret_val(pwl->length >= 0 && pwl->length <= MAX_LEN_WORKLIST, 0);
54  return pwl->length;
55 }
56 
60 bool worklist_is_empty(const struct worklist *pwl)
61 {
62  return !pwl || pwl->length == 0;
63 }
64 
70 bool worklist_peek(const struct worklist *pwl, struct universal *prod)
71 {
72  return worklist_peek_ith(pwl, prod, 0);
73 }
74 
80 bool worklist_peek_ith(const struct worklist *pwl, struct universal *prod,
81  int idx)
82 {
83  // Out of possible bounds.
84  if (idx < 0 || pwl->length <= idx) {
85  prod->kind = VUT_NONE;
86  prod->value.building = nullptr;
87  return false;
88  }
89 
90  *prod = pwl->entries[idx];
91 
92  return true;
93 }
94 
98 void worklist_advance(struct worklist *pwl) { worklist_remove(pwl, 0); }
99 
103 void worklist_copy(struct worklist *dst, const struct worklist *src)
104 {
105  dst->length = src->length;
106 
107  memcpy(dst->entries, src->entries, sizeof(struct universal) * src->length);
108 }
109 
113 void worklist_remove(struct worklist *pwl, int idx)
114 {
115  int i;
116 
117  // Don't try to remove something way outside of the worklist.
118  if (idx < 0 || pwl->length <= idx) {
119  return;
120  }
121 
122  // Slide everything up one spot.
123  for (i = idx; i < pwl->length - 1; i++) {
124  pwl->entries[i] = pwl->entries[i + 1];
125  }
126  // just setting the entry to zero:
127  pwl->entries[pwl->length - 1].kind = VUT_NONE;
128  // all the union pointers should be in the same place:
129  pwl->entries[pwl->length - 1].value.building = nullptr;
130  pwl->length--;
131 }
132 
138 bool worklist_append(struct worklist *pwl, const struct universal *prod)
139 {
140  int next_index = worklist_length(pwl);
141 
142  if (next_index >= MAX_LEN_WORKLIST) {
143  return false;
144  }
145 
146  pwl->entries[next_index] = *prod;
147  pwl->length++;
148 
149  return true;
150 }
151 
158 bool worklist_insert(struct worklist *pwl, const struct universal *prod,
159  int idx)
160 {
161  int new_len = MIN(pwl->length + 1, MAX_LEN_WORKLIST), i;
162 
163  if (idx < 0 || idx > pwl->length) {
164  return false;
165  }
166 
167  /* move all active values down an index to get room for new id
168  * move from [idx .. len - 1] to [idx + 1 .. len]. Any entries at the
169  * end are simply lost. */
170  for (i = new_len - 2; i >= idx; i--) {
171  pwl->entries[i + 1] = pwl->entries[i];
172  }
173 
174  pwl->entries[idx] = *prod;
175  pwl->length = new_len;
176 
177  return true;
178 }
179 
183 bool are_worklists_equal(const struct worklist *wlist1,
184  const struct worklist *wlist2)
185 {
186  int i;
187 
188  if (wlist1->length != wlist2->length) {
189  return false;
190  }
191 
192  for (i = 0; i < wlist1->length; i++) {
193  if (!are_universals_equal(&wlist1->entries[i], &wlist2->entries[i])) {
194  return false;
195  }
196  }
197 
198  return true;
199 }
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
bool are_universals_equal(const struct universal *psource1, const struct universal *psource2)
Return TRUE iff the two sources are equivalent.
#define MIN(x, y)
Definition: shared.h:49
enum universals_n kind
Definition: fc_types.h:740
universals_u value
Definition: fc_types.h:739
struct universal entries[MAX_LEN_WORKLIST]
Definition: worklist.h:25
int length
Definition: worklist.h:24
const struct impr_type * building
Definition: fc_types.h:579
void worklist_advance(struct worklist *pwl)
Remove first element from worklist.
Definition: worklist.cpp:98
bool worklist_peek(const struct worklist *pwl, struct universal *prod)
Fill in the id and is_unit values for the head of the worklist if the worklist is non-empty.
Definition: worklist.cpp:70
void worklist_copy(struct worklist *dst, const struct worklist *src)
Copy contents from worklist src to worklist dst.
Definition: worklist.cpp:103
void worklist_init(struct worklist *pwl)
Initialize a worklist to be empty.
Definition: worklist.cpp:32
bool worklist_peek_ith(const struct worklist *pwl, struct universal *prod, int idx)
Fill in the id and is_unit values for the ith element in the worklist.
Definition: worklist.cpp:80
bool worklist_is_empty(const struct worklist *pwl)
Returns whether worklist has no elements.
Definition: worklist.cpp:60
bool worklist_append(struct worklist *pwl, const struct universal *prod)
Adds the id to the next available slot in the worklist.
Definition: worklist.cpp:138
bool worklist_insert(struct worklist *pwl, const struct universal *prod, int idx)
Inserts the production at the location idx in the worklist, thus moving all subsequent entries down.
Definition: worklist.cpp:158
void worklist_remove(struct worklist *pwl, int idx)
Remove element from position idx.
Definition: worklist.cpp:113
bool are_worklists_equal(const struct worklist *wlist1, const struct worklist *wlist2)
Return TRUE iff the two worklists are equal.
Definition: worklist.cpp:183
int worklist_length(const struct worklist *pwl)
Returns the number of entries in the worklist.
Definition: worklist.cpp:51
#define MAX_LEN_WORKLIST
Definition: worklist.h:19