GoRogue has the concept of "spatial maps", which are really just an efficient way of representing a "sparse" set of objects on a map (eg not every object has one position). It abstracts away concepts pertaining to placing objects on a 2d grid, such as how many objects can exist at a location at once, whether or not the concept of layers/z-indexes exists, etc. Really, this should be in the primitives library, since although it requires some utility infrastructure to function properly, the core concept works for any 2D grid.
The code is about 50% unit tested, however most of it has been functionally tested fairly extensively in GoRogue. I intend to create more tests later, I figured getting it into this repository earlier rather than later is beneficial.
There are also a number of improvements I would like to make to this API. There are optimizations that can be performed (though most it is already quite well optimized), but more importantly I think it should be possible to implement an interface that avoids manual syncing of items if they have a Position field.
These APIs (both the spatial maps and some of the utility classes) are probably quite useful for SadConsole (at least SadConsole.Extended) and in general for grid-based games; so feel free to take some time and poke through them. The transition of these APIs to the primitives library presents a good opportunity to make improvements.
Changes
Added IHasID, which is an interface describing an object that has a semi-unique (usually randomly generated) identifier.
This is used to implement spatial maps
Added IHasLayer, which is an interface describing an object that has a z-index associated with it
Added IDGenerator, which is a helpful utility class useful when you want all objects to have a truly unique ID, as opposed to randomly generating and occasionally colliding.
Added CustomListEnumerators.cs, which contain enumerators defined for List<T> and IReadOnlyList<T> that iterate very quickly (exactly like the built-in C# enumerator does, but do not expose the actual list to the user and also implement IEnumerable, so can be used in the standard pattern that custom enumerators in this library use
MultiSpatialMap uses these to make GetItemsAt as fast as possible
Implemented the Pooling namespace, which implements an abstraction (and concrete implementations for) over the concept of a ListPool; basically an ArrayPool but for List.
IListPool is an interface representing a pool (so that structures can take one as a parameter, which ultimately allows a user to choose whether or not to use pooling
ListPool is the basic implementation of this interface.
NoPoolingListPool is a pseudo-implementation of the interface that does no pooling at all; this is what users should use if they want a data structure which supports pooling to not use pooling at all.
Implemented the SpatialMap namespace
Contains a series of interfaces which define the concept of a "spatial map".
SpatialMap/AdvancedSpatialMap are implementations of the spatial map interface which support only one object residing at a single location at once.
MultiSpatialMap/AdvancedMultiSpatialMap are implementations which support many objects residing at the same location.
LayeredSpatialMap/AdvancedLayeredSpatialMap are "combination" implementations that implement the concept of "layers", which are internally split into separate spatial maps. Each layer can elect to support multiple items at a single location on that layer, or not, independently, and pretty much all of its operations support "layer masking", which allows you to specify a layer mask and only apply operations to those layers.
LayerMasker is a utility class that basically implements bit-masks, but allows you to specify flags as numbers 0-31. This corresponds with LayeredSpatialMap's definition of a layer, and is used to implement that class. Other that it defining flags as values with IDs 0-31, there is nothing particularly special about this class compared to traditional bitmasking.
ToStringExtensions is a series of extension methods which implement methods that can conveniently turn lists, dictionaries, hash sets, and 2d arrays into strings. This is extremely convenient for user debugging, and is used to provide ToString implementations of spatial maps.
Overview
GoRogue has the concept of "spatial maps", which are really just an efficient way of representing a "sparse" set of objects on a map (eg not every object has one position). It abstracts away concepts pertaining to placing objects on a 2d grid, such as how many objects can exist at a location at once, whether or not the concept of layers/z-indexes exists, etc. Really, this should be in the primitives library, since although it requires some utility infrastructure to function properly, the core concept works for any 2D grid.
The code is about 50% unit tested, however most of it has been functionally tested fairly extensively in GoRogue. I intend to create more tests later, I figured getting it into this repository earlier rather than later is beneficial.
There are also a number of improvements I would like to make to this API. There are optimizations that can be performed (though most it is already quite well optimized), but more importantly I think it should be possible to implement an interface that avoids manual syncing of items if they have a
Position
field.These APIs (both the spatial maps and some of the utility classes) are probably quite useful for SadConsole (at least
SadConsole.Extended
) and in general for grid-based games; so feel free to take some time and poke through them. The transition of these APIs to the primitives library presents a good opportunity to make improvements.Changes
IHasID
, which is an interface describing an object that has a semi-unique (usually randomly generated) identifier.IHasLayer
, which is an interface describing an object that has a z-index associated with itIDGenerator
, which is a helpful utility class useful when you want all objects to have a truly unique ID, as opposed to randomly generating and occasionally colliding.CustomListEnumerators.cs
, which contain enumerators defined forList<T>
andIReadOnlyList<T>
that iterate very quickly (exactly like the built-in C# enumerator does, but do not expose the actual list to the user and also implementIEnumerable
, so can be used in the standard pattern that custom enumerators in this library useGetItemsAt
as fast as possiblePooling
namespace, which implements an abstraction (and concrete implementations for) over the concept of aListPool
; basically anArrayPool
but forList
.IListPool
is an interface representing a pool (so that structures can take one as a parameter, which ultimately allows a user to choose whether or not to use poolingListPool
is the basic implementation of this interface.NoPoolingListPool
is a pseudo-implementation of the interface that does no pooling at all; this is what users should use if they want a data structure which supports pooling to not use pooling at all.SpatialMap
namespaceSpatialMap
/AdvancedSpatialMap
are implementations of the spatial map interface which support only one object residing at a single location at once.MultiSpatialMap
/AdvancedMultiSpatialMap
are implementations which support many objects residing at the same location.LayeredSpatialMap
/AdvancedLayeredSpatialMap
are "combination" implementations that implement the concept of "layers", which are internally split into separate spatial maps. Each layer can elect to support multiple items at a single location on that layer, or not, independently, and pretty much all of its operations support "layer masking", which allows you to specify a layer mask and only apply operations to those layers.LayerMasker
is a utility class that basically implements bit-masks, but allows you to specify flags as numbers 0-31. This corresponds withLayeredSpatialMap
's definition of a layer, and is used to implement that class. Other that it defining flags as values with IDs 0-31, there is nothing particularly special about this class compared to traditional bitmasking.ToStringExtensions
is a series of extension methods which implement methods that can conveniently turn lists, dictionaries, hash sets, and 2d arrays into strings. This is extremely convenient for user debugging, and is used to provideToString
implementations of spatial maps.