thesadrogue / TheSadRogue.Primitives

A collection of primitive data structures for working with a 2-dimensional grid.
MIT License
21 stars 6 forks source link

Make Area More Like List #46

Open Chris3606 opened 4 years ago

Chris3606 commented 4 years ago

Currently, Area works as an ordered list that is guaranteed to have distinct elements. Elements are returned in the order they are inserted via Position, while PositionsSet returns a HashSet<Point> of the points. Area also provides functions like Contains(Point). Finally, it implements IEnumerable<Point>. I feel this has a number of shortcomings.

Proposal

I propose the following enhancements to remedy this difference and make Area more like what it claims to be: a list of points that cannot have duplicates and provides the fastest operations possible, while also providing some metadata about bounds.

Additions

Modifications

Notable Absent Functions

This is a very large restructure, so feedback is welcome; if it seems too extreme, feel free to say.

fcheadle commented 4 years ago

A couple thoughts stand out.

Insert: if area is already sorted, I see no reason to have this function (unless they're part of the dressing involved with IEnumerable).

I would like to propose some operators if I might: + and += to add all points together, - and -= to remove all overlapping points, & to return all overlapping points, ^ to return all points in one or the other but not both, | to return all points of both.

Chris3606 commented 4 years ago

Insert: if area is already sorted, I see no reason to have this function

I would contest that this may apply to many use cases, but not all. The assumption that inserting an element implies a strict sortable order may not be valid; you may, for example, just want to insert elements at the beginning to create something like a queue. Also, there are different efficiency implications to sorting a list via calling Sort one or more times vs inserting elements in sorted order to begin with - in a use case where maximum performance is required, each of those options may be appropriate in some cases. List provides both of these methods and they have disparate use cases there, so my thinking is they may have disparate use cases here as well.

I would like to propose some operators if I might

The set operators are an interesting idea. There are already member and static functions that provide these operations currently, however the operators may be a convenient addition.

One caveat to the operators though is returning a new Area is not as efficient as modifying an existing one: for example, area -= area2 results in the allocation of a new Area, whereas area.RemoveAll(area2) does not, so area.RemoveAll may be measurably more performant.