📄 scriptengine.cpp
字号:
/*
* name: CScriptEngine.cpp
*
* desc: 实现文件
*
*/
#include "StdAfx.h"
#include "..\MainFrm.h"
#include "GameMir.h"
/*
=======================================================================
函数名 : CScriptEngine
功能描述 :
参数 : void
返回值 : NULL
=======================================================================
*/
// ^如果当前地图名=\[(.+)\]$
// ^那么跳转到第\[(\d+)\]行$
// ^触发器:如果(.+),那么跳转到脚本第\[(\d+)\]行$
// ^如果((\S+)\s*)*$
CScriptEngine::CScriptEngine(CGameMir&Game) :
m_Game(Game),
m_LastResult(false),
m_RegexIf(L"^如果(.+)$",boost::regbase::normal|boost::regbase::icase),
m_RegexThen(L"^那么(.+)$",boost::regbase::normal|boost::regbase::icase)
{
InitializeCriticalSection(&m_RunSC);
// add by zdl. 2007-10-11
this->bNotifyStop_ = false;
this->bRunning_ = false;
this->bThreadMode_ = false;
// end of add
}
/*
=======================================================================
函数名 : ~CScriptEngine
功能描述 :
参数 : void
返回值 : NULL
=======================================================================
*/
// 触发器
// trigger
// 条件
// condition
CScriptEngine::~CScriptEngine(void)
{
DeleteCriticalSection(&m_RunSC);
}
/*
=======================================================================
函数名 : RegisterCommand
功能描述 :
参数 : void
返回值 : NULL
=======================================================================
*/
void CScriptEngine::RegisterCommand( std::wstring reg, SCRIPT_COMMAND_PROC proc )
{
sScriptCommand cmd;
cmd.second=proc;
cmd.first.assign(reg,boost::regbase::normal|boost::regbase::icase);
m_Commands.push_back(cmd);
}
/*
=======================================================================
函数名 : RegisterCondition
功能描述 :
参数 : void
返回值 : NULL
=======================================================================
*/
void CScriptEngine::RegisterCondition( std::wstring reg, SCRIPT_CONDITION_PROC proc )
{
sScriptCondition condition;
condition.second=proc;
condition.first.assign(reg,boost::regbase::normal|boost::regbase::icase);
m_Conditions.push_back(condition);
}
/*
=======================================================================
函数名 : LoadFile
功能描述 : 导入脚本文件
参数 : void
返回值 : NULL
=======================================================================
*/
bool CScriptEngine::LoadFile( std::string strFileName )
{
if(TryEnterCriticalSection(&m_RunSC))
{
LeaveCriticalSection(&m_RunSC);
}
else
{
m_Game.m_FrameWnd.AddLog(crGreen,"脚本: 脚本已经运行了!\n");
return false;
}
if ( strFileName.size()<=0 )
{
return false;
}
unsigned __int64 t1=timestamp();
// ReadFile
m_Scripts.clear();
CFile fileScript;
if (fileScript.Open(strFileName.c_str(),CFile::typeBinary|CFile::modeRead|CFile::shareDenyWrite)==FALSE)
{
m_Game.m_FrameWnd.AddLog(crGreen,"脚本: 脚本文件不存在!\n");
return false;
}
size_t flen=fileScript.GetLength();
char*pBuf=new char[flen+1];
ZeroMemory(pBuf,flen+1);
fileScript.Read(pBuf,flen);
pBuf[flen]=static_cast<char>(0);
std::wstring text;
LPWSTR UBuf=new WCHAR[flen+1];;
text=ToUnicode(pBuf,UBuf,flen);
delete[]pBuf;
delete[]UBuf;
std::vector<std::wstring> Lines;
const boost::wregex reSplit(L"\\s*\\n\\s*",boost::regbase::normal|boost::regbase::icase);
boost::regex_split(std::back_inserter(Lines),text,reSplit);
for(std::vector<std::wstring>::iterator pos=Lines.begin();pos!=Lines.end();pos++)
{
//匹配语句
const boost::wregex expression(L"^(?:(\\d+)\\s+)?(.+)$",boost::regbase::normal|boost::regbase::icase);
boost::wsmatch match;
std::wstring label;
sScriptLine line;
if (boost::regex_match( *pos, match, expression))
{
//m_FrameWnd.AddLog(crMessage,"%s\n",pos->c_str());
label=match.str(1);
text=match.str(2);
if ( !text.empty() )
{
switch ( text[0] )
{
case '*':
break;
case '<':
if ( text[text.length()-1]=='>')
{
line.first=text.substr(1,text.length()-2);
line.second=text;
m_Scripts.push_back(line);
//m_Game.m_FrameWnd.AddLog(crMessage,"脚本: % 8s %s \n",line.first.c_str(),line.second.c_str());
}
break;
default:
if(label.empty())
line.first.clear();
else
line.first=label;
line.second=text;
m_Scripts.push_back(line);
//m_Game.m_FrameWnd.AddLog(crMessage,"脚本: % 8s %s \n",line.first.c_str(),line.second.c_str());
break;
}
}
}
}
m_ip=m_Scripts.begin();
unsigned __int64 t2=timestamp()-t1;
m_Game.m_FrameWnd.AddLog(crGreen,"脚本: 加载完成!\n");
return true;
}
/*
=======================================================================
函数名 : Step
功能描述 :
参数 : void
返回值 : NULL
=======================================================================
*/
bool CScriptEngine::Step(void)
{
char buf[STRING_BUFFER_LENGTH];
if (m_Scripts.size()<=0)
return false;
if(m_ip==m_Scripts.end())
return false;
//sScriptLine line=*m_ip;
std::wstring str=m_ip->second;
boost::wsmatch m;
if (boost::regex_match(str, m, m_RegexIf))
{
str=m[1];
m_Game.m_FrameWnd.AddLog(crGreen,"脚本: 判断: %s !?\n",ToAnsi(str.c_str(),buf,STRING_BUFFER_LENGTH));
if ( !__do_If( str, m_LastResult ) )
{
m_Game.m_FrameWnd.AddLog(crError,"脚本: 未知的判断语句!!!!\n");
return false;
}
m_ip++;
return true;
}
else if (regex_match(str, m, m_RegexThen))
{
if (m_LastResult)
{
str=m[1];
}
else
{
m_ip++;
return true;
}
}
for(CommandList::iterator pos=m_Commands.begin();pos!=m_Commands.end();pos++)
{
if (regex_match(str, m, pos->first))
{
m_Game.m_FrameWnd.AddLog(crGreen,"脚本: 执行: \"%s\" !\n",ToAnsi(str.c_str(),buf,STRING_BUFFER_LENGTH));
SCRIPT_COMMAND_PROC cmd=pos->second;
DWORD dwRetVal=cmd(m_Game,*this,m,m_LastResult);
if ( (dwRetVal&SR_SUCCESS)!=0 )
{
if ( (dwRetVal&SR_NOMOVE)==0 )
m_ip++;
return true;
}
else
{
m_Game.m_FrameWnd.AddLog(crRed,"脚本: 语句\"%s\"执行失败!\n",ToAnsi(str.c_str(),buf,STRING_BUFFER_LENGTH));
return false;
}
}
}
m_Game.m_FrameWnd.AddLog(crRed,"脚本: 语法错误: %s !\n",ToAnsi(str.c_str(),buf,STRING_BUFFER_LENGTH));
return false;
}
/*
=======================================================================
函数名 : Jump
功能描述 : 跳到行
参数 : void
返回值 : NULL
=======================================================================
*/
bool CScriptEngine::Jump( int line )
{
return Jump(boost::lexical_cast<std::wstring>(line));
}
/*
=======================================================================
函数名 : Jump
功能描述 : 跳到标签
参数 : void
返回值 : NULL
=======================================================================
*/
bool CScriptEngine::Jump( std::wstring label )
{
for(sScript::iterator pos=m_Scripts.begin();pos!=m_Scripts.end();pos++)
{
if ( pos->first == label )
{
m_ip=pos;
return true;
}
}
char buf[STRING_BUFFER_LENGTH];
m_Game.m_FrameWnd.AddLog(crRed,"脚本: 跳转失败:%d不存在!\n",ToAnsi(label.c_str(),buf,STRING_BUFFER_LENGTH));
return false;
}
/*
=======================================================================
函数名 : Run
功能描述 : 运行
参数 : void
返回值 : NULL
=======================================================================
*/
void CScriptEngine::Run(bool threadmode)
{
// add by zdl. 2007-10-11
bNotifyStop_ = false;
bRunning_ = true;
this->bThreadMode_ = threadmode;
// end of add
if ( threadmode )
pThread_ = AfxBeginThread( ScriptRunThread, (LPVOID)this );
else
ScriptRunThread( (LPVOID)this );
}
void CScriptEngine::Stop( )
{
if (bRunning_)
{
this->bNotifyStop_ = true;
if (this->bThreadMode_)
{
DWORD dwWaitRet = ::WaitForSingleObject(pThread_->m_hThread, 5000);
if ( WAIT_TIMEOUT == dwWaitRet )
{
::TerminateThread(pThread_->m_hThread, 0);
}
bRunning_ = false;
}
}
}
/*
=======================================================================
函数名 : ScriptRunThread
功能描述 :
参数 : void
返回值 : NULL
=======================================================================
*/
UINT CScriptEngine::ScriptRunThread( LPVOID pParam )
{
CScriptEngine& se=*static_cast<CScriptEngine*>(pParam);
if(TryEnterCriticalSection(&se.m_RunSC))
{
while(se.Step())
{
// add by zdl. 2007-10-11
if (se.bNotifyStop_)
{
break;
}
// end of add
if (!se.m_Game.isInGame())
break;
}
se.m_ip=se.m_Scripts.begin();
LeaveCriticalSection(&se.m_RunSC);
se.m_Game.m_FrameWnd.AddLog(crRed,"脚本: 执行结束.\n");
}
else
{
se.m_Game.m_FrameWnd.AddLog(crRed,"脚本: 已经在运行中!!\n");
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -