# AssetsManager

Документ описывает реализацию `AssetsManager` на стороне клиента.

## Назначение

`AssetsManager` объединяет в одном объекте:
- таблицы привязок ресурсов (domain/key -> localId, serverId -> localId);
- загрузку и хранение ресурсов из ресурспаков;
- систему источников данных (packs/memory/cache) с асинхронной выдачей;
- перестройку заголовков ресурсов под локальные идентификаторы.

## Основные структуры данных

- `PerType` — набор таблиц на каждый тип ресурса:
  - `DKToLocal` и `LocalToDK` — двунаправленное отображение domain/key <-> localId.
  - `LocalParent` — union-find для ребиндинга локальных id.
  - `ServerToLocal` и `BindInfos` — привязки серверных id и их метаданные.
  - `PackResources` — набор ресурсов, собранных из паков.
- `Sources` — список источников ресурсов (pack, memory, cache).
- `SourceCacheByHash` — кэш успешного источника для хеша.
- `PendingReadsByHash` и `ReadyReads` — очередь ожидания и готовые ответы.

## Источники ресурсов

Источники реализованы через интерфейс `IResourceSource`:
- pack source (sync) — ищет ресурсы в `PackResources`.
- memory source (sync) — ищет в `MemoryResourcesByHash`.
- cache source (async) — делает чтения через `AssetsCacheManager`.

Алгоритм поиска:
1) Сначала проверяется `SourceCacheByHash` (если не протух по поколению).
2) Источники опрашиваются по порядку, первый `Hit` возвращается сразу.
3) Если источник вернул `Pending`, запрос попадает в ожидание.
4) `tickSources()` опрашивает асинхронные источники и переводит ответы в `ReadyReads`.

## Привязка идентификаторов

- `getOrCreateLocalId()` создаёт локальный id для domain/key.
- `bindServerResource()` связывает serverId с localId и записывает `BindInfo`.
- `unionLocalIds()` объединяет локальные id при конфликте, используя union-find.

## Ресурспаки

`reloadPacks()` сканирует директории, собирает ресурсы в `PackResources`,
а затем возвращает список изменений и потерь по типам.

Важно: ключи ресурсов всегда хранятся с разделителем `/`.
Для нормализации пути используется `fs::path::generic_string()`.

## Заголовки

- `rebindHeader()` заменяет id зависимостей в заголовках ресурса.
- `parseHeader()` парсит заголовок без модификаций.

## Поток данных чтения

1) `pushReads()` принимает список `ResourceKey` и пытается получить ресурс.
2) `pullReads()` возвращает готовые ответы, включая промахи.
3) `pushResources()` добавляет ресурсы в память и прокидывает их в кэш.

## Ограничения

- Класс не предназначен для внешнего многопоточного использования.
- Политика приоритета ресурсов в паке фиксированная: первый найденный ключ побеждает.
- Коллизии хешей не обрабатываются отдельно.
