Пожалуйста, включите JavaScript для просмотра этого сайта.

Скрипты Simple-Scada

История: Редактор скриптов

Изменения в компиляторе

Пред. Вверх След. Еще

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

Изменение 1. Локальные переменные скриптов теперь локальные в полном смысле, т.е. память для них выделяется динамически при каждом выполнении скрипта. А значит, они могут иметь произвольное значение в момент старта скрипта. Поэтому локальные переменные нужно обязательно инициализировать перед использованием. Например:

var
  a: integer;  // локальная переменная "a"
begin
  { можно предположить, что в коде ниже переменная "a" увеличится на 1 и станет равна 1.
    Это не так. Являясь локальной, она изначально может иметь любое значение в пределах
    integer и поэтому нельзя предугадать чему она будет равна после прибавления единицы }
  a := a + 1;
end.

 

Правильный вариант скрипта:

var
  a: integer;  // локальная переменная "a"
begin
  a := 0;      // перед использованием инициализируем локальную переменную "a" нулём
  a := a + 1;  // здесь "a" станет равна 1
end.

 

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

begin
  { здесь переменная vrCounter будет корректно увеличиваться на 1 при каждом 
    выполнении скрипта, ведь она глобальная и ее значение сохраняется при 
    каждом выполнении скрипта }
  vrCounter.Value := vrCounter.Value + 1;  
end.

 

Изменение 2. Компиляция блоков case..of со строками и boolean-значениями теперь недоступна. На это есть веские причины, связанные с особенностями работы case..of со строками и с потенциальными утечками памяти в строках при использовании case..of. Поэтому, все конструкции case..of, которые работают со строками или boolean-значениями должны быть заменены на конструкцию if..then..else, примеры ниже:

Пример 1. Было:

begin
  case myVar.AsStr of
    'start': Text1.Color := clGreen;
    'stop': Text1.Color := clRed;
    'pause': Text1.Color := clYellow;
  end;
end.

стало:

var
  aValue: string;
begin
  aValue := myVar.AsStr;
  if (aValue = 'start'then Text1.Text:= clGreen else
  if (aValue = 'stop'then Text1.Text:= clRed else
  if (aValue = 'pause'then Text1.Text:= clYellow;
end.

 

Пример 2. Было:

begin
  case myBool of
    false: myVal := 1;
     true: myVal := 2;
  end;
end;

стало:

begin
  if myBool then
    myVal := 2
  else
    myVal := 1;
end;