Anton
Anton
Но суть такая
Anton
Anton
переслать анимаху ввиде струтуры - ссылку на вьюху, проперти значения и время
Маjко
Там я не ковырялся =)
Там всё a bit tricky: для получения задач лучше юзать фьючерсовские потому что стрим, для отправки результатов — обычные, а то гемор)
Anton
Итак анимация
прилетела вьюха из угла (0, 0) в кординаты (100, 100)
и увеличилась с (0, 0) до (200, 200)
Добавить какой нить StateMachine (sm)
sm.set_frame_rate(60); // Чтобы обеспечить плавную анимацию
sm.add_transition_move(Arc(View), 100, 100, 1000ms); // 1sec
sm.add_transition_resize(Arc(View), 200, 200, 1000ms); // 1sec
Для move
// anim_time = 1000
step = anim_time / frame_rate; // 16.6
// x_aim, y_aim - конечный размер (100, 100)
x_step = x_aim / anim_time * step;
y_step = y_aim / anim_time * step;
loop 1 .. (frame_rate - 1) {
view.x += x_step;
view.y ~= y_step;
sleep(step)
}
view.x = x_aim;
view.y = y_aim;
Основная идея тут
Anton
что он лочить должен? Он может запустить тысячу разных анимаций с таймингами для них, и ждать, ибо нагрузки на set новых параметров стилей почти ничего не стоит сам по себе. Если анимация будет использовать для delay обычный sleep это будет фейл
Anton
Anton
Маjко
Anton
Anton
хотя мне уже кажется что мы в испорченный телефон играем) \
Маjко
Да, есть такое
Anton
и толком у каждого свои вариации вопроса
Anton
У мну только концепт, без кокретных тулз
Anton
Кроме тебя этим нихто тут не занимается =)
Anton
Вобщем смотрите: у меня есть контекст окна, для эвентов вроде клик, скролл мышкой, и тд - у окна есть свой ивентлуп - самый обычный аля loop {}, он само собой блокирует все что будет дальше. Во время его работы - я должен получить например положение мышки во время клика, сверить его с позициями кнопок и тд. Эвентов одновременно может быть много Hover, Click и тд. Их внутренняя обработка может быть более сложной - ибо как только я расчитал положение кнопки - я например должен перерисовать ее с стилями Hover и запустить например колбэк on_click - если это делать в контексте эвентлупа окна, это все блокируется и может вообще не срабатывать. Поэтому - эвентлуп окна запускается при инициализации сразу. Также запускается поток для основных прикладных эвентов для конкретных элементов - в который посылает эвенты вроде set_new_position_cursor() основной ивентлуп окна, и потом в отдельном треде, спокойно без тормозов он вычисляет по позициями элементов клики для обработки. После чего отправляет сигнал основному потоку "запусти этот колбэк для клика этого элемента". По этой же логике я хочу чтобы работал и поток анимаций - он обособленный, и также ленивый, все стили отправляются в очередь ленивую webrender-a - поэтому ивентлуп для анимаций будет работать очень быстро, и для очень большого количества вьюх в нем зарегистрированных. Почему я против например даже того чтобы оставлять обработку анимаций в потоке с обычными прикладными эвентами вроде клика? Потому что это будет слишком сильно засирать эвентами и обработчиками поток, а я хочу чтобы для каждого самодостаточного куска без блока работало все хорошо. Можно меня хуисосить мол нахуя сразу 3 треда: анимации, прикладной, окно - так я отвечу что для того чтобы сохранялась отзывчивость, чтобы после клика на кнопку мог сразу запустится колбэк в основном потоке - и сама по себе жить анимация: например я нажал на кнопку которая запускает анимацию длительностью 1 секунда. Я хочу чтобы анимация без блокировки сразу работала и позволяла нажимать на другие кнопки пока выполняется колбэк - иначе все будет люто тормозить и просирать фреймы
Anton
Вот так
Anton
высрал
Маjко
Ну и делай как делал тогда. Заведи CpuPool для обработки анимаций и все
Маjко
Никиких токий
Anton
И eventLoop на уровень приложения вынеси, вдруг у тебя несколько окон
Anton
ну ебаный насос, а как мне тогда в одном ивентлупе тогда например высчитывать delay сразу 100 вьюх положим с разными промежутками времени?
Anton
Для всех sleep юзать?
Маjко
Если хочешь на токио — сразу убирай свой ивентлуп, переписывай все события на отправку через фьючерский mpsc в общий для всех окон ивентлуп, от туда запускай на FuturesCpuPool все тяжелые операции
Anton
или для каждой анимации с CpuPool хуярить для каждой вьюхи свой тред?
Маjко
В 5 потоков уложишься при условии того, что 4 будут в CpuPool
Anton
Anton
Маjко
Ну тут вроде нет проблем особых. Просто отправляешь события с обработчиков в канал, дальше в ивентлупе разгребаешь, диспатчишь на FuturesCpuPool, всё
Anton
но все равно тогда остается оконные ивенты, значит нужна оболочка которая будет их обрабатываеть не в обычном ивентлупе, а в ивентлупе токио
Anton
Маjко
Херачь оконные ивенты в канал
Anton
тоесть у меня есть оконный ивентлуп
Anton
и я дичпатчу все из него в FuturesCpuPool
Anton
а уже в нем, я определяю набор фьюч для обработки и он сам их по тредам раскидывает для обработки
Anton
врубился
Маjко
ИМХО, тебе хватит одного ивентлупа, для всех окон.
Если ты все тяжелые задачи отправляешь в пул, тебе с головой хватит одного
Anton
ну вот если так подумать
Anton
то да
Anton
один ивентлуп
Anton
который принимает ивенты, и потом раскидывает их в полл потоков
Anton
в режиме фьюч
Anton
норм
Маjко
У тебя могут только возникнуть проблемы с отменой запущенной операции
Маjко
Но это как бы везде проблемы
Маjко
Хоть фьючи хоть потоки
Маjко
И "решаются" более-менее одинакого
Anton
ток вот еще один косяк, как тогда колбэки запускать
Anton
положим я раскидал все по пуллам, все отработало, получл координаты и поставил новые стили, а как и где тогда вызывать колбэк?
Anton
Должен ли колбэк быть фьючей, и как получить к ней доступ?) Отправить обратно во вьюху команду "запусти колбэк"?
Маjко
Зависит. Коллбек долго выполняется?
Маjко
А хотя похуй сколько
Anton
ну вообще в принципе похуй, главное чтобы он отзывчивость ui не блочил, и не блочил анимации
Маjко
pool.spawn(future.and_then(|data| callback(data)).or_else(|error| error_callback(error)));
Anton
тоесть блочить обработку других задач он в принципе может, но вот ui тред нит
Anton
Маjко
Будет блочить другие, UI не будет, как ты и хотел
Anton
норм
Anton
буду экспериментировать
Anton
во только я не представляю как создать вечный реактор в отдельном треде, к нему привязать CpuPool и в него кидать фьючи
Anton
вот тут у меня затупа
Anton
а примеров нет, есть только голый референс(
Anton
Зато хотябы есть сорсы =)
Tuntz
передавать данные между футурами с помощью крейта chan - норм вариант или костыль?
Aleksey
А чем тебе модуль mpsc из футур не угодил?
Tuntz
не знал про него
Tuntz
боевая задача - принять данные по udp, обработать, отправить дозапрос нескольким адресатам - планирую сделать через три футуры и tokio в качестве клея
Aleksey
Там есть штатный способ передать данные, а заодно создавать цепочки обработчиков любой степени сложности
Aleksey
Ну тебе нужны стримы и каналы из футур. А так же их комбинаторы
Aleksey
Смотри на функции select и join
Aleksey
Хотя для твоей задачи хватит обычной синхронщины, нафига жизнь усложнять
Tuntz
у меня уже написан вариант с двумя тредами и CSP (как на Go), сейчас хочу научиться асинхронщине
Anton
Привет. Появилась следующая задачка: нам нужно сделать настраиваемые с помощью дженериков числа. Например, настройка говорит, что максимальное число😷, а при создании из f32, нужно округлять в большую или меньшую сторону. Увы, в качестве дженерика можно указать только тип, те я не могу сделать Number<7,RoundMax>, приходится передавать в качестве дженериков типы, которые возвращают числа с помощью трейтов(О ужс), например Number<Seven, RoundMax>. Более того, нужно чтобы такой тип мог бы Add, Mul и тд, а трейты нельзя имплементить для трейтов, поэтому нужно чтобы Number был структурой?! Но ведь я же хочу получить некий настраиваемый ТИП, например Number16. Естественно я не хочу объявлять 100 типов и писать к ним impl From<..> for Type1..100 хоть даже с помощью макроса. Мне интересно, есть ли какой-то прямой выход?
Anton
увы, например в геймдеве, не выделишь по потоку на юзера(их то много), поэтому приходится писать асинхронщину. Имхо, футуры, конечно наиболее прямой выход и вообще за ними будущее =)
Anton
у меня уже написан вариант с двумя тредами и CSP (как на Go), сейчас хочу научиться асинхронщине
Marat
Привет. Появилась следующая задачка: нам нужно сделать настраиваемые с помощью дженериков числа. Например, настройка говорит, что максимальное число😷, а при создании из f32, нужно округлять в большую или меньшую сторону. Увы, в качестве дженерика можно указать только тип, те я не могу сделать Number<7,RoundMax>, приходится передавать в качестве дженериков типы, которые возвращают числа с помощью трейтов(О ужс), например Number<Seven, RoundMax>. Более того, нужно чтобы такой тип мог бы Add, Mul и тд, а трейты нельзя имплементить для трейтов, поэтому нужно чтобы Number был структурой?! Но ведь я же хочу получить некий настраиваемый ТИП, например Number16. Естественно я не хочу объявлять 100 типов и писать к ним impl From<..> for Type1..100 хоть даже с помощью макроса. Мне интересно, есть ли какой-то прямой выход?
Тебе зависимые типы нужны переходи на idris🌚
Anton
Добавлю: Каким-то образом я хочу получить такой тип, который бы настраивался СТАТИЧЕСКИ, те с помощью дженериков. Например, настройки бы он хранил в виде функции, не в объекте.
Anton
Эх, на расте нужно =) В своей одной либе я сумел таки извратиться и сделать типы, собирающиеся на этапе компиляции, те они были осуществлены с помощью структур с PhantomData и трейтов, умеющих выдавать определённые числа с помощью их методов, но теперь нужно, чтобы они таскали с собой и Add/ Mul и тут и попадаешь на проблему, что нельзя с трейтом Number их таскать =( Мозговзрывная задача конечно =))
Anton
А такие типы я хотел бы сделать, чтобы их применить в fn summ<A:Number, B:Number, C:Number😠a:A,b:B)-> C { a+b} и при этом A и B могут быть вовсем разными. Выход, конечно, есть, можно с помощью макросов создавать типы, например, create_number!(N12, 12, Round::Hight); Который имплементит всякое, но.. зато Idea не умеет раскрывать макросы =)) Хотя вряд ли это и понадобится, я же нигде не юзаю типы напрямую. Хм, наверно я так и сделаю, хотя, имхо, костыль.