Вверх ↑
Этот топик читают: Гость
Ответов: 9906
Рейтинг: 351
#1: 2006-10-03 15:35:26 ЛС | профиль | цитата
Есть предложение добавить две нижние точки ##EventHandle и ##EventIndex
Примерно таким образом:
procedure THIMultiElementEx.EventHandle(var Data:TData; Index:word);
begin
dtInteger(Data,integer(EvHandle));
end;

procedure THIMultiElementEx.EventIndex(var Data:TData; Index:word);
begin
dtInteger(Data,FList.IndexOf(EvHandle));
end;

procedure THIEditMultiEx.onEvent;
var X:THIEditMultiEx;
begin
X := THIMultiElementEx(FParent).EvHandle;
THIMultiElementEx(FParent).EvHandle := self;
_hi_onEvent(THIMultiElementEx(FParent).Events[Index],Data);
THIMultiElementEx(FParent).EvHandle := X;
end;

procedure THIEditMultiEx._Data;
var X:THIEditMultiEx;
begin
X := THIMultiElementEx(FParent).EvHandle;
THIMultiElementEx(FParent).EvHandle := self;
_ReadData(Data,THIMultiElementEx(FParent).Datas[Index]);
THIMultiElementEx(FParent).EvHandle := X;
end;

карма: 9

0
Администрация
Ответов: 15295
Рейтинг: 1519
#2: 2006-10-04 03:59:38 ЛС | профиль | цитата
В таком подходе смущает отсутствие гарантии того, что с точки ##EventHandle я считаю указатель на ту схему, которая вызвала onEvent... Это не очень хорошо
карма: 27
0
Ответов: 9906
Рейтинг: 351
#3: 2006-10-04 08:58:41 ЛС | профиль | цитата
Это почему такие гарантии пропадают

Мне кажется, что все нормально - как в стеке...
карма: 9

0
Администрация
Ответов: 15295
Рейтинг: 1519
#4: 2006-10-04 21:05:55 ЛС | профиль | цитата
Хотя бы потому, что есть одна глобальная переменная и много схем, которые в нее пишут. Если развивать мысль дальше, то получается, что пока отрабатывает:
 _hi_onEvent(THIMultiElementEx(FParent).Events[Index],Data);[/code]
кто-то еще может повторно вызвать:
procedure THIEditMultiEx.onEvent;[/code]
А вызвать он может повторно потому, что компоненты живут в среде с возможностью паралельного исполнения кода схем. Таже самая проблема возникает и в обычном языке:
int *globalVar;
void my_proc(int tempVar) {
globalVar = &tempVar;
do_work();
globalVar = NULL;
}

do_work() {
use_globalVar_1();
use_globalVar_2();
}

void use_globalVar_1() {
//...
}

void use_globalVar_2() {
//...
}
ф-ции use_globalVar используют данные из глобальной переменной globalVar. Этот код будет совершенно корректен, если мы никогда и нигде не вызовем my_proc повторно, в противном случае никаких гарантий никто дать не может.
В схемах HiAsm на данный момент существует как минимум два таких способа:
1) Использование таймера
2) Использование потока

[size=-2]------ Добавлено в 21:05 [/size]
[quote]Мне кажется, что все нормально - как в стеке...[/quote]
С тем, что все нормально и будет при повторном вызове onEvent из самого себя я и не спорю.
карма: 27
0
Ответов: 9906
Рейтинг: 351
#5: 2006-10-04 21:42:56 ЛС | профиль | цитата
Dilma, этот код таки отличается от твоего:
int *globalVar;
void my_proc(int tempVar) {
int*X = globalVar;
globalVar = &tempVar;
do_work();
globalVar = X;
}

do_work() {
use_globalVar_1();
use_globalVar_2();
}

void use_globalVar_1() {
//...
}

void use_globalVar_2() {
//...
}
тем, что my_proc можно вызывать повторно.

Таймер: его выход не является продолжением нашего события. Исходя из этого, если по его выходу мы прочитаем 0 (а именно его мы и прочитаем) - то именно так и должно быть.
((btw: я иного способа уничтожить самого себя, иначе как через таймер (PostMessage - по большому счету) и не придумал пока - вот уж где точно требуется, чтобы это не было продолжением нашего события))

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

[size=-2]------ Добавлено в 21:42
даже не очень понятно как вообще можно работать с таким контейнером, если позволять какому ни попадя потоку кликать ##select по своему усмотрению
карма: 9

0
Администрация
Ответов: 15295
Рейтинг: 1519
#6: 2006-10-04 21:57:33 ЛС | профиль | цитата
Galkov, повторно вызвать можно - тут спору нет. Но вот пока отрабатывают use_globalVar_1 или use_globalVar_2 вызов из другого потока my_proc приведет к не верной работе программы. Проблема это не программиста, а наша - целиком и полностью причем. Вот такой код выполняется корректно всегда:
;
void my_proc(int tempVar) {
do_work(&tempVar);
}

do_work(int *globalVar) {
use_globalVar_1(globalVar);
use_globalVar_2(globalVar);
}

void use_globalVar_1(int *globalVar) {
//...
}

void use_globalVar_2(int *globalVar) {
//...
}
Не меняя кода самой программы, а меняя только интерфейс мы обеспечили разработчика 100% корректным кодом. Скажем примерно это же было бы достигнуто в hiasm, если бы self не запоменался в глобальном EvHandle, а передавался скажем последним звеном в MT потоке по любому ивенту или запросу данных. Что-то около того:
...
AddMTData(Data, integer(self));
_hi_onEvent(THIMultiElementEx(FParent).Events[Index],Data);
...
а раз такая возможность есть хоть в каком-то виде, то это уже наша задача.
карма: 27
0
Ответов: 9906
Рейтинг: 351
#7: 2006-10-05 00:00:39 ЛС | профиль | цитата
Dilma писал(а):
Проблема это не программиста, а наша - целиком и полностью причем

