#ifndef _SCANNERSET_FSM_H_ #define _SCANNERSET_FSM_H_ #pragma once #include "SpFSM.h" #include "ScannerSet_server_g.h" #include "ScannerSet_msg_g.h" using namespace ScannerSet; #include "HSPScanner_client_g.h" using namespace HSPScanner; #include #include "EventCode.h" #include "ScannerSet_UserErrorCode.h" #define ISSUCCEEDED(hr) ((hr) == Error_Succeed) #define FAILURED(hr) (!(ISSUCCEEDED(hr))) #define DECLARE_ENTITY_CLIENT_ENTITY(tEntityName, tEntityBaseName) \ class C##tEntityName##Client : public tEntityBaseName##_ClientBase \ { \ public: \ C##tEntityName##Client(CEntityBase *pEntity) \ :tEntityBaseName##_ClientBase(pEntity) \ {/*empty constructor*/ } \ } class CHSPSInnerClient : public HSPScannerService_ClientBase { public: CHSPSInnerClient(CEntityBase *pEntity) :HSPScannerService_ClientBase(pEntity) { } }; enum EvtType { USER_EVT_STARTPREVIEW = (EVT_USER + 1), USER_EVT_STARTPREVIEW_FINISHED, USER_EVT_STOPPREVIEW, USER_EVT_STOPPREVIEW_FINISHED, USER_EVT_SETWINPOS, USER_EVT_SETWINPOS_FINISHED, USER_EVT_SCANIMAGE, USER_EVT_SCANIMAGEFINISHED, USER_EVT_SETPROPERTY, USER_EVT_SETPROPERTY_FINISHED, USER_EVT_SHOWPROPERTY, USER_EVT_SHOWPROPERTY_FINISHED, USER_EVT_GETSTATUS, USER_EVT_GETSTATUS_FINISHED, USER_EVT_GETINFO, USER_EVT_GETINFO_FINISHED, USER_EVT_DEV_INVALID, USER_EVT_DEV_RECOVER, USER_EVT_OPERATING, USER_EVT_RESET, USER_EVT_EXIT, USER_EVT_QUIT, ////////////////////////////////////////////////////////////////////////// USER_EVT_ESTIMATE, USER_EVT_ESTIMATE_FINISHED }; class StartPreviewEvent : public FSMEvent { public: StartPreviewEvent() : FSMEvent(USER_EVT_STARTPREVIEW){} ~StartPreviewEvent(){} SpReqAnsContext::Pointer m_ctx; virtual void OnUnhandled() { if(m_ctx != NULL) { m_ctx->Answer(Error_InvalidState, LOG_WARN_FSM_INVALID); } } }; class StopPreviewEvent : public FSMEvent { public: StopPreviewEvent() : FSMEvent(USER_EVT_STOPPREVIEW){} ~StopPreviewEvent(){} SpReqAnsContext::Pointer m_ctx; virtual void OnUnhandled() { if(m_ctx != NULL) { m_ctx->Answer(Error_InvalidState, LOG_WARN_FSM_INVALID); } } }; class ScanImageEvent : public FSMEvent { public: ScanImageEvent() : FSMEvent(USER_EVT_SCANIMAGE){} ~ScanImageEvent(){} SpReqAnsContext::Pointer m_ctx; virtual void OnUnhandled() { if(m_ctx != NULL) { m_ctx->Answer(Error_InvalidState, LOG_WARN_FSM_INVALID); } } }; class OperatingEvent: public FSMEvent { public: OperatingEvent(int iEvt):FSMEvent(USER_EVT_OPERATING),m_bindEvt(iEvt) {} ~OperatingEvent(){} int m_bindEvt; }; class SetPropertyEvent : public FSMEvent { public: SetPropertyEvent() : FSMEvent(USER_EVT_SETPROPERTY){} ~SetPropertyEvent(){} SpReqAnsContext::Pointer m_ctx; virtual void OnUnhandled() { if(m_ctx != NULL) { m_ctx->Answer(Error_InvalidState, LOG_WARN_FSM_INVALID); } } }; class ShowPropertyEvent : public FSMEvent { public: ShowPropertyEvent() : FSMEvent(USER_EVT_SHOWPROPERTY){} ~ShowPropertyEvent(){} SpReqAnsContext::Pointer m_ctx; virtual void OnUnhandled() { if(m_ctx != NULL) { m_ctx->Answer(Error_InvalidState, LOG_WARN_FSM_INVALID); } } }; class SetWinPosEvent : public FSMEvent { public: SetWinPosEvent() : FSMEvent(USER_EVT_SETWINPOS){} ~SetWinPosEvent(){} SpReqAnsContext::Pointer m_ctx; virtual void OnUnhandled() { if(m_ctx != NULL) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("set winpos unhandle!"); m_ctx->Answer(Error_InvalidState, LOG_WARN_FSM_INVALID); } } }; class GetDevStatusEvent : public FSMEvent { public: GetDevStatusEvent() : FSMEvent(USER_EVT_GETSTATUS){} ~GetDevStatusEvent(){} SpReqAnsContext::Pointer m_ctx; virtual void OnUnhandled() { if(m_ctx != NULL) { m_ctx->Answer(Error_InvalidState, LOG_WARN_FSM_INVALID); } } }; class GetDevInfoEvent : public FSMEvent { public: GetDevInfoEvent() : FSMEvent(USER_EVT_GETINFO){} ~GetDevInfoEvent(){} SpReqAnsContext::Pointer m_ctx; virtual void OnUnhandled() { if(m_ctx != NULL) { m_ctx->Answer(Error_InvalidState, LOG_WARN_FSM_INVALID); } } }; class CScannerFSM : public FSMImpl, public IFSMStateHooker { public: CScannerFSM(void); ~CScannerFSM(void); virtual ErrorCodeEnum OnInit(); virtual ErrorCodeEnum OnExit(); void SelfTest(EntityTestEnum eTestType,CSmartPointer pTransactionContext); enum {s0, s2, s4}; BEGIN_FSM_STATE(CScannerFSM) FSM_STATE_ENTRY(s0, "Idle", s0_on_entry, s0_on_exit, s0_on_event) FSM_STATE_ENTRY(s2, "Operating", s2_on_entry, s2_on_exit, s2_on_event) FSM_STATE_ENTRY(s4, "Invalid", s4_on_entry, s4_on_exit, s4_on_event) END_FSM_STATE() BEGIN_FSM_RULE(CScannerFSM, s0) FSM_RULE_ENTRY_ANY(s0, s4, USER_EVT_DEV_INVALID) FSM_RULE_ENTRY_ANY(s4, s0, USER_EVT_DEV_RECOVER) FSM_RULE_ENTRY_ANY(s0, s2, USER_EVT_OPERATING) /*S2 中所有处理结果都返回1,见 s2_on_event 实现*/ FSM_RULE_ENTRY(s2, s0, USER_EVT_STARTPREVIEW_FINISHED, 1) FSM_RULE_ENTRY(s2, s0, USER_EVT_STOPPREVIEW_FINISHED, 1) FSM_RULE_ENTRY(s2, s0, USER_EVT_SCANIMAGEFINISHED, 1) FSM_RULE_ENTRY(s2, s0, USER_EVT_SETPROPERTY_FINISHED, 1) FSM_RULE_ENTRY(s2, s0, USER_EVT_SHOWPROPERTY_FINISHED, 1) FSM_RULE_ENTRY(s2, s0, USER_EVT_SETWINPOS_FINISHED, 1) END_FSM_RULE() virtual void s0_on_entry(); virtual void s0_on_exit(); virtual unsigned int s0_on_event(FSMEvent* e); virtual void s2_on_entry(); virtual void s2_on_exit(); virtual unsigned int s2_on_event(FSMEvent* e); virtual void s4_on_entry(); virtual void s4_on_exit(); virtual unsigned int s4_on_event(FSMEvent* e); virtual void OnStateTrans(int iSrcState, int iDstState); int StartPreview(SpReqAnsContext::Pointer ctx); int StopPreview(SpReqAnsContext::Pointer ctx); int ScanImage(SpReqAnsContext::Pointer ctx); int SetProperty(SpReqAnsContext::Pointer ctx); int ShowLTProperty(SpReqAnsContext::Pointer ctx); int SetWinPos(SpReqAnsContext::Pointer ctx); int GetDevStatus(SpReqAnsContext::Pointer ctx); int GetDevInfo(SpReqAnsContext::Pointer ctx); bool IsWorking() { return (GetCurrState()->id == s2); } const char* GetChildEntityName() { return "HSPSCanner"; } ErrorCodeEnum OnDevExit(); private: CHSPSInnerClient* m_pHSPSClient; ErrorCodeEnum m_ecSelfTest; DWORD m_dwErroCode; int m_nFatalTimes; int m_nSrcState; int m_iEvt; public: DWORD GetCustLastErrorCode() { return m_dwErroCode; } void SetCustLastErrorCode(DWORD dwVal = 0) { m_dwErroCode = dwVal; } public: bool IsHSPSConnectSessionOK(); ErrorCodeEnum CheckHSPSConnectStatus(); ErrorCodeEnum ConnectToHSPScanner(); void FreeHSPScannerClient() { if(m_pHSPSClient) { m_pHSPSClient->GetFunction()->CloseSession(); m_pHSPSClient = NULL; } } ErrorCodeEnum GetHSPSInfo(); bool IsNoralEntityState(const EntityStateEnum& state) { if(state == EntityState_Idle || state == EntityState_Busy || state == EntityState_Pause || state == EntityState_UnLoading) { return true; } return false; } UINT UnitTest(); void AfterInit(); private: ErrorCodeEnum GetEntityCurState(EntityStateEnum& state, LPCTSTR lpcszEntityName) { CSmartPointer pFunc = GetEntityBase()->GetFunction(); CSmartPointer pFuncPrivilege = pFunc.ConvertCase(); CEntityRunInfo info = {0}; ErrorCodeEnum ecInfo = pFunc->GetEntityRunInfo(lpcszEntityName, info); if(ISSUCCEEDED(ecInfo)) { state = info.eState; } return ecInfo; } bool IsSuitableEntityAvailable() { if(ISSUCCEEDED(ConnectToHSPScanner())) { return true; } return false; } void ReleaseSuitableEntity() { FreeHSPScannerClient(); return; } ErrorCodeEnum LoadConfigAboutCamera(); template PVOID inline TransferCtx(CSmartPointer > ctx) { return (PVOID)ctx.GetRawPointer(); //return reinterpret_cast(ctx.GetRawPointer()); } }; struct StartPreviewTask : public ITaskSp { CScannerFSM* m_fsm; SpReqAnsContext::Pointer m_ctx; StartPreviewTask(CScannerFSM* fsm): m_fsm(fsm){} void Process() { FSMEvent* pEvt = new FSMEvent(USER_EVT_STARTPREVIEW_FINISHED); pEvt->param1 = m_fsm->StartPreview(m_ctx); m_fsm->PostEventFIFO(pEvt); return; } void SetContext( SpReqAnsContext::Pointer ctx) { m_ctx = ctx; return; } }; struct StopPreviewTask : public ITaskSp { CScannerFSM* m_fsm; SpReqAnsContext::Pointer m_ctx; StopPreviewTask(CScannerFSM* fsm): m_fsm(fsm){} void Process() { FSMEvent* pEvt = new FSMEvent(USER_EVT_STOPPREVIEW_FINISHED); const bool bOnlyHide = m_ctx->Req.reserved1 == 0 ? false : true; pEvt->param1 = m_fsm->StopPreview(m_ctx); m_fsm->PostEventFIFO(pEvt); return; } void SetContext( SpReqAnsContext::Pointer ctx) { m_ctx = ctx; return; } }; struct ScanImageTask : public ITaskSp { CScannerFSM* m_fsm; SpReqAnsContext::Pointer m_ctx; ScanImageTask(CScannerFSM* fsm): m_fsm(fsm){} void Process() { FSMEvent* pEvt = new FSMEvent(USER_EVT_SCANIMAGEFINISHED); pEvt->param1 = m_fsm->ScanImage(m_ctx); m_fsm->PostEventFIFO(pEvt); return; } void SetContext( SpReqAnsContext::Pointer ctx) { m_ctx = ctx; return; } }; struct SetPropertyTask : public ITaskSp { CScannerFSM* m_fsm; SpReqAnsContext::Pointer m_ctx; SetPropertyTask(CScannerFSM* fsm): m_fsm(fsm){} void Process() { FSMEvent* pEvt = new FSMEvent(USER_EVT_SETPROPERTY_FINISHED); pEvt->param1 = m_fsm->SetProperty(m_ctx); m_fsm->PostEventFIFO(pEvt); return; } void SetContext( SpReqAnsContext::Pointer ctx) { m_ctx = ctx; return; } }; struct ShowPropertyTask : public ITaskSp { CScannerFSM* m_fsm; SpReqAnsContext::Pointer m_ctx; ShowPropertyTask(CScannerFSM* fsm): m_fsm(fsm){} void Process() { FSMEvent* pEvt = new FSMEvent(USER_EVT_SHOWPROPERTY_FINISHED); pEvt->param1 = m_fsm->ShowLTProperty(m_ctx); m_fsm->PostEventFIFO(pEvt); return; } void SetContext( SpReqAnsContext::Pointer ctx) { m_ctx = ctx; return; } }; struct PendingTask : public ITaskSp { CScannerFSM* m_fsm; SpReqAnsContext::Pointer m_ctx; PendingTask(CScannerFSM* fsm): m_fsm(fsm){} void Process() { WaitingFSMForIdle(); SetWinPosEvent* pEvent = new SetWinPosEvent(); pEvent->m_ctx = m_ctx; m_fsm->PostEventFIFO(pEvent); return; } void SetContext( SpReqAnsContext::Pointer ctx) { m_ctx = ctx; return; } private: void WaitingFSMForIdle() { static const int waitTimes = 30; static const int waitEachTimeout = 300; int waitCurrTimes = 0; while(m_fsm->IsWorking() && (++waitCurrTimes <= waitTimes)) { Sleep(waitEachTimeout); } if(waitCurrTimes > waitTimes) { LogWarn(Severity_Low, Error_TimeOut, LOG_EVT_SCANNERSET_HSPSCNT_TASK_TIMEOUT, "Waiting FSM to Idle timeout!"); } } }; struct SetWinPosTask : public ITaskSp { CScannerFSM* m_fsm; SpReqAnsContext::Pointer m_ctx; SetWinPosTask(CScannerFSM* fsm): m_fsm(fsm){} void Process() { FSMEvent* pEvt = new FSMEvent(USER_EVT_SETWINPOS_FINISHED); pEvt->param1 = m_fsm->SetWinPos(m_ctx); m_fsm->PostEventFIFO(pEvt); return; } void SetContext( SpReqAnsContext::Pointer ctx) { m_ctx = ctx; return; } }; struct GetDevStatusTask : public ITaskSp { CScannerFSM* m_fsm; SpReqAnsContext::Pointer m_ctx; GetDevStatusTask(CScannerFSM* fsm): m_fsm(fsm){} void Process() { FSMEvent* pEvt = new FSMEvent(USER_EVT_GETSTATUS_FINISHED); m_fsm->GetDevStatus(m_ctx); m_fsm->PostEventFIFO(pEvt); return; } void SetContext( SpReqAnsContext::Pointer ctx) { m_ctx = ctx; return; } }; struct GetDevInfoTask : public ITaskSp { CScannerFSM* m_fsm; SpReqAnsContext::Pointer m_ctx; GetDevInfoTask(CScannerFSM* fsm): m_fsm(fsm){} void Process() { FSMEvent* pEvt = new FSMEvent(USER_EVT_GETINFO_FINISHED); m_fsm->GetDevInfo(m_ctx); m_fsm->PostEventFIFO(pEvt); return; } void SetContext( SpReqAnsContext::Pointer ctx) { m_ctx = ctx; return; } }; #endif //_SCANNERSET_FSM_H_