МодуліСтруктури даних3D Конфігуратор
З коробки редактор може обробляти будь-які об’єкти JS як вузли та з’єднання, за умови, що вони містять обов’язкове поле «id» для обох. Крім того, з’єднання повинні мати поля source
та target
. Ці об’єкти можуть бути як звичайними об’єктами з даними, так і об’єктами, що містять методи. Докладніше див. у гайді Структури даних.
Поточна версія редактора не підтримує імпорт/експорт за замовчуванням через деякі обмеження:
Припустімо, у нас є простий приклад, де вузол є дійсним JSON об’єктом
tsimport { NodeEditor, BaseSchemes, getUID } from 'rete' const editor = new NodeEditor<BaseSchemes>() const node = { id: getUID(), label: 'Label' } await editor.addNode(node)
У цьому випадку ми можемо легко експортувати такі вузли в JSON, щоб зберегти їх, наприклад, у базі даних.
Об’єкти, які не є дійсними JSON, наприклад екземпляри класів, об’єкти з функціями або об’єкти з циклічними посиланнями, можуть бути викликом. Відмова від них означала б втрату переваг використання JS.
Наприклад, класи вузлів можна використовувати для створення вузлів, що забезпечує більш надійну та зручну взаємодію за допомогою методів і забезпечує гнучкість використання різних парадигм.
tsimport { ClassicPreset } from 'rete' const node = new ClassicPreset.Node('Label') node.addOutput('port', new ClassicPreset.Output(socket, 'Label')) await editor.addNode(node)
Хоча серіалізація та десеріалізація можуть бути одним із способів перетворення таких об’єктів на дійсні JSON, цей підхід може не працювати в складних сценаріях.
Якщо ви хочете експортувати граф, ви можете використовувати наступний код як довідник. Зверніть увагу, що це не повністю функціональний код, а наближений, який допоможе вам реалізувати власні функції імпорту/експорту відповідно до ваших конкретних вимог.
tsconst data = { nodes: [] } const nodes = editor.getNodes() for (const node of nodes) { data.nodes.push({ id: node.id, label: node.label, inputs: /// .... controls: /// .... outputs: /// .... }) }
Щоб зробити зворотну трансформацію, ми повинні ініціалізувати екземпляри вузлів, входи, виходи та контроли на основі наданих об’єктів.
tsfor (const { id, label, inputs, outputs, controls } of data.nodes) { const node = new ClassicPreset.Node(label); node.id = id; /// ... inputs /// ... controls /// ... outputs await editor.addNode(node) }
Повний приклад можна знайти за посиланням. Зверніть увагу, що цей приклад було спрощено для зручності розуміння.
Крім того, імпорт або експорт входів і виходів може не завжди бути необхідним, якщо вони статичні, і ми знаємо тип вузла. У таких випадках ми можемо просто зберегти назву вузла та відповідні дані, які можна використовувати для створення екземплярів вузлів із заздалегідь визначеними портами. Перегляньте приклади 3D Конфігуратор і Модулі з реалізацією цього підходу.
Іншою проблемою під час імпорту графа може бути порядок, у якому необхідно імпортувати вузли. У простих випадках порядок буде таким же, як і порядок, у якому вони були додані до редактора.
tsconst graph = /// завантажений з БД дійсний JSON об’єкт for (const node of graph.nodes) { await editor.addNode(node) }
При роботі зі складнішими графами порядок додавання вузлів може змінюватися. Наприклад, у графі з вкладеними вузлами може знадобитися додати батьківські вузли перед дочірніми. Крім того, цілком можливо, що користувач може створити дочірній вузол перед його батьківським вузлом під час роботи в редакторі.
Давайте подивимося на приклад імпортування графа, де певні вузли мають поле parent
, що вказує на їх зв’язок з іншим вузлом. У результаті ці вузли потрібно імпортувати після того, як їх батьківський вузол буде створено.
tsasync function importForParent(nodes, parent = undefined) { const nodes = nodes.filter(node => node.parent === parent) for (const node of nodes) { await editor.addNode(node) await importForParent(nodes, node.id) } } const graph = /// завантажений з БД дійсний JSON об’єкт await importForParent(graph.nodes)
Оскільки цей підхід складніший і існує кілька способів його виконання, метод імпорту буде різним залежно від конкретного випадку використання.