⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 《深入brew开发》——第八章 brew的事件处理 - gemsea的专栏 - csdnblog.htm

📁 《深入BREW开发》——第七章 创建新的BREW应用程序
💻 HTM
📖 第 1 页 / 共 5 页
字号:
      <DIV align=center>图8.6 状态机基本原理</DIV>
      <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      </SPAN>状态机在代码上讲就是一个for(;;)循环,只有在创建一个用户界面之后才会暂时终止运行,可以实现这样功能的代码如下(可以在本书所附的示例代码Test5/FileExplorer应用目录下的AppStateMachine.c中找到这个函数):</DIV>
      <TABLE 
      style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse" 
      cellSpacing=0 cellPadding=0 border=1>
        <TBODY>
        <TR>
          <TD 
          style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 426.1pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid" 
          vAlign=top width=568>
            <DIV>/*====================================================================</DIV>
            <DIV>函数<SPAN>&nbsp;&nbsp;&nbsp; : CStateMachine_RunFSM</SPAN></DIV>
            <DIV>说明<SPAN>&nbsp;&nbsp;&nbsp; : </SPAN>有限状态机引擎。</DIV>
            <DIV>参数<SPAN>&nbsp;&nbsp;&nbsp; : pMe 
            [in]</SPAN>:指向CStateMachine对象结构的指针</DIV>
            <DIV>返回值&nbsp;: 无。</DIV>
            <DIV>备注<SPAN>&nbsp;&nbsp;&nbsp; : </SPAN>无</DIV>
            <DIV>====================================================================*/</DIV>
            <DIV>static void CStateMachine_RunFSM(CStateMachine *pMe)</DIV>
            <DIV>{</DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp; NextFSMAction nextFSMAction = 
            NFSMACTION_WAIT;</SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp; </SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp; for(;;)</SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp; {</SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nextFSMAction 
            = pMe-&gt;m_pfnState((IStateMachine *)pMe, </SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            pMe-&gt;m_pUserState);</SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            pMe-&gt;m_eWndRet&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 
            WNDRET_CREATE;</SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
            pMe-&gt;m_wWndParam&nbsp;&nbsp;&nbsp; = 0;</SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
            pMe-&gt;m_dwWndParam&nbsp;&nbsp; = 0;</SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
            </SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if 
            (nextFSMAction == NFSMACTION_WAIT)</SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            break;</SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp; }</SPAN></DIV>
            <DIV>} // End CStateMachine_RunFSM</DIV></TD></TR></TBODY></TABLE>
      <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      pMe-&gt;m_pfnState</SPAN>就是我们在应用程序中的状态函数,状态机根据这个函数的返回值nextFSMAction来判断是否暂停状态机的运行。从代码中可以看到当nextFSMAction为NFSMACTION_WAIT的时候这个for循环将被break语句打破。</DIV>
      <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      </SPAN>我们定义的状态机结构体如下所示(下面的代码综合了AppStateMachine.h和.c的内容):</DIV>
      <TABLE 
      style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse" 
      cellSpacing=0 cellPadding=0 border=1>
        <TBODY>
        <TR>
          <TD 
          style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 426.1pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid" 
          vAlign=top width=568>
            <DIV>// 状态处理函数返回给状态处理主函数的值类型</DIV>
            <DIV>typedef enum _NextFSMAction{</DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp; NFSMACTION_WAIT,</SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp; NFSMACTION_CONTINUE</SPAN></DIV>
            <DIV>} NextFSMAction;</DIV>
            <DIV>&nbsp;</DIV>
            <DIV>typedef NextFSMAction (*PFNSTATE)(IStateMachine *po, void 
            *pUser);</DIV>
            <DIV>&nbsp;</DIV>
            <DIV>typedef struct _CStateMachine{</DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp; AEEVTBL(IStateMachine) 
            *pvt;</SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp; 
            uint32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            m_nRefs;</SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp; </SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp; // IShell interface</SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp; 
            IShell&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            *m_pShell;</SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp; </SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp; &nbsp;PFNSTATE&nbsp;&nbsp;&nbsp;&nbsp; 
            m_pfnState;&nbsp;&nbsp;&nbsp;&nbsp; // </SPAN>状态处理函数</DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp; void 
            *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            m_pUserState;&nbsp;&nbsp; // </SPAN>用户数据</DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp; PFNAEEEVENT 
            m_pfnEvent;&nbsp;&nbsp;&nbsp;&nbsp; // </SPAN>事件处理函数</DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp; void 
            *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            m_pUserEvent;&nbsp;&nbsp; // </SPAN>用户数据</DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            m_eWndRet;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Windows</SPAN>返回值</DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            uint16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            m_wWndParam;&nbsp;&nbsp;&nbsp; // Windows</SPAN>返回值word参数</DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            uint32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            m_dwWndParam;&nbsp;&nbsp; // Windows</SPAN>返回值dword参数</DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AEECLSID 
            &nbsp;&nbsp;&nbsp;&nbsp;m_dwAppClsID;&nbsp;&nbsp; // 
            </SPAN>当前使用此接口的应用程序Class ID</DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            boolean&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            m_bSuspending;&nbsp;// </SPAN>当前状态机是否被挂起</DIV>
            <DIV>}CStateMachine;</DIV></TD></TR></TBODY></TABLE>
      <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      </SPAN>应用程序中将通过一个指针变量来保存一个这样的结构体。我们将创建的用户界面叫做一个Window。状态机使用m_pfnState来获得状态,使用m_pfnEvent来处理用户Window的事件,在m_pfnState状态函数执行的时候创建Window。</DIV>
      <DIV><STRONG><FONT 
      size=3><SPAN>8.2.3</SPAN><SPAN>实现状态机</SPAN>管理的接口</FONT></STRONG></DIV>
      <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      </SPAN>为了能够管理状态机,我们必须提供一些管理状态机的接口:</DIV>
      <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      1</SPAN>、启动状态机,通过这个接口应用程序可以选择在何时启动这个状态机。</DIV>
      <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      2</SPAN>、终止状态机,通过这个接口应用程序可以选择在何时终止状态机的运行。</DIV>
      <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      3</SPAN>、挂起状态机,通过这个接口应用程序可以暂停状态机的运行,同时保存相关的状态数据,以便于恢复状态机的运行。</DIV>
      <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      4</SPAN>、恢复状态机,通过这个接口应用程序可以恢复一个被挂起的状态机继续运行。</DIV>
      <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      5</SPAN>、转移状态,通过这个接口应用程序可以转移到下一个状态去处理。</DIV>
      <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      6</SPAN>、创建一个窗口(Window),通过这个接口应用程序可以创建一个显示界面。</DIV>
      <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      7</SPAN>、关闭一个窗口(Window),通过这个接口应用程序可以关闭一个显示界面,同时设置相应的Window返回值给状态处理函数。</DIV>
      <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      8</SPAN>、Window事件捕获函数,应用程序将通过这个接口将事件传递给Window的事件捕获函数。</DIV>
      <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      9</SPAN>、辅助函数,如获得当前的状态,以及获得当前窗口的返回值等操作。</DIV>
      <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      </SPAN>与上面描述功能基本相近的各个函数已经定义在了FileExplorer应用程序中的AppStateMachine.c的文件中。他们的形式如下:</DIV>
      <TABLE 
      style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse" 
      cellSpacing=0 cellPadding=0 border=1>
        <TBODY>
        <TR>
          <TD 
          style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 426.1pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid" 
          vAlign=top width=568>
            <DIV>/*====================================================================</DIV>
            <DIV>函数<SPAN>&nbsp;&nbsp;&nbsp; 
            </SPAN>:IStateMachine_HandleEvent</DIV>
            <DIV>描述<SPAN>&nbsp;&nbsp;&nbsp; 
            </SPAN>:状态机的事件捕获函数,在此函数中将事件传递给在当前状态中打开的窗口</DIV>
            <DIV>参数<SPAN>&nbsp;&nbsp;&nbsp; </SPAN>:po[in] 指向当前状态机结构体的指针</DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            eCode[in] </SPAN>当前的事件代码</DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            wParam[in] </SPAN>事件的16位参数</DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            dwParam[in] </SPAN>事件的32位参数</DIV>
            <DIV>返回值&nbsp;:如果捕获事件则返回TRUE,否则返回FALSE</DIV>
            <DIV>====================================================================*/</DIV>
            <DIV>static boolean IStateMachine_HandleEvent(IStateMachine 
            *po,</DIV>
            <DIV><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            AEEEvent&nbsp;eCode,</SPAN></DIV>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -