Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AssetManagement #1

Open
Prunkles opened this issue Aug 23, 2021 · 1 comment
Open

AssetManagement #1

Prunkles opened this issue Aug 23, 2021 · 1 comment
Assignees
Labels
feature New feature or request

Comments

@Prunkles
Copy link
Contributor

Prunkles commented Aug 23, 2021

Требования:

  • Мониторинг. Возможность узнать какие ассеты загружены, кем используются, и вся остальная необходимая информация для дебага
  • Перезагрузка и отложенная загрузка ассетов
  • язабылдополните
@Prunkles Prunkles assigned Prunkles and unassigned Prunkles Aug 23, 2021
@Prunkles Prunkles added the feature New feature or request label Aug 23, 2021
@DragonFrai DragonFrai removed their assignment Aug 24, 2021
@DragonFrai
Copy link
Contributor

DragonFrai commented Aug 24, 2021

Как я представляю себе примерное использование:
Блок визуально может описываться, например, json содержащим описание модели и наложенных текстур. Уже загруженные ассеты будут совместно использоваться в разных местах (те же текстуры в разных моделях). При перезагрузке ресурсов, например в случае добавления ресурспака, уже более неиспользуемые ассеты будут выгружаться. И это не должно требовать перезагрузку уже используемых ассетов.

Мы могли бы требовать dispose от того, кто загрузил ресурс, но тогда создается проблема с совметным переиспользованием ассетов. Поэтому логично было бы делегировать эта задачу на саму систему ассетов. Но с dispose возникают некоторые проблемы в многопоточном коде.

На данный момент IAssetMonitor.Value это текущее значение ассета. Однако, если сама система ассетов будет заниматься dispose ресурсов, может возникнуть следующая ситуация: Система рендера взяла переменную с текущей текстурой для рендера, система ассетов обновила соответствующий ресурс и вызвала dispose у старой текстуры, а система рендера использует уже disposed текстуру.

Я пока вижу следующие основные варианты:

  • Оставить по тупому без автодиспоуса - даже не представляю как при переиспользовании одного ресурса в разных местах

  • RwLock вокруг Value - В целом должно быть дёшево большую часть времени, но требует взятия лока на чтение при каждом использовании.

  • Диспоусинг на атомарных счётчиках ссылок (Arc) с mutex/spinlock/rwlock (Mutex<Arc>) - Расширение предыдущего пунка. Всё еще требует Mutex или его аналог. И в отличие от чистого RwLock позволит системам копировать Arc на ресурс, сохраняя его до уведомления об изменении (внутренняя синхронизация для обновления копии Arc потребуется, но может быть намного дешевле). Если использовать RwLock<Arc>, то можно комбинировать копирование Arc с чтением "на недолго" из самого RwLock. Считаю это наиболее оптимальным вариантом для синхронизации "на месте".

  • Добавить получению сервисов Read и Write доступ, а ассеты это всего лишь дескриптор ресурса в сервисе-хранилище. При этом система ассетов будет получать хранилище мутабельно и заменять старые ассеты на новые. - синхронизация на этом уровне обязанность шедулера и может быть максимально дешевой. (Но это требует особого стиля написания кода, который не вызывает потоко-опасных функции на сервисе при Read доступе) (Хотя говорят в дотнет и так нужно ему следовать пока ты не уверен что объект используется только в одном потоке) (прим: Обращение к индексу массива очень дёшево, по крайней мере на x86)

  • finnalize. -- самый удобный, доказуемвй в компайлтайме и наименее детерминированный способ. Лучше него просто ничего нет. Он, разумеется, даёт доп нагрузку на гц и не очищающуюся не менаджед память, типа текстур. Хотя последнее можно обойти через ее мониторинг и вызов гц. Разве что нужны обертки для библиотечных типов реализовавших Dispose, но не финализатор.
    Но прикинуть накладные расходы со стороны ГЦ и влияние вызовов финализаторов на задержки я не могу.
    Задержки на синхронизацию здесь сопоставимы с вариантом Read и Write сервисов.

Если обобщить, получим три типа защиты от use after dispose:

  1. Синхронизация на уровне ассета.
  2. Синхронизация на уровне хранилища ассетов.
  3. Dispose в деструкторах объектов.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants