Модуль FsmManager
Модуль FsmManager является библиотечным добавлением к программному интерфейсу Конечных Автоматов
- т.е. к функциям FSM API.
Модуль FsmManager (Менеджер Конечных Автоматов) содержит:
константы (_con_FsmManager.inc),
переменные (_var_FsmManager.inc) и
функции (_fun_FsmManager.inc)
для работы с конечными автоматами (FSM = FiniteStateMachine).
FsmManager разработан в первую очередь для создания управляющих программ на основе Конечных Автоматов
в рамках технологии SMI,
но может использоваться и без этой технологии (автономно).
Подключение:
Использование библиотеки FsmManager предполагает использование следующего шаблона программы
(код подключения выделен жирным шрифтом):
program Demo; { How to use FsmManager }
const
{------------------------------}{ Declare uses program constants: }
{$I _con_StdLibrary} { Include all Standard constants, }
{------------------------------}{ And add User defined constants: }
{$I _con_FsmManager} { FsmManager constants }
// User code - constants...
var
{------------------------------}{ Declare uses program variables: }
{$I _var_StdLibrary} { Include all Standard variables, }
{------------------------------}{ And add User defined variables: }
{$I _var_FsmManager} { FsmManager variables }
// User code - variables...
{------------------------------}{ Declare procedures & functions: }
{$I _fun_StdLibrary} { Include all Standard functions, }
{------------------------------}{ And add User defined functions: }
{$I _fun_FsmManager} { FsmManager functions }
// User code - functions...
{
Clear user application strings...
}
procedure ClearApplication;
begin
ClearFsmManager;
// User code - clear...
end;
{
User application Initialization...
}
procedure InitApplication;
begin
InitFsmManager;
// User code - init...
end;
{
User application Finalization...
}
procedure FreeApplication;
begin
FreeFsmManager;
// User code - free...
end;
{
User application Polling...
}
procedure PollApplication;
begin
PollFsmManager;
// User code - poll...
end;
{
Process data coming from standard input...
}
procedure StdIn_Processor(var Data:String);
var cmd,arg:String; n:Integer;
begin
ViewImp('CON: '+Data);
{
Handle "@cmd=arg" or "@cmd arg" commands:
}
cmd:='';
arg:='';
if GotCommand(Data,cmd,arg) then begin
// User code - handle stdin...
{
Handle other commands by default handler...
}
StdIn_DefaultHandler(Data,cmd,arg);
end;
Data:='';
cmd:='';
arg:='';
end;
{***************************************************}
{***************************************************}
{*** ***}
{*** MMM MMM AAA IIII NNN NN ***}
{*** MMMM MMMM AAAA II NNNN NN ***}
{*** MM MMMM MM AA AA II NN NN NN ***}
{*** MM MM MM AA AA II NN NN NN ***}
{*** MM MM AAAAAAA II NN NNNN ***}
{*** MM MM AA AA IIII NN NNN ***}
{*** ***}
{***************************************************}
{$I _std_main}{*** Please never change this code ***}
{***************************************************}
Константы:
см. файл _con_FsmManager.inc
Переменные:
см. файл _var_FsmManager.inc
Функции:
см. файл _fun_FsmManager.inc
Функции API условно делятся на прикладные (которые бывают нужны для создания прикладных программ)
и служебные (которые предназначены в основном для внутреннего использования и обычно не вызываются явно).
Некоторые служебные функции вызывать напрямую запрещено, иначе это нарушит логику работы программы.
Напротив, некоторые прикладные функции являются основными,
то есть обычно должны присутствовать в прикладной программе.
function fsm_init(arg:String):Integer;
Функция создает экземпляр менеджера Конечных Автоматов - FSM (Finite State Machine manager)
с начальными параметрами, заданными списком аргументов arg, состоящим из слов, разделенных пробелами.
Функция возвращает ссылку (reference) на созданный менеджер FSM
и используется для создания экземпляров FSM в прикладных программах.
При вызове fsm_init(arg) параметр arg содержит разделенные пробелами опции
в форме -option value или -option=value.
Опции могут принимать следующие значения:
-dns node - задает имя (node) компьютера для сервера имен (DNS) в сети DIM
это имя может быть использовано для взаимодействия с DIM сервером
-dom domain - задает имя домена (domain), который надо создать в Менеджере FSM
имя домена должно удовлетворять обычным требованиям для имен (см. fsm_is_valid_name)
-sml smlfile - задает имя файла (smlfile) на языке SML, который надо загрузить в этом домене
имя файла задается относительно каталога основного файла конфигурации (обычно ..\Config)
-verbose n - задает режим (n) печати fsm_verbose_mode, n=(0/1)=(кратко/подробно)
значение по умолчанию (1) задается также в переменной конфигурации fsm_verbose_mode
-listing n - задает режим (n) вывода в отладочный файл fsm_listing_mode, n=(0/1)=(не/создавать файл *.lst)
значение по умолчанию (1) задается также в переменной конфигурации fsm_listing_mode
-name id - задает имя (id) для создаваемого менеджера FSM
При задании аргументов они обрабатываются последовательно (слева направо),
поэтому домен (-dom) надо задавать перед заданием файла (-sml).
При этом возможно последовательное задание и чтение нескольких доменов.
Например:
fsm:=fsm_init('-name FsmTest -dns localhost -dom DEMO -sml demo.sml -dom TEST -sml test.sml');
-name FsmTest - задает имя для Менеджера FSM
-dns localhost - задает DIM DNS равным localhost
-dom DEMO - создает в Менеджере домен DEMO
-sml demo.sml - загружает в домен DEMO файл demo.sml на языке SML
-dom TEST - создает в Менеджере домен TEST
-sml test.sml - загружает в домен TEST файл test.sml на языке SML
Примечание:
Прикладная программа несет всю ответственность за созданные экземпляры FSM.
Все созданные прикладной программой FSM-ссылки (fsm) должны быть очищены в конце работы программы
(например, в процедуре FreeApplication) вызовом fsm_kill(fsm).
procedure fsm_kill(var fsm:Integer);
Процедура удаляет экземпляр менеджера Конечных Автоматов - FSM (Finite State Machine)
со ссылкой fsm и очищает (обнуляет) ссылку.
Все созданные прикладной программой FSM-ссылки (fsm) должны быть очищены в конце работы программы
(например, в процедуре FreeApplication) вызовом fsm_kill(fsm).
При выполнении процедура fsm_kill(fsm) вызывает fsm_free(fsm), а затем обнуляет ссылку fsm.
procedure procedure fsm_trouble(errno:Integer; msg:String);
Сервисная процедура, которая фиксирует ошибку в работе менеджера Конечных Автоматов (FSM) с номером (errno)
и выводит сообщение (msg), если установлено значение fsm_verbose_mode.
function fsm_is_valid_name(name:String; typ:Integer):Boolean;
Проверяет, является ли строка (name) допустимым именем (идентификатором) для элементов с типом (typ) (fsm_type_domain,object,state,action,parameter).
Имя (domain,parameter,class,objectset,function) допустимо, если оно содержит символы [a-zA-Z_0-9] и начинается с символов [a-zA-Z_].
Это соответствует шаблону регулярного выражения /[a-zA-Z_]+[a-zA-Z_0-9]*/i.
В именах элементов (object,state,action) также допустимо использовать символы [&:.-].
Имена (идентификаторы) являются не чувствительными к регистру.
function fsm_is_valid_host(name:String):Boolean;
Проверяет, является ли строка (name) допустимым именем сервера (hostname) согласно стандартам (RFC 952, RFC 1123).
Имя сервера допустимо, если оно содержит символы [a-z\-\.0-9] и начинается с символов [a-z0-9].
Длина имени не должна превышать 253 символа. Имена серверов являются не чувствительными к регистру.
Функция, используя путь (path) вида DOMAIN::OBJECT/STATE/ACTION#PARAMETER, извлекает (extract) имя (name) элемента заданного типа,
например:
name:=fsm_extract_name('EGP::UPS/OFF/SWITCH_ON#VOLTAGE',fsm_type_domain); // домен EGP
name:=fsm_extract_name('EGP::UPS/OFF/SWITCH_ON#VOLTAGE',fsm_type_object); // объект UPS
name:=fsm_extract_name('EGP::UPS/OFF/SWITCH_ON#VOLTAGE',fsm_type_state); // состояние OFF
name:=fsm_extract_name('EGP::UPS/OFF/SWITCH_ON#VOLTAGE',fsm_type_action); // действие SWITCH_ON
name:=fsm_extract_name('EGP::UPS/OFF/SWITCH_ON#VOLTAGE',fsm_type_parameter); // параметр VOLTAGE
При отсутствии заданного компонента имени или неверном имени возвращается пустая строка.
function fsm_dump(fsm:Integer; mode:Integer; filter:String):String;
Отладочная функция, которая возвращает краткое содержимое Менеджера FSM:
в виде ключа Path (при mode=0) или в виде ключа со значением Path => Declaration (при mode=1) для каждого элемента FSM.
Параметр фильтра (filter) задает список слов, которые надо включать или ^пропускать при выводе.
Функция используется для отладочного вывода при разработке прикладного кода.
Команда @smiuisrv_fsm_dump mode filter позволяет вызывать функцию в консоли
(при использовании модуля SmiuiSrv).
Например:
@smiuisrv_fsm_dump - вывод списка всех ключей
@smiuisrv_fsm_dump 1 demo::run - вывод (подробный) ключей, содержащих DEMO::RUN
@smiuisrv_fsm_dump 1 demo::run ^class - вывод (подробный) ключей, содержащих DEMO::RUN и не содержащих CLASS
procedure fsm_add_iparam(ref:Integer; name:String; data:Integer);
procedure fsm_add_fparam(ref:Integer; name:String; data:Real);
procedure fsm_add_sparam(ref:Integer; name:String; data:String);
procedure fsm_put_iparam(ref:Integer; name:String; data:Integer);
procedure fsm_put_fparam(ref:Integer; name:String; data:Real);
procedure fsm_put_sparam(ref:Integer; name:String; data:String);
function fsm_ask_iparam(ref:Integer; name:String):Integer;
function fsm_ask_fparam(ref:Integer; name:String):Real;
function fsm_ask_sparam(ref:Integer; name:String):String;
Процедуры и функции для добавления (add), записи (put) и запроса (ask) значения параметров разного типа (int,float,string)
с именем (name) в контейнерном элементе (ref).
Базовые функции чтения/записи (get/set) FSM API
используют для обращения к параметрам ссылки, а не имена, что не всегда бывает удобно.
Эти процедуры позволяют использовать параметры удобной для программирования форме.
Например:
obj:=fsm_find(fsm,'DEMO::LOGGER'); // Найти ссылку объекта DEMO::LOGGER
fsm_add_iparam(obj,'RUN_NUMBER',123); // Задать параметр int RUN_NUMBER = 123
run:=fsm_ask_iparam(obj,'RUN_NUMBER'); // Прочитать параметр RUN_NUMBER
Следует иметь в виду, что функции доступа к параметрам по имени (ask/add/put) работают несколько медленнее,
чем функции доступа к параметрам по ссылке (get/set).
При необходимости высокоскоростной обработки предпочтение надо отдавать работе по ссылкам.
Кроме того, функции (ask/add/put) регистрируют счетчик ошибки при неверном доступе
(несуществующий параметр или неверный тип).
function fsm_get_cookies(ref:Integer):String;
function fsm_get_cookie(ref:Integer; name:String):String;
procedure fsm_set_cookie(ref:Integer; name,value:String);
Функции чтения/записи дополнительных данных (cookie) с именем (name) и значением (value) для контейнерного элемента со ссылкой (ref).
Дополнительные данные (Куки) отличаются от регулярных параметров (parameter).
Во-первых, Куки - это всегда строковые данные (параметры бывают разных типов).
Во-вторых, доступ к Кукам намного "дороже" по времени, т.к. они хранятся в одной длинной строке (fsm_ctrl(ref,'cookie'))
в виде списка строк (name=value), разделенных EOL.
Поэтому в Куках хранятся данные, которые используются эпизодически, а не постоянно (в цикле опроса).
Также надо иметь в виду, что в Куках нельзя гранить строки, содержащие разделитель EOL,
т.к. он уже используется для разделения записей Куки.
В файлах SML куки сохраняются в виде строк вида !name: value,
то есть в комментариях SML (за исключением специальных опций !color:, !visible:,
которые обрабатываются особым образом).
procedure fsm_insert_in(ref:Integer; id:String);
procedure fsm_remove_from(ref:Integer; id:String);
procedure fsm_remove_all_from(ref:Integer);
- процедуры вставки(insert)/удаления(remove) объекта или набора объектов с именем (id), в набор объектов со ссылкой (ref).
Вставка набора объектов (objectset) возможна, если набор имеет атрибут union,
в противном случае предполагается вставка объектов (object).
Процедура fsm_remove_all_from(ref) удаляет все объекты из набора,
т.е. очищает его, в результате чего получается пустой набор {}.
function fsm_is_includes(ref:Integer; id:String):Boolean;
- функция проверяет, входит ли объект с именем (id) в набор объектов со ссылкой (ref).
function fsm_validate_dns(ref:Integer; dns:String):String;
Вспомогательная функция, которая корректирует (validate) имя сервера имен (dns).
При этом в качестве имени (dns) можно использовать псевдонимы:
пустая строка (dns='') задает значение по умолчанию (подставляется hostname),
а точка (dns='.') задает полное имя локального компьютера (computername).
function fsm_readback_sml(ref:Integer):String;
Отладочная функция, которая возвращает содержимое Менеджера FSM в виде текста SML.
Функция используется для отладочного вывода при разработке прикладного кода.
function fsm_parse_sml(fsm,txt:Integer; domain:String):Integer;
Функция разбора (parse) текста (txt) формата языка SML, в домене (domain) менеджера (fsm).
Функция возвращает счетчик ошибок разбора или ноль при успешном разборе текста.
В результате разбора содержимого теста создает в домене (domain) элементы и структуры данных, описанные в тексте SML.
Обычно функция вызывается не явно, а косвенно, при вызовах fsm_init или fsm_read_sml.
function fsm_read_sml(fsm:Integer; domain,sml:String):Integer;
Функция чтения (read) файла с именем (sml) в формате языка SML, в (существующем) домене (domain) менеджера (fsm).
Функция возвращает счетчик ошибок чтения и разбора или ноль при успешном чтении и разборе текста.
В результате разбора содержимого файла создает в домене (domain) элементы и структуры данных, описанные в файле SML.
Обычно функция вызывается не явно, а косвенно, при вызове fsm_init.
procedure ClearFsmManager;
procedure InitFsmManager;
procedure FreeFsmManager;
procedure PollFsmManager;
Стандартные процедуры очистки/инициализации/завершения/опроса модуля FsmManager.
Они должны вызываться так, как показано в шаблоне.
Желаю успешного использования FsmManager!