-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Provide point types with coordinate system type-safety #32017
Conversation
namespace coords | ||
{ | ||
|
||
enum class scale { |
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.
Maybe a tag type (not enumeration value) is better. It allows easier adding of new systems. All properties (like scaling/absolute vs relative) can be done withing that tag type.
E.g.
class sub_map_system;
class map_system {
// this would allow converting map_system to sub_map_system, but not to say vehicle coordinates
// instead of a debug message this would yield a compiler error (as there is no factor_to( vehicle_system) function)
static int factor_to( const sub_map_system & ) {
return 12;
}
};
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 think the code is simpler with two independent features rather than a tag type that controls all aspects. Could use types rather than an enum. I chose the enum because more meta-programming logic can be written in "regular C++" constexpr
functions, rather than type-specialization style, which I was hoping would be clearer and easier to follow.
I'll try to keep both approaches in mind, though, if this version gets unwieldy.
6e07ea5
to
80f77cb
Compare
Remove almost all (x, y, z) APIs and replace wityh point / tripoint APIs. This is a first step towards making these APIs type-safe (CleverRaven#32017). A couple of APIs remain because they're more complex to change and this commit was already very big.
* Typo * Add some point / tripoint overloads for APIs A bunch of map / overmap functions take x, y, z coordinates. Add overloads to (some of) those taking a point or tripoint. For now, those overloads just forward to the original function, but the ultimate goal is to remove the originals and only have the new overloads. * Overhaul overmapbuffer APIs Remove almost all (x, y, z) APIs and replace wityh point / tripoint APIs. This is a first step towards making these APIs type-safe (#32017). A couple of APIs remain because they're more complex to change and this commit was already very big.
* Typo * Add some point / tripoint overloads for APIs A bunch of map / overmap functions take x, y, z coordinates. Add overloads to (some of) those taking a point or tripoint. For now, those overloads just forward to the original function, but the ultimate goal is to remove the originals and only have the new overloads. * Overhaul overmapbuffer APIs Remove almost all (x, y, z) APIs and replace wityh point / tripoint APIs. This is a first step towards making these APIs type-safe (CleverRaven#32017). A couple of APIs remain because they're more complex to change and this commit was already very big.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Thanks, stalebot. Still working on it :). |
overmap_terrain, | ||
segment, | ||
overmap, | ||
vehicle |
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.
vehicle scale should possibly be split into two scales: vehicle_mount (the unrotated nominal displacement from the 0,0,0 position) and vehicle_actual (the current projection of a vehicle_mount along a tileray). Perhaps those should be special origins.
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.
Yeah, I haven't delved too deeply into vehicle stuff yet. My thoughts were that the mount coords would be origin vehicle, scale vehicle, while the projected-into-world coordinates would be origin vehicle, scale map_square. But I'm not too tied to that idea yet.
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'm not too particular about how they're laid out, I just hate:
void coord_translate( int dir, const point &pivot, const point &p, point &q )
because it's not immediately clear that p and q are actually supposed to be separate types and whether pivot is the same or a different type.
If that becomes
void coord_translate( int dir, const veh_veh_point &pivot, const veh_veh_point &p, veh_ms_point &q )
then I'm satisfied, aside from veh_veh_point
looking kind of silly.
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.
scale veh
should be scale mnt
, so:
void coord_translate( int dir, const veh_mnt_point &pivot, const veh_mnt_point &p, veh_ms_point &q )
which doesn't look too bad.
70fce43
to
22bf0b5
Compare
Now that #41693 demonstrates the end-goal of this effort a little more clearly I think this PR is in a state where it can be reasonably reviewed, and I'm marking it ready. The code here still doesn't actually do anything, but adding enough to allow it to will make for a huge PR (like #41693) so I'm offering this as the first bite-sized chunk. More will follow once this is merged. |
Hah, I've just realised that it's exactly one year from opening this PR that I mark it ready for review. Interesting coincidence... |
Hopefully now fixed the clang-tidy issues. The test failures looked unrelated. |
CI now looks good to me (as good as it can be, right now, anyway). |
This takes the form of a wrapper class around point and/or tripoint which adds type parameters for the coordinate system in which the point has meaning. Added some helper functions to point.h needed to implement the conversions.
This tests project_to and project_remain.
Add arithmetic and comparison operator overloads, constructors, hashing.
We need a complicated way to report constepxr errors in older gcc versions because gcc 5.3 didn't quite implement all of C++14 constexpr properly. Add a macro that performs the workaround solution on gcc < 6, but uses a neater solution (including an error message) on other compilers.
After reading this code more, I've decided that the notation and mnemonics I'm adding are easier to understand if you put the origin before scale. e.g. point_sm_ms is a "submap map square", and point_rel_omt is a "relative overmap terrain".
Using these points in a larger proof of concept revealed the need for more operators. Add them. * Allow adding or subtracting raw points from coord_points (so that e.g. point_north, etc. can be used easily). * Allow more mixed-dimension arithmetic. * Allow subtracting two similarly-typed points to create a relative point. * Allow non-const access to individual coordinates.
They call a virtual function from the constructor. Marking them final suppresses the clang warning about this.
We are specifically testing the APIs that this check would refactor the code away from.
b7ff03b
to
9a0fdae
Compare
Summary
SUMMARY: Infrastructure "Provide point types with coordinate system type safety"
Purpose of change
Cataclysm has a lot of different coordinate systems. It's confusing to work with them, but even more so it's confusing to read code working with points and have no idea what type system they're in.
This PR aims to provide a collection of
point
/tripoint
types which encode the coordinate system in their type, so that it becomes clear what points mean and easier to correctly use APIs that havepoint
/tripoint
arguments or return values.Describe the solution
coords
to contain all the details.point
ortripoint
, with added coordinate system info.project_to
andproject_remain
for coordinate system transformations. Between them, these two functions can do anything that any of the functions incoordinate_conversions.h
can do.point
/tripoint
and coordinate system combinations for ease of use.constexpr
all the things.Catch::Generator
andCatch::StringMaker
specializations for easier working withpoint
/tripoint
in tests.Deferred to a future PR:
Note that this initial PR does not intend to actually convert code to use the new types, although I will try to do at least some experiments with them to verify that things work smoothly.
For the purposes of this PR, look at the tests for usage examples. For broader context, see #41693 which demonstrates the use of these types on a fairly large scale for various overmap-related stuff.
Describe alternatives you've considered
There are other ways to express the coordinate systems than the scale/origin pair I've chosen. This approach is very nice for the conversion functions. I think it will owrk nicely in general, but that requires further experimentation.
Additional context
The new class template is mostly agnostic to the underlying implementation of the
point
type, so there is room to support more storage choices in the same framework, e.g. if we wanted to have a more compact type that used less memory and offered less precision.