边工作边学习,最近做语音模块,老大安排了任务去做语音唤醒实现。自己啪啪啪傻不垃圾的就用最简单的粗鄙方法实现了,老大看了看之后说,可以用状态机模式做的试试,然后就在老大的带领下,学习了状态机颇有收获。
一、什么是状态模式。
官方解释:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类
自己理解:就是外界调用类A对象的某个方法时,当这个方法改变了某种状态,然后就会在这个方法里面切换到对应的状态B类中。
二、看代码理解
2.1 所有状态需要一个管理类。
wakeupEngineManager
wakeupEngineManager {
public:
wakeupEngineManager() : mCurrentStatus(std::make_shared<IdleStatus>(this)) { }
bool changeToNotWakeupStates( ){
if ( nullptr != mCurrentStatus) {
mCurrentStatus -> changeToNotWakeupStates();
}
}
bool changeToWakeuped() {
if ( nullptr != mCurrentStatus) {
mCurrentStatus -> changeToWakeuped();
}
}
bool changeToIdle() {
if ( nullptr != mCurrentStatus) {
mCurrentStatus -> changeToIdle();
}
}
void changeStatus(std::shared_ptr<WakeupStatusBase> currentStatus) {
mCurrentStatus = currentStatus;
}
private:
std::shared_ptr mCurrentStatus ;
}
2.2 WakeupStatusBase.h 所有状态的基类。
class WakeupStatusBase {
public:
WakeupStatusBase(){};
virtual ~WakeupStatusBase(){};
virtual bool changeToNotWakeupStates = 0;
virtual bool changeToWakeuped() = 0;
virtual bool changeToIdle() = 0;
virtual int currentStatusClass() = 0;
};
2.3 其中的一个状态类 NotWakeupStatus 代表唤醒引擎启动了,但是还没有唤醒。
NotWakeupStatus,继承自 WakeupStatusBase
class NotWakeupStatus: public WakeupStatusBase {
public:
NotWakeupStatus(wakeupEngineManager * engine) {
mWakeupEngine = engine;
}
bool changeToNotWakeupStates() {
// 在这里方法里面做初始化唤醒引擎的动作。
return true;
}
bool changeToWakeuped(){
if (nullptr != mWakeupEngine) {
mWakeupEngine-> changeStatus(std::make_shared<WakeupedStatus> (mWakeupEngine));
}
return true;
}
bool changeToIdle() {
if (nullptr != mWakeupEngine) {
mWakeupEngine-> changeStatus(std::make_shared<IdleStatus> (mWakeupEngine));
}
return true;
}
private:
wakeupEngineManager * mWakeupEngine;
}
后面的 wakeupedStatus 和 idleStatus的类基本和 NotWakeupStatus 一样只是实现 基类的方法有点差异。
2.4 其中的一个状态类 WakeupedStatus 代表唤醒了。
WakeupedStatus ,继承自 WakeupStatusBase
class WakeupedStatus : public WakeupStatusBase {
public:
WakeupedStatus (wakeupEngineManager * engine) {
mWakeupEngine = engine;
}
bool changeToNotWakeupStates() {
if (nullptr != mWakeupEngine) {
mWakeupEngine-> changeStatus(std::make_shared<NotWakeupStatus> (mWakeupEngine));
}
return true;
}
bool changeToWakeuped(){
// 在这里做唤醒之后的事情
}
bool changeToIdle() {
if (nullptr != mWakeupEngine) {
mWakeupEngine-> changeStatus(std::make_shared<IdleStatus> (mWakeupEngine));
}
return true;
}
private:
wakeupEngineManager * mWakeupEngine;
}
2.5 其中的一个状态类 IdleStatus 代表唤醒模块失去了麦克风焦点或者是被的缘故,不能在使用了。
IdleStatus ,继承自 WakeupStatusBase
class IdleStatus : public WakeupStatusBase {
public:
WakeupedStatus (wakeupEngineManager * engine) {
mWakeupEngine = engine;
}
bool changeToNotWakeupStates() {
if (nullptr != mWakeupEngine) {
mWakeupEngine-> changeStatus(std::make_shared<NotWakeupStatus> (mWakeupEngine));
}
return true;
}
bool changeToWakeuped(){
// 不能够从idle直接到wakeuped。
return false;
}
bool changeToIdle() {
// 做切换到idle状态应该做的事情
return true;
}
private:
wakeupEngineManager * mWakeupEngine;
}
三 、 分析代码下来基本的状态机模式就是事件触发迁移到该事件对应的状态。
来源:CSDN
作者:lisiwei1994
链接:https://blog.csdn.net/lisiwei1994/article/details/103769874