Вверх ↑
Этот топик читают: Гость
Ответов: 4630
Рейтинг: 749
#121: 2014-01-20 14:10:27 ЛС | профиль | цитата
tsdima писал(а):
Говоря, что каждый компонент есть объект

Не увидел нигде такой необходимости. Объектами (причем в терминах HiAsm, а не целевого языка) можно делать только сложные функционально компоненты. Ничто не мешает иметь десяток-другой примитивных компонентов, реализующих логику (циклы, условия, память), и простые операторы (математика, операции со строками и т.п.), то-есть, те компоненты, для которых нецелесообразно делать ссылку на базовый объект, а проще положить копию на поле.
карма: 26

0
Ответов: 2125
Рейтинг: 159
#122: 2014-01-20 14:20:41 ЛС | профиль | цитата
Netspirit писал(а):
Возникало желание усовершенствовать контейнеры. В моем случае - разделение контейнеров на "пользовательские", которые есть сейчас (предназначенные исключительно для визуального-функционального выделения частей схемы) и "фиксированные" - компоненты из палитры, реализованные в виде контейнера с жестко заданным перечнем внешних точек (для управления контейнером из внешней схемы) и отдельно заданными внутренними точками для использования внутренней схемой.

На мой взгляд нужно различать действительно контейнеры (фиксированные, в твоей терминологии) и просто часть схемы, свёрнутую в один компонент. Функциональность свернуть/развернуть часть схемы не простая, но нужная. Может возникнуть путаница: контейнер и свёрнутая часть схемы может выглядеть одинаково.

Хотя, можно было бы превращать свёрнутую часть схемы в контейнер, добавляя её на палитру. При этом развернуть такую схему было бы уже невозможно. Развернуть можно было бы только после удаления её из палитры, а все имеющиеся копии превращать в одинаковые копии свёрнутых частей схем, или использовать линки.
карма: 1

0
Разработчик
Ответов: 26156
Рейтинг: 2127
#123: 2014-01-20 14:23:32 ЛС | профиль | цитата
Netspirit писал(а):
Ничто не мешает иметь десяток-другой примитивных компонентов, реализующих логику (циклы, условия, память), и простые операторы (математика, операции со строками и т.п.), то-есть, те компоненты, для которых нецелесообразно делать ссылку на базовый объект, а проще положить копию на поле.

Без четкой типизации данных мы получим те же самые грабли, которые видим сейчас
карма: 22

0
Ответов: 9906
Рейтинг: 351
#124: 2014-01-20 14:29:14 ЛС | профиль | цитата
tsdima писал(а):
Замечу, однако, что разница с наследованием не очень большая

Вот именно поэтому я и принял для себя решение - пусть этой разницей кодогенерация занимается. И не будем пользователю парить мозги этой разницей.
Для него ее нет.

tsdima писал(а):
Можно и множественное наследование таким образом разрешить. Т.е. объявление родителем приводит лишь к тому, что интерфейс родителя становится виден снаружи.

Угу. Просто я думаю, что это уже решено (гипотетически).
Если мы имеем второй Interface внутри контейнера, который наследует реализацию от другого элемента, и его handle выведен на улицу через нижнюю точку - чем тебе не dynamic_cast.
Скажу больше. Если парентом объявлен VirtualObject - чем тебе не виртуальное наследование
карма: 9

0
Ответов: 2125
Рейтинг: 159
#125: 2014-01-20 14:38:05 ЛС | профиль | цитата
Galkov писал(а):
Interface внутри контейнера

Необходимость компонента Interface для наследования мне показалась спорной. Зачем ставить Interface и потом указывать его тип, когда можно просто поместить компонент нужного нам типа? Не надо пугать пользователя такими словами, пусть будет просто что-нибудь типа "Сделать точки видимыми снаружи".
------------ Дoбавленo в 14.38:
Self тоже под вопросом. Можно использовать связку VirtualObject + родительский компонент. Вызов точки через VirtualObject будет виртуальным.
карма: 1

0
Ответов: 4630
Рейтинг: 749
#126: 2014-01-20 14:47:32 ЛС | профиль | цитата
tsdima писал(а):
просто часть схемы, свёрнутую в один компонент

Одно другому не противоречит: "пользовательский" контейнер с любой внутренней схемой должно быть можно без проблем преобразовать в отдельный "компонент" (поместить в отдельную вкладку Палитры). Это реализует важный механизм повторного использования частей схемы ("функции" в терминах текстовых языков). А также - возможность создавать несуществующие на данный момент компоненты при условии наличия достаточного количества примитивов.

