-
-
Notifications
You must be signed in to change notification settings - Fork 875
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
Change: Add path cache for ships #7072
Conversation
6310595
to
50ab38b
Compare
Fixed doxygen comments for the std::deque functions and helper. |
I tried to break this, by e.g.
Everything I tried was handled as expected.
|
Great PR! I hope it gets approved soon. |
50ab38b
to
102670e
Compare
Updated to not call HandlePathfindingResult() as commented. |
src/ship.h
Outdated
/** | ||
* All ships have this type. | ||
*/ | ||
struct Ship FINAL : public SpecializedVehicle<Ship, VEH_SHIP> { | ||
TrackBitsByte state; ///< The "track" the ship is following. | ||
ShipPathCache path; ///< Cached path. | ||
TileIndex path_dest; ///< Cached path destination. |
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.
It would be great if path_dest could be removed, although I don't know whether it is possible. Maybe clearing the cached path when orders change and when path becomes invalid (and other cases, if any) would be much better.
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.
The problem is v->dest_tile is touched in so many places, in non-ship-specific code too, it would be pretty invasive to do so.
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.
I tried it on the last commit of this branch. I think I covered all cases where a path may become invalid because of orders.
Don't know which approach is better, but I wouldn't keep a TileIndex just for marking whether a path is still valid or not.
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.
Hmm, what about virtual methods? This commit implements this.
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.
👏 If this works, fantastic.
EDIT: On a second thought and as I am not expert with virtual methods, if we have:
Vehicle *v;
v->CallToVirtualMethod();
and Ship is derived from Vehicle, will it call to the virtual function of Ship, isn't it?
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.
Yes, it will call the virtual function on Ship as expected. There is a small performance penalty for this but I don't think that's relevant here.
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.
Just to be sure...
If I call UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth,...
and inside UpdateOrderDest(...) there is a call to:
v->SetDest()
It will call the virtual method Ship::SetDest and not Vehicle::SetDest ?
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.
Yup.
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.
Then, after all this hassle, it is up to you to decide whether it is best to use path_dest or clearing cache when dest_tile changes.
I haven't reviewed the code for load/saving dequeues, but the other part of the code looks great.
This is a great improvement and I hope you have it soon approved.
…-degree turns are changed.
6dfeea5
to
ebf3e76
Compare
Updated version to remove clumsy path_dest member and clear the path cache directly, using virtual methods. |
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.
Too late for this?
/* Cached path is invalid so continue with pathfinder. */ | ||
} | ||
|
||
v->path.clear(); |
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.
Can this line (v->path.clear()) be inside the "if(not empty 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.
Er... yes :/ Oops!
If you are interested in extending this to NPF, these two commits may come useful for a starting point. Note that these commits should be adapted:
If not interested in taking on this, let me know and I will try to do it. |
If you want to give it a go, please do open a PR. I don't intend to spend much time on it myself but if you can see what needs to be done, that's great! |
Next weekend I will check this and create a PR if it works. |
This is an attempt to improve performance of YAPF by caching the path found for a number of steps, removing the need to call the pathfinder every time the ship enters a new tile.
Significant performance improvements have been observed, in one save reducing the average ship ticks from ~ 60ms down to 17ms, allowing the game to run in realtime: http://fuzzle.org/~petern/ottd/shipcache2.png
As the path cache is required to be synchronized, changes to the save/load system have been implemented to include std::deque functionality.