67 lines
4.0 KiB
Markdown
67 lines
4.0 KiB
Markdown
# 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()` добавляет ресурсы в память и прокидывает их в кэш.
|
||
|
||
## Ограничения
|
||
|
||
- Класс не предназначен для внешнего многопоточного использования.
|
||
- Политика приоритета ресурсов в паке фиксированная: первый найденный ключ побеждает.
|
||
- Коллизии хешей не обрабатываются отдельно.
|