Автор Тема: Запрет на досрочный выход  (Прочитано 4300 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Vint

  • Супермодератор
  • Герой форума
  • *
  • Сообщений: 3845
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • Просмотр профиля
Запрет на досрочный выход
« : Январь 10, 2013, 03:22:59 pm »
Какой есть способ правильно экстренно выбраться из кучи вложенных циклов/подпрограмм  глобально ну хотя бы в «корень» скрипта?

Какие можно придумать способы? Мне пока в голову пришло только рекурсивно вызывать скрипт LOAD("скрипт.cms"). Можно ли так делать? Или это тот же досрочный выход из цикла? Я понимаю, что переменные сохраняются, а вот сбрасывается там стэк или как всё там реализовано не знаю. С программированием не знаком. В далёкие времена, для себя писал программки на ассемблере для Z80. Так там RET как раз был выход из подпрограммы. И выходов могло быть много (привет Оравэну). RET снимала с вершины стэка адрес возврата из подпрограммы. Можно было хитрым макаром, следя за стэком выскочить куда угодно из любого числа подпрограмм или вообще в любое место не нарушая работы.

Чёт я отвлёкся...

Зачем это нужно?  Всегда хочется правильной, если нужно длительной и бесперебойной работы скрипта. Речь сейчас не об ошибках в скрипте (представим, что ошибок нет), а о согласовании работы скрипта и целевого приложения. Для универсальности и исключения влияния нестабильной скорости интернет соединения, параллельно работающих программ и т.д., я если необходимо ожидать реакцию целевого приложения (например игры), в большинстве мест использую цикл ожидания с проверкой пиксела/картинки/суммы и т.п.

Типа такого:

Код: Clickermann
  1.      $fon = 1
  2.      WHILE($fon = 1)
  3.         GETSCREEN
  4.         IF (PXL($lx+60, $ly-137)=6643283)
  5.            $fon = 0              // выходим из цикла fon
  6.         END_IF
  7.         WAITMS(100)
  8.      END_CYC

Так вот, если с целевой программой что-то пошло не так (не отработал клик или вылезло незапланированное окно), то всё из цикла мы уже не вылазим.
Сейчас я конечно использую внутри подобного цикла проверку на время ожидания или количество циклов. Выход правда получается сильно запутанным даже при двух вложениях, а если больше, наступает Амба с растущим числом проверок и перескоков GOTO к концу циклов/подпрограмм. Короче чёрт ногу сломит если делать всё по правильному.
Если можно использовать  LOAD самой себя из под кучи вложенных циклов то это хоть какой-то выход.

Пример:
Код: Clickermann
  1. #name "Рекурсия"
  2.  
  3. IF($reboot > 0)
  4.   // здесь проводится обработка ошибок если нужно и разная реакция с раздачей слонов
  5.   // перезагружаем страницу/перезапускаем приложение, топаем по метке внутрь скрипта и т.д.
  6.   //...
  7.   $reboot = 0
  8. END_IF
  9.  
  10. // основная программа
  11.  
  12. //...
  13. WHILE(условие1)
  14.   WHILE(условие2)
  15.      // и т.д.
  16.       GOSUB(proverka)      //  проводим проверку на зависание/сбой
  17.   END_CYC
  18. END_CYC
  19. //...
  20.  
  21. //--------------------------------
  22. SUB (proverka)
  23.   IF(условие)
  24.      $reboot = 1
  25.      LOAD("Опыты\Рекурсия.cms")
  26.   END_IF
  27. END_SUB
  28. //--------------------------------


Если так нельзя, как можно? Может сделать хотя бы какой нибудь RESET который будет перезапускать скрипт с очисткой переменных и всяких входов в циклы. Короче то же что и стоп/пуск.

Если кого запутал - простите :)


Oraven

  • Супермодератор
  • Герой форума
  • *
  • Сообщений: 3685
  • Котэ
    • Просмотр профиля
Re: Запрет на досрочный выход
« Ответ #1 : Январь 10, 2013, 05:18:36 pm »
RESET я уже предлагал но пока что то не двигается дело.

Как вариант используй выход на начало скрипта по ГОТО. Хоть там и написано что будет ошибка он ошибок не наблюдается.


Код: Clickermann
  1. start:
  2.  
  3. GOSUB(sub_name)
  4.  
  5. print("После суба")
  6.  
  7. HALT
  8.  
  9. SUB(sub_name)
  10. print("Я в субе")
  11. WAITMS(100)
  12. GOTO(start)
  13. END_SUB

Vint

  • Супермодератор
  • Герой форума
  • *
  • Сообщений: 3845
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • Просмотр профиля
Re: Запрет на досрочный выход
« Ответ #2 : Январь 10, 2013, 05:24:52 pm »
Нет, сразу то ничего не наблюдается. Но я думаю есть что-то в виде стэка. И если не выйти из последнего, из преведущего уже не вернуться. Но это в моём применении не важно. Опасаюсь при длительной работе скрипта он может жрать память или пойти вразнос. Хотелось бы конкретики, чем чревато?


