2009-03-14 6 views
21

Я хотел бы реализовать узловой-интерфейс, в основном DAG, где каждый узел выполняет операцию по его входных соединений и выводит что-то (что вы можете подключиться к другому узлу)Реализация графического интерфейса на основе узлов?

Некоторые примеры приложений:


В качестве первой цели, я хотел бы иметь графическое приложение только с 2 узлами. «Число», которое просто выводит фиксированное число, и узел «Добавить», который принимает два входа и выводит сумму этих двух.

Как люди ответили так далеко, у меня есть общее представление о том, как представлять данные в коде, например, в Python'y ищет псевдо-код:

class Number: 
    def __init__(self, value): 
     self.value = value 

    def eval(self): 
     return self.value 

class Add: 
    def __init__(self, input1, input2): 
     self.input1 = input1 
     self.input2 = input2 

    def eval(self): 
     return self.input1.eval() + self.input2.eval() 


a = Number(20) 
b = Number(72) 

adder = Add(a, b) 
print adder.eval() 

Как бы я получил о обертке пользовательский графический интерфейс вокруг этого? Что-то вроде следующего, но немного менее нарисованного вручную!

nodal UI mockup

Где бы мне начать? В настоящее время я планирую написать его в Objective-C/Cocoa, хотя я более чем открыт для предложений для других языков.

ответ

4

Я бы начал с моделирования некоторых базовых интерфейсов (в смысле ООП, а не в смысле GUI). Кажется, у вас будет узел, который будет принимать коллекцию входов и один вывод. Вы не указали каких широких типов данных, но вам нужен какой-то подходящий метод представления ваших входов/выходов. Для вашей первой цели это может быть целое число.

В некотором общем стиле C ООП языка (надеюсь, что это имеет смысл):

class Node<T> { 
    Node<T>[] inputs; 
    T eval(); 
} 

class AdderNode extends Node<int> { 
    int eval() { 
     int accum = 0; 
     for (inputs : i) 
      accum += i.eval(); 
     return i; 
    } 
} 

class ConstNode<int I> extends Node<int> { 
    int eval() { return I; } 
} 

AdderNode a; 
a.inputs.add(ConstNode<2>()); 
a.inputs.add(ConstNode<3>()); 
a.eval(); 

Вы могли бы расширить, заменив Int с неким абстрактным классом, родовым, или интерфейсом. Разумеется, фактическая реализация будет зависеть от фактического языка.

1

Я бы начал с моделирования интересных операций. В конечном итоге вы подключите их к пользовательскому интерфейсу, но это рулевое колесо и педаль газа, а не двигатель.

То, что вы пытаетесь построить, имеет много общего с языками программирования: переменными, значениями, типами, выражениями, оценкой и т. Д. Многие из метафор применимы и могут дать некоторые рекомендации.

Если вы используете .NET 3.5, у вас есть опция Expression Trees, которая позволяет вам представлять и компилировать выражения кода во время выполнения.

Например, чтобы смоделировать свою первую цель:

using System.Linq.Expressions; 

ConstantExpression theNumber2 = Expression.Constant(2); 
ConstantExpression theNumber3 = Expression.Constant(3); 

BinaryExpression add2And3 = Expression.Add(theNumber2, theNumber3); 

Чтобы вызвать выражение, нужно обернуть add2And3 с методом. Это делается с лямбда-выражения:

Expression<Func<int>> add2And3Lambda = Expression.Lambda<Func<int>>(add2And3); 

Func<int> представляет собой метод, который не принимает никаких параметров и возвращает int. В C#, код представлен add2And3Lambda будет:

() => 2 + 3 

Так что у нас есть это выражение дерево, корень которого является метод. Поскольку метод вызываемой, мы можем собрать дерево в экземпляр базового типа делегата:

Func<int> add2And3Func = add2And3Lambda.Compile(); 

Теперь мы можем ссылаться на коде мы построили:

int theNumber5 = add2And3Func(); 

Каждого выражения доступно. Поддерживаются языки NET.

Представьте, что каждый узел вашего графика имеет связанный с ним связанный Expression. Это может дать вам представление о силе деревьев выражений и о том, как они могут помочь вам в решении этой задачи.

1

Все эти узловые системы имеют общий характер, что они описывают функциональный язык программирования. Функция принимает несколько параметров и возвращает один результат, независимо от того, для какой цели он был разработан. Некоторые примеры:

  • График: Размытие (изображение, ядро, Radius) -> Image

  • Math: Добавить (номер, номер) -> Номер

  • Relational: Фильтр (таблица, Предикат) -> Таблица

основном это сводится к функции подписи, как Func<object[], object> (C#).

Вы столкнулись с вопросом о том, как сделать вашу систему узлов стойкой. Вы хотите сделать результат использования узла как параметра только одним другим узлом (деревом) или несколькими узлами (графом)?

Пример дерева, непосредственно имеют параметры а дочерние узлы:

Add(
    Multiply(
    Constant(5), 
    Constant(4) 
), 
    Multiply(
    Constant(5), 
    Constant(3) 
) 
) 

Пример графа, хранить все узлы в списке и использовать только ссылки:

A := Constant(5) 
B := Constant(4) 
C := Constant(3) 

D := Func(Multiply, A, B) 
E := Func(Multiply, A, C) 

F := Func(Add, D, E) 
0

Может bwise имеет что-то интересное?

В нижней половине this page показан пример использования bwise для создания блока умножения, который принимает два числа в качестве входных данных.

1

Я нашел некоторую полезную информацию о реализации такого интерфейса в какао:

  • Intro to Quartz и Intro to Quartz II - описывает основной рисунок в NSView
  • FlowChartView на Cocoadev - в значительной степени то, что я искал, реализации интерфейса кварцевого композитора.
0

Я реализовал Execution график, как вы описали в этом проекте: GRSFramework

Исходный код можно найти here.

В настоящее время я работаю над выпуском лучшей, очищенной версии этой системы в проекте ExecutionGraph.
Это может быть интересно для вас.

Тогда есть также библиотека TensorFlow от Google, которая имеет аналогичную систему реализованного TensorFlow

0

Я наткнулся на эту тему, исследуя для подобного решения. Недавно я нашел хороший проект на github https://github.com/nodebox/nodebox который, кажется, именно то, что вы ищете. По крайней мере, один мог извлечь и принять компоненты редактора из проекта.

С уважением, Стефан

+0

Добро пожаловать в StackOverflow, спасибо за желание внести свой вклад, но ответы со ссылками только обескураживают. Ознакомьтесь с [рекомендациями по ответам] (https://stackoverflow.com/help/how-to-answer). Хорошее эмпирическое правило состоит в том, чтобы посмотреть на ваш ответ без ссылки, и если это не принесет никакой пользы, подумайте о расширении. – JaredMcAteer

 Смежные вопросы

  • Нет связанных вопросов^_^