Files
Main/Assets/GameAssets/Resources/Lua/Common/ExternalLib/AI/FSM/StateMachine.lua
2025-01-25 04:38:09 +08:00

157 lines
3.7 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

------------------------------------------------
--作者xihan
--日期2019-07-02
--文件StateMachine.lua
--模块StateMachine
--描述:状态机类
------------------------------------------------
local StateMachine = {
--状态机所有者
Owner = nil,
--配置信息
Config = nil,
--前一个状态
PreState = nil,
--当前状态
CurState = nil,
--前一个状态的参数
PreParam = nil,
--当前参数
CurParam = nil,
--方法名缓存
FuncNameCache = nil,
--配置id
ConfigId = nil,
--当前状态更新函数可nil
StateUpdateFunc = nil,
}
function StateMachine:New(owner, configId)
local _t = Utils.DeepCopy(self);
_t:SetOwner(owner);
if configId then
_t:SetConfig(configId);
end
return _t;
end
function StateMachine:SetOwner(owner)
self.Owner = owner;
end
function StateMachine:SetConfig(configId)
self:Clear();
if not self.Owner or not configId or configId == -1 then
return;
end
self.ConfigId = configId;
self.ID = self.Owner.ID;
local _cfgPath = string.format("Config.AI.%s",configId);
--移除是为了方便调试
Utils.RemoveRequiredByName(_cfgPath);
local _cfg = require(_cfgPath);
self.Config = Utils.DeepCopy(_cfg);
self.Config.Owner = self.Owner;
self.Config.ChangeState = function(cfg, cfgState, cfgParam)
self:ChangeState(cfgState, cfgParam);
end
self.Config:Init();
end
function StateMachine:GetFunc(state, funcName)
if not self.FuncNameCache[state] then
self.FuncNameCache[state] = {};
end
if not self.FuncNameCache[state][funcName] then
self.FuncNameCache[state][funcName] = string.format("On_%s_%s", state, funcName);
end
return self.Config[self.FuncNameCache[state][funcName]];
end
function StateMachine:GetCurState()
return self.CurState;
end
function StateMachine:GetOwner()
return self.Owner;
end
--改变状态
function StateMachine:ChangeState(State, param)
if self.CurState == State then
return
end
local _checkFunc = self:GetFunc(State,"Check");
if State and (not _checkFunc or _checkFunc and _checkFunc(self.Config, self.PreState, self.PreParam)) then
self.PreState = self.CurState;
self.PreParam = self.CurParam;
if self.PreState then
local _exitFunc = self:GetFunc(self.PreState,"Exit");
if _exitFunc then
_exitFunc(self.Config);
end
end
self.CurState = State;
self.CurParam = param;
self.Config.CurState = State;
self.Config.CurParam = param;
local _enterFunc = self:GetFunc(State,"Enter");
if _enterFunc then
_enterFunc(self.Config);
end
self.StateUpdateFunc = self:GetFunc(State, "Update");
return true;
end
return false;
end
--恢复上一个状态
function StateMachine:RevertState()
if self.PreState then
self:ChangeState(self.PreState, self.PreParam);
end
end
--判断当前的状态
function StateMachine:IsState(State)
return self.CurState == State;
end
--更新
function StateMachine:Update()
if not self.Config then
return;
end
if self.CurState then
if self.StateUpdateFunc then
self.StateUpdateFunc (self.Config);
end
end
self.Config:Update();
end
--处理消息
function StateMachine:PushEvent(args)
if self.Config then
self.Config:Event(args);
end
end
--清理状态
function StateMachine:Clear()
self.CurState = nil;
self.PreState = nil;
self.PreParam = nil;
self.CurParam = nil;
self.ConfigId = nil;
self.Config = nil;
self.StateUpdateFunc = nil;
self.FuncNameCache = {};
end
return StateMachine;