-
Notifications
You must be signed in to change notification settings - Fork 13
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
[fontdrasil] Typed coordinate spaces #632
Conversation
4eb0767
to
241f7e9
Compare
At a glance I like it, will do an actual review later. |
241f7e9
to
227ba0a
Compare
I've added a second commit here that impls |
227ba0a
to
4e37c45
Compare
fontdrasil/src/coords.rs
Outdated
//TODO: Code review: this constructor can create invalid values, | ||
//particularly in the case of NormalizedCoords. We could fix this | ||
//a number of ways, for instance by clamping the space or else by making | ||
//it fallible. Do we care? What solution would we prefer? |
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.
leave it like this, sometimes it is useful to be able to make a NormalizedCoord that exceeds -1 or +1 (but is still within the F2Dot14 bounds) e.g. restricting axis min/max duing VF partial instancing.
It's clear already what needs to be done when the NormalizedCoord is used; 0 is default by definition, -1 is min, +1 is max, anything beyond will never be accessed because instance input location must be clamped.
looks neat though I am still unsure what the PhantomData is actually doing |
Oh I see. The generic struct Coord doesn't store a Space type but needs to behave differently based on it; so the zero-sized PhantomData here acts as a "type marker". |
So yea, The reason you don't do |
4e37c45
to
02f535b
Compare
} | ||
} | ||
}; | ||
} |
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 wish there wasn't a macro but I don't have a better idea.
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 alternative is just to write essentially the same code three times. Is your concern based on the insanity of macros in C? Rust's macros are much more constrained, and it makes it easier to refactor things in the future, since we'd only need to edit in one place.
This started out as just an experiment, but I ended up fleshing it out to the point where it is mergeable, if we wish. The basic motivation was seeing the duplication in methods defined on the various `Coords`, and wanting to unify that.
This is just about making tests easier to read.
02f535b
to
135a2ed
Compare
This started out as just an experiment, but I ended up fleshing it out to the point where it is mergeable, if we wish.
The basic idea is that instead of having separate types for each coordinate in each space, we actually use the space as a type parameter, and then have a single
Coord
type that is generic over that parameter. This means that we define all conversions in terms of the coordinate space, and then we can define methods on a singleCoord
type that are available everywhere. (We can also define methods that are specific to a coordinate in a particular space.)So... I'm anticipating a lot of tell-me-whys here, and I fundamentally agree that this is not a hugely important change. The main advantages as I see them is that this version has slightly better ergonomics and is a bit more maintainable, while generating slightly less code. The downside is that it uses an advanced language feature,
PhantomData
.Finally, if we decide this is not actually an improvement then I hope at least it is a useful illustration of an idiomatic approach to this problem.
edit:
Having played with this a bit more, I am more convinced this (or something in this vein) is the right design. The basic rationale is that doing things this way lets you make other code more generic; for instance it would now be very easy to make our
PiecewiseLinearMap
be generic over a pair of coordinate spaces, like:and because we know that both types are
Coord
s, we can know there is always some available set of methods. This would not work if we were using the current coord types and doingPiecewiseLinearMap<T, U>
since we don't now anything aboutT
andU
in that case.basically: The advantage of
Coord
is that it encapsulates all of the general behaviour of a coordinate, regardless of the coordinate space, and that is actually a useful distinction in some cases.