Skip to content

Commit b390440

Browse files
committed
Templatise
1 parent 4615e8d commit b390440

File tree

15 files changed

+185
-120
lines changed

15 files changed

+185
-120
lines changed

libopenage/curve/container/array.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,19 @@ class Array : event::EventEntity {
111111
std::pair<time::time_t, T> next_frame(const time::time_t &t, const index_t index) const;
112112

113113

114-
void set_insert_range(const time::time_t &t, auto begin_it, auto end_it) {
115-
ENSURE(std::distance(begin_it, end_it) <= Size,
116-
"trying to insert more values than there are postions: max allowed = " << Size);
117-
index_t i = 0;
114+
/**
115+
* Insert a range of elements into the Array.
116+
*
117+
* @param t Time of insertion.
118+
* @param begin_it iterator pointing to the first element in the container you wish to insert.
119+
* @param end_it iterator pointing to one after the last element in the container you wish to insert.
120+
* @param i Index of the array at which insertion will begin.
121+
*
122+
* @return Time-value pair of the first keyframe with time > t.
123+
*/
124+
void set_insert_range(const time::time_t &t, auto begin_it, auto end_it, index_t i = 0) {
125+
ENSURE(std::distance(begin_it, end_it) <= Size - i,
126+
"trying to insert more values than there are postions: max allowed = " << Size - i);
118127
std::for_each(begin_it, end_it, [&](const T &val) { this->set_insert(t, i++, val); });
119128
}
120129

libopenage/curve/tests/container.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,21 @@ void test_array() {
342342
TESTEQUALS(*it, 6);
343343
++it;
344344
TESTEQUALS(*it, 7);
345+
346+
// Test set_insert-range
347+
std::vector<int> vec = {100, 200, 300};
348+
349+
a.set_insert_range(5, vec.begin(), vec.end(), 1);
350+
// a = [[0:0, 1:4, 2:25, 3:35],[0:0, 1:5, 6:100],[0:0, 1:6, 6:200],[0:0, 1:7, 5:40, 6:300]]
351+
352+
it = a.begin(6);
353+
TESTEQUALS(*it, 35);
354+
++it;
355+
TESTEQUALS(*it, 100);
356+
++it;
357+
TESTEQUALS(*it, 200);
358+
++it;
359+
TESTEQUALS(*it, 300);
345360
}
346361

347362

libopenage/pathfinding/cost_field.cpp

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -11,80 +11,4 @@
1111

1212
namespace openage::path {
1313

14-
CostField::CostField(size_t size) :
15-
size{size},
16-
valid_until{time::TIME_MIN},
17-
cells(this->size * this->size, COST_MIN),
18-
cell_cost_history() {
19-
log::log(DBG << "Created cost field with size " << this->size << "x" << this->size);
20-
}
21-
22-
size_t CostField::get_size() const {
23-
return this->size;
24-
}
25-
26-
cost_t CostField::get_cost(const coord::tile_delta &pos) const {
27-
return this->cells.at(pos.ne + pos.se * this->size);
28-
}
29-
30-
cost_t CostField::get_cost(size_t x, size_t y) const {
31-
return this->cells.at(x + y * this->size);
32-
}
33-
34-
cost_t CostField::get_cost(size_t idx) const {
35-
return this->cells.at(idx);
36-
}
37-
38-
void CostField::set_cost(const coord::tile_delta &pos, cost_t cost, const time::time_t &valid_until) {
39-
this->set_cost(pos.ne + pos.se * this->size, cost, valid_until);
40-
}
41-
42-
void CostField::set_cost(size_t x, size_t y, cost_t cost, const time::time_t &valid_until) {
43-
this->set_cost(x + y * this->size, cost, valid_until);
44-
}
45-
46-
const std::vector<cost_t> &CostField::get_costs() const {
47-
return this->cells;
48-
}
49-
50-
void CostField::set_costs(std::vector<cost_t> &&cells, const time::time_t &valid_until) {
51-
ENSURE(cells.size() == this->cells.size(),
52-
"cells vector has wrong size: " << cells.size()
53-
<< "; expected: "
54-
<< this->cells.size());
55-
56-
this->cells = std::move(cells);
57-
this->valid_until = valid_until;
58-
this->cell_cost_history.set_insert_range(valid_until, this->cells.begin(), this->cells.end());
59-
}
60-
61-
bool CostField::stamp(size_t idx, cost_t cost, const time::time_t &stamped_at) {
62-
if (this->cost_stamps[idx].has_value()) return false;
63-
64-
cost_t original_cost = this->get_cost(idx);
65-
this->cost_stamps[idx]->original_cost = original_cost;
66-
this->cost_stamps[idx]->stamp_time = stamped_at;
67-
68-
this->set_cost(idx, cost, stamped_at);
69-
return true;
70-
}
71-
72-
bool CostField::unstamp(size_t idx, const time::time_t &unstamped_at) {
73-
if (!this->cost_stamps[idx].has_value() || unstamped_at < this->cost_stamps[idx]->stamp_time) return false;
74-
75-
cost_t original_cost = cost_stamps[idx]->original_cost;
76-
77-
this->set_cost(idx, original_cost, unstamped_at);
78-
this->cost_stamps[idx].reset();
79-
return true;
80-
}
81-
82-
bool CostField::is_dirty(const time::time_t &time) const {
83-
return time >= this->valid_until;
84-
}
85-
86-
void CostField::clear_dirty() {
87-
this->valid_until = time::TIME_MAX;
88-
}
89-
9014
} // namespace openage::path

libopenage/pathfinding/cost_field.h

Lines changed: 103 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,26 @@
1010
#include "pathfinding/types.h"
1111
#include "time/time.h"
1212

13+
#include "cost_field.h"
14+
15+
#include "error/error.h"
16+
#include "log/log.h"
17+
18+
#include "coord/tile.h"
19+
#include "pathfinding/definitions.h"
1320

1421
namespace openage {
1522
namespace coord {
1623
struct tile_delta;
1724
} // namespace coord
1825

19-
const unsigned int CHUNK_SIZE = 100;
20-
2126
namespace path {
2227

2328
/**
2429
* Cost field in the flow-field pathfinding algorithm.
2530
*/
31+
32+
template <size_t N>
2633
class CostField {
2734
public:
2835
/**
@@ -171,8 +178,101 @@ class CostField {
171178
/**
172179
* Array curve recording cell cost history,
173180
*/
174-
curve::Array<cost_t, CHUNK_SIZE> cell_cost_history;
181+
curve::Array<cost_t, N> cell_cost_history;
175182
};
176183

184+
template <size_t N>
185+
CostField<N>::CostField(size_t size) :
186+
size{size},
187+
valid_until{time::TIME_MIN},
188+
cells(this->size * this->size, COST_MIN),
189+
cell_cost_history() {
190+
log::log(DBG << "Created cost field with size " << this->size << "x" << this->size);
191+
}
192+
193+
template <size_t N>
194+
size_t CostField<N>::get_size() const {
195+
return this->size;
196+
}
197+
198+
template <size_t N>
199+
cost_t CostField<N>::get_cost(const coord::tile_delta &pos) const {
200+
return this->cells.at(pos.ne + pos.se * this->size);
201+
}
202+
203+
template <size_t N>
204+
cost_t CostField<N>::get_cost(size_t x, size_t y) const {
205+
return this->cells.at(x + y * this->size);
206+
}
207+
208+
template <size_t N>
209+
cost_t CostField<N>::get_cost(size_t idx) const {
210+
return this->cells.at(idx);
211+
}
212+
213+
template <size_t N>
214+
void CostField<N>::set_cost(const coord::tile_delta &pos, cost_t cost, const time::time_t &valid_until) {
215+
this->set_cost(pos.ne + pos.se * this->size, cost, valid_until);
216+
}
217+
218+
template <size_t N>
219+
void CostField<N>::set_cost(size_t x, size_t y, cost_t cost, const time::time_t &valid_until) {
220+
this->set_cost(x + y * this->size, cost, valid_until);
221+
}
222+
223+
template <size_t N>
224+
const std::vector<cost_t> &CostField<N>::get_costs() const {
225+
return this->cells;
226+
}
227+
228+
template <size_t N>
229+
void CostField<N>::set_costs(std::vector<cost_t> &&cells, const time::time_t &valid_until) {
230+
ENSURE(cells.size() == this->cells.size(),
231+
"cells vector has wrong size: " << cells.size()
232+
<< "; expected: "
233+
<< this->cells.size());
234+
235+
this->cells = std::move(cells);
236+
this->valid_until = valid_until;
237+
this->cell_cost_history.set_insert_range(valid_until, this->cells.begin(), this->cells.end());
238+
}
239+
240+
template <size_t N>
241+
bool CostField<N>::stamp(size_t idx, cost_t cost, const time::time_t &stamped_at) {
242+
if (this->cost_stamps[idx].has_value()) {
243+
return false;
244+
}
245+
return false;
246+
247+
cost_t original_cost = this->get_cost(idx);
248+
this->cost_stamps[idx]->original_cost = original_cost;
249+
this->cost_stamps[idx]->stamp_time = stamped_at;
250+
251+
this->set_cost(idx, cost, stamped_at);
252+
return true;
253+
}
254+
255+
template <size_t N>
256+
bool CostField<N>::unstamp(size_t idx, const time::time_t &unstamped_at) {
257+
if (!this->cost_stamps[idx].has_value() or unstamped_at < this->cost_stamps[idx]->stamp_time) {
258+
return false;
259+
}
260+
cost_t original_cost = cost_stamps[idx]->original_cost;
261+
262+
this->set_cost(idx, original_cost, unstamped_at);
263+
this->cost_stamps[idx].reset();
264+
return true;
265+
}
266+
267+
template <size_t N>
268+
bool CostField<N>::is_dirty(const time::time_t &time) const {
269+
return time >= this->valid_until;
270+
}
271+
272+
template <size_t N>
273+
void CostField<N>::clear_dirty() {
274+
this->valid_until = time::TIME_MAX;
275+
}
276+
177277
} // namespace path
178278
} // namespace openage

libopenage/pathfinding/demo/demo_0.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ void path_demo_0(const util::Path &path) {
3232
auto field_length = 10;
3333

3434
// Cost field with some obstacles
35-
auto cost_field = std::make_shared<CostField>(field_length);
35+
auto cost_field = std::make_shared<CostField<100>>(field_length);
3636

3737
const time::time_t time = time::TIME_ZERO;
3838
cost_field->set_cost(coord::tile_delta{0, 0}, COST_IMPASSABLE, time);
@@ -203,7 +203,7 @@ void RenderManager0::run() {
203203
this->window->close();
204204
}
205205

206-
void RenderManager0::show_cost_field(const std::shared_ptr<path::CostField> &field) {
206+
void RenderManager0::show_cost_field(const std::shared_ptr<path::CostField<100>> &field) {
207207
Eigen::Matrix4f model = Eigen::Matrix4f::Identity();
208208
auto unifs = this->cost_shader->new_uniform_input(
209209
"model",
@@ -551,7 +551,7 @@ void RenderManager0::init_passes() {
551551
renderer->get_display_target());
552552
}
553553

554-
renderer::resources::MeshData RenderManager0::get_cost_field_mesh(const std::shared_ptr<CostField> &field,
554+
renderer::resources::MeshData RenderManager0::get_cost_field_mesh(const std::shared_ptr<CostField<100>> &field,
555555
size_t resolution) {
556556
// increase by 1 in every dimension because to get the vertex length
557557
// of each dimension

libopenage/pathfinding/demo/demo_0.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ class MeshData;
2828
} // namespace renderer
2929

3030
namespace path {
31+
template <size_t N>
3132
class CostField;
33+
3234
class IntegrationField;
3335
class FlowField;
3436

@@ -80,7 +82,7 @@ class RenderManager0 {
8082
*
8183
* @param field Cost field.
8284
*/
83-
void show_cost_field(const std::shared_ptr<path::CostField> &field);
85+
void show_cost_field(const std::shared_ptr<path::CostField<100>> &field);
8486

8587
/**
8688
* Draw an integration field to the screen.
@@ -144,7 +146,7 @@ class RenderManager0 {
144146
*
145147
* @return Mesh data for the cost field.
146148
*/
147-
static renderer::resources::MeshData get_cost_field_mesh(const std::shared_ptr<path::CostField> &field,
149+
static renderer::resources::MeshData get_cost_field_mesh(const std::shared_ptr<path::CostField<100>> &field,
148150
size_t resolution = 2);
149151

150152
/**

libopenage/pathfinding/integration_field.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const integrated_t &IntegrationField::get_cell(size_t idx) const {
3737
return this->cells.at(idx);
3838
}
3939

40-
std::vector<size_t> IntegrationField::integrate_los(const std::shared_ptr<CostField> &cost_field,
40+
std::vector<size_t> IntegrationField::integrate_los(const std::shared_ptr<CostField<100>> &cost_field,
4141
const coord::tile_delta &target) {
4242
ENSURE(cost_field->get_size() == this->get_size(),
4343
"cost field size "
@@ -97,7 +97,7 @@ std::vector<size_t> IntegrationField::integrate_los(const std::shared_ptr<CostFi
9797
return this->integrate_los(cost_field, target, start_cost, std::move(start_cells));
9898
}
9999

100-
std::vector<size_t> IntegrationField::integrate_los(const std::shared_ptr<CostField> &cost_field,
100+
std::vector<size_t> IntegrationField::integrate_los(const std::shared_ptr<CostField<100>> &cost_field,
101101
const std::shared_ptr<IntegrationField> &other,
102102
sector_id_t other_sector_id,
103103
const std::shared_ptr<Portal> &portal,
@@ -208,7 +208,7 @@ std::vector<size_t> IntegrationField::integrate_los(const std::shared_ptr<CostFi
208208
return wavefront_blocked_main;
209209
}
210210

211-
std::vector<size_t> IntegrationField::integrate_los(const std::shared_ptr<CostField> &cost_field,
211+
std::vector<size_t> IntegrationField::integrate_los(const std::shared_ptr<CostField<100>> &cost_field,
212212
const coord::tile_delta &target,
213213
integrated_cost_t start_cost,
214214
std::vector<size_t> &&start_wave) {
@@ -334,7 +334,7 @@ std::vector<size_t> IntegrationField::integrate_los(const std::shared_ptr<CostFi
334334
return wavefront_blocked;
335335
}
336336

337-
void IntegrationField::integrate_cost(const std::shared_ptr<CostField> &cost_field,
337+
void IntegrationField::integrate_cost(const std::shared_ptr<CostField<100>> &cost_field,
338338
const coord::tile_delta &target) {
339339
ENSURE(cost_field->get_size() == this->get_size(),
340340
"cost field size "
@@ -351,7 +351,7 @@ void IntegrationField::integrate_cost(const std::shared_ptr<CostField> &cost_fie
351351
this->integrate_cost(cost_field, {target_idx});
352352
}
353353

354-
void IntegrationField::integrate_cost(const std::shared_ptr<CostField> &cost_field,
354+
void IntegrationField::integrate_cost(const std::shared_ptr<CostField<100>> &cost_field,
355355
sector_id_t other_sector_id,
356356
const std::shared_ptr<Portal> &portal) {
357357
ENSURE(cost_field->get_size() == this->get_size(),
@@ -382,7 +382,7 @@ void IntegrationField::integrate_cost(const std::shared_ptr<CostField> &cost_fie
382382
this->integrate_cost(cost_field, std::move(start_cells));
383383
}
384384

385-
void IntegrationField::integrate_cost(const std::shared_ptr<CostField> &cost_field,
385+
void IntegrationField::integrate_cost(const std::shared_ptr<CostField<100>> &cost_field,
386386
std::vector<size_t> &&start_cells) {
387387
// Cells that still have to be visited by the current wave
388388
std::vector<size_t> current_wave = std::move(start_cells);
@@ -487,7 +487,7 @@ void IntegrationField::update_neighbor(size_t idx,
487487
}
488488
}
489489

490-
std::vector<std::pair<int, int>> IntegrationField::get_los_corners(const std::shared_ptr<CostField> &cost_field,
490+
std::vector<std::pair<int, int>> IntegrationField::get_los_corners(const std::shared_ptr<CostField<100>> &cost_field,
491491
const coord::tile_delta &target,
492492
const coord::tile_delta &blocker) {
493493
std::vector<std::pair<int, int>> corners;

0 commit comments

Comments
 (0)