Files
Roblox-Elevator-Game/src/server/main/Elevators/Otis1960/RelayAlgorithm.lua
2024-05-27 02:36:28 -04:00

95 lines
2.6 KiB
Lua

--!optimize 2
--!native
--!strict
type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor))
type Impl_Constructor = {
__index: Impl_Constructor,
constructor: Constructor_Fun,
--Class functions
Sort: (self: ClassConstructor, ElevatorGoingUp: boolean) -> (),
Check: (self: ClassConstructor, ElevatorGoingUp: boolean) -> (),
RawInsert: (self: ClassConstructor, ElevatorGoingUp: boolean, RequestedLevel: number) -> (),
AddFloor: (self: ClassConstructor, ElevatorGoingUp: boolean, RequestedLevel: number) -> boolean
}
type Constructor_Fun = (BoxAlignPosition: AlignPosition, ElevatorAttributes: ElevatorAttributes, DoorAttributes: DoorAttributes) -> ClassConstructor
type Constructor_Return_Props = {
BoxAlignPosition: AlignPosition,
ElevatorAttributes: ElevatorAttributes,
DoorAttributes: DoorAttributes,
__FloorQueue: FloorQueue,
Events: {
Sorted: BindableEvent
}
}
type ElevatorAttributes = {
CurrentFloor: IntValue,
GoingUp: BoolValue,
Moving: BoolValue,
}
type DoorAttributes = {
Relay: {
Open: BoolValue
}
}
export type FloorQueue = {number?}
export type RelayAlgorithmConstructor = ClassConstructor
local RelayAlgorithm = {} :: Impl_Constructor
RelayAlgorithm.__index = RelayAlgorithm
function RelayAlgorithm.constructor(BoxAlignPosition, ElevatorAttributes, DoorAttributes)
return setmetatable({
Events = {
Sorted = Instance.new("BindableEvent")
},
BoxAlignPosition = BoxAlignPosition,
ElevatorAttributes = ElevatorAttributes,
DoorAttributes = DoorAttributes,
__FloorQueue = {},
}, RelayAlgorithm)
end
--The Otis relay based call logic
--https://youtu.be/BCN9mQOT3RQ
function RelayAlgorithm:Sort(ElevatorGoingUp)
table.sort(self.__FloorQueue, function(a, b): boolean
if ElevatorGoingUp then
return a<b
else
return a>b
end
end)
self.Events.Sorted:Fire(self.__FloorQueue)
end
function RelayAlgorithm:Check(ElevatorGoingUp)
if self.__FloorQueue[1] == self.ElevatorAttributes.CurrentFloor.Value then
table.remove(self.__FloorQueue, 1)
end
if #self.__FloorQueue ~= 0 then
self:Sort(ElevatorGoingUp)
return true
end
return false
end
function RelayAlgorithm:RawInsert(ElevatorGoingUp, RequestedLevel)
table.insert(self.__FloorQueue, ElevatorGoingUp == self.ElevatorAttributes.GoingUp.Value and 1 or #self.__FloorQueue+1, RequestedLevel)
self:Sort(ElevatorGoingUp)
end
function RelayAlgorithm:AddFloor(ElevatorGoingUp, RequestedLevel)
self:RawInsert(ElevatorGoingUp, RequestedLevel)
return not self.ElevatorAttributes.Moving.Value and self.DoorAttributes.Relay.Open.Value
end
return RelayAlgorithm