Files
FoodFactory/src/VoxelGrid/VoxelRegistry.cs

155 lines
4.4 KiB
C#

namespace ChickenGameTest;
using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
using SJK.Functional;
public interface IVoxelGridRegistry
{
VoxelGuid Register<T>(T voxelNode, params Vector3I[] positions) where T : class;
void UnRegister(VoxelGuid id);
IEnumerable<T> Get<T>(Vector3I voxelPos);
IEnumerable<T> Get<T>(params Vector3I[] voxelPos);
}
public readonly record struct VoxelGuid(Guid Id);
public sealed class VoxelRegistry : IVoxelGridRegistry
{
private readonly Dictionary<Guid, VoxelEntry> _voxelPositions = new();
private readonly record struct VoxelEntry(object Item, Vector3I[] Entries);
private Dictionary<Vector3I, ICollection<object>> _data;
public VoxelRegistry()
{
_data = new();
}
public IEnumerable<T> Get<T>(Vector3I voxelPos)
{
if (!_data.TryGetValue(voxelPos, out var entrys))
{
yield break;
}
foreach (var item in entrys.OfType<T>())
{
yield return item;
}
}
public IEnumerable<T> Get<T>(params Vector3I[] voxelPos)
{
foreach (var item in voxelPos)
{
foreach (var item2 in Get<T>(item))
{
yield return item2;
}
}
}
public VoxelGuid Register<T>(T voxelNode, params Vector3I[] positions) where T : class
{
void register(Vector3I pos, T point)
{
if (!_data.TryGetValue(pos, out var entrys))
{
entrys = [];
_data[pos] = entrys;
}
entrys.Add(point);
}
foreach (var pos in positions)
{
register(pos, voxelNode);//TODO Acount For Rotation
}
var guid = new VoxelGuid(Guid.NewGuid());
_voxelPositions[guid.Id] = new(voxelNode, positions);
return guid;
}
public void UnRegister(VoxelGuid id) =>
_voxelPositions.GetValue(id.Id).IfSome(e =>
{
foreach (var item in e.Entries)
{
_data.GetValue(item).IfSome(i => i.Remove(e.Item));
}
});
}
public enum Direction
{
Up, Down, Left, Right, Front, Back
}
public static class DirectionExtession
{
public static Vector3I ToVector(this Direction direction) => direction switch
{
Direction.Up => Vector3I.Up,
Direction.Down => Vector3I.Down,
Direction.Left => Vector3I.Left,
Direction.Right => Vector3I.Right,
Direction.Front => Vector3I.Forward,
Direction.Back => Vector3I.Back,
_ => throw new NotSupportedException($"{nameof(direction)} does not support value {direction}")
};
public static Direction Reverse(this Direction direction) => direction switch
{
Direction.Up => Direction.Down,
Direction.Down => Direction.Up,
Direction.Left => Direction.Right,
Direction.Right => Direction.Left,
Direction.Front => Direction.Back,
Direction.Back => Direction.Front,
_ => throw new NotSupportedException($"{nameof(direction)} does not support value {direction}")
};
public static Direction RotateClockWise(this Direction direction) => direction switch
{
Direction.Up => Direction.Up,
Direction.Down => Direction.Down,
Direction.Left => Direction.Back,
Direction.Right => Direction.Front,
Direction.Front => Direction.Right,
Direction.Back => Direction.Left,
_ => throw new NotSupportedException($"{nameof(direction)} does not support value {direction}")
};
public static Direction RotateCounterClockWise(this Direction direction) => direction switch
{
Direction.Up => Direction.Up,
Direction.Down => Direction.Down,
Direction.Right => Direction.Front,
Direction.Left => Direction.Back,
Direction.Back => Direction.Right,
Direction.Front => Direction.Left,
_ => throw new NotSupportedException($"{nameof(direction)} does not support value {direction}")
};
}
public interface IStorage<T> where T : class
{
StorageDefinition Definition { get; }
IEnumerable<T> GetAllItems();
void Remove(T item);
bool TryInsert(T item);
record StorageDefinition(string Name, ItemType Type);
}
public record ItemType(string Name);
public partial class ItemStoragePool : Node, IStorage<IBeltItem>
{
[Export] public int MaxAmount { get; set; } = 5;
public IStorage<IBeltItem>.StorageDefinition Definition { get; set; } = default!;
private readonly List<IBeltItem> _items = [];
public IEnumerable<IBeltItem> GetAllItems() => _items;
public bool TryInsert(IBeltItem item)
{
if (_items.Count >= MaxAmount)
{
return false;
}
_items.Add(item);
return true;
}
public void Remove(IBeltItem item) => _items.Remove(item);
}