Newer
Older
PrismSoftware / ECTrainer2 / ECTrainer.cpp

#include "ECTrainer.h"
#include "ECTrainerGUI.h"
#include "SceneCamera.h"
#include "Stimulus.h"
#include "Marker.h"
#include "ImageProc.h"
#include "EyeTrack.h"
#include "TobiiREST.h"
#include "BitalMonitor.h"
#include "Worker.h"

// コンストラクタ
ECTrainer::ECTrainer(HINSTANCE hInstance)
	: _AppRunning(true)
	, _HomographyOK(false)
	, _CalibResult(0)
	, _hInstance(hInstance)
{
	_pMarker = new Marker();
	_pProcs[GUI] = new ECTrainerGUI(this);
	_pProcs[IMGPROC] = new ImageProc(this, _pMarker);
	_pProcs[SCNCAM] = new SceneCamera(this);
	_pProcs[STIM] = new Stimulus(this, _pMarker);
	_pProcs[EYETR] = new EyeTrack(this, _pMarker);
	_pProcs[REST] = new TobiiREST(this);
	_pProcs[BITAL] = new BitalMonitor(this);
	_pProcs[WORKER] = new Worker(this);
	_MovieToShow = _T("");
}

// デストラクタ
ECTrainer::~ECTrainer() {
	for (int i = 0; i < PROC::NUM; i++) {
		if (_pProcs[i]) delete _pProcs[i];
	}
}

// 初期化
bool ECTrainer::Process() {
	// プロセス初期化
	if (!((ECTrainerGUI*)_pProcs[GUI])->Init(_hInstance)) return false;
	for (int i = 1; i < PROC::NUM; i++) {
		if (!_pProcs[i]->Init()) return false;
	}

	// スレッド開始
	const int N_THREADS = PROC::NUM;	// GUIが抜けてKeepAliveが増えるので同数
	DWORD thIds[N_THREADS];
	HANDLE thHandles[N_THREADS];
	thHandles[0] = CreateThread(NULL, 0, KeepAliveThreadEntry, this, 0, &thIds[0]);
	for (int i = 1; i < N_THREADS; i++) {
		thHandles[i] = CreateThread(NULL, 0, ThreadEntry, _pProcs[i], 0, &thIds[i]);
	}
	_pProcs[GUI]->MainLoop();

	// スレッド終了
	DWORD timeOut = 1000; // タイムアウト(ms)
	if (WaitForMultipleObjects(N_THREADS, thHandles, TRUE, timeOut) != WAIT_TIMEOUT) {
		OutputDebugString(_T("All threads stopped sccessfully.\n"));
	} else {
		OutputDebugString(_T("Waiting threads stop timeout.\n"));
	}
	for (int i = 0; i < N_THREADS; i++) {
		if (thHandles[i]) CloseHandle(thHandles[i]);
	}

	return true;
}

// キャリブレーション開始
void ECTrainer::CalibStart() {
	((Stimulus*)_pProcs[STIM])->SetPage(Stimulus::PAGES::CALIB);
	((TobiiREST*)_pProcs[REST])->Start();
}

// キャリブレーション結果表示
int ECTrainer::CheckCalibResult() {
	int res = _CalibResult;
	if (res > 0) ((Stimulus*)_pProcs[STIM])->SetPage(Stimulus::PAGES::CALIB_COMPLETE);
	if (res < 0) ((Stimulus*)_pProcs[STIM])->SetPage(Stimulus::PAGES::CALIB_FAILED);
	_CalibResult = 0;
	return res;
}

// 開始
void ECTrainer::StartStim() {
	((Stimulus*)_pProcs[STIM])->SetPage(Stimulus::PAGES::START);
}

// 開始
void ECTrainer::StopStim() {
	((Stimulus*)_pProcs[STIM])->SetPage(Stimulus::PAGES::STOP);
}

// 次へ
void ECTrainer::NextStim() {
	((Stimulus*)_pProcs[STIM])->SetPage(Stimulus::PAGES::NEXT);
}

// 視野画像バッファに画像を設定
void ECTrainer::SetSceneBuffer(cv::Mat& img) {
	((ECTrainerGUI*)_pProcs[GUI])->SetSceneBuffer(img);
}

// 刺激画像バッファに画像を設定
void ECTrainer::SetDispBuffer(cv::Mat& img) {
	((ECTrainerGUI*)_pProcs[GUI])->SetDispBuffer(img);
}

// 共通スレッド開始点
DWORD WINAPI ECTrainer::ThreadEntry(LPVOID lpParameter) {
	((BaseProcess*)lpParameter)->MainLoop();
	return 0;
}

// KeepAliveスレッド開始点
DWORD WINAPI ECTrainer::KeepAliveThreadEntry(LPVOID lpParameter) {
	((EyeTrack*)((ECTrainer*)lpParameter)->_pProcs[EYETR])->KeepAliveLoop();
	return 0;
}

// 視野画像中の注視点設定
void ECTrainer::SetGazeV(cv::Point gazeV) {
	//((EyeTrack*)_pProcs[EYETR])->SetGazeV(gazeV);
}

// 視野画像中の注視点取得
cv::Point ECTrainer::GetGazeV() {
	return ((EyeTrack*)_pProcs[EYETR])->GetGazeV();
}

// 刺激画像中の注視点取得
cv::Point2f ECTrainer::GetGazeI() {
	return ((EyeTrack*)_pProcs[EYETR])->GetGazeI();
}

// 右目の位置取得
cv::Point2f ECTrainer::GetEyeR() {
	//return _pStimulus->GetEyeR();
	return cv::Point2f(0.5, 0.5);
}

// 右目の位置取得
cv::Point2f ECTrainer::GetEyeL() {
	//return _pStimulus->GetEyeL();
	return cv::Point2f(0.5, 0.5);
}

// バッテリー残量取得
int ECTrainer::BatteryLevel() {
	return ((TobiiREST*)_pProcs[REST])->BatteryLevel();
}