Именованные "анонимные функции":
.filter> Named: n1 ( bla )
.filter> Named: n2 global
Их имя нужно только для отладки и диагностики.
Это можно применять для "именования" post- и pred-условий:
Pre:
( x = 1 ?assure 'bla' )
Named: n1 ( y = 2 ?assure 'bla' )
;
Post:
( z = 1 ?assure 'bla' )
Named: n1 ( i = 2 ?assure 'bla' )
;
Или:
Pre:
( x = 1 ?assure 'bla' )
Условие: n1 ( y1 = 2 ?assure 'bla' )
Условие: n2 ( y2 = 2 ?assure 'bla' )
global1
global2
Условие: n3 ( y3 = 2 ?assure 'bla' )
( x1 = 10 ?assure 'bla' )
;
Или:
До:
( x = 1 ?верно 'bla' )
Условие: n1 ( y1 = 2 ?верно 'bla' )
Условие: n2 ( y2 = 2 ?верно 'bla' )
global1
global2
Условие: n3 ( y3 = 2 ?верно 'bla' )
( x1 = 10 ?верно 'bla' )
;
Или:
Предусловия:
( должно: ( x = 1 ) 'bla' )
Условие: n1 ( должно: ( y1 = 2 ) 'bla' )
Условие: n2 ( должно: ( y2 = 2 ) 'bla' )
"Глобальное условие 1"
"Глобальное условие 2"
Условие: n3 ( должно: ( y3 = 2 ) 'bla' )
( должно: ( x1 = 10 ) 'bla' )
;
До:
"Очищать тестовую базу" // - это ДО
"Очищать таблицу стилей"
"Открыть документ" "Конституция"
;
Параметры:
"Выливать в RTF"
"Восстанавливать позицию мыши"
;
Тест:
"Выделить документ"
"Заменить" 'а' на 'б'
;
Постусловия:
"Drag&Drop завершён"
;
После:
"Закрывать все окна"
"Очищать тестовую базу" // - это ПОСЛЕ
;
В таком порядке и вызывается:
Предусловия, До, Параметры, Тест, Постусловия, После.
Все секции - опциональны.
Для этого сделать TtfwNamedBeginLike с соответствующим конструктором.
И звать его из Named:, который определить на стороне скриптов.
Не забыть про трансляцию resultType и paramTypes, а также innerDictionary etc.
И прочей инфраструктуры для работы с компилированными словами.
Сделать ещё конструкции:
"В диалоге" "Номер 2 или больше" "Удаление конституции" отвечать Всегда
"В диалоге" "Удаление конституции" отвечать Нет
"В диалоге" "Удаление документа" отвечать Да
"В диалоге" "Поиск/замена" выполнять "Выбор метки"
"Для диалога" "Выход из приложения" "Проверять его отсутствие"
"В диалоге" "Любом другом" отвечать Нет
После слова "В диалоге" предполагаются на самом деле две лямбды:
1. Comparator. Туда передаётся DialogInfo, а возвращается Boolean.
2. Executor.
Comparator и Executor - самом деле могут связываться в цепочки, как в примере про диалог #2.
Предикатов на самом деле просто складываются в список и последовательно выполняются для каждого диалога.
По аналогии с RULES.
Никакого "волшебства".
Это некоторым образом похоже на "предикаты" и "машину вывода" Prolog'а.
Порядок предикатов - влияет на порядок вычисления предикатов.
Это вместо wait:XXX/waited?
Т.е. делаем "декларативность", а не "императивность".
Мы НЕ ОЖИДАЕМ, диалога, а говорим, что надо делать, если он появился.
Ну и старый "добрый" (на самом деле - бардачный) механизм пока оставляем. Для обратной совместимости.
Возможно для наглядности стоит ещё ввести секцию Диалоги: перед секцией Тест:.
Ещё надо сделать конструкцию:
"Локальные диалоги":
(
Предикат1
Предикат2
Предикат3
...
ПредикатN
)
( код )
предикатов для диалогов действительны ТОЛЬКО для указанного локального кода.
Там две лямбды:
1. Регистрация обработчиков диалогов.
2. Код, приводящие к диалогу.
Ели один из ожидаемых дипломов не показан, то надо поднимать исключение - 'неожиданный диалог'.
Для совместимости со старым кодом.
Собственно с этого и надо начать.
Это больше похоже на текущий механизм.
И это похоже на механизм TF aVar (). Тоже лямбда, обёрнутая в try..finally.
Ещё надо сделать:
PredicatExecutor.
LambdaExecutor.
Etc.
Для удобства работы со словами на стороне Delphi.
В итоге - убрать wait, waited, answer, modal, etc.
А всё свести к modalService и dialogStack.
И написать что-то вроде:
Function modalService.Execute (aForm): TModalResult;
Result := mrCancel;
if dialogStack.Execute(aForm, Result) then
Exit
else
if TBatchService.IsBatchMode then
raise EBatchMode.Create('нельзя показывать модальный диалог в пакетном режиме')
else
Result := aForm.ShowModal;
Слова wait:XXX временно перенести на сторону скриптов, вывести их через wait:Button. А потом их вообще убить.
Потом переделать всё это на Thread. И убрать hackedVCL/needCancelModal.
А потом подобным образом отрефакторить menu.Popup.
Ещё сделать глобальную функцию/примесь для переделки ShowModal и copyPaste "от Димы".
Переделать регистрацию констант mrXXX на RTTI. Ну как TColor и TCursor.
Вообще подумать о регистрации ВСЕХ констант, через RTTI и RegisterIdent.
http://docwiki.embarcadero.com/RADStudio/Seattle/en/Colors_in_the_VCL