On Friday, 21 March 2014 at 16:21:18 UTC, Jakob Ovrum wrote:
On Friday, 21 March 2014 at 11:04:58 UTC, Vladimir Panteleev wrote:

Some highlights from a recent overhaul of the graphics package from my D library. It makes use of a number of D-specific language features, so I've tried to make the article accessible to people new to D as well.

That's really cool. I have some notes though:

* All the function templates separate the template declaration from the function declaration, when they can just use the function template syntax.

Where this is done, it is on purpose. For example, the "invert" declaration as it appears in the article wouldn't be possible with the shorthand function template syntax.

 * Any particular reason that coordinate integers are signed?

Yes. I've tried using unsigned coordinates in the past. It was awful.

My conclusion is that if you ever need to subtract values, you should use signed types.

`isView` seems to prefer `size_t`.

int implicitly casts to size_t but not the other way around.

 * `warp` exclusively uses string expression arguments...

Yeah. A lambda would need to receive x, y, w and h, and we don't have naryFun in Phobos. (It's there but commented out for some reason.)

To a small extent, I made some compromises for the first iteration for the sake of code looking good for the article, and maybe with the help of feedback improve on that.

For example, a problem I've struggled with is avoiding having two overloads for almost every function in image.d. I've tried multiple approaches: default arguments (in the form of *new Image!COLOR), templates, string mixins, UDAs, pointers, but they all were rather ugly or impractical. Some related compiler issues are 8074, 12386, 12425 and 12426 - fixing those might make some of those approaches more feasible.

* I'd recommend sticking to structs (often with AliasThis) over mixins for as far as it goes, as it's much more structured, thus easier to read and reason with.

That doesn't work if you need two-way communication. Although you can pass outer methods as aliases to the inner struct, but then you have to use crazy tricks to make methods of the inner struct static in respect to the inner struct but bound to the outer one via the alias. I've played with this quite a bit for ae.utils.serialization, but I don't think it fits here. Unless I'm missing something?

It's always nice to know examples of high performance range-based code. I noticed that the `View` concept does not have the concept of stride or access to pixels using a single absolute coordinate; maybe if that was the case, the `blitTo` algorithm could be optimized to its conclusion, instead of copying scanlines one by one.

That's what my previous design used. But ultimately, unless you're dealing with very narrow images, I don't think there will be a noticeable difference in performance. This design is more flexible, though (e.g. vjoiner can serve scanlines from different sources).

Thanks for the feedback.

Reply via email to