СлавьЯнИнъ

  • Активный участник
  • ***
  • Сообщений: 179
    • Просмотр профиля
Re: Запрет на досрочный выход
« Ответ #3 : Январь 11, 2013, 09:57:28 am »
Винт, привет!

Суть вопроса ясна. При любой реакции приложения скрипт должен работать.
Я для этого использую такую схему.
Здача: Н
Этапы выполнения: 1, 2, 3, 4...№, 0.
То есть любая задача по плечу кликеру путём выполнения последовательности простых действий.
Каждый этап выполнения, далее блок, имеет одну и туже структуру. Блок 0 используется для завершения цикла выполнения задачи, т.е. обнуляет переменные и проверяет, чтобы всё закончилось как надо.
Код: Clickermann
  1. SUB ( Block# )
  2. // описание блока
  3. // == // объвление переменных
  4. // == // проверка входящих данных
  5. // == // действия блока
  6. // == // проверка результата действия блока
  7. // == // проверка завершения блока и переход к следующему
  8. end_sub
Структура настолько проста, что кажется всё понятно. Если нет - обсудим.
Следует отметить, что в последней части блока "переход к следующему" происходит в зависимости от результата действий и\или входящих данных. То есть ключ к универсальности скрипта - проверки и гибкая система переходов между блоками(этапами выполнения задачи).
При этом такая структура снимает нужду в использовании GOTO.
« Последнее редактирование: Январь 11, 2013, 09:59:40 am от СлавьЯнИнъ »
добрый смех равняет всех

HolyKirka

  • Зашел в гости
  • *
  • Сообщений: 16
    • Просмотр профиля
Re: Запрет на досрочный выход
« Ответ #4 : Январь 11, 2013, 07:09:28 pm »
Всему этому делу сильно бы помогло наличие функций.

ЦИТРИН

  • Супермодератор
  • Оплот сообщества
  • *
  • Сообщений: 484
  • Марафон опавших листьев, коктейль из дыма и мыслей
    • Просмотр профиля
Re: Запрет на досрочный выход
« Ответ #5 : Январь 13, 2013, 02:20:17 am »
Ну вот простой пример проверки истекшего  времени задержки.
Как тут можно обойтись без goto?

Код: Clickermann
  1. $time29 = $_time_t + 180
  2. wwwar9:
  3. If( $time29 < $_time_t )
  4.   LCLICK(897,178)  // закрыть окно
  5.   waitms(rnd(150,250))
  6.   LCLICK(897,178)  // закрыть окно
  7.   waitms(rnd(2250,2350))
  8.   goto(wwwar12)
  9. end_if
  10.  
И ещё непонятно , для чего обнулять переменные,  если можно перед  новым блоком настряпать новых и присвоить им нули  через DEFINE ?
Бабочки полёт будит тихую поляну в солнечном свету...

ЦИТРИН

  • Супермодератор
  • Оплот сообщества
  • *
  • Сообщений: 484
  • Марафон опавших листьев, коктейль из дыма и мыслей
    • Просмотр профиля
Re: Запрет на досрочный выход
« Ответ #6 : Январь 13, 2013, 02:26:59 am »
используй выход на начало скрипта по ГОТО. Хоть там и написано что будет ошибка он ошибок не наблюдается.
В этом случае таки идут ошибки , но как-то странновато.
 То есть, то нет.
 Помогает иногда сохранить скрипт, выйти из программы  и снова его запустить.
А на лету по "применить" часто  не пашет.
Бабочки полёт будит тихую поляну в солнечном свету...

HolyKirka

  • Зашел в гости
  • *
  • Сообщений: 16
    • Просмотр профиля
Re: Запрет на досрочный выход
« Ответ #7 : Январь 13, 2013, 03:15:38 am »
2 ЦИТРИН
Не совсем понятен приведенный Вами код - что то с метками там...  А еще можно цикл WHILE попробовать использовать, можно добавлять переменные для указания статуса... Вариантов много. На самом деле все зависит от конкретной задачи. Можно делать и без ГОТО :)

Johnny

  • Создатель
  • Герой форума
  • *
  • Сообщений: 593
    • Просмотр профиля
Re: Запрет на досрочный выход
« Ответ #8 : Январь 13, 2013, 08:19:33 am »
не можно, а нужно.

Нет, сразу то ничего не наблюдается. Но я думаю есть что-то в виде стэка. И если не выйти из последнего, из преведущего уже не вернуться.
this. если выпрыгивать через goto из цикла или саба то в стэке будут накапливаться точки возврата, которые в нормальном режиме работы удаляются из стэка при завершении цикла\саба. помимо неминуемой утечки памяти, в ряде случаев это приведет к сбоям в логике

самый оптимальный вариант для цикла - выход через флаг