ru
Feedback
Random Rust Dev

Random Rust Dev

Открыть в Telegram

Разработка на языке Rust. Пишу простыни со своими мыслями о Rust и проектах на нем.

Больше
216
Подписчики
-124 часа
-27 дней
+230 день
Архив постов
Получился вот такой вот проводок. Ваши мысли?

Сегодня я обновил egui в egui-snarl и egui-probe. Решил за одно и добавить все ломающие изменения. На скрине пример, показыва
Сегодня я обновил egui в egui-snarl и egui-probe. Решил за одно и добавить все ломающие изменения. На скрине пример, показывающий, что получится если некоторые пины будут задавать не стандартный WireStyle

Давненько ничего не писал. Ни тут не писал, ни на Rust. Хватит это терпеть, как говориться. Сегодня добавил еще одну структуру данных в свой арсенал. Сей арсенал запакован в crate amity (англ. peaceful relations, as between nations; friendship). Который я и опубликовал. https://docs.rs/amity/latest/amity/ Верхнеуровневая документация хромает, но стараюсь хотя бы типы и методы задокументировать как следует. Что есть в этой библиотеке. От простого к сложному 1. `CacheAlign и CachePadded` позволяют выравнивать данные по краям кэш-линий, избегая ситуации false sharing. False sharing происходит когда два потока одновременно обращаются к двум разным областям памяти, которые разделяют кэш-линию. Один поток делает запись и инвалидирует всю кэш-линию, второй поток вынужден ее обновлять, хотя данные, которые нужны потоку вовсе не поменялись. Предоставленные типы могут быть использованы для конструирования других конкурентных структур данных. 2. `TripleBuffer` - очень простой в использовании и эффективный single-producer single-consumer канал с емкостью очереди 1. Особенно полезен, когда consumer читает значения и их можно переиспользовать в producer-е, экономя гига-циклы. Например когда значения содержат ссылки на ресурсы или аллоцирую память. К тому же producer знает, было ли значение прочитано consumer-ом или нет и обновить его соответствующе, что может дать не только бонус к производительности, но и вовсе сделать алгоритм невозможный с обычным каналом. 3. `BackOff` используется в различных алгоритмах ожидания, что бы делать сначала busy spin, переходить к более энергоэффективным thread yield и наконец остановке треда. 4. `RawSpin` - самая простая имплементация блокировки на основе busy spin. Использует BackOff. Совместим в lock_api. 5. `FlipBuffer` - кольцевой буфер с возможностью добавлять в значения параллельно и без блокировок. Но только пока вместимости хватает. `FlipQueue` - надстройка над FlipBuffer, которая добавляет значения под shared lock, пока хватает вместимости и делает unique lock при необходимости, а так же что бы забрать значения. Оба варианта могут быть использованы в fork-join сценариях, где fork-и могут эффективно добавлять значения в очередь, а забираются они после join или очень редко в fork-ах. 6. `park` - модуль с абстрактным thread parking. С `std` можно использовать Thread и стандартный паркинг. Без std остается thread yield. Но пользователь может использовать кастомную реализацию. Блокирующие алгоритмы (кроме spin) могут использовать любую реализацию. 7. `PtrState и AtomicPtrState` - комбинирует указатель и состояние в одном значении и позволяет атомарно читать и модифицировать. Неатомарная версия предоставлена для полноты. `AtomicPtrState` занимает 1 usize и позволяет совершать те же операции что и AtomicUsize или AtomicPtr. Для состояния используются биты, которые гарантируются быть нулевыми в указателе в результате выравнивания. Адрес и состояние аккуратно разделяются и смешиваются, гарантируя сохранение provenance указателя. 8. `CondVar` - классический conditional variable на основе AtomicPtrState. Все операции требуют не более одного CAS вы цикле. Может использовать любой thread parking из модуля выше. Позволяет закодировать 8 бит состояния и обновлять, записывать, ожидать его. И другие экспериментальные вещи. У этого crate-а нет зависимостей кроме lock_api для реализации трейтов из него и объявления синонимов типов. Можно использовать с/без std и alloc. Библиотеке явно не хватает серьезного тестирования, но как минимум некоторые тесты под miri она проходит.

