Class ScyllaTriGrid<TCell>
Dense, pre-allocated array-backed triangular grid that stores per-cell data of type
TCell, addressed by TriCoord lane coordinates.
Inherited Members
Namespace: Scylla.Core.Structures
Assembly: ScyllaCore.dll
Syntax
public sealed class ScyllaTriGrid<TCell> : IScyllaGrid<TriCoord, TCell>, IScyllaCollection
Type Parameters
| Name | Description |
|---|---|
| TCell | The type of data stored in each grid cell. May be a value type or a reference type. |
Remarks
Internally the grid is laid out as a rectangular region of Width × Height
cell positions, each holding two triangles - a downward (orientation 0, sum = 1)
and an upward (orientation 1, sum = 2) - in a flat array. The index formula is:
col = A - 1
row = B - 1
orientation = (A+B+C == 1) ? 0 : 1
index = (row * Width + col) * 2 + orientation
The total cell count is always Width × Height × 2. All cells are
pre-allocated at construction and initialised to default(TCell); for a
specific default value use the builder's WithDefaultValue option.
This class is unsynchronized by default. Call AsSynchronized(object) or
use the builder's Synchronized() option to obtain a thread-safe wrapper.
For grids where most cells are empty, prefer ScyllaSparseTriGrid<TCell> to avoid the up-front memory cost.
var grid = new ScyllaTriGrid<int>(10, 10, new TriGridLayout(1f));
grid[new TriCoord(1, 1, 0)] = 42; /* downward triangle (sum=1) */
grid[new TriCoord(1, 1, 1)] = 99; /* upward triangle (sum=2) */
Constructors
ScyllaTriGrid(int, int, TriGridLayout)
Creates a new dense triangular grid with the specified dimensions and layout,
pre-allocating all width × height × 2 cells and initialising them to
default(TCell).
Declaration
public ScyllaTriGrid(int width, int height, TriGridLayout layout)
Parameters
| Type | Name | Description |
|---|---|---|
| int | width | The number of rectangular columns. Must be at least 1. Determines the valid A
lane range |
| int | height | The number of rectangular rows. Must be at least 1. Determines the valid B lane
range |
| TriGridLayout | layout | The TriGridLayout supplying the triangle edge length and world-space origin for coordinate conversion. |
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown when |
Properties
Capabilities
Gets the feature and capability flags supported by this collection instance.
Declaration
public ScyllaCollectionCapabilities Capabilities { get; }
Property Value
| Type | Description |
|---|---|
| ScyllaCollectionCapabilities | A bitfield of ScyllaCollectionCapabilities flags describing which optional operations the concrete instance supports. The value None indicates that only the base contract (Count, IsEmpty, Clear()) is available. |
Remarks
Use Capabilities for feature detection in place of type-casting. For example:
if ((collection.Capabilities & ScyllaCollectionCapabilities.SupportsPeek) != 0)
{
// safe to call TryPeek through IScyllaCollection<T>
}
Synchronized wrappers cache the capability flags of their inner collection at construction time, so the value returned is stable and does not require synchronization.
See Also
CellCount
Gets the number of populated (logically active) cells in the grid.
Declaration
public int CellCount { get; }
Property Value
| Type | Description |
|---|---|
| int | For dense grids, this always equals Count - every cell slot is pre-allocated and considered populated regardless of its stored value. The value is fixed at construction and never changes. For sparse grids, this equals the number of cells that have been explicitly written via TrySet(TCoord, TCell) and not yet removed. The value may be zero on a freshly created or cleared sparse grid. |
See Also
Count
Gets the number of items currently contained in the collection.
Declaration
public int Count { get; }
Property Value
| Type | Description |
|---|---|
| int | A non-negative integer representing the current element count.
Returns |
Remarks
On unsynchronized collections, Count is not thread-safe and may return a stale
value when accessed concurrently. On synchronized wrappers, reading Count is
protected by the internal lock.
Height
Gets the number of rectangular rows in this grid. The valid B lane range for cells
in this grid is 1..Height (inclusive).
Declaration
public int Height { get; }
Property Value
| Type | Description |
|---|---|
| int |
IsEmpty
Always returns false. A dense grid pre-allocates all cells at construction
time, so there is never a state where no cells exist.
Declaration
public bool IsEmpty { get; }
Property Value
| Type | Description |
|---|---|
| bool |
this[TriCoord]
Gets or sets the cell value at the specified triangle coordinate using direct array
access. Throws if the coordinate is out of bounds rather than returning
default; use TryGet(TriCoord, out TCell) or TrySet(TriCoord, TCell) for non-throwing
access.
Declaration
public TCell this[TriCoord coord] { get; set; }
Parameters
| Type | Name | Description |
|---|---|---|
| TriCoord | coord | The triangle coordinate of the cell to access. |
Property Value
| Type | Description |
|---|---|
| TCell |
Exceptions
| Type | Condition |
|---|---|
| IndexOutOfRangeException | Thrown when |
Layout
Gets the TriGridLayout that defines the triangle edge length and world-space origin used by GridToWorld(TriCoord) and WorldToGrid(Vector2).
Declaration
public TriGridLayout Layout { get; }
Property Value
| Type | Description |
|---|---|
| TriGridLayout |
SyncRoot
Gets the synchronization root object used to externally coordinate multi-step operations with this collection.
Declaration
public object SyncRoot { get; }
Property Value
| Type | Description |
|---|---|
| object | A non-null object suitable for use with |
Remarks
When this collection is a synchronized wrapper, SyncRoot must be non-null and
stable for the entire lifetime of the wrapper. All internal operations on the wrapper
must lock on this same object. This allows callers to perform atomic multi-step
sequences:
lock (collection.SyncRoot)
{
if (!collection.IsEmpty)
typedCollection.TryRemove(out var item);
}
For unsynchronized collections (SyncRoot == null), callers are responsible for
supplying and consistently applying their own external synchronization mechanism.
A null SyncRoot does not mean the collection is thread-safe;
consult ThreadSafety for the authoritative guarantee.
See Also
ThreadSafety
Gets the thread-safety guarantees provided by this collection instance.
Declaration
public ScyllaCollectionThreadSafety ThreadSafety { get; }
Property Value
| Type | Description |
|---|---|
| ScyllaCollectionThreadSafety | A ScyllaCollectionThreadSafety value indicating whether the collection is unsynchronized, synchronized via a lock, or safe for lock-free concurrent access. Most core implementations return Unsynchronized. Synchronized wrappers return Synchronized. |
Remarks
Always check this property (or SyncRoot) before assuming a collection is
safe for concurrent use. Do not rely solely on the absence of a non-null SyncRoot
to infer thread safety; use this property as the authoritative source.
See Also
Width
Gets the number of rectangular columns in this grid. The valid A lane range for
cells in this grid is 1..Width (inclusive).
Declaration
public int Width { get; }
Property Value
| Type | Description |
|---|---|
| int |
Methods
AsSynchronized(object)
Creates and returns a thread-safe ScyllaTriGrid<TCell>.SynchronizedScyllaTriGrid wrapper that serialises all operations on this grid using a lock.
Declaration
public ScyllaTriGrid<TCell>.SynchronizedScyllaTriGrid AsSynchronized(object syncRoot = null)
Parameters
| Type | Name | Description |
|---|---|---|
| object | syncRoot | An optional external lock object to share with other synchronized collections for
compound atomic operations. If |
Returns
| Type | Description |
|---|---|
| ScyllaTriGrid<TCell>.SynchronizedScyllaTriGrid | A ScyllaTriGrid<TCell>.SynchronizedScyllaTriGrid wrapping this instance with
|
Clear()
Removes all items from the collection and resets it to an empty state.
Declaration
public void Clear()
Remarks
Implementations that store reference-type elements should null out internal slots after
clearing to avoid retaining object references and preventing garbage collection.
After Clear returns, Count must be 0 and
IsEmpty must be true.
On synchronized wrappers this operation is protected by the collection's internal lock. On unsynchronized collections, callers are responsible for external coordination.
Contains(TriCoord)
Determines whether the specified coordinate is addressable and populated in this grid.
Declaration
public bool Contains(TriCoord coord)
Parameters
| Type | Name | Description |
|---|---|---|
| TriCoord | coord | The coordinate to test. |
Returns
| Type | Description |
|---|---|
| bool |
For dense grids, returns
For sparse grids, returns |
Remarks
This method is equivalent to checking whether TryGet(TCoord, out TCell) would return
true for the same coordinate. Use it when you only need the existence check
and do not need the value.
See Also
CreateBuilder()
Creates a new fluent builder for constructing a ScyllaTriGrid<TCell> with complex configuration.
Declaration
public static ScyllaTriGrid<TCell>.Builder CreateBuilder()
Returns
| Type | Description |
|---|---|
| ScyllaTriGrid<TCell>.Builder | A new ScyllaTriGrid<TCell>.Builder instance with default settings. |
Fill(TCell)
Sets every cell in the grid to the specified value, overwriting any existing data. This increments the internal version counter, invalidating any active ScyllaTriGrid<TCell>.Enumerator instances.
Declaration
public void Fill(TCell value)
Parameters
| Type | Name | Description |
|---|---|---|
| TCell | value | The value to write into every cell. |
GetEnumerator()
Returns an allocation-free enumerator that iterates through all cells in this grid in row-major order.
Declaration
public ScyllaTriGrid<TCell>.Enumerator GetEnumerator()
Returns
| Type | Description |
|---|---|
| ScyllaTriGrid<TCell>.Enumerator | An ScyllaTriGrid<TCell>.Enumerator positioned before the first cell. |
Remarks
Use this method on the concrete ScyllaTriGrid<TCell> type (not via
an interface) to avoid boxing the value-type ScyllaTriGrid<TCell>.Enumerator. Modifying
the grid while enumeration is in progress will cause the next MoveNext call
to throw InvalidOperationException.
GetNeighborsNonAlloc(TriCoord, Span<TriCoord>)
Writes the edge-sharing neighbors of the specified coordinate that lie within this grid's bounds into the provided buffer, without allocating.
Declaration
public int GetNeighborsNonAlloc(TriCoord coord, Span<TriCoord> buffer)
Parameters
| Type | Name | Description |
|---|---|---|
| TriCoord | coord | The triangle coordinate whose in-bounds neighbors are needed. |
| Span<TriCoord> | buffer | A span to receive the neighbor coordinates. Entries are written starting at index 0. Writing stops when the buffer is full. |
Returns
| Type | Description |
|---|---|
| int | The number of in-bounds neighbors written into |
Remarks
All three candidate neighbors are computed via
GetEdgeNeighbors(TriCoord, Span<TriCoord>) on a stack-allocated buffer; only those
that pass IsInBounds(TriCoord) are written to buffer.
GridToWorld(TriCoord)
Converts a triangle coordinate to the world-space centroid position using this grid's Layout.
Declaration
public Vector2 GridToWorld(TriCoord coord)
Parameters
| Type | Name | Description |
|---|---|---|
| TriCoord | coord | The triangle coordinate to convert. |
Returns
| Type | Description |
|---|---|
| Vector2 | The world-space |
See Also
IsInBounds(TriCoord)
Determines whether the specified coordinate is a valid triangle with a lane sum of 1 or 2, and whose A and B lanes fall within the grid's column and row ranges.
Declaration
public bool IsInBounds(TriCoord coord)
Parameters
| Type | Name | Description |
|---|---|---|
| TriCoord | coord | The triangle coordinate to test. |
Returns
| Type | Description |
|---|---|
| bool |
|
TryGet(TriCoord, out TCell)
Attempts to retrieve the value stored at the specified coordinate without throwing on failure.
Declaration
public bool TryGet(TriCoord coord, out TCell value)
Parameters
| Type | Name | Description |
|---|---|---|
| TriCoord | coord | The grid coordinate to look up. |
| TCell | value | When this method returns |
Returns
| Type | Description |
|---|---|
| bool |
|
Remarks
Prefer this method over direct indexer access when the coordinate's validity is not guaranteed, as it avoids the cost of exception handling on out-of-bounds access. For dense grids, "within bounds" means the coordinate maps to a valid flat-array index. For sparse grids, "within bounds" additionally requires that the cell has been set.
See Also
TrySet(TriCoord, TCell)
Attempts to store a value at the specified coordinate without throwing on failure.
Declaration
public bool TrySet(TriCoord coord, TCell value)
Parameters
| Type | Name | Description |
|---|---|---|
| TriCoord | coord | The grid coordinate to write to. |
| TCell | value | The value to store at |
Returns
| Type | Description |
|---|---|
| bool |
|
Remarks
For dense grids, this writes to the pre-allocated cell at
coord and returns false if the coordinate falls outside
the grid's dimensions.
For sparse grids, this inserts or updates the entry at
coord and returns false only when the grid is bounded
and coord falls outside the defined bounds. On unbounded sparse
grids this method always returns true.
A successful call increments CellCount on sparse grids when
coord is newly written for the first time.
See Also
WorldToGrid(Vector2)
Converts a world-space position to the nearest triangle coordinate using this grid's Layout.
Declaration
public TriCoord WorldToGrid(Vector2 worldPos)
Parameters
| Type | Name | Description |
|---|---|---|
| Vector2 | worldPos | The world-space position to convert. |
Returns
| Type | Description |
|---|---|
| TriCoord | The TriCoord of the triangle that contains
|