Author Topic: Запрет на досрочный выход  (Read 8742 times)

0 Members and 1 Guest are viewing this topic.

Vint

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

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

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

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

Типа такого:

Code: (clickermann) [Select]
      $fon = 1
      WHILE($fon = 1)
         GETSCREEN
         IF (PXL($lx+60, $ly-137)=6643283)
            $fon = 0              // выходим из цикла fon
         END_IF
         WAITMS(100)
      END_CYC

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

Пример:
Code: (clickermann) [Select]
#name "Рекурсия"

IF($reboot > 0)
   // здесь проводится обработка ошибок если нужно и разная реакция с раздачей слонов
   // перезагружаем страницу/перезапускаем приложение, топаем по метке внутрь скрипта и т.д.
   //...
   $reboot = 0
END_IF

// основная программа

//...
WHILE(условие1)
   WHILE(условие2)
      // и т.д.
       GOSUB(proverka)      //  проводим проверку на зависание/сбой
   END_CYC
END_CYC
//...

//--------------------------------
SUB (proverka)
   IF(условие)
      $reboot = 1
      LOAD("Опыты\Рекурсия.cms")
   END_IF
END_SUB
//--------------------------------


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

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


Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
Re: Запрет на досрочный выход
« Reply #1 on: January 10, 2013, 05:18:36 PM »
RESET я уже предлагал но пока что то не двигается дело.

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


Code: (clickermann) [Select]
start:

GOSUB(sub_name)

print("После суба")

HALT

SUB(sub_name)
print("Я в субе")
WAITMS(100)
GOTO(start)
END_SUB

Vint

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


СлавьЯнИнъ

  • Активный участник
  • ***
  • Posts: 179
    • View Profile
Re: Запрет на досрочный выход
« Reply #3 on: January 11, 2013, 09:57:28 AM »
Винт, привет!

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

HolyKirka

  • Зашел в гости
  • *
  • Posts: 16
    • View Profile
Re: Запрет на досрочный выход
« Reply #4 on: January 11, 2013, 07:09:28 PM »
Всему этому делу сильно бы помогло наличие функций.

ЦИТРИН

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

Code: (clickermann) [Select]
$time29 = $_time_t + 180
wwwar9:
If( $time29 < $_time_t )
   LCLICK(897,178)  // закрыть окно
   waitms(rnd(150,250))
   LCLICK(897,178)  // закрыть окно
   waitms(rnd(2250,2350))
   goto(wwwar12)
end_if
И ещё непонятно , для чего обнулять переменные,  если можно перед  новым блоком настряпать новых и присвоить им нули  через DEFINE ?
Бабочки полёт будит тихую поляну в солнечном свету...

ЦИТРИН

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

HolyKirka

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

Johnny

  • Создатель
  • Герой форума
  • *
  • Posts: 593
    • View Profile
Re: Запрет на досрочный выход
« Reply #8 on: January 13, 2013, 08:19:33 AM »
не можно, а нужно.

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

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