-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Pathfinder history #1748
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
base: master
Are you sure you want to change the base?
Pathfinder history #1748
Changes from all commits
23cbefd
4315f31
fc0809a
f37e8b5
772dd4a
b878671
8316062
e123e28
8d216b9
63c919d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
|
||
#pragma once | ||
|
||
#include <algorithm> | ||
#include <array> | ||
|
||
#include "curve/container/iterator.h" | ||
|
@@ -42,8 +43,8 @@ class Array : event::EventEntity { | |
* @param notifier Function to call when this curve changes. | ||
* @param default_vals Default values for the array elements. | ||
*/ | ||
Array(const std::shared_ptr<event::EventLoop> &loop, | ||
size_t id, | ||
Array(const std::shared_ptr<event::EventLoop> &loop = nullptr, | ||
size_t id = 0, | ||
const std::string &idstr = "", | ||
const EventEntity::single_change_notifier ¬ifier = nullptr, | ||
const std::array<T, Size> &default_vals = {}) : | ||
|
@@ -109,6 +110,14 @@ class Array : event::EventEntity { | |
*/ | ||
std::pair<time::time_t, T> next_frame(const time::time_t &t, const index_t index) const; | ||
|
||
|
||
void set_insert_range(const time::time_t &t, auto begin_it, auto end_it) { | ||
ENSURE(std::distance(begin_it, end_it) <= Size, | ||
"trying to insert more values than there are postions: max allowed = " << Size); | ||
index_t i = 0; | ||
std::for_each(begin_it, end_it, [&](const T &val) { this->set_insert(t, i++, val); }); | ||
} | ||
Comment on lines
+114
to
+119
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice idea. Would it also make sense to make |
||
|
||
/** | ||
* Insert a new keyframe value at time t. | ||
* | ||
|
@@ -118,7 +127,7 @@ class Array : event::EventEntity { | |
* @param index Index of the array element. | ||
* @param value Keyframe value. | ||
*/ | ||
void set_insert(const time::time_t &t, const index_t index, T value); | ||
void set_insert(const time::time_t &t, const index_t index, const T &value); | ||
|
||
/** | ||
* Insert a new keyframe value at time t. Erase all other keyframes with elem->time > t. | ||
|
@@ -127,7 +136,7 @@ class Array : event::EventEntity { | |
* @param index Index of the array element. | ||
* @param value Keyframe value. | ||
*/ | ||
void set_last(const time::time_t &t, const index_t index, T value); | ||
void set_last(const time::time_t &t, const index_t index, const T &value); | ||
|
||
/** | ||
* Replace all keyframes at elem->time == t with a new keyframe value. | ||
|
@@ -136,7 +145,7 @@ class Array : event::EventEntity { | |
* @param index Index of the array element. | ||
* @param value Keyframe value. | ||
*/ | ||
void set_replace(const time::time_t &t, const index_t index, T value); | ||
void set_replace(const time::time_t &t, const index_t index, const T &value); | ||
|
||
/** | ||
* Copy keyframes from another container to this container. | ||
|
@@ -324,7 +333,7 @@ consteval size_t Array<T, Size>::size() const { | |
template <typename T, size_t Size> | ||
void Array<T, Size>::set_insert(const time::time_t &t, | ||
const index_t index, | ||
T value) { | ||
const T &value) { | ||
// find elem_ptr in container to get the last keyframe with time <= t | ||
auto hint = this->last_elements[index]; | ||
auto e = this->containers.at(index).insert_after(Keyframe{t, value}, hint); | ||
|
@@ -338,7 +347,7 @@ void Array<T, Size>::set_insert(const time::time_t &t, | |
template <typename T, size_t Size> | ||
void Array<T, Size>::set_last(const time::time_t &t, | ||
const index_t index, | ||
T value) { | ||
const T &value) { | ||
// find elem_ptr in container to get the last keyframe with time <= t | ||
auto hint = this->last_elements[index]; | ||
auto e = this->containers.at(index).last(t, hint); | ||
|
@@ -363,7 +372,7 @@ void Array<T, Size>::set_last(const time::time_t &t, | |
template <typename T, size_t Size> | ||
void Array<T, Size>::set_replace(const time::time_t &t, | ||
const index_t index, | ||
T value) { | ||
const T &value) { | ||
// find elem_ptr in container to get the last keyframe with time <= t | ||
auto hint = this->last_elements[index]; | ||
auto e = this->containers.at(index).insert_overwrite(Keyframe{t, value}, hint); | ||
|
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -14,7 +14,8 @@ namespace openage::path { | |||||||||
CostField::CostField(size_t size) : | ||||||||||
size{size}, | ||||||||||
valid_until{time::TIME_MIN}, | ||||||||||
cells(this->size * this->size, COST_MIN) { | ||||||||||
cells(this->size * this->size, COST_MIN), | ||||||||||
cell_cost_history() { | ||||||||||
log::log(DBG << "Created cost field with size " << this->size << "x" << this->size); | ||||||||||
} | ||||||||||
|
||||||||||
|
@@ -54,6 +55,28 @@ void CostField::set_costs(std::vector<cost_t> &&cells, const time::time_t &valid | |||||||||
|
||||||||||
this->cells = std::move(cells); | ||||||||||
this->valid_until = valid_until; | ||||||||||
this->cell_cost_history.set_insert_range(valid_until, this->cells.begin(), this->cells.end()); | ||||||||||
} | ||||||||||
|
||||||||||
bool CostField::stamp(size_t idx, cost_t cost, const time::time_t &stamped_at) { | ||||||||||
if (this->cost_stamps[idx].has_value()) return false; | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please always make if clauses multi-line for consistent code style.
Suggested change
|
||||||||||
|
||||||||||
cost_t original_cost = this->get_cost(idx); | ||||||||||
this->cost_stamps[idx]->original_cost = original_cost; | ||||||||||
this->cost_stamps[idx]->stamp_time = stamped_at; | ||||||||||
|
||||||||||
this->set_cost(idx, cost, stamped_at); | ||||||||||
return true; | ||||||||||
} | ||||||||||
|
||||||||||
bool CostField::unstamp(size_t idx, const time::time_t &unstamped_at) { | ||||||||||
if (!this->cost_stamps[idx].has_value() || unstamped_at < this->cost_stamps[idx]->stamp_time) return false; | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here and
Suggested change
|
||||||||||
|
||||||||||
cost_t original_cost = cost_stamps[idx]->original_cost; | ||||||||||
|
||||||||||
this->set_cost(idx, original_cost, unstamped_at); | ||||||||||
this->cost_stamps[idx].reset(); | ||||||||||
return true; | ||||||||||
} | ||||||||||
|
||||||||||
bool CostField::is_dirty(const time::time_t &time) const { | ||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,9 @@ | |
|
||
#include <cstddef> | ||
#include <vector> | ||
#include <optional> | ||
|
||
#include "curve/container/array.h" | ||
#include "pathfinding/types.h" | ||
#include "time/time.h" | ||
|
||
|
@@ -14,6 +16,8 @@ namespace coord { | |
struct tile_delta; | ||
} // namespace coord | ||
|
||
const unsigned int CHUNK_SIZE = 100; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The value should probably not be hardcoded because then the cost field size is not configurable anymore. I think we either need to make |
||
|
||
namespace path { | ||
|
||
/** | ||
|
@@ -89,6 +93,7 @@ class CostField { | |
inline void set_cost(size_t idx, cost_t cost, const time::time_t &valid_until) { | ||
this->cells[idx] = cost; | ||
this->valid_until = valid_until; | ||
this->cell_cost_history.set_insert(valid_until, idx, this->cells[idx]); | ||
} | ||
|
||
/** | ||
|
@@ -106,6 +111,27 @@ class CostField { | |
*/ | ||
void set_costs(std::vector<cost_t> &&cells, const time::time_t &changed); | ||
|
||
/** | ||
* Stamp a cost field cell at a given time. | ||
* | ||
* @param idx Index of the cell. | ||
* @param cost Cost to set. | ||
* @param stamped_at Time at which the cost cell is to be stamped. | ||
* | ||
* @return True if the cell was successfully stamped, false if the cell was already stamped. | ||
*/ | ||
bool stamp(size_t idx, cost_t cost, const time::time_t &stamped_at); | ||
|
||
/** | ||
* Unstamp a cost field cell at a given time. | ||
* | ||
* @param idx Index of the cell. | ||
* @param unstamped_at Time at which the cost cell is to be unstamped. | ||
* | ||
* @return True if the cell was successfully unstamped, false if the cell was already not stamped. | ||
*/ | ||
bool unstamp(size_t idx, const time::time_t &unstamped_at); | ||
|
||
/** | ||
* Check if the cost field is dirty at the specified time. | ||
* | ||
|
@@ -135,6 +161,17 @@ class CostField { | |
* Cost field values. | ||
*/ | ||
std::vector<cost_t> cells; | ||
|
||
/** | ||
* Cost stamp vector. | ||
*/ | ||
std::vector<std::optional<cost_stamp_t>> cost_stamps; | ||
|
||
|
||
/** | ||
* Array curve recording cell cost history, | ||
*/ | ||
curve::Array<cost_t, CHUNK_SIZE> cell_cost_history; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How should There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes that would be enough I think. |
||
}; | ||
|
||
} // namespace path | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,4 +1,4 @@ | ||||||||||||||||||||||
// Copyright 2024-2024 the openage authors. See copying.md for legal info. | ||||||||||||||||||||||
// Copyright 2024-2025 the openage authors. See copying.md for legal info. | ||||||||||||||||||||||
|
||||||||||||||||||||||
#pragma once | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
@@ -7,6 +7,7 @@ | |||||||||||||||||||||
#include <memory> | ||||||||||||||||||||||
#include <utility> | ||||||||||||||||||||||
|
||||||||||||||||||||||
#include "time/time.h" | ||||||||||||||||||||||
|
||||||||||||||||||||||
namespace openage::path { | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
@@ -124,4 +125,19 @@ using cache_key_t = std::pair<portal_id_t, sector_id_t>; | |||||||||||||||||||||
*/ | ||||||||||||||||||||||
using field_cache_t = std::pair<std::shared_ptr<IntegrationField>, std::shared_ptr<FlowField>>; | ||||||||||||||||||||||
|
||||||||||||||||||||||
/** | ||||||||||||||||||||||
* Cost stamp for a given cost field cell. | ||||||||||||||||||||||
*/ | ||||||||||||||||||||||
struct cost_stamp_t { | ||||||||||||||||||||||
Comment on lines
+128
to
+130
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A small explanation of stamping for people who don't know what that is would be nice here. I added a suggesion below.
Suggested change
|
||||||||||||||||||||||
/** | ||||||||||||||||||||||
* Original cost of the stamped cell. | ||||||||||||||||||||||
*/ | ||||||||||||||||||||||
cost_t original_cost; | ||||||||||||||||||||||
|
||||||||||||||||||||||
/** | ||||||||||||||||||||||
* Time the cost field cell was stamped. | ||||||||||||||||||||||
*/ | ||||||||||||||||||||||
time::time_t stamp_time; | ||||||||||||||||||||||
}; | ||||||||||||||||||||||
|
||||||||||||||||||||||
} // namespace openage::path |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, would be nice if the method gets documented :)