На всякий случай уточню: под "фиксированными" контейнерами я имел в виду компоненты, типа ChildPanel, ChildForm, которые от "пользовательских" отличаются тем, что имеют жестко заданный функционал (а возможность добавлять пользователем свои точки скорее нудная необходимость для того, чтобы вызвать методы компонента из внешней схемы)
карма: 26

0
Ответов: 9906
Рейтинг: 351
#127: 2014-01-20 15:40:24 ЛС | профиль | цитата
tsdima писал(а):
Хотя, можно было бы превращать свёрнутую часть схемы в контейнер, добавляя её на палитру.

Собственно, именно это я и предложил.

tsdima писал(а):
Зачем ставить Interface и потом указывать его тип, когда можно просто поместить компонент нужного нам типа?

Указали.
А в какое место будем засовывать новые методы.
Ну и наконец - абстрактный интерфейс. Это означает не более, чем то -- что парент является пустышкой.
Т.е., имеются в виду элементы, обладающие одинаковым набором точек, но ничего общего изнутри.

И чего, теперь: избавились (предположим на секунду) от интерфейса, но получили какую-то глупую пустышку... Кстати, я так и не понял - а пустышку-то откуда возьмем....

tsdima писал(а):
Self тоже под вопросом. Можно использовать связку VirtualObject + родительский компонент

Нет, мне семантика Self-а представляется иной: VirtualObject + самый последний наследник.
Который, (в отличии от предка) пока еще не известен.
Разная у них семантика.

Но с одним соглашусь: Self - под вопросом.
Логически он вытекает из наследования реализации. Которая как бы появилась логически не из предыдущих предложений, а по нашей доброй воле.
Логически появилось лишь наследование интерфейса. Как необходимый (да еще и общепринятый) критерий совместимости статического и динамического типов. И все, что из этого следует: не более, чем наследование интерфейсов (в COM, например -- только такое наследование и есть).

Но ведь наследование реализации - тоже полезная штука.
О чем нам говорит принцип Оккама: не вводи новые сущности без необходимости. Вот он и вопрос для обсуждения: является ли наследование реализации для нас штукой настолько нужной, что вводим "новые сущности"
карма: 9

0
Ответов: 2125
Рейтинг: 159
#128: 2014-01-20 15:53:12 ЛС | профиль | цитата
nesco писал(а):
Без четкой типизации данных мы получим те же самые грабли, которые видим сейчас

Не совсем понял, о какой типизации идёт речь, но сейчас точки не имеют строго определённого типа, хотя их семантика предполагает какой-то тип. И если на точку приходят данные не того типа, то они автоматически конвертируются. Если бы точки имели определённый тип, то конвертацией занималась бы сама связь, и это можно было бы учесть в кодогенераторе. С другой стороны, можно было бы предположить, что компонент по разному обрабатывает данные разных типов, и это мог бы учитывать упоминаемый в документе Galkov-ым некий "элемент-пин": он мог бы иметь несколько правых точек, по одной на каждый поддерживаемый тип (и не только базовый, но и пользовательский).
------------ Дoбавленo в 15.53:
Galkov писал(а):
А в какое место будем засовывать новые методы.

Новые методы - это имеющиеся элементы-пины. Но тут ты скорее прав: автоматически добавлять их к VirtualObject (который играл бы роль Self) если он ссылается на родителя - костыль, не вписывающийся в парадигму.

Galkov писал(а):
Ну и наконец - абстрактный интерфейс. Это означает не более, чем то -- что парент является пустышкой.
Т.е., имеются в виду элементы, обладающие одинаковым набором точек, но ничего общего изнутри.

...Кстати, я так и не понял - а пустышку-то откуда возьмем....

На данный момент - это MultiElement с набором точек и пустой изнутри. Если добавить его в палитру (в нашем новом HiAsm), то получим абстрактный интерфейс.

карма: 1

0
Разработчик
Ответов: 26156
Рейтинг: 2127
#129: 2014-01-20 16:03:33 ЛС | профиль | цитата
tsdima писал(а):
то они автоматически конвертируются

Вот это и является основным тормозом. На мой взгляд, элемент должен иметь строго прописанный тип входных и выходных данных, а линковкой должна заниматься среда, и если типы не совпадают, то автоматически вставлять нужный конвертор в разрыв связи, но обязательно визуализировать, что бы видно было, что, где и во что конвертируется. Я уже намедни предлагал эту идею. Если нужен пользовательский тип выходной или входной точки, то можно описать эту структуру в описании свойств точки или создать свой собственный элемент нужной структуры используя вертикальное программирование. Это так, размышления на тему.
карма: 22