У меня выработалась хорошая привычка сразу документировать safety требования и обоснования вокруг unsafe кода. unsafe fn - сразу пишу как не получить с ней UB. unsafe {} - почему тут не будет UB. Для этого есть clippy lint clippy::undocumented_unsafe_blocks. Также всегда советую делать #![forbid(unsafe_op_in_unsafe_fn)] если нету #![forbid(unsafe)]. Но есть один случай, когда приходится писать
// SAFETY: Practically safe, but generally nope.
unsafe { ... }
И ничего тут не поделаешь. Можно сколько угодно протаскивать unsafe наверх, хоть до main, но там придется сделать вот такой unsafe блок. Что ж это за жестокая ирония и когда крабам приходится идти на трюки и соглашаться на "безопасно на практике" вместо полной гарантии безопасности? Первый написавший правильный ответ в комментарии к посту заслужит почет и уважение.

photo content

Пофиксил все артефакты, которые проявились в демке при использовании разных стилей. Для этого подключил https://github.com/zakarumych/egui-probe и задерайвил EguiProbe для SnarlStyle и добавил виджет в демку. Теперь все стили графа можно редактировать прямо вот так.

https://crates.io/crates/egui-snarl Версия 0.2 Рефакторинг, API без RefCell и с типизированными идентификаторами нод. Новые опциональные области для контента в нодах - тело между пинами и футер в самом низу. Опциональный попап при наведении курсора на ноду. Фикс скейлинга, теперь почти нет дребезжания размера нод. И другие мелкие изменения. Сделал все крупные запланированные ломающие изменения. Дальше можно и без них все планы реализовать.

Подготовил релиз второй версии нодграфов. Заинтересованные могут посмотреть на изменения в API и дать ценный фидбэк заранее

Сонная башка не додумалась нормально прислать логотип. Хорошо что rustc находит все ошибки сонной башки, что бы не надо было
Сонная башка не додумалась нормально прислать логотип. Хорошо что rustc находит все ошибки сонной башки, что бы не надо было дебажить всю ночь

egui-snarl обзавелся логотипом
egui-snarl обзавелся логотипом

Вспомнилось тут, что бусти у меня тоже есть https://boosty.to/zakarumych

Слегка подвыгорел и взял небольшую паузу в разработке движка. Планировал чем заняться дальше в первую очередь. И тут вот такой мотиватор пожаловал. Наконец-то одобрили мой профиль на GitHub Sponsors https://github.com/sponsors/zakarumych Я буду капец как рад даже одному :)

Добавил возможность реагировать на сильные столкновения, а не на все вообще. Коллайдеры не-сенсоры скорее всего только в таких и будут заинтересованны. На этом я заканчиваю взрывать мячики. Следующий шаг - завершить рендер пайплайн для пиксельной игры

Это не про Раст, но тем не менее, это гениально! tldr Используя символы из юникода, который разрешен в идентификаторах, но вы
Это не про Раст, но тем не менее, это гениально! tldr Используя символы из юникода, который разрешен в идентификаторах, но выглядят как больше/меньше, этот человек делает мономорфизацию с шаблона что бы писать утиный дженерик код в Go. Да это почти не отличается от того как раньше работали шаблоны в С++ и вполне подошло бы для других языков. Но вы еще найдите язык 1. Без дженериков 2. С юникодом Кажется это только Go :)

Ах да, точно, еще же я починил отображение нескольких игровых симуляций в ed!

Зарефакторил плагины физики и движения. Теперь для создания тел и коллайдеров не нужно тянуть ресурс физики, что упрощает API, так как с захваченным ресурсом физики нельзя было вызывать world.spawn и приходилось создавать тело и коллайдер заранее. Теперь тело в физическом мире само проинициализируется перед следующим шагом симуляции. Еще сделал возможность создавать коллайдеры для тел в дочерних сущностях. При дропе тела или сущности с телом дочерние сущности с коллайдерами будут уничтожены. Плагин движения теперь не мешает прикладывать силу и импульс к телам из других источников. А для кинематических тел корректно прикладывается не сила а скорость или позиция. Так же добавил компонент флаг что бы отмечать позиционные кинематические тела, что бы только к ним применять изменения из компонента трансформа. А после симуляции только от активных динамических тел пишется новая позиция в компонент трансформа. На видео шарики при взрыве расталкивают соседей, прикладывая им мгновенный импульс. В общем, чувствую, пора делать мини-игру, а не просто системами жонглировать. И желательно прямо с этим обрубком SDF-рендера :) Если у вас есть идеи, милости прошу в комментарии.

Пофиксил сегодня глупейший баг. Нужно было из вектора пройтись по всем элементам и вызвать метод, возвращающий bool, и вернуть true если хотя бы один вызов метода вернет true. Угадайте, что я сделал не так?

Всех с наступившим! Желаю всем быстрой компиляции и благосклонного борроучеккера!

photo content