Она станет наша, когда мы продекларируем что-то подобное.
А чтобы это сделать, нам надо целиком сменить кодовую часть.

К примеру: FChild тоже в плане параллельных потоков "глобальная" переменная. Чтобы она стала локальной - ее надо поместить в стек, и тоже при аттачить в хвост данным. Появятся новые проблемы, но и их можно будет решить.
И таких рассуждений - почти по всем элементам. А в результате - совершенно новая конструкция, не в лучшую сторону отличающаяся эффективностью. Зачем - неизвестно.
((Собственно, такой же разговор, как и про реентерабельность, в народе - "кольцевание" ))



Подводим итог: единственный вариант неработоспособности - конфликт данных при исполнении метода одного и того же объекта в параллельных потоках.
Спрашивать, столько у нас в базе элементов свободных от этого конфликта - не буду.
И мне не представляется, что нашей задачей является освобождение всех элементов от этого конфликта. Даже более: мне это представляется вредным, идущим в разрез со структурой ООП

Ну, в общем, нет, так нет.
карма: 9

0
Администрация
Ответов: 15295
Рейтинг: 1519
#8: 2006-10-05 00:19:53 ЛС | профиль | цитата
Может быть имеет смысл пока сделать так:
Add(MultiElementEx,484487,280,119)
{
}
BEGIN_SDK
Add(EditMultiEx,14847170,3,3)
{
EventCount=#11:onEventData|
DataCount=#4:Self|
Width=293
Height=130
}
Add(DoData,1259221,112,70)
{
link(onEventData,14847170:onEventData,[(213,76)(213,9)])
link(Data,14847170:Self,[(118,18)(9,18)])
}
END_SDK
где Self - зарезервированная точка и хранит указатель та текущую схему. Далее, если по onEvent необходимо знать откуда именно был вызван метод просто передаем Self наружу. Примерно тоже самое, что предложил до этого... Менее удобно конечно, но зато более безопаснее.
карма: 27
0
Ответов: 9906
Рейтинг: 351
#9: 2006-10-05 00:48:28 ЛС | профиль | цитата
О какой опасности мы говорим

Вот о такой: code_375
И сколько бы трудов мы не потратили на возможность параллельной работы в EditMultiEx - все это пойдет прахом на следующем модуле обработки - он на это не рассчитан.

И мое утверждение заключается в том, что позаботиться о синхронизации этих потоков - забота программиста, взявшегося за параллельное программирование. В данном случае, скажем, выход на улицу подключить через onSyncExec
А наша - дать ему удобный инструмент для синхронизации.

И никакой опасности.
А принимать во внимание опасность разработки некорректного алгоритма - явный перебор
карма: 9

0
файлы: 1code_375.txt [796B] [561]
Администрация
Ответов: 15295
Рейтинг: 1519
#10: 2006-10-05 01:00:20 ЛС | профиль | цитата
А что показывает приведенная схема?
карма: 27
0
Ответов: 9906
Рейтинг: 351
#11: 2006-10-05 01:16:23 ЛС | профиль | цитата
Что значит, что показывает

Вот есть такая задача, которая выполняется десятком параллельных потоков, результаты всех поступают в условный единый центр обработки (мультики содержанием не набиты, естественно)
И именно в аналогичной задаче несинхронные параллельные события могут испортить гипотетический EventHandle.

Утверждение в том, что в тот момент, когда они его попортят (независимо, от того, используем ли мы эту точку) - они еще много чего попортят.
И ставить себе в цель ликвидировать и это "еще много чего" - не следует
Даже если юзеру, занимающемуся параллельным программированием ничего не хочется знать о синхронизации.
Не сможем мы освободить его от этого знания.
А как только он поставит синхронизацию - у нас EventHandle тоже будет корректно работать...


Не знаю уж, понятно ли ....
карма: 9

0
Администрация
Ответов: 15295
Рейтинг: 1519
#12: 2006-10-05 03:16:34 ЛС | профиль | цитата
Galkov, то, что сейчас что-то некорректно может работать(кстате что?) не дает право продолжать писать не верно работающие конструкции. История показывает, что спорные моменты удается легко и просто обойти с развитием и усложнением внутреннего устройства hiasm. Скажем, при написание компонент вкладки Графика, у которых есть точки типа Point1 и Point2 прекрасно понимал, что принимать данные в формате X + Y*65536 это совершенно не правильно, но городить по четыре точки на одни только координаты тоже вариант не самый лучший. Причем очевидно, что первый способ работает только при условие X и Y < 65536... Зато делались бы они сейчас эту проблему с легкостью можно бы было решить с использованием MT.
Проблема с handle схем абсолютно аналогична и сегодня можно решить либо двумя выше описанными способами, причем первый при некоторых условиях может не верно работать, а второй(с точкой self) работает верно всегда, но сильно проигрывает в удобстве его использования.
карма: 27
0
Ответов: 2125
Рейтинг: 159
#13: 2006-10-05 10:32:47 ЛС | профиль | цитата
Self - зарезервированная точка и хранит указатель та текущую схему
И SelfIndex ещё. Ещё безопаснее, вроде бы.
карма: 1

0
Администрация
Ответов: 15295
Рейтинг: 1519
#14: 2006-10-05 15:19:34 ЛС | профиль | цитата
Видимо так и стоит сделать.
карма: 27
0
Ответов: 9906
Рейтинг: 351
#15: 2006-10-05 16:25:30 ЛС | профиль | цитата
Ерунда все это - шерстить кодогенератор из-за простейшего и беспроблемного вопроса.
Верный признак неправильной локализации задачи
карма: 9

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