0
Ответов: 2125
Рейтинг: 159
#130: 2014-01-20 16:15:37 ЛС | профиль | цитата
nesco писал(а):
если типы не совпадают, то автоматически вставлять нужный конвертор

... а если конвертора не существует - запрещать соединять точки.

nesco писал(а):
Если нужен пользовательский тип выходной или входной точки, то можно описать эту структуру в описании свойств точки

То есть, мы приходим к тому, что тип точки описывает входные аргументы метода. Их может быть и несколько. А формированием такого кортежа может заниматься какой-нибудь элемент типа DoData с аналогичным набором верхних точек.
карма: 1

0
Разработчик
Ответов: 26156
Рейтинг: 2127
#131: 2014-01-21 01:07:34 ЛС | профиль | цитата
tsdima писал(а):
а если конвертора не существует - запрещать соединять точки

На основные типы конверторы должны быть изначально, как базовые. Если конвертора нет, то либо его создать, либо применить компонент структуры, в котором есть базовый тип, пусть это будет тот же прообраз TData, но в него я бы включил еще одно поле типа Pointer, специально для передачи указателей, сейчас переводом целого в указатель мы занимаемся внутри элементов.
------------ Дoбавленo в 16.34:
Еще можно было бы предложить передавать созданные элементы вместе со схемой, и при чтении все компоненты, отличные от базовых, запихивать в специально созданную акладку. Каждая новая схема будет иметь свой собственный набор дополнительных элементов. Если понравился какой-то сторонний элемент, то можно перетащить его в свои вкладки, тогда он не будет удаляться с новой схемой.
------------ Дoбавленo в 01.07:
А если вообще пойти другим путем и сделать всего три элемента -- базовый элемент, элемент класса и элемент метода с возможность работы в различных режимах. Все, остальное получать при помощи только этих трех элементов Элементы класса участвовать в построении схемы не будут, будут участвовать только базовые элементы и элементы методов. Элементы методов можно будет группировать в базовый элемент, который будет неким интерфейсным мостом между схемой и группой внутренних элементов, те по типу наших контейнеров. Все это получается что-то типа наших менеджеров, только на более низком уровне, те более детализовано.
Бредовая мысль пришла в голову, решил поделиться
карма: 22

0
Ответов: 9906
Рейтинг: 351
#132: 2014-01-21 08:27:30 ЛС | профиль | цитата
Возвращаясь к пройденному.
Потому что понимание рекурсии в ООП - не самый тривиальный вопрос.
И копья-то мы ломали на эту тему. В свое время. Подзабыл я просто все эти диспуты....

