/************************************************************************* * ModernUO * * Copyright 2019-2023 - ModernUO Development Team * * Email: hi@modernuo.com * * File: TileList.cs * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * *************************************************************************/ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Server.Buffers; namespace Server; public class TileList { private static readonly StaticTile[] _emptyTiles = Array.Empty(); private StaticTile[] _tiles; public int Count { get; private set; } public void AddRange(ReadOnlySpan tiles) { if (tiles.Length == 0) { return; } TryResize(tiles.Length); tiles.CopyTo(_tiles.AsSpan(Count)); Count += tiles.Length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void Add(StaticTile* ptr) => Add(Marshal.PtrToStructure((nint)ptr)); public void Add(StaticTile tile) { TryResize(1); _tiles[Count++] = tile; } public void Add(ushort id, byte x, byte y, sbyte z, short hue = 0) { TryResize(1); ref var tile = ref _tiles[Count++]; tile.m_ID = id; tile.m_X = x; tile.m_Y = y; tile.m_Z = z; tile.m_Hue = hue; } public void Add(ushort id, sbyte z) { TryResize(1); ref var tile = ref _tiles[Count++]; tile.m_ID = id; tile.m_X = 0; tile.m_Y = 0; tile.m_Z = z; tile.m_Hue = 0; } private void TryResize(int length) { _tiles ??= STArrayPool.Shared.Rent(length); var newLength = Count + length; if (newLength > _tiles.Length) { var old = _tiles; _tiles = STArrayPool.Shared.Rent(newLength); old.CopyTo(_tiles.AsSpan()); STArrayPool.Shared.Return(old); } } public StaticTile[] ToArray() { if (Count == 0) { return _emptyTiles; } var tiles = new StaticTile[Count]; _tiles.AsSpan(0, Count).CopyTo(tiles); // Cleanup STArrayPool.Shared.Return(_tiles); _tiles = null; Count = 0; return tiles; } }