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

📄 logplayer.cpp

📁 The application wizard has created this SoccerDoctor application for you. This application not onl
💻 CPP
字号:
#include "StdAfx.h"
#include "logplayer.h"
#include "MainFrm.h"
#include "CycleSlider.h"
/************************************************************************/
/*                   CParserThread Class                                */
/************************************************************************/
int CParserThread::Run()
{
	_bAlive = true;
	_pParser->parseLog(*_pLogFile);
	_bAlive = false;
	_pLogFile->Close();
	return 0;
}
BOOL CParserThread::InitInstance()
{
	// do nothing
	return TRUE;
}
CParserThread::~CParserThread()
{
	if( _bAlive) {
		::TerminateThread(m_hThread,0);
	}
}

/************************************************************************/
/*                   CLogPlayer Class                                   */
/************************************************************************/
CLogPlayer::CLogPlayer(void) : m_cycle_infos(8000),_pParserThread(NULL),_pGZFile(NULL)
{
	_LogParserFactory.init(this);
	_DispinfoParserFactory.init(this);
	init();
}

CLogPlayer::~CLogPlayer(void)
{
	if( _pParserThread ){
		delete _pParserThread;
		_pParserThread = NULL;
	}
	if( _pGZFile ){
		delete _pGZFile;
	}
}

void CLogPlayer::init()
{
	m_player_types.clear();
	m_cycle_infos.clear();
	m_dFreq = 100.0;
	m_nCurrent = 0;
	m_bTimerAlive = false;
	m_bReverse = false;
}

bool CLogPlayer::addDispInfo(const dispinfo_t2* pInfo)
{
	CDispinfoParser* pParser = _DispinfoParserFactory.getParser(2); // fix me
	if( pParser)
		return pParser->parseDispinfo((BYTE *)pInfo);
	else
		return false;
}

bool CLogPlayer::DoCommand(LogPlayerCommand cmd,CString strValue)
{
	switch(cmd){
	case CmdLoad:
		return LoadLog();
		break;
	case CmdOpen:
		return OpenLog(strValue);
		break;
	case CmdPlay:
		PlayLog();
		break;
	case CmdReverse:
		ReverseLog();
		break;
	case CmdStop:
		StopPlay();
		break;
	case CmdAccelerate:
		Accelerate();
		break;
	case CmdDecelerate:
		Decelerate();
		break;
	case CmdRewind:
		RewindLog();
		break;
	case CmdForward:
		Forward();
		break;
	case CmdBackward:
		Backward();
		break;
	case CmdJump:
		JumpTo();
		break;
	case CmdClean:
		init();
		break;
	case CmdSaveLog:
		SaveLog();
		break;
	default:
		break;
	}
	return true;
}
void CLogPlayer::Decelerate()
{
	if(!m_bTimerAlive)
		return;
	if(m_dFreq < 1000){
		m_dFreq *= 2.0;
		TimerStop();
		TimerStart();
	}

}

void CLogPlayer::Accelerate()
{
	if(!m_bTimerAlive)
		return;
	if(m_dFreq > 10){
		m_dFreq /= 2.0;
		TimerStop();
		TimerStart();
	}

}

bool CLogPlayer::LoadLog( )
{
	CFileDialog openDlg(TRUE,NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, NULL, NULL,0);
	if(openDlg.DoModal()!=IDOK){
		return false;	
	}
	return OpenLog(openDlg.GetPathName());
}
bool CLogPlayer::OpenLog(CString logFileName)
{
	/* close previous opened file before opening new one */
	TimerStop();
	if( _pParserThread ){
		delete _pParserThread;
		_pParserThread = NULL;
	}
	if( _pGZFile ){
		delete _pGZFile;
		_pGZFile = NULL;
	}
	_pGZFile = new CGZFile(logFileName);
	if( _pGZFile->Good() ){
		ParseLog(_pGZFile);
	}
	return true ;
}

bool CLogPlayer::ParseLog(CGZFile *pLogFile)
{
	m_cycle_infos.clear();
	m_player_types.clear();

	CLogParser* pParser = _LogParserFactory.getParser(*pLogFile);
		
	if( pParser != NULL ) {
		_pParserThread = new CParserThread(pLogFile,pParser);
		_pParserThread->CreateThread(); // 读文件线程开始
	}

	return false; // 没有东西能这个分析此文件
}

void CLogPlayer::PlayLog()
{
	TimerStart();
	m_bReverse = false;

}

void CLogPlayer::ReverseLog()
{
	TimerStart();
	m_bReverse = true;
}

