Нужна помощь зала.
Не могу придумать, как изобразить плоскости в визуализаторе к athena.
(Это там где точки и линии).
2д хорошо работает, надо 3д доработать.
И вот там и появляются плоскости.
Но они ж бесконечные. И в проекции на экран станут либо линией, либо весь вьюпорт займут.
Если изображать какой-то прямоугольник на плоскости, то какой?
Не могу придумать, как изобразить плоскости в визуализаторе к athena.
(Это там где точки и линии).
2д хорошо работает, надо 3д доработать.
И вот там и появляются плоскости.
Но они ж бесконечные. И в проекции на экран станут либо линией, либо весь вьюпорт займут.
Если изображать какой-то прямоугольник на плоскости, то какой?
Представьте, что вам сейчас надо выбрать графический API для нового проекта.
Выбрали ли бы вы
Если да, то почему? Если нет, то почему?
Если не слышали раньше, то вот, посмотрите пожалуйста 🥺
https://github.com/zakarumych/mev
Выбрали ли бы вы
mev
?Если да, то почему? Если нет, то почему?
Если не слышали раньше, то вот, посмотрите пожалуйста 🥺
https://github.com/zakarumych/mev
GitHub
GitHub - zakarumych/mev: GAPI
GAPI. Contribute to zakarumych/mev development by creating an account on GitHub.
😁3🔥1
Rust Tip для начинающих
Реализуя
К сожалению трейты из метода
Но можно еще посмотреть на то что бы перегрузить
Удачного вам итерирования!
Реализуя
Iterator
, снабдите его кастомной реализацией size_hint
, nth
, count
, last
и fold, если они могут быть лучше чем реализованный в трейте.size_hint
по-умолчанию возвращает (0, None), что значит от нуля до бесконечности. Его можно перегрузить почти всегда.nth
по-умолчанию просто вызывает next
n+1 раз. Если итератор может прыгнуть - кастомная реализация будет кстати.count
по-умолчанию итерируется до конца и подсчитывает. Если размер известен заранее, то стоит перегрузить count
. А еще реализовать ExactSizedIterator
Если размер известен и доступ к любому элементу есть, то перегружайте last
, что бы этот метод не итерировался от начала и до концаfold
по-умолчанию вызывает в цикле next
. Если в next
есть какая-то дополнительная логика, которая не нужна если итератор поглощается целиком, то кастомный fold
поможет избавиться лишних вычислений.К сожалению трейты из метода
try_fold
еще недоступны на stable, так что его перегрузить не получится.Но можно еще посмотреть на то что бы перегрузить
all
и any
.Удачного вам итерирования!
👍25
Rust Tip выходного дня.
Rust это крутой язык, но отдыхать очень важно.
Лучше не тратить на петы все выходные.
Постарайтесь выйти на прогулку.
После выгорания программировать на Rust становится сложнее.
Rust это крутой язык, но отдыхать очень важно.
Лучше не тратить на петы все выходные.
Постарайтесь выйти на прогулку.
После выгорания программировать на Rust становится сложнее.
🤝20🔥6❤3👎3👍2💯1
Известно, что файлы - самураи. Потому что у файла нет цели, только путь.
😁15🤯9🔥3⚡1
Шутки, которые нельзя перевести лучше не переводить.
-
- Assuming multiplications in
-
this^2 = -1
. Is this real?- Assuming multiplications in
t*h*i*s
are commutative, than it's equivalent is shit, and shit is getting real!👍14🔥1
Любой ieee754 формат с плавающей точкой содержит:
0% натуральных чисел.
Столько же отрицательных целых.
200% нулей.
И 0% остальных рациональных чисел.
0% натуральных чисел.
Столько же отрицательных целых.
200% нулей.
И 0% остальных рациональных чисел.
😁14👍2
Сорвалась сессия в ДнД.
Второй раз подряд.
Вывод: нельзя лить в прод в пятницу. Инциденты на работе мешают спасать мир.
Второй раз подряд.
Вывод: нельзя лить в прод в пятницу. Инциденты на работе мешают спасать мир.
😁10💯3
Rust Tip для тех, кто кодит ночью (или прочитает утром)
Давайте разберем семейство трейтов
Это семейство представляет собой иерархию
Что же они означают? На самом деле все очень просто, стоит лишь разложить все по полочкам.
Семейство Fn использует специальный синтаксический сахар, и мы обязаны писать так:
Вместо
Далее если не указаны аргументы и возвращаемый тип, значит информация применима к любым аргументам и типам возврата.
Итак по порядку. 🧵
Давайте разберем семейство трейтов
Fn
.Это семейство представляет собой иерархию
FnOnce
, FnMut
, Fn
, где следующий включает предыдущий.Что же они означают? На самом деле все очень просто, стоит лишь разложить все по полочкам.
Семейство Fn использует специальный синтаксический сахар, и мы обязаны писать так:
Fn(A, B, C) -> R
, аналогично синтаксису функций, только без имен аргументов.Вместо
Fn<Args, Output=R>
, где Args
- тьюпл с типами аргументов, так как эта форма нестабильна.Далее если не указаны аргументы и возвращаемый тип, значит информация применима к любым аргументам и типам возврата.
Итак по порядку. 🧵
👍10🤝1
Понедельничный Rust Tip.
Простой совет для невыспавшихся за выходные.
Старайтесь не добавлять трейт баунды в объявление типа.
Любой
В результате некоторые методы, которые никак не зависят это реализации этого трейта, будут на него завязаны.
Конечно иногда придется. Например если вы используете ассоциированный тип в объявлении полей.
Простой совет для невыспавшихся за выходные.
Старайтесь не добавлять трейт баунды в объявление типа.
Любой
T: Trait
потребуют добавить этот баунд во все имплы и функции, кроме случаев, где вместо T
будет конкретный тип.В результате некоторые методы, которые никак не зависят это реализации этого трейта, будут на него завязаны.
Конечно иногда придется. Например если вы используете ассоциированный тип в объявлении полей.
👍6
Запоздалый Rust Tip.
Используйте impl AsRef<T>, impl AsMut<T> и impl Into<T> в аргументах, когда ожидается, что вызываться функция будет удобнее с автоматической конверсией без потери выразительности API.
Но только если
Классический пример это AsRef<Path> аргументы в std всюду, где нужен &Path, потому что удобно вызывать со строковым литералом. При этом на вызывающей стороны не возникает вопросов, куда там оно сконвертируется.
Еще хороший пример - impl Into<EnumType>, где для вариантов есть отдельный тип, который конвертируется в этот вариант. Концептуально они должны быть одним и тем же.
Использовать ли impl Trait или объявить generic, дело вкуса по большей части. Единственная разница в невозможности явно указать тип. Если вы ожидаете, что пользователю функции когда-то понадобится явно указать тип - объявляйте, иначе можно и с анонимным.
Используйте impl AsRef<T>, impl AsMut<T> и impl Into<T> в аргументах, когда ожидается, что вызываться функция будет удобнее с автоматической конверсией без потери выразительности API.
Но только если
T
это не дженерик. Иначе придется его явно указывать.Классический пример это AsRef<Path> аргументы в std всюду, где нужен &Path, потому что удобно вызывать со строковым литералом. При этом на вызывающей стороны не возникает вопросов, куда там оно сконвертируется.
Еще хороший пример - impl Into<EnumType>, где для вариантов есть отдельный тип, который конвертируется в этот вариант. Концептуально они должны быть одним и тем же.
Использовать ли impl Trait или объявить generic, дело вкуса по большей части. Единственная разница в невозможности явно указать тип. Если вы ожидаете, что пользователю функции когда-то понадобится явно указать тип - объявляйте, иначе можно и с анонимным.
👍6👏1💯1
Вот еще один Rust Tip
Делайте derive макросы для своих трейтов.
Если из структуры типа примерно понятно, как реализовать трейт - этот трейт отличный кандидат для
Это значительно уменьшит количество бойлерплейта и уменьшит вероятность глупых ошибок, что мы можем допустить при ручной реализации трейта.
Процедурные макросы могут показаться довольно сложными сначала. Надо парсить и генерировать код.
На самом деле все просто, так как у нас есть крейты
С помощью
А
Не забудьте при генерации Rust кода устанавливать корректные
Так же существует множество надстроек, что делают процедурные макросы вовсе тривиальными. Хотя каждая обладает своими ограничениями.
Делайте derive макросы для своих трейтов.
Если из структуры типа примерно понятно, как реализовать трейт - этот трейт отличный кандидат для
derive
.Это значительно уменьшит количество бойлерплейта и уменьшит вероятность глупых ошибок, что мы можем допустить при ручной реализации трейта.
Процедурные макросы могут показаться довольно сложными сначала. Надо парсить и генерировать код.
На самом деле все просто, так как у нас есть крейты
syn
и quote
.С помощью
syn
можно без труда распарсить код на Rust, который передается в процедурный макрос. А с помощью иных крейтов можно и содержимое аттрибутов распарсить как по волшебству.А
quote
поможет сгенерировать код реализации трейта из шаблона с подстановками.Не забудьте при генерации Rust кода устанавливать корректные
Span
-ы. Это поможет пользователю макроса найти причину ошибки.Так же существует множество надстроек, что делают процедурные макросы вовсе тривиальными. Хотя каждая обладает своими ограничениями.
❤10👍6
Пятнично.
Я заметил, что у меня есть почти все ачивки в ER.
И не хватало только пары легендарок и 2х концовок.
И у меня был перс, прошедший базу в Jorney 2, кроме ластов.
Что, ж. Собрал леги (пришлось пройти весь квест Ранни, но на это ушел всего час), завалил ластов.
Бегом в Jorney 3. Взял 2 великие руны (Годрик и Райкард), проскочил Линдел, Напрямик к Огненному Гиганту, заваливая только боссов, что встречались по дороге.
Фарум Азула как нож сквозь масло (Jorney 3 кажется проще чем Jorney 2).
Маликет взят с первого пула, несмотря на небольшой факап с бафанием.
На Всезнайке попотел.
Годфри дал жару еще хлеще, оставил его на утро. Утром с первого пула.
Радагон и Зверь с нескольких пулов.
Я точно мучался на Jorney 2 намного больше.
А ведь за весь Jorney 3 я вкачал че-то типа 240-245. Потому что руны с нескольких боссов профукал на вайпах на следующих.
В целом что хочу сказать.
Elden Ring это одна из лучших игр, в какие я играл. Максимально советую всем любителям помахать мечем.
И не бойтесь сложности, она проще чем Dark Souls.
Я заметил, что у меня есть почти все ачивки в ER.
И не хватало только пары легендарок и 2х концовок.
И у меня был перс, прошедший базу в Jorney 2, кроме ластов.
Что, ж. Собрал леги (пришлось пройти весь квест Ранни, но на это ушел всего час), завалил ластов.
Бегом в Jorney 3. Взял 2 великие руны (Годрик и Райкард), проскочил Линдел, Напрямик к Огненному Гиганту, заваливая только боссов, что встречались по дороге.
Фарум Азула как нож сквозь масло (Jorney 3 кажется проще чем Jorney 2).
Маликет взят с первого пула, несмотря на небольшой факап с бафанием.
На Всезнайке попотел.
Годфри дал жару еще хлеще, оставил его на утро. Утром с первого пула.
Радагон и Зверь с нескольких пулов.
Я точно мучался на Jorney 2 намного больше.
А ведь за весь Jorney 3 я вкачал че-то типа 240-245. Потому что руны с нескольких боссов профукал на вайпах на следующих.
В целом что хочу сказать.
Elden Ring это одна из лучших игр, в какие я играл. Максимально советую всем любителям помахать мечем.
И не бойтесь сложности, она проще чем Dark Souls.
👍5👎4🤷♂2
Rust Tip по оптимизации дебажного билда.
В Cargo.toml можно указать, что в
Такая запись заставит сборщик оптимизировать зависимость
А вот так можно оптимизировать все зависимости разом.
А так будут оптимизировать билдскрипты и процедурные макросы.
Оптимизируя зависимости вы ускорите процесс дебега, если только вам не надо заходить внутрь функций зависимости. При необходимости уберите оптимизацию для нее.
Приятного вам дебага.
В Cargo.toml можно указать, что в
dev
профиле нужно оптимизировать определенные зависимости.Такая запись заставит сборщик оптимизировать зависимость
foo
.
[profile.dev.package.foo]
opt-level = 3
А вот так можно оптимизировать все зависимости разом.
[profile.dev.package."*"]
opt-level = 2
А так будут оптимизировать билдскрипты и процедурные макросы.
[profile.dev.build-override]
opt-level = 3
Оптимизируя зависимости вы ускорите процесс дебега, если только вам не надо заходить внутрь функций зависимости. При необходимости уберите оптимизацию для нее.
Приятного вам дебага.
❤7👍2💯2
Занимался сегодня рефакторингом небольшого крейта
Сделал чистку всех предупреждений с
В крейте функционал для работы со временем в играх.
И минимум сложностей.
Во первых
Предполагается использовать
Удобно для контроля времени в симуляции. Паузы, буллет таймы, перемотки. Просто вся симуляция должна использовать
Ознакомиться с кодом можно здесь.
https://github.com/zakarumych/gametime
gametime
.Сделал чистку всех предупреждений с
clippy::pedantic
и задокументировал всё, хоть и минимально.В крейте функционал для работы со временем в играх.
И минимум сложностей.
Во первых
TimeStamp
- точка во времени с наносекундной точностью. Относительно чего-то. Обычно относительно того, откуда они берутся.TimeSpan
- промежуток между меньшим и большим TimeStamp
ами. Почти как Duration
, но лишь u64 наносекунд.Clock
- часы. Связывают монотонный таймер core::time::Instant
и TimeStamp
ы. Генерирует ClockStep
, на каждый вызов Clock::step
, где есть текущий TimeStamp
и TimeSpan
между текущим и предыдущим.Предполагается использовать
Clock
в главном цикле, делать Clock::step
в начале каждой итерации и раздавать ClockStep
везде, где нужно знать время.GlobalClock
- как Clock
, но используют единую для процесса точку отсчета. Требуется std
и global_reference
фичаClockRate
- часы со скоростью. Использует внешний источник TimeSpan
, генерирует ClockStep
с указанной относительной скоростью. Без накапливаемой потери точности.Удобно для контроля времени в симуляции. Паузы, буллет таймы, перемотки. Просто вся симуляция должна использовать
ClockStep
из ClockRate
, а не общего Clock
.FrequencyTicker
- генератор тиков с заданной частотой. Использует внешний TimeSpan
и возвращает итератор по ClockStep
тиков, произошедших в течение этого времени. Без накапливаемой потери точности.Ознакомиться с кодом можно здесь.
https://github.com/zakarumych/gametime
GitHub
GitHub - zakarumych/gametime: Time calculations oriented for games
Time calculations oriented for games. Contribute to zakarumych/gametime development by creating an account on GitHub.
🔥9
Если кто-то из подписчиков пользуется egui-snarl, то я сделал PR (вместо того что бы лить в main)
https://github.com/zakarumych/egui-snarl/pull/73
https://github.com/zakarumych/egui-snarl/pull/73
GitHub
Add pin heights setting into NodeLayout by zakarumych · Pull Request #73 · zakarumych/egui-snarl
This change fixes problem with misaligned pins and gives better control to the user.
Allows to make pin rows equally sized
And to specify minimal size of a row
Allows to make pin rows equally sized
And to specify minimal size of a row
👍2🔥1