Put this value into App::update()
At startup, the App must get Channels ONCE from DB (async, before using App::update) and than use this cached data in UI.
I don't understand how I can do it in this case. Helps, please!
Можно на русском отвечать, это я просто из другого чата скопировал😅
Речь идёт про Egui. Может кто подсказать?
https://docs.rs/tokio/latest/tokio/sync/struct.Mutex.html#method.try_lock И проверяй в цикле егуи каждый раз
Но вообще зачем тебе мьютекс
Я ни от кого не могу добиться внятного руководства по egui, поэтому тычусь то там, то сям. До этого я с Qt 6 работал на питоне. Там всё гораздо проще хоть тоже тыкалсяб сам везде инфу собирал. Но от Qt бинарники очень пухлые получаются. Да и хочется на нативном расте всё сделать
Если сделаешь пример чтоб на плейграунде это поможет
Вот здесь можно код глянуть. Оно запускается, но там обращение к БД ещё в fn update() находится, что конечно же не правильно. Это открытый проект. Хочу сам обучиться и другим оставить для изучения https://github.com/hardglitch/rss-reader
Вот так это выглядит на данный момент
у меня есть подобный проект, где мьютексами шерю данные между тредами и через каналы тригерю логику. Насчет бест практис хз, я тут не стесняюсь в экспериментах, но работает https://github.com/antonguzun/lazy_crafter/blob/main/src/ui/ui_app.rs#L81
Вот как раз из-за того опыта с Qt (и возможно другими обычными GUI библиотеками) у тебя (как у многих тут я смотрю) совсем не правильное понимание как надо работать с egui. Потому что в отличие от большинства GUI библиотек, работающих в retained mode, egui работает в immediate mode. А это означает, что у него самого полностью (ну на самом деле внутри него это чуть нарушается ради обработки сложного пользовательского ввода, но ты этого не видишь и не чувствуешь) отсутствует внутреннее состояние. И таким образом нет абсолютно никакой потребности для организации вызовов "из ядра в gui", которые в случае классических retained библиотек раскидываются по всем углам приложения. Т.е. в ту сторону (а вот в обратную, при перенаправление команд пользовательского ввода в ядро они возможно и могут пригодиться, но это уже зависит от устройства ядра) никакие каналы, мьютексы и т.п. не нужны и скорее могут только навредить. В случае egui тебе надо просто подготовить некое ядро приложения, которое будет предоставлять функции (не блокирующие и вообще максимально быстрые), возвращающие необходимый для отображения набор данных. А egui будет банально отображать эти данные 60 раз в секунду, вызывая эти функции каждый раз.
Это я уже понял. Мне бы реализацию глянуть. Все только общими фразами отделываются
egui всетаки позволяет производить рендер только по взаимодействию, например при движении мыши. Мне очень не хотелось жечь цпу просто так, поэтому выбрал такой вариант. Часть работы происходит в бекграунде и ui в случае отсутвия взаимодействия по таймеру перерендеривается. Тут удобны и каналы и мьютексы оказались
Емнип детального руководства нет; надо экзамплы смотреть сначала, а из важного лейаутинг в документации описан. Дальше только виджеты кладёшь в лейаут с позициями и собираешь от них интересующий отклик (clicked и прочее).
а что непонятного то по реализации? У тебя в любом случае есть реализация egui'ного (точнее на самом деле в eframe оно конечно же) App с функцией update в которой и происходит вся прорисовка. Делаешь себе новую сущность скажем с именем Core (и функциями типа get_data и update_data, не блокирующимися и не асинхронными) и кладёшь её в App. И потом просто вызываешь из update в нужных местах. А если в приложение встречаются какие-то нетривиальности с многопоточностью, асинхронностью и прочим, то они все будут сконцентрированы уже в твоём Core, т.е. вне egui. Т.е. речь идёт о том, что каким бы сложным в смысле параллельного выполнения и т.п. не было приложения, к egui это отношения иметь не будет (как раз в следствие использования immediate mode).
да, и не просто позволяет а по дефолту как раз и установлен такой режим, чтобы не жрать аккумуляторы на мобильных устройствах. А вот для реалтайм приложений или для игр обычно отдельно включают режим перерисовки с частотой монитора. ) Но это всё никак не влияет на сказанное мною)
есть на примете хороший экземляр аппки на егуи? А то я полностью обмазался локами в ui треде
так а ты их демку (https://www.egui.rs) то смотрел? Там много чего есть, и редактор и анимация и т.д. И везде ссылка на реализующий код.
да, а по поводу твоих локов и т.п. - вообще не понятно откуда они могли взяться. Единственная во всём egui функция, которая может понадобиться "снаружи" https://docs.rs/egui/latest/egui/struct.Context.html#method.request_repaint позволяет вызов из любых потоков.
не нашел в демо примерах взаимодействия с бекендом. Там же статика одна.
Есть во вкладках сверху http запрос
так я про код говорю, там примеры на виджеты
а причём тут egui и взаимодействие с бэкендом? Это дело совсем другого кода и совсем других библиотек. Для egui ты просто готовишь набор нужных данных и он их отображает на экран. А как эти данные подготовлены egui вообще не касается.
если эти данные готовятся в другом треде, то как зашерить их без мьютекса? Бекенд долго считает данные, по завершении на короткое время лочит мьютекс и записывает результаты и релизит. ui при рендеринге лочит мьютекс чтобы прочитать новые данные для отображения Это антипаттерн для такой аппки?
У меня сейчас данные сохраняются в Memory контекста, поэтому никаких мутехов
если данные считаются редко и долго, то кажется логичным иметь не общую память, а передавать владение каждый раз. Но в целом и твой вариант тоже должен быть нормальным)
ну так то локи есть в самом контексте... ))) Но они там продуманы хотя бы)
Ну я потому и использую, что уже продуманы. Самому с нуля костылить не вижу смысла
а передача владения между тредами как может быть реализована? Просто отправляем данные в канал и ui овверрайдит свой стейт новыми данными?
Я к этому как раз пришёл, но застрял. Завтра попробую на свежую голову штурмануть ещё разок
Там нету ничего. Я уже весь оф чат в дискорде затрахал своими вопросами😅
А можешь код показать, если не секрет?
да) Но надо понимать пару нюансов: 1. канал внутри на самом деле тоже использует блокировки (но опять же продумано), так что надо весьма аккуратно с этим, если беспокоит производительность. 2. Если прокидывать канал, то условно говоря не "в гуи", а "в основной поток Core" или что-то такое - egui в этом процессе нигде не светится) Вроде как разницы нет, но это позволяет чётко отделять gui и реальную функциональность.
Спасибо, не подскажешь литературу/гайды для погружения. Интересно какие объемы данных целесообразно гонять через каналы.
Сейчас не у компа, сорри, напиши в лс и я скину по возможности
Обсуждают сегодня