Все, что говорил раньше, но в виде схемы:
Add(MainForm,2953706,427,168)
{
Width=234
Height=706
Position=1
link(onCreate,15485450:doRandomize,[(564,188)(564,153)])
}
Add(MultiElementEx,13059321,686,231)
{
Mode=1
Name="Sort"
@IsLib=True
link(Array,9304427:Array,[])
}
BEGIN_SDK
Add(EditMultiEx,7479706,21,21)
{
WorkCount=#6:doSort|
DataCount=#5:Array|
Width=552
Height=354
VOffset=140
HOffset=140
link(doSort,4468939:doCompare,[])
}
Add(MultiElementEx,4736351,455,252)
{
elink(13059321)
link(Array,7212801:Var2,[])
}
Add(MultiElementEx,2292698,399,259)
{
elink(13059321)
link(Array,9438745:Var2,[])
}
Add(IntegerArray,16352659,455,84)
{
IntArray=[]
}
Add(IntegerArray,10517189,399,84)
{
IntArray=[]
}
Add(ArrayRW,813269,294,154)
{
link(Array,10669136:Var1,[(300,138)])
}
Add(ArrayRW,3150729,294,217)
{
link(Array,64932:Var1,[(300,201)])
}
Add(GetDataEx,7212801,455,133)
{
link(Data,16352659:Array,[])
}
Add(GetDataEx,9438745,399,196)
{
link(Data,10517189:Array,[])
}
Add(ArrayEnum,994920,161,161)
{
link(onItem,14688563:doSwitch,[])
link(onEndEnum,10544971:doEvent1,[(221,174)(221,258)])
link(Array,11124387:Var2,[])
}
Add(Switch,14688563,231,161)
{
Point(onOn)
Point(onOff)
link(onOn,813269:doAdd,[])
link(onOff,3150729:doAdd,[(284,181)(284,237)])
}
Add(Hub,10544971,231,252)
{
OutCount=3
link(onEvent1,4736351:doSort,[])
link(onEvent2,2292698:doSort,[])
link(onEvent3,7586658:doMerge,[])
}
Add(MultiElementEx,7586658,336,266)
{
@Hint=#37:Слияние двух отсортированных массивов|
Name="Mrg"
link(In1,64932:Var2,[])
link(In2,10669136:Var2,[])
link(Out,11124387:Var3,[(356,89)])
AddHint(-78,49,178,26,@Hint)
}
BEGIN_SDK
Add(EditMultiEx,517209,21,21)
{
WorkCount=#7:doMerge|
DataCount=#3:In1|3:In2|3:Out|
}
END_SDK
Add(GetDataEx,64932,336,196)
{
Angle=1
link(Data,9438745:Var1,[])
}
Add(GetDataEx,10669136,343,133)
{
Angle=1
link(Data,7212801:Var1,[])
}
Add(GetDataEx,11124387,161,84)
{
link(Data,7479706:Array,[])
}
Add(ArrayRW,14669575,77,112)
{
Point(Count)
link(Array,11124387:Var1,[(83,89)])
}
Add(If_else,4468939,84,161)
{
Type=2
Op2=Integer(1)
link(onTrue,994920:doEnum,[])
link(Op1,14669575:Count,[])
}
END_SDK
Add(Edit,3522873,427,105)
{
Width=226
Align=2
Text="100"
DataType=1
ClearAfterEnter=1
Point(doSelectAll)
link(onEnter,3614744:doEvent1,[])
}
Add(ListBox,9304427,672,112)
{
Top=20
Width=226
Height=646
Align=5
}
Add(Hub,3614744,490,112)
{
OutCount=3
link(onEvent1,3522873:doSelectAll,[(515,118)(515,97)(417,97)(417,125)])
link(onEvent2,9304427:doClear,[])
link(onEvent3,413181:doFor,[(515,132)(515,146)])
}
Add(For,413181,525,140)
{
Start=1
InData=0
link(onEvent,15485450:doRandom,[])
}
Add(Random,15485450,588,140)
{
Max=10000
Quality=1
link(onRandom,9304427:doAdd,[(627,146)(627,118)])
}
Add(Button,9551663,427,231)
{
Left=420
Top=230
Align=4
Caption="СОРТИРОВКА"
link(onClick,13059321:doSort,[])
}

Вот, nesco, это есть решение рекурсивной задачи
Достаточно ли оно очевидно
По моему, так очевидней и некуда.


------------ Дoбавленo в 08.27:
А, да... Забыл добавить:
1) Схема незакончена, Содержимое мультика Mrg нарисуйте сами. И оно даже и заработает.
2) Ну и Вы помните: внутрь линка лучше не ходить - снег башка попадет. Возможно (я не ходил).
карма: 9

0
Разработчик
Ответов: 26156
Рейтинг: 2127
#133: 2014-01-21 10:13:49 ЛС | профиль | цитата
Galkov писал(а):
По моему, так очевидней и некуда

А если повторно обратиться, опять создастся N-е количество экземпляров Режим-то OnlyOnce у нас не реализован
карма: 22

0
Ответов: 9906
Рейтинг: 351
#134: 2014-01-21 10:30:48 ЛС | профиль | цитата
Ты ошибаешься.
Реализован. И всегда был реализован, с самого зарождения. Поверь мне -- я это точно помню

Ровно в тот момент, когда select указывает "в никуда" -- это работает в режиме OnlyOnce: создал, исполнил для созданного, убил
------------ Дoбавленo в 10.30:
Вот, поставил комментарии методом тупого копипастинга:
#pas
procedure THIMultiElementEx.doWork;
var F:THIEditMultiEx;
begin
if FChild = nil then // когда select указывает "в никуда"
begin
F := CreateInstance; // создал
_hi_OnEvent(F.Works[Index],Data); // исполнил для созданного
F.MainClass.Destroy; // убил
end
else _hi_OnEvent(FChild.Works[Index],Data);
end;
карма: 9

0
Разработчик
Ответов: 26156
Рейтинг: 2127
#135: 2014-01-21 10:44:26 ЛС | профиль | цитата
Galkov писал(а):
Ровно в тот момент, когда select указывает "в никуда"

О! Интересно, этот момент я прозевал. Век живи, век учись Значит режим OnlyOnce не выбирается, но работает при отсутсвии выбора
карма: 22

0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)