SyntaxGameServer/RCCService2018/content/LuaPackages/OtterImpl/createGroupMotor.lua

124 lines
2.4 KiB
Lua

local RunService = game:GetService("RunService")
local assign = require(script.Parent.assign)
local createSignal = require(script.Parent.createSignal)
local GroupMotor = {}
GroupMotor.prototype = {}
GroupMotor.__index = GroupMotor.prototype
local function createGroupMotor(initialValues)
assert(typeof(initialValues) == "table")
local states = {}
for key, value in pairs(initialValues) do
states[key] = {
value = value,
complete = true,
}
end
local self = {
__goals = {},
__states = states,
__allComplete = true,
__onComplete = createSignal(),
__onStep = createSignal(),
}
setmetatable(self, GroupMotor)
return self
end
function GroupMotor.prototype:start()
self.__connection = RunService.RenderStepped:Connect(function(dt)
self:step(dt)
end)
end
function GroupMotor.prototype:stop()
if self.__connection ~= nil then
self.__connection:Disconnect()
end
end
function GroupMotor.prototype:step(dt)
assert(typeof(dt) == "number")
if self.__allComplete then
return
end
local allComplete = true
local values = {}
for key, state in pairs(self.__states) do
if not state.complete then
local goal = self.__goals[key]
if goal ~= nil then
local maybeNewState = goal:step(state, dt)
if maybeNewState ~= nil then
state = maybeNewState
self.__states[key] = maybeNewState
end
else
state.complete = true
end
if not state.complete then
allComplete = false
end
end
values[key] = state.value
end
local wasAllComplete = self.__allComplete
self.__allComplete = allComplete
self.__onStep:fire(values)
if allComplete and not wasAllComplete then
self.__onComplete:fire(values)
end
end
function GroupMotor.prototype:setGoal(goals)
assert(typeof(goals) == "table")
self.__goals = assign({}, self.__goals, goals)
for key in pairs(goals) do
local state = self.__states[key]
if state == nil then
error(("Cannot set goal for the value %s because it doesn't exist"):format(tostring(key)), 2)
end
state.complete = false
end
self.__allComplete = false
end
function GroupMotor.prototype:onStep(callback)
assert(typeof(callback) == "function")
return self.__onStep:subscribe(callback)
end
function GroupMotor.prototype:onComplete(callback)
assert(typeof(callback) == "function")
return self.__onComplete:subscribe(callback)
end
function GroupMotor.prototype:destroy()
self:stop()
end
return createGroupMotor