Rick Posted November 26, 2016 Share Posted November 26, 2016 State management is a very common thing for a lot of different tasks. I've made a fairly basic state management script in lua that I'm using and was thinking it would be handy if LE maybe had some state management built into Script's. Each state generally has an Enter, Exit, Update (maybe Draw for 2D) function. In the LE Script's these could be named functions that we add during init. Might be nice to be able to do: self.entity:AddState("reload", self.Reload_Enter, self.Reload_Exit, self.Reload_Update, self.Reload_PostRender) self.entity:ChangeState("reload") Just a thought. Quote Link to comment Share on other sites More sharing options...
Josh Posted November 26, 2016 Share Posted November 26, 2016 Example script? Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Rick Posted November 27, 2016 Author Share Posted November 27, 2016 Below is the state manager script itself. It can call onEnter, onExit, onUpdate functions that you add for each state. The onUpdate can be called at intervals vs every frame if you need (think AI thinking and maybe it has some heavier processing to it that you don't want to do every frame). if StateManager ~= nil then return end StateManager = {} function StateManager:Create(container) local obj = {} obj.states = {} obj.container = container obj.activeState = nil obj.nextState = nil obj.lastState = nil obj.lastUpdate = Time:GetCurrent() for k,v in pairs(StateManager) do obj[k] = v end return obj end -- methods param = { onEnter = self.function, onUpdate = self.function, onExit = self.function } function StateManager:AddState(name, methods, updateInterval) self.states[name] = {} self.states[name].methods = methods self.states[name].updateInterval = updateInterval or 0 end function StateManager:GetCurrentState() return self.activeState end function StateManager:ChangeState(name) -- this happens the FIRST time we change to the first state if self.activeState == nil then self.activeState = name self.nextState = nil else self.nextState = name self.lastUpdate = self.states[self.nextState].updateInterval * -2 -- make it so Update is called once right away end local name = self.container.entity:GetKeyValue("name") System:Print("Changing state to "..name.." for "..name) end function StateManager:ChangeToLastState() self:ChangeState(self.lastState) end function StateManager:Update() if self.activeState == nil then return end -- check for switching states if self.nextState ~= nil then -- exit function of current state if self.states[self.activeState].methods.onExit ~= nil then self.states[self.activeState].methods.onExit(self.container) end -- set new state self.lastState = self.activeState -- save off the last state self.activeState = self.nextState self.nextState = nil -- enter function of new state if self.states[self.activeState].methods.onEnter ~= nil then self.states[self.activeState].methods.onEnter(self.container) end end -- update function of current state called every interval if self.states[self.activeState].methods.onUpdate ~= nil then if Time:GetCurrent() >= self.states[self.activeState].updateInterval + self.lastUpdate then self.lastUpdate = Time:GetCurrent() self.states[self.activeState].methods.onUpdate(self.container) end end end I'll have to work up an example I guess. Looking at the MonsterAI.lua it seems like it might be a good one to do with a state machine. It basically removes a bunch of if/else statements you'd normally have and directs things to the onEnter/onExit/onUpdate methods of each state and you just change between states based on what's happening. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.