728x90
1. 바이트 코드 패턴 정의
- 가상 머신 명령어를 인코딩한 데이터로 행동을 표현할 수 있는 유연함을 제공하는 패턴
2. 명령어 집합
enum Instruction
{
INST_SET_HEALTH = 0x00,
ISNT_SET_WISDOM = 0x01,
INST_SET_AGILITY = 0x02,
INST_PLAY_SOUND = 0x03,
INST_SPAWN_PARTICLES = 0x04,
INST_LITERAL = 0x05,
INST_GET_HEALTH = 0x06,
INST_GET_WISDOM = 0x07,
INST_GET_AGILITY = 0x08,
INST_ADD = 0x09,
};
- 명령어는 열거형으로 표현할 수 있다.
- 명령어들을 데이터로 인코딩하기 위해서는 열거형 값( Byte )을 배열에 저장하면 된다.
- 데이터로 인코딩 된 명령어들은 열거형 값들의 배열, 즉 바이트들의 목록이다 보니 '바이트코드'라고 불린다.
3. 명령어를 해석하고 실행시키기 위한 API메서드
switch ( instruction )
{
case INST_SET_HEALTH:
SetHealth( 0, 100 );
break;
case ISNT_SET_WISDOM:
SetWisdom( 0, 100 );
break;
case INST_SET_AGILITY:
SetAgility( 0, 100 );
break;
case INST_PLAY_SOUND:
PlaySound( SoundData::SOUND_BANG );
break;
case INST_SPAWN_PARTICLES:
SpawnParticles( Particle::PARTICLE_FLAME );
break;
}
- 위와 같이 가상 머신( 인터프리터 )은 코드와 데이터를 연결한다.
4. VM에서 래핑 한 코드
class VM
{
public:
void Interpret( char bytecode[], int size )
{
for ( int index = 0; index < size; ++index )
{
char instruction = bytecode[ index ];
switch (instruction)
{
case INST_SET_HEALTH:
// ..
break;
}
}
}
};
- 바이트코드를 읽어 명령어를 실행한다.
5. 스택 머신을 이용한 명령어 실행 순서 제어
class VM
{
private:
static const int MAX_STACK = 128;
int stackSize;
int stack[ MAX_STACK ];
private:
void Push( int InValue )
{
// +스택 오버플로 검사
stack[ stackSize++ ] = InValue;
}
int Pop()
{
// +스택 비어 있지 않은지 검사
return stack[ --stackSize ];
}
public:
VM() : stackSize(0) {}
void Interpret( char bytecode[], int size )
{
for ( int index = 0; index < size; ++index )
{
char instruction = bytecode[ index ];
switch ( instruction )
{
case INST_SET_HEALTH:
{
int amount = Pop();
int wizard = Pop();
SetHealth( wizard, amount );
}
break;
case INST_LITERAL:
{
// 바이트코드에서 다음 바이트 값을 읽는다.
int value = bytecode[ ++index ];
Push( value );
}
break;
case INST_GET_HEALTH:
{
int wizard = Pop();
Push( GetHealth( wizard ) );
}
break;
case INST_ADD:
{
int b = Pop();
int a = Pop();
Push( a + b );
}
break;
//case ISNT_SET_WISDOM:
//...
//case INST_SET_AGILITY:
//...
//case INST_PLAY_SOUND:
//...
//...
}
}
}
};
- 스택에서 값을 얻어오기 위해 리터럴 명령어를 추가한다.
- 리터럴 값 이후에 나오는 바이트를 값으로 읽어 스택에 넣어 사용한다.
- Get, Set 명령어를 통해 다양한 행동을 할 수 있도록 조합하여 사용한다.
반응형
'Design Pattern > 게임 프로그래밍 패턴' 카테고리의 다른 글
[Design Pattern] 컴포넌트 패턴 (0) | 2022.08.05 |
---|---|
[Design Pattern] 하위 클래스 샌드박스 패턴 (0) | 2022.08.02 |
[Design Pattern] 업데이트 메서드 패턴 (0) | 2022.08.01 |
[Design Pattern] 게임 루프 패턴 (0) | 2022.07.31 |
[Design Pattern] 상태 패턴 (0) | 2022.07.31 |