diff --git a/ECTrainer2/BaseProcess.cpp b/ECTrainer2/BaseProcess.cpp index d500023..30cdb3d 100644 --- a/ECTrainer2/BaseProcess.cpp +++ b/ECTrainer2/BaseProcess.cpp @@ -63,22 +63,17 @@ return 0; } -// �X���b�h�I���҂� +// �X���b�h�I���҂��@����I���Ńn���h���‚��� bool BaseProcess::WaitForExit(DWORD timeOut) { if (!_threadHandle) return false; - DWORD rv = ::WaitForSingleObject(_threadHandle, timeOut); - return (rv == WAIT_OBJECT_0); + bool rv = (::WaitForSingleObject(_threadHandle, timeOut) == WAIT_OBJECT_0); + if (rv) CloseHandle(_threadHandle); + return rv; } // ���b�Z�[�W�𑗂� -bool BaseProcess::Tell(int msgid) { +bool BaseProcess::Tell(ECTMSG msg, WPARAM wp, LPARAM lp) { if (!_messageQueReady || !_threadID) return false; // ���b�Z�[�W�L���[�̏����m�F - if (::GetCurrentThreadId() == _threadID) ::PostQuitMessage(0); - else ::PostThreadMessage(_threadID, msgid, 0, 0); + ::PostThreadMessage(_threadID, (int)msg, wp, lp); return true; } - -// �X���b�h�n���h����‚��� -void BaseProcess::CloseThread() { - CloseHandle(_threadHandle); -} diff --git a/ECTrainer2/BaseProcess.h b/ECTrainer2/BaseProcess.h index 3fc3f86..95a7d8c 100644 --- a/ECTrainer2/BaseProcess.h +++ b/ECTrainer2/BaseProcess.h @@ -3,9 +3,10 @@ #include class ECTrainer; +enum class ECTMSG; -// �e�����̊�{�N���X +// �����̊�{�N���X class BaseProcess { protected: @@ -33,7 +34,5 @@ // �X���b�h�I���҂� bool WaitForExit(DWORD timeOut = 3000); // ���b�Z�[�W�𑗂� - bool Tell(int msgid); - // �X���b�h�n���h����‚��� - void CloseThread(); + bool Tell(ECTMSG msg, WPARAM wp = 0, LPARAM lp = 0); }; diff --git a/ECTrainer2/ECTrainer.cpp b/ECTrainer2/ECTrainer.cpp index 37f9760..8a9461e 100644 --- a/ECTrainer2/ECTrainer.cpp +++ b/ECTrainer2/ECTrainer.cpp @@ -54,7 +54,6 @@ for (int i = (int)PROC::REST; i < (int)PROC::NUM; i++) { auto rv = _pProcs[i]->WaitForExit(); mwut::DebugPrintf(_T("Process %d exit %s\n"), i, rv ? _T("ok") : _T("ng")); - _pProcs[i]->CloseThread(); } return true; @@ -63,7 +62,13 @@ // �A�v���P�[�V�������~ void ECTrainer::StopApp() { _AppRunning = false; - for (int i = 0; i < (int)PROC::NUM; i++) _pProcs[i]->Tell(WM_QUIT); + for (int i = 0; i < (int)PROC::NUM; i++) _pProcs[i]->Tell(ECTMSG::QUIT); +} + +// ���b�Z�[�W�{�b�N�X�\�� +void ECTrainer::MsgBox(LPCWSTR msg, UINT icon) { + ::MessageBox(PECTrainerGUI()->GetMainHWnd(), msg, + _T("Eye Communication Trainer"), MB_OK | icon); } // ���ʃX���b�h�J�n�_ diff --git a/ECTrainer2/ECTrainer.h b/ECTrainer2/ECTrainer.h index de85bca..d31b960 100644 --- a/ECTrainer2/ECTrainer.h +++ b/ECTrainer2/ECTrainer.h @@ -1,11 +1,12 @@ #pragma once #include +#include #include "myOpenCV.h" #define ADDR "192.168.71.50" -#define EYEDEVICE_GLASS2 -//#define EYEDEVICE_NONE +//#define EYEDEVICE_GLASS2 +#define EYEDEVICE_NONE class BaseProcess; class ECTrainerGUI; @@ -20,11 +21,27 @@ class Marker; // ���b�Z�[�W�ꗗ -enum class EMSG { +enum class ECTMSG { + QUIT = WM_QUIT, CALIB_START = WM_USER, CALIB_END, }; +// �A�v���P�[�V������� +enum class APP_STATUS { + BOOT, IDLE, CALIB, EXEC +}; + +// �L�����u���[�V�������� +enum class CALIB_STATUS { + DONE, FAIL, ERR +}; + +// �h���y�[�W +enum class STIM_PAGE { + OPENING, CALIB, CALIB_COMPLETE, CALIB_FAILED, START, STOP, NEXT, BACK, WHITE +}; + class ECTrainer { // �v���Z�X�ꗗ�i���������j GUI�擪, SCNCAM->ALIVE->EYETR @@ -60,6 +77,8 @@ bool IsAppRun() { return _AppRunning; } // �A�v���P�[�V�������s�����ǂ��� // �A�v���P�[�V�������~ void StopApp(); + // ���b�Z�[�W�{�b�N�X�\�� + void MsgBox(LPCWSTR msg, UINT icon = 0); void SetMovieToShow(std::wstring file) { _MovieToShow = file; } std::wstring GetMovieToShow() { return _MovieToShow; } }; diff --git a/ECTrainer2/ECTrainerGUI.cpp b/ECTrainer2/ECTrainerGUI.cpp index 0e25392..b086ad8 100644 --- a/ECTrainer2/ECTrainerGUI.cpp +++ b/ECTrainer2/ECTrainerGUI.cpp @@ -152,9 +152,7 @@ switch (_pEct->PWorker()->GetAppStatus()) { case APP_STATUS::IDLE: if (cvui::button(140, 30, "CALIBRATION")) { - _pEct->PSceneCamera()->Tell(WM_USER); - _pEct->PECTrainerGUI()->Tell(WM_USER); - _pEct->PWorker()->StartCalibration(); + _pEct->PWorker()->Tell(ECTMSG::CALIB_START); } if (cvui::button(140, 30, "START")) { //fStimulus = true; diff --git a/ECTrainer2/ECTrainerGUI.h b/ECTrainer2/ECTrainerGUI.h index 51a63aa..24c44f3 100644 --- a/ECTrainer2/ECTrainerGUI.h +++ b/ECTrainer2/ECTrainerGUI.h @@ -11,7 +11,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); -#define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; } +#define SAFE_RELEASE(x) if (x) { x->Release(); x = NULL; } #define CHECK(x) { if(((HRESULT)(x)) < 0) return false; } class ECTrainerGUI : public BaseProcess diff --git a/ECTrainer2/MyWinUtils.h b/ECTrainer2/MyWinUtils.h index bdd90b9..83523ea 100644 --- a/ECTrainer2/MyWinUtils.h +++ b/ECTrainer2/MyWinUtils.h @@ -5,6 +5,9 @@ #include #include +#define SAFE_DELETE(x) if (x) { delete x; x = NULL; } +#define SAFE_DELETE_ARRAY(x) if (x) { delete [] x; x = NULL; } + namespace mwut { typedef std::vector> STR_TABLE; @@ -36,4 +39,22 @@ // �f�B�X�v���C���擾�R�[���o�b�N BOOL CALLBACK MonitorEnumProc( HMONITOR hMon, HDC hdcMon, LPRECT lpMon, LPARAM dwData); + + // ���S�ȃf���[�g + void SafeDelete(void** ptr); + + // �����x�^�C�}�[�N���X + class HPTimer { + LARGE_INTEGER _nFreq; // ���g�� + LARGE_INTEGER _nBegin; // �J�n���� + LARGE_INTEGER _nLast; // �O��₢���킹���� + double Calc(LARGE_INTEGER before); + + public: + HPTimer(); + double Elapse(); // �J�n������̌o�ߎ���(ms) + double Interval(); // �O�񂩂�̌o�ߎ���(ms) + void Reset(); // �J�n���ԃ��Z�b�g + static void HPSleep(double delayms); // �����xSleep + }; } diff --git a/ECTrainer2/SceneCamera.cpp b/ECTrainer2/SceneCamera.cpp index 668db27..ea49356 100644 --- a/ECTrainer2/SceneCamera.cpp +++ b/ECTrainer2/SceneCamera.cpp @@ -41,7 +41,5 @@ _buffer.Put(scene); Sleep(0); - _pEct->PECTrainerGUI()->Tell(WM_USER + 1); - return true; } diff --git a/ECTrainer2/Stimulus.h b/ECTrainer2/Stimulus.h index db41dba..5a18846 100644 --- a/ECTrainer2/Stimulus.h +++ b/ECTrainer2/Stimulus.h @@ -10,9 +10,6 @@ class Marker; - -enum class STIM_PAGE { OPENING, CALIB, CALIB_COMPLETE, CALIB_FAILED, START, STOP, NEXT, BACK, WHITE }; - struct StimInfo { int type; // 1:�摜 2:���� std::string filename; // �񎦃t�@�C�� diff --git a/ECTrainer2/TobiiREST.cpp b/ECTrainer2/TobiiREST.cpp index 37e2000..27c0734 100644 --- a/ECTrainer2/TobiiREST.cpp +++ b/ECTrainer2/TobiiREST.cpp @@ -6,8 +6,7 @@ // �R���X�g���N�^ TobiiREST::TobiiREST(ECTrainer* pEct) :BaseProcess(pEct) - , _CalibTrigger(false) - , _CalibStatus(CALIB_STATUS::NONE) + //, _CalibTrigger(false) , _BatteryLevel(999) , _lastBatteryQuery(0) { @@ -50,12 +49,12 @@ bool TobiiREST::Routine() { // �L�����u���[�V���� - if (_CalibTrigger) { - _CalibTrigger = false; - if (StartCalib()) { - QueryCalibResult(); - } - } + //if (_CalibTrigger) { + // _CalibTrigger = false; + // if (StartCalib()) { + // QueryCalibResult(); + // } + //} // �o�b�e���[���擾 DWORD cTime = timeGetTime(); @@ -69,6 +68,18 @@ return true; } +// �C�x���g���� +bool TobiiREST::EventProc(MSG& msg) { + switch (msg.message) { + case (int)ECTMSG::CALIB_START: // �L�����u���[�V���� + if (StartCalib()) { + QueryCalibResult(); + } + break; + } + return true; +} + // �L�����u���[�V�����J�n bool TobiiREST::StartCalib() { try @@ -110,14 +121,14 @@ values.push_back(_T("calibrated")); std::wstring status = REST_Handler::WaitForStatus(url.c_str(), _T("ca_state"), values); if (status == _T("failed")) { - _CalibStatus = CALIB_STATUS::FAIL; + ((BaseProcess*)_pEct->PWorker())->Tell(ECTMSG::CALIB_END, (int)CALIB_STATUS::FAIL); mwut::DebugPrintf(_T("Calibration failed\n")); } else { - _CalibStatus = CALIB_STATUS::DONE; + ((BaseProcess*)_pEct->PWorker())->Tell(ECTMSG::CALIB_END, (int)CALIB_STATUS::DONE); mwut::DebugPrintf(_T("Calibration successful\n")); } #else - _CalibStatus = CALIB_STATUS::DONE; + ((BaseProcess*)_pEct->PWorker())->Tell(ECTMSG::CALIB_END, (int)CALIB_STATUS::DONE); mwut::DebugPrintf(_T("Calibration skipped\n")); #endif return true; @@ -125,7 +136,7 @@ catch (const std::exception & e) { UNREFERENCED_PARAMETER(e); // e.what() ���}���`�o�C�g������Ȃ̂Ŏg���Ȃ� - _CalibStatus = CALIB_STATUS::ERR; + ((BaseProcess*)_pEct->PWorker())->Tell(ECTMSG::CALIB_END, (int)CALIB_STATUS::ERR); mwut::DebugPrintf(_T("Error in TobiiREST::QueryCalibResult()\n")); return false; } diff --git a/ECTrainer2/TobiiREST.h b/ECTrainer2/TobiiREST.h index 6463675..d1113ff 100644 --- a/ECTrainer2/TobiiREST.h +++ b/ECTrainer2/TobiiREST.h @@ -5,8 +5,6 @@ #define SERVER _T("http://192.168.71.50") -enum class CALIB_STATUS { NONE, DONE, FAIL, ERR }; - class TobiiREST : public BaseProcess { const DWORD BATTERY_QUERY_INTERVAL = 60000; // ms @@ -14,8 +12,7 @@ utility::string_t _ProjectID; utility::string_t _ParticipantID; utility::string_t _CalibrationID; - bool _CalibTrigger; - CALIB_STATUS _CalibStatus; + //bool _CalibTrigger; int _BatteryLevel; // ���ڑ��� 999 DWORD _lastBatteryQuery; // �O��̃o�b�e���[���擾���� @@ -23,13 +20,16 @@ bool StartCalib(); bool QueryCalibResult(); bool QueryBatteryLevel(); + // ���b�Z�[�W���� + virtual bool EventProc(MSG& msg); + // �ʏ폈�� + bool Routine(); public: TobiiREST(ECTrainer* pEct); bool Init(); - bool Routine(); - void StartCalibration() { _CalibStatus = CALIB_STATUS::NONE; _CalibTrigger = true; }; + //void StartCalibration() { + // _CalibTrigger = true; }; int GetBatteryLevel() { return _BatteryLevel; }; - CALIB_STATUS GetCalibStatus() { return _CalibStatus; } }; diff --git a/ECTrainer2/Worker.cpp b/ECTrainer2/Worker.cpp index df51edf..e9a810e 100644 --- a/ECTrainer2/Worker.cpp +++ b/ECTrainer2/Worker.cpp @@ -1,66 +1,75 @@ -#include "common.h" +//#include "common.h" +#include "Worker.h" +#include "ECTrainer.h" +#include "EyeTrack.h" +#include "Stimulus.h" +#include "BitalMonitor.h" +#include "Marker.h" +#include "myWinUtils.h" -Worker::Worker(ECTrainer* pEct) - : BaseProcess(pEct) +// �R���X�g���N�^ +Worker::Worker(ECTrainer* pEct) : BaseProcess(pEct) , _AppStatus(APP_STATUS::BOOT) , _fpLog(NULL) - , _StartTime(0) { + , _pTimer(NULL) +{ } +// �f�X�g���N�^ +Worker::~Worker() { + if (_fpLog) fclose(_fpLog); + mwut::SafeDelete((void**)&_pTimer); +} + bool Worker::Init() { if (_tfopen_s(&_fpLog, LOG_FILENAME.c_str(), _T("w")) != 0) { - ::MessageBox(_pEct->PECTrainerGUI()->GetMainHWnd(), _T("Can't open log file."), _T("Error"), 0); + _pEct->MsgBox(_T("Can't open log file."), MB_ICONERROR); return false; } _ftprintf(_fpLog, _T("time,gazeVx,gazeVy,H11,H12,H13,H21,H22,H23,H31,H32,H33,RR\n")); _AppStatus = APP_STATUS::IDLE; - _StartTime = cv::getTickCount(); + _pTimer = new mwut::HPTimer(); return true; } +// ��{���� bool Worker::Routine() { // �������X�V��҂� Sleep(0); if (!_pEct->PEyeTrack()->IsNewGazeV()) return true; - // ��ԍX�V - if (_AppStatus == APP_STATUS::CALIB) { - switch (_pEct->PTobiiREST()->GetCalibStatus()) { - case CALIB_STATUS::DONE: - _pEct->PStimulus()->SetPage(STIM_PAGE::CALIB_COMPLETE); - this->WriteLog(_T("Calibration complete.")); - _AppStatus = APP_STATUS::IDLE; - break; - case CALIB_STATUS::FAIL: - case CALIB_STATUS::ERR: - _pEct->PStimulus()->SetPage(STIM_PAGE::CALIB_FAILED); - this->WriteLog(_T("Calibration failed.")); - _AppStatus = APP_STATUS::IDLE; - break; - } - } - this->WriteLog(); return true; } -// �f�X�g���N�^ -Worker::~Worker() { - fclose(_fpLog); -} +// �C�x���g���� +bool Worker::EventProc(MSG& msg) { + switch (msg.message) { + case (int)ECTMSG::CALIB_START: + if (_AppStatus == APP_STATUS::IDLE) { + _pEct->PStimulus()->SetPage(STIM_PAGE::CALIB); + ((BaseProcess*)_pEct->PTobiiREST())->Tell(ECTMSG::CALIB_START); + _AppStatus = APP_STATUS::CALIB; + this->WriteLog(_T("Calibration start.")); + } + break; -// �L�����u���[�V�����J�n -bool Worker::StartCalibration() { - if (_AppStatus != APP_STATUS::IDLE) return false; - _pEct->PStimulus()->SetPage(STIM_PAGE::CALIB); - _pEct->PTobiiREST()->StartCalibration(); - _AppStatus = APP_STATUS::CALIB; - this->WriteLog(_T("Calibration start.")); + case (int)ECTMSG::CALIB_END: + if (msg.wParam == (int)CALIB_STATUS::DONE) { + _pEct->PStimulus()->SetPage(STIM_PAGE::CALIB_COMPLETE); + this->WriteLog(_T("Calibration complete.")); + } else { + _pEct->PStimulus()->SetPage(STIM_PAGE::CALIB_FAILED); + this->WriteLog(_T("Calibration failed.")); + } + _AppStatus = APP_STATUS::IDLE; + break; + } return true; } @@ -84,8 +93,7 @@ void Worker::WriteLog(const TCHAR* msg) { _mtxLog.lock(); - auto elapse = (cv::getTickCount() - _StartTime) * 1000. / cv::getTickFrequency(); - _ftprintf(_fpLog, _T("%.1f"), elapse); + _ftprintf(_fpLog, _T("%.1f"), _pTimer->Elapse()); if (msg) { _ftprintf(_fpLog, msg); diff --git a/ECTrainer2/Worker.h b/ECTrainer2/Worker.h index 356b72c..31506c9 100644 --- a/ECTrainer2/Worker.h +++ b/ECTrainer2/Worker.h @@ -7,25 +7,30 @@ #include #include -enum class APP_STATUS { BOOT, IDLE, CALIB, EXEC }; +namespace mwut { + class HPTimer; +}; + +enum class APP_STATUS; class Worker : public BaseProcess { const std::wstring LOG_FILENAME = _T("log.txt"); APP_STATUS _AppStatus; FILE* _fpLog; - int64 _StartTime; + mwut::HPTimer* _pTimer; std::mutex _mtxLog; void WriteLog(const TCHAR* msg = NULL); + bool Routine(); + bool EventProc(MSG& msg); public: + // �R���X�g���N�^ Worker(ECTrainer* pEct); // �f�X�g���N�^ ~Worker(); bool Init(); - bool Routine(); - bool StartCalibration(); bool StartStim(); bool StopStim(); APP_STATUS GetAppStatus() { return _AppStatus; } diff --git a/ECTrainer2/myWinUtils.cpp b/ECTrainer2/myWinUtils.cpp index 95b2dac..4b7b17c 100644 --- a/ECTrainer2/myWinUtils.cpp +++ b/ECTrainer2/myWinUtils.cpp @@ -100,5 +100,54 @@ displays->push_back(*lpMon); return TRUE; } -} + // ���S�ȃf���[�g + void SafeDelete(void** ptr) { + if (*ptr) { + delete* ptr; + *ptr = NULL; + } + } + + + // �����x�^�C�}�[�N���X + + // �R���X�g���N�^ + HPTimer::HPTimer() { + QueryPerformanceFrequency(&_nFreq); + QueryPerformanceCounter(&_nBegin); + } + + // �o�ߎ��ԎZ�o + double HPTimer::Calc(LARGE_INTEGER before) { + LARGE_INTEGER cur; + QueryPerformanceCounter(&cur); + double elapse = (cur.QuadPart - before.QuadPart) * 1000.0 / _nFreq.QuadPart; + _nLast = cur; + return elapse; + } + + // �J�n������̌o�ߎ���(ms) + double HPTimer::Elapse() { + return this->Calc(_nBegin); + } + + // �O�񂩂�̌o�ߎ���(ms) + double HPTimer::Interval() { + return this->Calc(_nLast); + } + + // �J�n���ԃ��Z�b�g + void HPTimer::Reset() { + QueryPerformanceCounter(&_nBegin); + } + + // �����xSleep + void HPTimer::HPSleep(double delayms) { + HPTimer timer; + while (1) { + if (timer.Elapse() > delayms) break; + Sleep(0); + } + } +} diff --git "a/\343\203\241\343\203\203\343\202\273\343\203\274\343\202\270\345\233\263.xlsx" "b/\343\203\241\343\203\203\343\202\273\343\203\274\343\202\270\345\233\263.xlsx" index 412cfa0..15b4bad 100644 --- "a/\343\203\241\343\203\203\343\202\273\343\203\274\343\202\270\345\233\263.xlsx" +++ "b/\343\203\241\343\203\203\343\202\273\343\203\274\343\202\270\345\233\263.xlsx" Binary files differ