1 #include "list.h"
2 
3 #include "core/array.h"
4 
5 #define SMALL_SIZE_STEP 500
6 #define LARGE_SIZE_STEP 2000
7 #define BURNING_SIZE_STEP 500
8 
9 static struct {
10     array(int) small;
11     array(int) large;
12     array(int) burning;
13 } data;
14 
building_list_small_clear(void)15 void building_list_small_clear(void)
16 {
17     data.small.size = 0;
18 }
19 
building_list_small_add(int building_id)20 void building_list_small_add(int building_id)
21 {
22     if (!data.small.blocks && !array_init(data.small, SMALL_SIZE_STEP, 0, 0)) {
23         return;
24     }
25     int *element = array_advance(data.small);
26     if (!element) {
27         element = array_last(data.small);
28     }
29     *element = building_id;
30 }
31 
building_list_small_size(void)32 int building_list_small_size(void)
33 {
34     return data.small.size;
35 }
36 
building_list_small_item(int index)37 int building_list_small_item(int index)
38 {
39     return *array_item(data.small, index);
40 }
41 
building_list_large_clear(void)42 void building_list_large_clear(void)
43 {
44     data.large.size = 0;
45 }
46 
building_list_large_add(int building_id)47 void building_list_large_add(int building_id)
48 {
49     if (!data.large.blocks && !array_init(data.large, LARGE_SIZE_STEP, 0, 0)) {
50         return;
51     }
52     int *element = array_advance(data.large);
53     if (!element) {
54         element = array_last(data.large);
55     }
56     *element = building_id;
57 }
58 
building_list_large_size(void)59 int building_list_large_size(void)
60 {
61     return data.large.size;
62 }
63 
building_list_large_item(int index)64 int building_list_large_item(int index)
65 {
66     return *array_item(data.large, index);
67 }
68 
building_list_burning_clear(void)69 void building_list_burning_clear(void)
70 {
71     data.burning.size = 0;
72 }
73 
building_list_burning_add(int building_id)74 void building_list_burning_add(int building_id)
75 {
76     if (!data.burning.blocks && !array_init(data.burning, BURNING_SIZE_STEP, 0, 0)) {
77         return;
78     }
79     int *element = array_advance(data.burning);
80     if (!element) {
81         element = array_last(data.burning);
82     }
83     *element = building_id;
84 }
85 
building_list_burning_size(void)86 int building_list_burning_size(void)
87 {
88     return data.burning.size;
89 }
90 
building_list_burning_item(int index)91 int building_list_burning_item(int index)
92 {
93     return *array_item(data.burning, index);
94 }
95 
building_list_save_state(buffer * small,buffer * large,buffer * burning,buffer * burning_totals)96 void building_list_save_state(buffer *small, buffer *large, buffer *burning, buffer *burning_totals)
97 {
98     int buf_size = data.small.size * sizeof(int32_t);
99     int *value;
100     if (buf_size) {
101         uint8_t *buf_data = malloc(buf_size);
102         buffer_init(small, buf_data, buf_size);
103         array_foreach(data.small, value)
104         {
105             buffer_write_i32(small, *value);
106         }
107     }
108 
109     buf_size = data.large.size * sizeof(int32_t);
110     if (buf_size) {
111         uint8_t *buf_data = malloc(buf_size);
112         buffer_init(large, buf_data, buf_size);
113         array_foreach(data.large, value)
114         {
115             buffer_write_i32(large, *value);
116         }
117     }
118 
119     buf_size = data.burning.size * sizeof(int32_t);
120     if (buf_size) {
121         uint8_t *buf_data = malloc(buf_size);
122         buffer_init(burning, buf_data, buf_size);
123         array_foreach(data.burning, value)
124         {
125             buffer_write_i32(burning, *value);
126         }
127     }
128 
129     buffer_write_i32(burning_totals, data.burning.size);
130 }
131 
building_list_load_state(buffer * small,buffer * large,buffer * burning,buffer * burning_totals,int is_new_version)132 void building_list_load_state(buffer *small, buffer *large, buffer *burning, buffer *burning_totals, int is_new_version)
133 {
134     data.small.size = 0;
135     data.large.size = 0;
136     data.burning.size = 0;
137 
138     if (!is_new_version) {
139         int size = small->size / sizeof(int16_t);
140         for (int i = 0; i < size; i++) {
141             building_list_small_add(buffer_read_i16(small));
142         }
143         size = large->size / sizeof(int16_t);
144         for (int i = 0; i < size; i++) {
145             building_list_large_add(buffer_read_i16(large));
146         }
147         size = burning->size / sizeof(int16_t);
148         for (int i = 0; i < size; i++) {
149             building_list_burning_add(buffer_read_i16(burning));
150         }
151 
152         buffer_skip(burning_totals, 4);
153     } else {
154         int size = small->size / sizeof(int32_t);
155         for (int i = 0; i < size; i++) {
156             building_list_small_add(buffer_read_i32(small));
157         }
158         size = large->size / sizeof(int32_t);
159         for (int i = 0; i < size; i++) {
160             building_list_large_add(buffer_read_i32(large));
161         }
162         size = burning->size / sizeof(int32_t);
163         for (int i = 0; i < size; i++) {
164             building_list_burning_add(buffer_read_i32(burning));
165         }
166     }
167     data.small.size = 0;
168     data.large.size = 0;
169     data.burning.size = buffer_read_i32(burning_totals);
170 }
171