using DatReaderWriter; using DatReaderWriter.Enums; using DatReaderWriter.Lib.IO; using AcDream.Core.Content; using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; // Phase O-T7: verbatim copy of WorldBuilder.Shared.Services.IDatReaderWriter + // IDatDatabase, taken into our tree so the WorldBuilder.Shared project // reference could be dropped. // // MP1a (2026-07-05, Task 4): moved to AcDream.Content, namespace only — // MeshExtractor's constructor takes IDatReaderWriter and must be GL-free. // MP1b review (finding 7): the concrete DatCollection-backed implementation // (DatCollectionAdapter, this assembly) now lives HERE too — one shared // adapter for ObjectMeshManager (App), acdream-bake, and the equivalence // suite, so the three consumers can never drift apart. namespace AcDream.Content; /// /// Interface for the dat reader/writer /// public interface IDatReaderWriter : IDisposable, IDatObjectSource { /// /// Gets the source directory of the DAT files. /// string SourceDirectory { get; } /// /// Tries to get the raw bytes of a file from a specific region database. /// bool TryGetFileBytes(uint regionId, uint fileId, ref byte[] bytes, out int bytesRead); /// /// The portal database /// IDatDatabase Portal { get; } /// The single cell database exposed by DatCollection. IDatDatabase Cell { get; } /// /// The cell region databases. Each key is a cell region ID /// ReadOnlyDictionary CellRegions { get; } /// /// The high res database /// IDatDatabase HighRes { get; } /// /// The language database /// IDatDatabase Language { get; } /// Alias matching DatCollection's Local database name. IDatDatabase Local { get; } /// Enumerates typed ids across the database selected for the type. IEnumerable GetAllIdsOfType() where T : IDBObj; /// /// A mapping of region ids to region dat file entry ids. key: region id, value: region dat file entry /// ReadOnlyDictionary RegionFileMap { get; } /// /// Gets the current portal iteration. /// int PortalIteration { get; } /// /// Gets the current cell iteration (from the first cell region). /// int CellIteration { get; } /// /// Gets the current high res iteration. /// int HighResIteration { get; } /// /// Gets the current language iteration. /// int LanguageIteration { get; } // Write-path methods — preserved from WB's interface for verbatim // compatibility but not exercised by ObjectMeshManager in acdream. /// Attempts to save a database object to the appropriate DAT. bool TrySave(T obj, int iteration = 0) where T : IDBObj; /// Attempts to save a database object to the appropriate DAT for a specific region. bool TrySave(uint regionId, T obj, int iteration = 0) where T : IDBObj; /// /// Resolution of a data ID to a database and type /// public record IdResolution(IDatDatabase Database, DBObjType Type); /// /// Resolves a data ID to all possible databases and types. /// public IEnumerable ResolveId(uint id); /// /// Resolves one data ID using acdream's canonical precedence without /// materializing a result collection: Portal, HighRes, Language, Cell. /// Production's concrete adapter overrides this with direct B-tree probes. /// bool TryResolvePreferred( uint id, [NotNullWhen(true)] out IDatDatabase? database, out DBObjType type) { IDatDatabase? highRes = null; DBObjType highResType = DBObjType.Unknown; IDatDatabase? language = null; DBObjType languageType = DBObjType.Unknown; IDatDatabase? cell = null; DBObjType cellType = DBObjType.Unknown; foreach (IdResolution resolution in ResolveId(id)) { if (ReferenceEquals(resolution.Database, Portal)) { database = resolution.Database; type = resolution.Type; return true; } if (ReferenceEquals(resolution.Database, HighRes)) { highRes = resolution.Database; highResType = resolution.Type; } else if (ReferenceEquals(resolution.Database, Language)) { language = resolution.Database; languageType = resolution.Type; } else if (ReferenceEquals(resolution.Database, Cell)) { cell = resolution.Database; cellType = resolution.Type; } } database = highRes ?? language ?? cell; type = highRes is not null ? highResType : language is not null ? languageType : cellType; return database is not null; } } /// /// Interface for a dat database, providing methods to retrieve files and objects. /// public interface IDatDatabase : IDisposable { DatDatabase Db { get; } /// Retrieves the current iteration of the database. int Iteration { get; } /// Retrieves all file IDs of a specific type. public IEnumerable GetAllIdsOfType() where T : IDBObj; /// Attempts to retrieve a database object by its file ID. public bool TryGet(uint fileId, [MaybeNullWhen(false)] out T value) where T : IDBObj; /// Attempts to retrieve the raw bytes of a file by its ID. bool TryGetFileBytes(uint fileId, [MaybeNullWhen(false)] out byte[] value); /// Attempts to retrieve the raw bytes of a file by its ID into a provided buffer. bool TryGetFileBytes(uint fileId, ref byte[] bytes, out int bytesRead); /// Attempts to save a database object. bool TrySave(T obj, int iteration = 0) where T : IDBObj; }