Random Rust Dev
367 subscribers
73 photos
41 videos
1 file
28 links
Разработка на языке Rust.
Пишу простыни со своими мыслями о Rust и проектах на нем.
Download Telegram
egui-snarl позволяет создать нод-граф для любых целей.
У него вообще нет предположений о том что ноды и связи значат.
Ноды тоже, это просто данные.

Для начала я собрал вот такой простенький пример.
В отличии от существующих нод-граф крейтов у egui-snarl используется концепт вьюера.
Это он решает какие у ноды пины, сколько их, как выглядят, что рисуется рядом с ними.
egui-snarl предоставляет контейнер для графа Snarl и трейт для вьюера SnarlViewer.
При отрисовке Snarl::show регулярно обращается к SnarlViewer что бы отрисовать шапку ноды, узнать сколько сейчас пинов у ноды, отрисовать контент у пина, узнать как выглядит сам пин, а так же с событиями, что бы вьюер сам решил что делать, соединять ли ноды, а может между ними вставить еще одну для преобразования типа, удалять ли связь или ноду.
Граф на картинке выше имеет очень простое определение типа ноды.
Это такой вот энум

enum DemoNode {
/// Node with single input.
/// Displays the value of the input.
Sink,

/// Value node with a single output.
/// The value is editable in UI.
Integer(i32),

/// Value node with a single output.
String(String),

/// Value node with a single output.
///
/// It has two inputs, ediable if not connected.
Add(Vec<i32>),

/// Converts URI to Image
Show(String),
}


И уже вьюер сам знает что у Sink есть 1 вход и 0 выходов, а у Add входов сколько значений + 1, а выход 1
Так же вьюер решает, что Sink показывает у своего входа.
Когда Sink подключен к выходу от Integer или Add, то вьюер сделает ui.label() с числовым значением, от String со строковым значением, а от Show загрузит картинку, хотя в типе там тоже строка лежит.

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

1. Для организации зависимостей между системами для ЕЦС. Snarl с системами будет передан в скедулер.
Планирую дать возможность менять порядок систем прямо в рантайме, когда симуляция игры запущена в эдиторе.
2. Для визуализации рендерграфа. Как-то модифицировать граф будет нельзя, только двигать ноды по плоскости.
Сейчас вот подумал, что для рендерграфа можно при выборе пина показывать содержимое. Даже для буферов, если будет описание структуры данных там
Сообщение для комментов
То ли копилот знает алгоритм де Кастельжо, то ли просто угадал
Вообще у людей разное отношение к копилоту и подобным ИИ для порграммистов.

Для меня это просто code completer 80го уровня.
Я никогда не прошу его реализовать функцию, я начинаю писать, а он предлагает. И часто угадывает.

Хотя функции на пару строк может и целиком угадать просто исходя из аргументов и возвращаемого типа.
This media is not supported in your browser
VIEW IN TELEGRAM
Оказывается находить кривую рядом с курсором очень даже просто.
Почти как рисовать. Сэмплишь многоточек и находишь расстояние до них.
Но для перфа сделал еще иерархичные баундин боксы до достаточно короткой секции
3
This media is not supported in your browser
VIEW IN TELEGRAM
В визуальном программировании часто приходится на каждую маленькую операцию вставлять ноду.
Но зачем?

Заменил ноду Add на ноду Expr в демке к egui-snarl.
Теперь можно написать выражение с числами и переменными и его результат будет на выходе.
А для каждой переменной будет вход.

Все же я хочу что бы этот TextEdit был прямо в шапке ноды. Но пока не придумал как объединить это с перетаскиванием ноды за шапку.
👍6
This media is not supported in your browser
VIEW IN TELEGRAM
Наконец-то получилось сделать тягание ноды за любой неинтерактивный спот на ней.

А еще ресайз ноды, так что в нее точно помещается весь контент с отступами, но не больше.
🔥2
Нужно ли добавить флаг в стиль что бы связи рисовались под нодами, а не над ними
Anonymous Poll
43%
Да
21%
Нет
29%
Потом
7%
Я бы сам сделал
Это даже проще чем казалось
🔥4
Выглядит неплохо. Сделаю это стилем по-умолчанию
This media is not supported in your browser
VIEW IN TELEGRAM
Сделал схлопывание нод.
Получилось вроде прилично.
Пришлось, правда, переделать отрисовку, разделив рисование заголовка и пинов.

Обычный егуйный CollaspingHeader просто клипает содержимое во время анимации.
Мне же захотелось сделать похитрее - схлопывающийся контент уезжает наверх.
🔥4
This media is not supported in your browser
VIEW IN TELEGRAM
Схлопывание замедленном режиме
👍5
This media is not supported in your browser
VIEW IN TELEGRAM
Зум в egui это сложно, но вот что выходит пока
👍2
Вот теперь зум получается хорошим.
Нужен только один workaround в пользовательском коде для TextEdit - задать явно desired_size и margin.
Первый можно просто занулить, для второго взять ui.spacing().item_spacing например.

За одно переставил зум на колесико мышки. Ограничение зума и скорость будет в SnarlStyle