Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add dirty flag and integrate #1725

Open
wants to merge 34 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9ea8b58
Add dirty flag and integrate
dmwever Dec 4, 2024
a12b347
Update libopenage/pathfinding/cost_field.cpp
dmwever Dec 6, 2024
73647d4
Add const to time_t and improve docstrings
dmwever Dec 6, 2024
5a17e4e
change sector is_dirty to a reference
dmwever Dec 6, 2024
22e594f
Change fieldCache to unique_ptr and add docs
dmwever Dec 6, 2024
ce77c9f
Grammar
dmwever Dec 6, 2024
d33d4f7
Grammar
dmwever Dec 6, 2024
3adb802
Use contains()
dmwever Dec 6, 2024
6251a72
Merge branch 'master' into Add-Cost-Field-Dirty-Flag
dmwever Dec 7, 2024
fd72608
several changes
dmwever Dec 7, 2024
b9f6bd1
next round of changes
dmwever Dec 21, 2024
6f2c407
Update libopenage/pathfinding/cost_field.h
dmwever Dec 25, 2024
e7fb51e
- more fixes
dmwever Dec 25, 2024
4561388
Update cost_field.h
dmwever Jan 2, 2025
bf33b18
Update libopenage/pathfinding/cost_field.h
dmwever Jan 2, 2025
6e6c7a6
Update libopenage/pathfinding/cost_field.h
dmwever Jan 2, 2025
cf3cd96
Update libopenage/pathfinding/integrator.h
dmwever Jan 2, 2025
d5cfcf0
Update libopenage/pathfinding/integrator.h
dmwever Jan 2, 2025
904f44b
Update Demo
dmwever Jan 3, 2025
91df9f5
Merge remote-tracking branch 'upstream/master' into Add-Cost-Field-Di…
dmwever Jan 3, 2025
9040a3c
gamestate: Add request time to pathfinding request.
heinezen Jan 13, 2025
1ad186c
path: Fix warning for cost field member ordering.
heinezen Jan 13, 2025
e30126a
path: Fix missing initialization of integrator's field cache.
heinezen Jan 13, 2025
cbb5f3b
Fix sanity check complaints.
heinezen Jan 13, 2025
dea6b18
path: Make is_dirty check const.
heinezen Jan 13, 2025
9b506b9
path: Make demo 1 comments more verbose.
heinezen Jan 13, 2025
b73fe42
path: Activate cache usage in demo 1.
heinezen Jan 13, 2025
c2de560
patg: Remove 'is_dirty' method from sector code.
heinezen Jan 13, 2025
f378c52
path: Cleanup field cache code.
heinezen Jan 13, 2025
b971a7b
path: Avoid duplicate lookups for field cache in integrator.
heinezen Jan 13, 2025
d771627
Update copying.md
dmwever Jan 13, 2025
48a6955
- Sanity Fixes
dmwever Jan 16, 2025
4b4dd25
Add old email for sanity checks
dmwever Jan 16, 2025
66e4004
Update .mailmap
dmwever Jan 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libopenage/pathfinding/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
add_sources(libopenage
cost_field.cpp
definitions.cpp
field_cache.cpp
flow_field.cpp
grid.cpp
integration_field.cpp
Expand Down
22 changes: 18 additions & 4 deletions libopenage/pathfinding/cost_field.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ namespace openage::path {

CostField::CostField(size_t size) :
size{size},
cells(this->size * this->size, COST_MIN) {
cells(this->size * this->size, COST_MIN),
changed{time::time_t::min_value()} {
dmwever marked this conversation as resolved.
Show resolved Hide resolved
log::log(DBG << "Created cost field with size " << this->size << "x" << this->size);
}

Expand All @@ -33,29 +34,42 @@ cost_t CostField::get_cost(size_t idx) const {
return this->cells.at(idx);
}

void CostField::set_cost(const coord::tile_delta &pos, cost_t cost) {
void CostField::set_cost(const coord::tile_delta &pos, cost_t cost, time::time_t &changed) {
dmwever marked this conversation as resolved.
Show resolved Hide resolved
this->cells[pos.ne + pos.se * this->size] = cost;
this->changed = changed;
}

void CostField::set_cost(size_t x, size_t y, cost_t cost) {
void CostField::set_cost(size_t x, size_t y, cost_t cost, time::time_t &changed) {
this->cells[x + y * this->size] = cost;
this->changed = changed;
}

void CostField::set_cost(size_t idx, cost_t cost) {
this->cells[idx] = cost;
this->changed = time::TIME_ZERO;
}
dmwever marked this conversation as resolved.
Show resolved Hide resolved
dmwever marked this conversation as resolved.
Show resolved Hide resolved

void CostField::set_cost(size_t idx, cost_t cost,time::time_t &changed) {
this->cells[idx] = cost;
this->changed = changed;
}

const std::vector<cost_t> &CostField::get_costs() const {
return this->cells;
}

void CostField::set_costs(std::vector<cost_t> &&cells) {
void CostField::set_costs(std::vector<cost_t> &&cells, time::time_t &changed) {
ENSURE(cells.size() == this->cells.size(),
"cells vector has wrong size: " << cells.size()
<< "; expected: "
<< this->cells.size());

this->cells = std::move(cells);
this->changed = changed;
}

bool CostField::is_dirty(time::time_t &time) {
return time <= this->changed;
dmwever marked this conversation as resolved.
Show resolved Hide resolved
}

} // namespace openage::path
28 changes: 25 additions & 3 deletions libopenage/pathfinding/cost_field.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <vector>

#include "pathfinding/types.h"
#include "time/time.h"


namespace openage {
Expand Down Expand Up @@ -64,17 +65,19 @@ class CostField {
*
* @param pos Coordinates of the cell (relative to field origin).
* @param cost Cost to set.
* @param changed Time cost is set.
*/
void set_cost(const coord::tile_delta &pos, cost_t cost);
void set_cost(const coord::tile_delta &pos, cost_t cost, time::time_t &changed);

/**
* Set the cost at a specified position.
*
* @param x X-coordinate of the cell.
* @param y Y-coordinate of the cell.
* @param cost Cost to set.
* @param changed Time cost is set.
dmwever marked this conversation as resolved.
Show resolved Hide resolved
*/
void set_cost(size_t x, size_t y, cost_t cost);
void set_cost(size_t x, size_t y, cost_t cost, time::time_t &changed);

/**
* Set the cost at a specified position.
Expand All @@ -84,6 +87,15 @@ class CostField {
*/
void set_cost(size_t idx, cost_t cost);

/**
* Set the cost at a specified position.
*
* @param idx Index of the cell.
* @param cost Cost to set.
* @param changed Time cost is set.
*/
void set_cost(size_t idx, cost_t cost, time::time_t &changed);

/**
* Get the cost field values.
*
Expand All @@ -95,15 +107,25 @@ class CostField {
* Set the cost field values.
*
* @param cells Cost field values.
* @param changed Time cost is set.
*/
void set_costs(std::vector<cost_t> &&cells);
void set_costs(std::vector<cost_t> &&cells, time::time_t &changed);

/**
* Check if the cost field is dirty at the specified time.
*
* @param time Specified time to check.
*/
dmwever marked this conversation as resolved.
Show resolved Hide resolved
bool is_dirty(time::time_t &time);

private:
/**
* Side length of the field.
*/
size_t size;

time::time_t changed;
dmwever marked this conversation as resolved.
Show resolved Hide resolved

/**
* Cost field values.
*/
Expand Down
20 changes: 11 additions & 9 deletions libopenage/pathfinding/demo/demo_0.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,17 @@ void path_demo_0(const util::Path &path) {

// Cost field with some obstacles
auto cost_field = std::make_shared<CostField>(field_length);
cost_field->set_cost(coord::tile_delta{0, 0}, COST_IMPASSABLE);
cost_field->set_cost(coord::tile_delta{1, 0}, 254);
cost_field->set_cost(coord::tile_delta{4, 3}, 128);
cost_field->set_cost(coord::tile_delta{5, 3}, 128);
cost_field->set_cost(coord::tile_delta{6, 3}, 128);
cost_field->set_cost(coord::tile_delta{4, 4}, 128);
cost_field->set_cost(coord::tile_delta{5, 4}, 128);
cost_field->set_cost(coord::tile_delta{6, 4}, 128);
cost_field->set_cost(coord::tile_delta{1, 7}, COST_IMPASSABLE);

time::time_t time = time::TIME_ZERO;
cost_field->set_cost(coord::tile_delta{0, 0}, COST_IMPASSABLE, time);
cost_field->set_cost(coord::tile_delta{1, 0}, 254, time);
cost_field->set_cost(coord::tile_delta{4, 3}, 128, time);
cost_field->set_cost(coord::tile_delta{5, 3}, 128, time);
cost_field->set_cost(coord::tile_delta{6, 3}, 128, time);
cost_field->set_cost(coord::tile_delta{4, 4}, 128, time);
cost_field->set_cost(coord::tile_delta{5, 4}, 128, time);
cost_field->set_cost(coord::tile_delta{6, 4}, 128, time);
cost_field->set_cost(coord::tile_delta{1, 7}, COST_IMPASSABLE, time);
log::log(INFO << "Created cost field");

// Create an integration field from the cost field
Expand Down
16 changes: 14 additions & 2 deletions libopenage/pathfinding/demo/demo_1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "pathfinding/portal.h"
#include "pathfinding/sector.h"
#include "util/timer.h"
#include "time/time_loop.h"
#include "time/clock.h"

#include "renderer/gui/integration/public/gui_application_with_logger.h"
#include "renderer/opengl/window.h"
Expand All @@ -25,13 +27,17 @@
namespace openage::path::tests {

void path_demo_1(const util::Path &path) {
auto time_loop = std::make_shared<time::TimeLoop>();
time_loop->run();
auto clock = time_loop->get_clock();
dmwever marked this conversation as resolved.
Show resolved Hide resolved
auto grid = std::make_shared<Grid>(0, util::Vector2s{4, 3}, 10);

time::time_t time = clock->get_time();
// Initialize the cost field for each sector.
for (auto &sector : grid->get_sectors()) {
auto cost_field = sector->get_cost_field();
std::vector<cost_t> sector_cost = sectors_cost.at(sector->get_id());
cost_field->set_costs(std::move(sector_cost));
cost_field->set_costs(std::move(sector_cost), time);
}

// Initialize portals between sectors.
Expand Down Expand Up @@ -87,16 +93,20 @@ void path_demo_1(const util::Path &path) {
coord::tile start{2, 26};
coord::tile target{36, 2};

time::time_t request_time = clock->get_time();

PathRequest path_request{
grid->get_id(),
start,
target,
request_time
};

log::log(INFO << "Pathfinding request at " << request_time);
grid->init_portal_nodes();
timer.start();
Path path_result = pathfinder->get_path(path_request);
timer.stop();

log::log(INFO << "Pathfinding took " << timer.getval() / 1000 << " us");

// Create a renderer to display the grid and path
Expand Down Expand Up @@ -127,6 +137,7 @@ void path_demo_1(const util::Path &path) {
grid->get_id(),
start,
target,
clock->get_time()
};

timer.reset();
Expand All @@ -147,6 +158,7 @@ void path_demo_1(const util::Path &path) {
grid->get_id(),
start,
target,
clock->get_time()
};

timer.reset();
Expand Down
32 changes: 32 additions & 0 deletions libopenage/pathfinding/field_cache.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2024-2024 the openage authors. See copying.md for legal info.

#include "field_cache.h"

namespace openage::path {

void FieldCache::add(std::pair<unsigned long long, unsigned long long> cache_key,
std::shared_ptr<IntegrationField> &integration_field,
std::shared_ptr<FlowField> &flow_field) {
this->cache[cache_key] = std::make_pair(integration_field, flow_field);
}

void FieldCache::evict(std::pair<unsigned long long, unsigned long long> cache_key) {
this->cache.erase(cache_key);
}

bool FieldCache::is_cached(std::pair<unsigned long long, unsigned long long> cache_key) {
auto cached = this->cache.find(cache_key);
return cached != this->cache.end();
dmwever marked this conversation as resolved.
Show resolved Hide resolved
}

std::shared_ptr<IntegrationField> FieldCache::get_integration_field(std::pair<unsigned long long, unsigned long long> cache_key) {
auto cached = this->cache.find(cache_key);
return cached->second.first;
}

std::shared_ptr<FlowField> FieldCache::get_flow_field(std::pair<unsigned long long, unsigned long long> cache_key) {
auto cached = this->cache.find(cache_key);
return cached->second.second;
}

} // namespace openage::path
dmwever marked this conversation as resolved.
Show resolved Hide resolved
66 changes: 66 additions & 0 deletions libopenage/pathfinding/field_cache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2024-2024 the openage authors. See copying.md for legal info.

#pragma once

#include <memory>
#include <unordered_map>

#include "pathfinding/types.h"
#include "util/hash.h"

namespace openage {
namespace coord {
struct tile_delta;
} // namespace coord

namespace path {
class IntegrationField;
class FlowField;

class FieldCache
dmwever marked this conversation as resolved.
Show resolved Hide resolved
{
public:
FieldCache() = default;
~FieldCache() = default;

void add(std::pair<unsigned long long, unsigned long long> cache_key,
dmwever marked this conversation as resolved.
Show resolved Hide resolved
dmwever marked this conversation as resolved.
Show resolved Hide resolved
std::shared_ptr<IntegrationField> &integration_field,
std::shared_ptr<FlowField> &flow_field);

void evict(std::pair<unsigned long long, unsigned long long> cache_key);

bool is_cached(std::pair<unsigned long long, unsigned long long> cache_key);

std::shared_ptr<IntegrationField> get_integration_field(std::pair<unsigned long long, unsigned long long> cache_key);

std::shared_ptr<FlowField> get_flow_field(std::pair<unsigned long long, unsigned long long> cache_key);

using get_return_t = std::pair<std::shared_ptr<IntegrationField>, std::shared_ptr<FlowField>>;
dmwever marked this conversation as resolved.
Show resolved Hide resolved

private:
/**
* Hash function for the field cache.
*/
struct pair_hash {
template <class T1, class T2>
std::size_t operator()(const std::pair<T1, T2> &pair) const {
return util::hash_combine(std::hash<T1>{}(pair.first), std::hash<T2>{}(pair.second));
}
};

/**
* Cache for already computed fields.
*
* Key is the portal ID and the sector ID from which the field was entered. Fields that are cached are
* cleared of dynamic flags, i.e. wavefront or LOS flags. These have to be recalculated
* when the field is reused.
*/

dmwever marked this conversation as resolved.
Show resolved Hide resolved
std::unordered_map<std::pair<portal_id_t, sector_id_t>,
get_return_t,
pair_hash>
cache;
};

} // namespace path
} // namespace openage
dmwever marked this conversation as resolved.
Show resolved Hide resolved
Loading