[C++] HSM 实现示例

#include <iostream>
#include <stack>
using namespace std;

struct Virtual
{
	virtual ~Virtual() { }
};

struct Context;

struct State : Virtual
{
	virtual void Handle(Context& data) { Update(data); };
	virtual void Entry(Context& data);
	virtual void Update(Context& data) { }
	virtual void Exit(Context& data);
};

struct Normal : State
{
	void Handle(Context& data);
};

struct StandBy : Normal
{
	void Handle(Context& data);
	void Entry(Context& data);
	void Update(Context& data);
};

struct Move : Normal
{
	void Handle(Context& data);
	void Entry(Context& data);
	void Update(Context& data);
};

struct Shoot : State
{
	void Handle(Context& data);
	void Entry(Context& data);
	void Update(Context& data);
};

struct Context
{
	StandBy standBy_;
	Move move_;
	Shoot shoot_;

	stack<State*> active_;

	char input = 0;

	Context() { active_.push(&standBy_); }

	void Handle() { active_.top()->Handle(*this); }
} context;

enum : char
{
	FIRE = 'f',
	STOP = 's',
	MOVE = 'm',
};

void State::Entry(Context& data)
{
	data.active_.push(this);
}

void State::Exit(Context& data)
{
	data.active_.pop();
}

void Normal::Handle(Context& data)
{
	if (FIRE == data.input)
	{
		data.shoot_.Entry(data);
	}
	else
	{
		State::Handle(data);
	}
}

void StandBy::Handle(Context& data)
{
	if (MOVE == data.input)
	{
		Exit(data);
		data.move_.Entry(data);
	}
	else
	{
		Normal::Handle(data);
	}
}

void StandBy::Entry(Context& data)
{
	Normal::Entry(data);
	cout << __FUNCTION__ << endl;
}

void StandBy::Update(Context& data)
{
	Normal::Update(data);
	cout << __FUNCTION__ << endl;
}

void Move::Handle(Context& data)
{
	if (STOP == data.input)
	{
		Exit(data);
		data.standBy_.Entry(data);
	}
	else
	{
		Normal::Handle(data);
	}
}

void Move::Entry(Context& data)
{
	Normal::Entry(data);
	cout << __FUNCTION__ << endl;
}

void Move::Update(Context& data)
{
	Normal::Update(data);
	cout << __FUNCTION__ << endl;
}

void Shoot::Handle(Context& data)
{
	if (FIRE != data.input)
	{
		Exit(data);
	}
	else
	{
		Update(data);
	}
}

void Shoot::Entry(Context& data)
{
	State::Entry(data);
	cout << __FUNCTION__ << endl;
}

void Shoot::Update(Context& data)
{
	State::Update(data);
	cout << __FUNCTION__ << endl;
}

int main()
{
	for (;;)
	{
		cin >> context.input;
		context.Handle();
	}
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据