Class SenseMap
Implementation of ISenseMap that implements the required fields/methods in a way applicable to many typical use cases.
Inherited Members
Namespace: GoRogue.SenseMapping
Assembly: GoRogue.dll
Syntax
public class SenseMap : SenseMapBase, ISenseMap, IReadOnlySenseMap
Remarks
This implementation of ISenseMap implements the enumerables by using a pair of hash maps to keep track of the positions which are non-0 in the current (and previous) calculate calls. This provides relatively efficient implementations that should be applicable to a variety of use cases.
The calculation, by default, is performed by first calling the CalculateLight() function of all sources. This is performed in parallel via a Parallel.ForEach loop, if there is more than one source and the ParallelCalculate property is set to true. Generally, even at 2 sense sources there is notable benefit to parallelizing the calculation; however feel free to use this flag to tweak this to your use case.
After all calculations are complete, the OnCalculate() implementation then takes the result view of each source and copies it to the appropriate section of the ResultView property. This is done sequentially, in order to avoid any problems with overlapping sources. Values are aggregated by simply adding the current value and the new value together.
If you want to customize the way values are aggregated together, you may customize the ApplySenseSourceToResult(ISenseSource) function. This function is used to apply the result view of the specified sense source onto the result view. If you simply want to change the aggregation method, then you can copy-paste the function and change the line that performs the aggregation; the aggregation method itself is not provided as a separate function for performance reasons. You may also override this function to customize the order/method of performing the aggregation.
Most other customization would require overriding the OnCalculate() function.
You may also simply create your own implementation of ISenseSource, either by directly implementing that interface or inheriting from SenseMapBase. This may be the best option if, for example, you want to avoid the use of a hash set in the enumerable implementation.
Constructors
View SourceSenseMap(IGridView<double>, CustomResultViewWithResize?, bool, IEqualityComparer<Point>?)
Constructor.
Declaration
public SenseMap(IGridView<double> resistanceView, CustomResultViewWithResize? resultViewAndResizer = null, bool parallelCalculate = true, IEqualityComparer<Point>? hasher = null)
Parameters
Type | Name | Description |
---|---|---|
IGridView<double> | resistanceView | The resistance view to use for calculations. |
CustomResultViewWithResize? | resultViewAndResizer | The view in which the sense map calculation results are stored, along with a method to use to resize it as needed. If unspecified or null, an ArrayView will be used for the result view, and the resize function will allocate a new ArrayView of the appropriate size as needed. This should be sufficient for most use cases. The resizer function must return a view with all of its values set to 0.0, which has the given width and height. |
bool | parallelCalculate | Whether or not to calculate the sense sources in parallel using Parallel.ForEach. Has no effect if there is only one source added. |
IEqualityComparer<Point> | hasher | The hashing algorithm to use for points in hash sets. Defaults to the default hash algorithm for Points. |
Fields
View SourceCurrentSenseMapBacking
A hash set which contains the positions which have non-0 values in the most current calculation result.
Declaration
protected HashSet<Point> CurrentSenseMapBacking
Field Value
Type | Description |
---|---|
HashSet<Point> |
Remarks
This hash set is the backing structure for NewlyInSenseMap and NewlyOutOfSenseMap, as well as CurrentSenseMap. During OnCalculate(), this value is cleared before the new calculations are performed.
Typically you will only need to interact with this if you are overriding OnCalculate(); in this case, if you do not call this class's implementation, you will need to perform this clearing yourself.
In order to preserve the use of whatever hasher was passed to the class at startup, it is recommended that you do not re-allocate this structure entirely. See OnCalculate() for a way to manage both this and PreviousSenseMapBacking that does not involve re-allocating.
PreviousSenseMapBacking
A hash set which contains the positions which had non-0 values in the previous calculation result.
Declaration
protected HashSet<Point> PreviousSenseMapBacking
Field Value
Type | Description |
---|---|
HashSet<Point> |
Remarks
This hash set is the backing structure for NewlyInSenseMap and NewlyOutOfSenseMap.
Typically you will only need to interact with this if you are overriding OnCalculate(); in this case, if you do not call this class's implementation, you will need to ensure this is set as appropriate before the new calculation is performed.
In order to preserve the use of whatever hasher was passed to the class at startup, it is recommended that you do not re-allocate this structure entirely. See OnCalculate() for a way to manage both this and CurrentSenseMapBacking that does not involve re-allocating.
Properties
View SourceCurrentSenseMap
IEnumerable of only positions currently "in" the sense map, eg. all positions that have a value other than 0.0.
Declaration
public override IEnumerable<Point> CurrentSenseMap { get; }
Property Value
Type | Description |
---|---|
IEnumerable<Point> |
Overrides
View SourceNewlyInSenseMap
IEnumerable of positions that DO have a non-zero value in the sense map as of the most current Calculate call, but DID NOT have a non-zero value after the previous time Calculate was called.
Declaration
public override IEnumerable<Point> NewlyInSenseMap { get; }
Property Value
Type | Description |
---|---|
IEnumerable<Point> |
Overrides
View SourceNewlyOutOfSenseMap
IEnumerable of positions that DO NOT have a non-zero value in the sense map as of the most current Calculate call, but DID have a non-zero value after the previous time Calculate was called.
Declaration
public override IEnumerable<Point> NewlyOutOfSenseMap { get; }
Property Value
Type | Description |
---|---|
IEnumerable<Point> |
Overrides
View SourceParallelCalculate
Whether or not to calculate each sense source's spread algorithm in parallel. Has no effect if there is only one source added.
Declaration
public bool ParallelCalculate { get; set; }
Property Value
Type | Description |
---|---|
bool |
Remarks
When this is set to true, calling of CalculateLight() will happen in parallel via multiple threads. A Parallel.ForEach will be used, which will enable the use of a thread pool.
In either case, the default implementation of sense sources always have their own result views on which they perform their calculations, so there is no concern with overlapping sources. This does NOT affect the copying of sense source's values from its local result view to the sense map's one, which in the default implementation is always sequential.
Methods
View SourceApplySenseSourceToResult(ISenseSource)
Takes the given source and applies its values to the appropriate sub-area of ResultViewBacking. Adds any locations that end up with non-0 values to the CurrentSenseMapBacking hash set.
Declaration
protected virtual void ApplySenseSourceToResult(ISenseSource source)
Parameters
Type | Name | Description |
---|---|---|
ISenseSource | source | The source to apply. |
Remarks
Override this if you need to control the aggregation function (eg. do something other than add values together), or if you want to apply results of sense source calculations to the sense map in a different way.
OnCalculate()
Performs CalculateLight() on all sources, and aggregates their results into ResultViewBacking.
Declaration
protected override void OnCalculate()
Overrides
Remarks
Custom implementations should implement this function to perform their calculation; the Calculate function calls reset first, then calls this, automatically firing relevant events.
Reset()
Resets the given sense map by erasing the current recorded result values.
Declaration
public override void Reset()
Overrides
Remarks
After this function is called, any value in ResultView will be 0. Additionally,CurrentSenseMap will be blank.