2012-04-05 8 views
0

У нас есть довольно большое приложение USSD, которое использует модуль gen_fsm от Erlang для управления параметрами меню.Изменение состояния gen_fsm на функцию в другом модуле

В текущей версии есть один файл menus_fsm.erl, содержащий более 5000 строк кода gen_fsm. Наша следующая версия дает нам возможность разделить menus_fsm.erl на отдельные файлы, чтобы сделать его более удобным для обслуживания в будущем.

В старой версии, чтобы отобразить меню помощи мы сделать следующее (help_menu/1 вызывается из кода не показано, что отображает главное меню):

-module(menus_fsm).  
% Snipped some irrelvant code 

help_menu(StateData) -> 
    % Display the first menu 
    send_menu(StateData, "Please Select:\n1. Option 1\n2. Option 2"), 
    {next_state, waitHelpMenuChoice, StateData, ?MENU_TOUT}; 

waitHelpMenuChoice(Params, StateData) -> 
    io:format("Got Help menu response: ~p", [Params]), 
    doTerminate(ok,"Help Menu", StateData). 

Я оставил вне много кода, показывает точку входа в FSM и т. д.

В новой версии, мы хотим двигаться help_menu/1 и waitHelpMenuChoice/2 нового модуля help_menu, который вызывается из menus_fsm, например, так:

-module(help_menu).  
% Snipped some irrelevant code 

help_menu(StateData) -> 
    menus_fsm:send_menu(StateData, "Please Select:\n1. Option 1\n2. Option 2"), 
    {next_state, waitHelpMenuChoice, StateData, ?MENU_TOUT}; 

waitHelpMenuChoice(Params, StateData) -> 
    io:format("Got Help menu response: ~p", [Params]), 
    menus_fsm:doTerminate(ok,"Help Menu", StateData). 

Проблемы с линией {next_state, waitHelpMenuChoice, StateData, ?MENU_TOUT};: gen_fsm ожидает waitHelpMenuChoice будет в модуле menus_fsm, который вернет меня туда, где мы начали.

Я пытался заменить проблемную линию

{next_state, fun help_menu:waitHelpMenuChoice/2, StateData, ?MENU_TOUT}; 

, но это просто Leas ошибки вроде следующего: {badarg,[{erlang,apply,[conv_fsm,#Fun<help_menu.waitHelpMenuChoice.2>,[]]}

Кто-нибудь есть какие-либо предложения о том, как обойти это?

ответ

0

Возможно, вы можете использовать http://www.erlang.org/doc/man/gen_fsm.html#enter_loop-6, чтобы сделать это? Не уверен, что это будет работать, чтобы вызвать его внутри другого fsm, но, возможно, стоит попробовать.

0

Мне удалось найти решение моего собственного вопроса. Если это кажется очевидным, это может быть потому, что я немного новичок в Erlang.

Я добавил новую функцию wait_for_menu_response/2 в модуль menus_fsm, который обрабатывает переходы состояний от имени других модулей.

-module(menus_fsm), 
-export([wait_for_menu_response/2]). 
% ...snip... 
wait_for_menu_response(Params, {Function, StateData}) -> 
    Function(Params, StateData). 

Затем help_menu модуль был изменен следующим образом:

-module(help_menu).  
% ...snip... 

help_menu(StateData) -> 
    menus_fsm:send_menu(StateData, "Please Select:\n1. Option 1\n2. Option 2"), 
    {next_state, wait_for_menu_response, {fun waitHelpMenuChoice/2, StateData}, ?MENU_TOUT}. 

waitHelpMenuChoice(Params, StateData) -> 
    io:format("Got Help menu response: ~p", [Params]), 
    menus_fsm:doTerminate(ok,"Help Menu", StateData). 

так gen_fsm остается в пределах menus_fsm модуля, когда он вызывает wait_for_menu_response, но wait_for_menu_response теперь свободно ссылаться на help_menu:waitHelpMenuChoice/2. help_menu:waitHelpMenuChoice/2 не нужно было каким-либо образом изменять.

На самом деле, в моем окончательном варианте функция menus_fsm:send_menu была изменена, чтобы принять fun waitHelpMenuChoice/2 в качестве третьего параметра, так что функция help_menu становится просто:

help_menu(StateData) -> 
    menus_fsm:send_menu(StateData, "Please Select:\n1. Option 1\n2. Option 2", 
     fun waitHelpMenuChoice/2). 

, но я думаю, что мое объяснение выше иллюстрирует идею лучше ,

 Смежные вопросы

  • Нет связанных вопросов^_^