diff --git a/Solver/ActionPool.cs b/Solver/ActionPool.cs index 9ab1880..c213ee5 100644 --- a/Solver/ActionPool.cs +++ b/Solver/ActionPool.cs @@ -43,22 +43,36 @@ public readonly struct ActionPool private unsafe struct EnumBuffer { - public fixed byte Data[MaskSize]; + private fixed byte data[MaskSize]; - public ref ActionType this[int index] => ref Unsafe.As(ref Data[index]); + public ActionType this[int index] => (ActionType)data[index]; - public Span AsSpan() => new(Unsafe.AsPointer(ref this[0]), MaskSize); + public EnumBuffer(ReadOnlySpan actions) + { + fixed (byte* dataPtr = data) + actions.CopyTo(new Span(dataPtr, MaskSize)); + } + + public readonly ActionType[] ToArray(int size) + { + fixed (byte* dataPtr = data) + return new Span(dataPtr, size).ToArray(); + } } private unsafe struct LUTBuffer { - public fixed byte Data[EnumSize]; + private fixed byte data[EnumSize]; - public ref byte this[ActionType index] => ref Data[(byte)index]; + public byte this[ActionType index] => data[(byte)index]; -#pragma warning disable MA0099 - public Span AsSpan() => new(Unsafe.AsPointer(ref this[0]), EnumSize); -#pragma warning restore MA0099 + public LUTBuffer(ReadOnlySpan actions) + { + for (var i = 0; i < EnumSize; i++) + data[i] = 0xFF; + for (var i = 0; i < actions.Length; i++) + data[(byte)actions[i]] = (byte)i; + } } // List of accepted actions (max 32) @@ -67,22 +81,16 @@ public readonly struct ActionPool private readonly LUTBuffer acceptedActionsLUT; private readonly byte size; - internal ReadOnlySpan AcceptedActions => acceptedActions.AsSpan().Slice(0, size); + internal ActionType[] AcceptedActions => acceptedActions.ToArray(size); public ActionPool(ReadOnlySpan actions) { if (actions.Length > MaskSize) throw new ArgumentOutOfRangeException(nameof(actions), actions.Length, $"ActionPool only supports up to {MaskSize} actions"); + acceptedActions = new(actions); + acceptedActionsLUT = new(actions); size = (byte)actions.Length; - - acceptedActions.AsSpan().Fill((ActionType)0xFF); - acceptedActionsLUT.AsSpan().Fill(0xFF); - - actions.CopyTo(acceptedActions.AsSpan()); - - for (var i = 0; i < size; i++) - acceptedActionsLUT[acceptedActions[i]] = (byte)i; } [Pure] diff --git a/Solver/Simulator.cs b/Solver/Simulator.cs index e31565b..45fc9a4 100644 --- a/Solver/Simulator.cs +++ b/Solver/Simulator.cs @@ -8,6 +8,7 @@ namespace Craftimizer.Solver; internal sealed class Simulator : SimulatorNoRandom { public readonly ActionPool Pool; + private readonly ActionType[] poolActions; private readonly int maxStepCount; public override CompletionState CompletionState @@ -24,6 +25,7 @@ internal sealed class Simulator : SimulatorNoRandom public Simulator(in ActionPool pool, int maxStepCount) { Pool = pool; + poolActions = Pool.AcceptedActions; this.maxStepCount = maxStepCount; } @@ -135,7 +137,7 @@ internal sealed class Simulator : SimulatorNoRandom return new(); var ret = new ActionSet(); - foreach (var action in Pool.AcceptedActions) + foreach (var action in poolActions) if (CanUseAction(action, strict)) ret.AddAction(in Pool, action); return ret;