using System; using System.Collections.Generic; using MinecraftClient.Inventory.ItemPalettes; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Core; public abstract class StructuredComponentRegistry(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) { private Dictionary ComponentParsers { get; } = new(); private Dictionary IdToComponent { get; } = new(); private Dictionary ComponentToId { get; } = new(); protected void RegisterComponent(int id, string name) where T : StructuredComponent { if (string.IsNullOrEmpty(name) || string.IsNullOrWhiteSpace(name)) throw new ArgumentNullException(nameof(name)); name = name.ToLower(); if (ComponentParsers.ContainsKey(name) || IdToComponent.ContainsValue(name) || ComponentToId.ContainsKey(name) || IdToComponent.ContainsKey(id)) throw new InvalidOperationException($"A component with name '{name}' or id '{id}' is already registered."); ComponentParsers[name] = typeof(T); IdToComponent[id] = name; ComponentToId[name] = id; } public StructuredComponent ParseComponent(int id, Queue data) { if (IdToComponent.TryGetValue(id, out var name)) { if (ComponentParsers.TryGetValue(name, out var type)) { var component = Activator.CreateInstance(type, dataTypes, itemPalette, subComponentRegistry) as StructuredComponent ?? throw new InvalidOperationException($"Could not instantiate a parser for a structured component type {name}"); component.TypeId = id; component.Parse(data); return component; } } throw new Exception($"No parser found for component with ID {id}"); } public string GetComponentNameById(int id) { if (IdToComponent.TryGetValue(id, out var value)) return value; throw new Exception($"No component found for ID {id}"); } public int GetComponentIdByName(string name) { name = name.ToLower(); if (ComponentToId.TryGetValue(name, out var value)) return value; throw new Exception($"No ID found for component {name}"); } }