Files
Roblox-Elevator-Game/src/server/main/Elevators/System/RelayAlgorithm.luau
2024-09-06 14:58:12 -04:00

95 lines
2.9 KiB
Lua

--!optimize 2
--!strict
--Slap this here
--The Otis relay based call logic
--https://youtu.be/BCN9mQOT3RQ
local StorageService = game:GetService("ReplicatedStorage")
local Enums = require(StorageService:WaitForChild("Enums"))
type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor))
type Impl_Constructor = {
__index: Impl_Constructor,
constructor: Constructor_Fun,
--Class functions
Sort: (self: ClassConstructor, Direction: Enums.ElevatorCallDirectionValues) -> (),
AddFloor: (self: ClassConstructor, Direction: Enums.ElevatorCallDirectionValues, RequestedLevel: number) -> (),
}
export type RelayAlgorithmEvents = {
Sorted: RBXScriptSignal<Enums.ElevatorCallDirectionValues, FloorDirectionQueue>,
Added: RBXScriptSignal<Enums.ElevatorCallDirectionValues, number>,
__eventInstances__: {
Sorted: BindableEvent,
Added: BindableEvent
}
}
type Constructor_Fun = (ElevatorBoxModel: AlignPosition) -> ClassConstructor
type Constructor_Return_Props = {
ElevatorBoxModel: AlignPosition,
FloorQueue: FloorQueue,
Events: RelayAlgorithmEvents,
}
type DoorAttributes = {
Relay: {
Open: BoolValue
}
}
export type FloorDirectionQueue = {number?}
export type FloorQueue = {
Up: FloorDirectionQueue,
Down: FloorDirectionQueue
}
export type RelayAlgorithmConstructor = ClassConstructor
local RelayAlgorithm = {} :: Impl_Constructor
RelayAlgorithm.__index = RelayAlgorithm
function RelayAlgorithm.constructor(ElevatorBoxModel)
local Sorted = Instance.new("BindableEvent") :: BindableEvent
local Added = Instance.new("BindableEvent") :: BindableEvent
return setmetatable({
ElevatorBoxModel = ElevatorBoxModel,
FloorQueue = {
Up = {},
Down = {},
},
Events = {
Sorted = Sorted.Event,
Added = Added.Event,
__eventInstances__ = {
Sorted = Sorted,
Added = Added
}
},
}, RelayAlgorithm)
end
function RelayAlgorithm:Sort(Direction)
if Direction == Enums.ElevatorCallDirection.Up then
table.sort(self.FloorQueue.Up, function(FirstFloorIndex, LastFloorIndex): boolean
return FirstFloorIndex<LastFloorIndex
end)
self.Events.__eventInstances__.Sorted:Fire(Enums.ElevatorCallDirection.Up, self.FloorQueue.Up)
elseif Direction == Enums.ElevatorCallDirection.Down then
table.sort(self.FloorQueue.Down, function(FirstFloorIndex, LastFloorIndex): boolean
return FirstFloorIndex>LastFloorIndex
end)
self.Events.__eventInstances__.Sorted:Fire(Enums.ElevatorCallDirection.Down, self.FloorQueue.Down)
else
warn(`[{script.Name}.lua]: :Sort method failed. Called an unknown enum direction, direction={Direction}`, debug.traceback())
end
end
function RelayAlgorithm:AddFloor(Direction, RequestedLevel)
table.insert(Direction == Enums.ElevatorCallDirection.Up and self.FloorQueue.Up or self.FloorQueue.Down, RequestedLevel)
self.Events.__eventInstances__.Added:Fire(Direction, RequestedLevel)
end
return RelayAlgorithm