|
První jednoduchý skript
|
|
01.12.2005
Začneme opravdu jednoduchým skriptem, který do konzole vypíše toto
I am talking.
I am talking.
Proto si vytvoříme enumerátor:
enum EScriptOpCode
{
K_OP_TALK,
K_OP_END
};
|
Třída CInstruction
|
|
class CInstruction
{
EScriptOpCode m_eCode;
public:
CInstruction(EScriptOpCode _eCode) : m_eCode(_eCode){}
~CInstruction(){}
EScriptOpCode GetCode() const
{
return m_eCode;
}
};
Ukládá a vrací enumeratory skriptů
talk
a
end
|
Třída CScript
|
|
class CScript
{
std::vector<CInstruction> m_vInstruction;
public:
CScript(const std::vector<CInstruction>& _rvInstruction)
: m_vInstruction(_rvInstruction){}
~CScript(){}
const CInstruction* GetInstruction() const
{
return &m_vInstruction[0];
}
};
Ukládá a vrací pole instrukcí.
|
Třída CVirtualMachine
|
|
class CVirtualMachine
{
/// useful abstractions
/// pointers used as non-modifying dynamic references
typedef const CScript* TScriptRef;
typedef const CInstruction* TInstrRef;
std::vector<CScript> m_vScript;
TScriptRef m_tScript; /// current script
TInstrRef m_tInstrRoot; /// root instruction
TInstrRef m_tInstrCurr; /// current instruction
size_t m_uiNumScripts; /// number of loaded scripts
/// Add script to list and retrieve id
size_t AddScript(const CScript& _rScript)
{
m_vScript.push_back(_rScript);
return m_uiNumScripts++;
}
/// Set current script by id
void SelectScript(size_t _uiScriptId)
{
assert(_uiScriptId < m_uiNumScripts); /// make sure the id is valid
m_tScript = &m_vScript[_uiScriptId];
m_tInstrRoot = m_tScript->GetInstruction();
}
public:
CVirtualMachine()
: m_tScript(0), m_tInstrRoot(0), m_tInstrCurr(0), m_uiNumScripts(0){}
~CVirtualMachine(){}
/// Execute script
void Execute(size_t _uiScriptId);
size_t Load(const CScript& _rkScript)
{
return AddScript(_rkScript);
}
};
Načítá skripty do pole a vrací index.
size_t Load(const CScript& _rkScript)
{
return AddScript(_rkScript);
}
Potom za běhu engine volá funkci
void CVirtualMachine::Execute(size_t _uiScriptId)
{
/// Select root script by script index
SelectScript(_uiScriptId);
/// Set our iterator to the beginning
m_tInstrCurr = m_tInstrRoot;
while (m_tInstrCurr)
{
switch(m_tInstrCurr->GetCode())
{
case K_OP_TALK:
std::cout << "I am talking." << std::endl;
// Iterate
++m_tInstrCurr;
break;
case K_OP_END:
/// Discontinue the loop
m_tInstrCurr = 0;
break;
}
}
}
Která nastaví skript podle indexu
_uiScriptId
/// Set current script by id
void SelectScript(size_t _uiScriptId)
{
assert(_uiScriptId < m_uiNumScripts); /// make sure the id is valid
m_tScript = &m_vScript[_uiScriptId];
m_tInstrRoot = m_tScript->GetInstruction();
}
Nastaví aktuální instrukci
/// Set our iterator to the beginning
m_tInstrCurr = m_tInstrRoot
a pokud instrukce existuje
while (m_tInstrCurr)
získává a provádí skript
switch(m_tInstrCurr->GetCode())
{
case K_OP_TALK:
std::cout << "I am talking." << std::endl;
// Iterate
++m_tInstrCurr;
break;
case K_OP_END:
/// Discontinue the loop
m_tInstrCurr = 0;
break;
}
|
Test skriptu
|
|
Při načítání scény:
Vytvoříme virtual machine VM
CVirtualMachine kVM;
Vytvoříme instrukce a skript
// build the script
vector<CInstruction> vInstr;
vInstr.push_back(CInstruction(K_OP_TALK)); // talk twice
vInstr.push_back(CInstruction(K_OP_TALK)); // talk twice
vInstr.push_back(CInstruction(K_OP_END)); // then end
CScript kScript(vInstr);
Načteme skript a získáme jeho index.
/// Load the script and save the id
size_t uiScriptId = kVM.Load(kScript);
Při běhu aplikace:
Předáváme VM index skriptu. Tento skript se aktivuje.
/// execute the script by its id
kVM.Execute(uiScriptId);
home
/
opengl game