void CLogPlayer::StopPlay()
{
	TimerStop();
}

void CLogPlayer::TimerStart()
{
	if(!m_bTimerAlive){
		_pMainFrame->SetTimer(IDT_LOGPLAYER,(UINT)m_dFreq,NULL);
		m_bTimerAlive = true;
	}
}
void CLogPlayer::TimerStop()
{
	if(m_bTimerAlive){
		_pMainFrame->KillTimer(IDT_LOGPLAYER);
		m_bTimerAlive = false;
	}
}
void CLogPlayer::WriteStatus(CString str)
{
	_pMainFrame->WriteStatus(str);
}

const cycle_info_t* CLogPlayer::GetDisplayInfo()
{
	_Mutex.Lock();
	if( m_cycle_infos.empty() ){
		_Mutex.Unlock();
		return NULL;
	}
	if( m_bTimerAlive ){
		if( m_bReverse ){
			if( m_nCurrent > 0 )
				m_nCurrent--;
			else
				TimerStop();
		} else {
			if( m_nCurrent < m_cycle_infos.size() - 1)
				m_nCurrent++;
			else
				TimerStop();
		}
	}
	_CurrentCycle = m_cycle_infos[m_nCurrent];
	_Mutex.Unlock();
	return &_CurrentCycle;
}
const cycle_info_t* CLogPlayer::GetLastDispInfo()
{
	if( m_cycle_infos.empty() ) {
		return NULL;
	}
	return &m_cycle_infos[m_cycle_infos.size()-1];
}
bool CLogPlayer::getCommandStatus(LogPlayerCommand cmd)
{
	if( cmd == CmdLoad ) {
		return true; // 打开文件随时可以
	}
	if( m_cycle_infos.empty() ) {
		return false; // 没有记录,不能播放
	}
	switch(cmd){
	case CmdPlay:
		return !m_bTimerAlive || ( m_bTimerAlive && m_bReverse);
		break;
	case CmdReverse:
		return !m_bTimerAlive || (m_bTimerAlive && !m_bReverse);
		break;
	case CmdStop:
		return m_bTimerAlive;
		break;
	case CmdAccelerate:
		return m_dFreq > MIN_FREQ;
		break;
	case CmdDecelerate:
		return m_dFreq < MAX_FREQ;
		break;
	case CmdRewind:
		return m_nCurrent != 0;
		break;
	default:
		break;
	}
	return true;
}

void CLogPlayer::RewindLog()
{
	TimerStop();
	m_nCurrent = 0;
}

void CLogPlayer::Backward()
{
	TimerStop();
	if(m_nCurrent >0)
		m_nCurrent--;

}

void CLogPlayer::Forward()
{
	TimerStop();
	if(m_nCurrent < m_cycle_infos.size() - 1)
		m_nCurrent++;
}

short CLogPlayer::GetMaxCycle()
{
	if(m_cycle_infos.empty())
		return 0;
	else
		return m_cycle_infos[m_cycle_infos.size()-1].cycle;
}

short CLogPlayer::GetMinCycle()
{
	if(m_cycle_infos.empty())
		return 0;
	else
		return m_cycle_infos[0].cycle;
}

short CLogPlayer::GetCurrentCycle()
{
	if(m_cycle_infos.empty())
		return 0;
	else
		return m_cycle_infos[m_nCurrent].cycle;
}

void CLogPlayer::JumpTo()
{
	bool bRestorTimer = m_bTimerAlive;
	TimerStop();
	CCycleSlider cycleSlider(this,GetMinCycle(),GetMaxCycle(),GetCurrentCycle());
	if( cycleSlider.DoModal() == IDOK )
		m_nCurrent = FindCyclePos(cycleSlider.GetPos());
	if( bRestorTimer ){
		TimerStart();
	}
}

int CLogPlayer::FindCyclePos(short nCycle)
{
	// 二分查找
	short nMin = 0;
	short nMax = m_cycle_infos.size() - 1;
	short nMid = (nMin + nMax)/2; // 中点
	
	while(true){
		if( m_cycle_infos[nMid].cycle == nCycle ){
			return nMid;
		}
		if( m_cycle_infos[nMid].cycle < nCycle ){ // 目标在右边
			nMin = nMid;
		}else{ // 目标在左边
			nMax = nMid;
		}		
		nMid = (nMax + nMin)/2;
		if( nMid == nMax || nMid == nMin ){ // 目标已找到,或者已不可能找到
			return nMid;
		}
	}
	
	return nMid;
}
void CLogPlayer::DisplayCycle(UINT nCycle)
{
	if( m_cycle_infos.empty() )
		return ;
	int nPos = FindCyclePos(nCycle);
	if( nPos >= 0 ){
		_pMainFrame->DisplayCycle(&m_cycle_infos[nPos]);
	}
	
}

const player_type_t* CLogPlayer::getPlayerType(UINT nType)
{
	for(UINT i = 0; i < m_player_types.size() ;i++){
		if(ntohs(m_player_types[i].id) == nType)
			return &m_player_types[i];
	}
	return NULL;
}
void CLogPlayer::addOneCycle(const cycle_info_t& cInfo) 
{ 
	_Mutex.Lock();
	m_cycle_infos.push_back(cInfo) ; 
	_pMainFrame->analyzeCycle(cInfo.show);
	if( m_cycle_infos.size() ==	1 ){ // 第一帧
		_CurrentCycle = cInfo;
		_pMainFrame->DisplayCycle(&_CurrentCycle);
	}
	_Mutex.Unlock();
}
bool CLogPlayer::SaveLog(void)
{
	bool bRestorTimer = m_bTimerAlive;
	TimerStop();
	CFileDialog saveDlg(FALSE,NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, NULL, NULL,0);
	if(saveDlg.DoModal()!=IDOK){
		return false;	
	}
	
	CGZFile saveFile(saveDlg.GetPathName(),CGZFile::ModeSave);
	saveFile.Write("ULG",3);
	BYTE iVersion = 3;
	saveFile.Write(&iVersion,sizeof(iVersion));
	CString TeamNameLeft,TeamNameRight;
	short ScoreLeft=0,ScoreRight=0;
	char PlayMode = 0;
	short_showinfo_t2 info;
	saveFile.Write(htons(PARAM_MODE));
	saveFile.Write(&m_ServerParams,sizeof(server_params_t));
	saveFile.Write(htons(PPARAM_MODE));
	saveFile.Write(&m_PlayerParams,sizeof(player_params_t));
	for( int i=0; i<m_player_types.size(); i++ ){
		saveFile.Write(htons(PT_MODE));
		saveFile.Write(&m_player_types[i],sizeof(player_type_t));
	}
	for( int i=0; i<m_cycle_infos.size(); i++ ){
		if(!m_cycle_infos[i].bSight){
			if( PlayMode != m_cycle_infos[i].show.pmode ){
				PlayMode = m_cycle_infos[i].show.pmode;
				saveFile.Write(htons(PM_MODE));
				saveFile.Write(&PlayMode,sizeof(PlayMode));
			}
			if( TeamNameLeft != m_cycle_infos[i].show.team[0].name || TeamNameRight != m_cycle_infos[i].show.team[1].name ||
				ScoreLeft != m_cycle_infos[i].show.team[0].score || ScoreRight != m_cycle_infos[i].show.team[1].score ){
				saveFile.Write(htons(TEAM_MODE));
				TeamNameLeft = m_cycle_infos[i].show.team[0].name;
				TeamNameRight = m_cycle_infos[i].show.team[1].name;
				ScoreLeft = m_cycle_infos[i].show.team[0].score;
				ScoreRight = m_cycle_infos[i].show.team[1].score;
				saveFile.Write(m_cycle_infos[i].show.team,sizeof(m_cycle_infos[i].show.team));
			}
			if( strlen(m_cycle_infos[i].msg) > 0 ){
				const char* p1=m_cycle_infos[i].msg;
				const char* p2;
				short len;
				while( *p1 && (p2 = strstr(p1,MSG_FOOTER)) ){ // MSG_FOOTER是每一行的结尾
					saveFile.Write(htons(MSG_MODE));
					saveFile.Write(htons(MSG_BOARD));
					len = p2 - p1;
					saveFile.Write(htons(len)); // 不用写入MSG_FOOTER
					saveFile.Write((const voidp)p1,len);
					p1 = p2 + strlen(MSG_FOOTER); // skip MSG_FOOTER
				}
			}
			
			saveFile.Write(htons(SHOW_MODE));
			info.ball = m_cycle_infos[i].show.ball;
			memcpy(info.pos,m_cycle_infos[i].show.pos,sizeof(info.pos));
			info.time = m_cycle_infos[i].show.time;
			saveFile.Write(&info,sizeof(info));
		}
	}
	if( bRestorTimer ){
		TimerStart();
	}
	return false;
}

⌨️ 快捷键说明

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