This is a really poorly done question on your part -- You haven't described what you're doing or exactly what you have in mind.
I'm going to assume you have an elevator, and either an "up", "down", and "stop" button, and a "call to this floor" button (maybe a few of these).
That means the elevator has a few states: moving up, moving down, or stopped.
Based on the last button that was pressed, it has a particular state (or we could get more complicated).
At this point, there are two approaches. Since the important state changes are when you press buttons, it might actually be best to not have some constant loop and just do work when the buttons are pressed. This gets a little complicated, but I'll outline it first, because it sometimes looks nice.
The other option is for something to constantly be looking at the elevator's state and make sure it is appropriate based on the last button pressed. I'll do this second.
Events
I'm going to use a "hypothetical" elevator where the only thing I do is set a variable velocity -- 1 for up, -1 for down, 0 for stopped.
function stopButton()
velocity = 0
end
function upButton()
velocity = 1
end
function downButton()
velocity = -1
end
This is remarkably simple -- no loops required.
Now, let's consider a "call" button. For this, we need to know where the elevator is. We'll use y to mean the elevator's position (but we won't set y, only read from it). I'll use ty as the "target y" (the y of the given floor) in this event:
function callTo(ty)
if ty == y then
velocity = 0
elseif ty < y then
velocity = -1
else
velocity = 1
end
end
This will make the elevator go towards the floor, but it won't stop when it gets there.
An idiomatic way would be to use a while loop (though a repeat until would be equivalent)
function callTo(ty)
while ty ~= y do
if ty < y then
velocity = -1
else
velocity = 1
end
wait()
end
velocity = 0
end
This will work -- but it will only work with 1 call at a time.
One simple solution is the debounce pattern - we essentially "disable" calling as long as it is still going to its floor:
canCall = true
function callTo(ty)
if not canCall then
return
end
canCall = false
while ty ~= y do
end
velocity = 0
canCall = true
end
This may be what we want, but it may not. We may want to interrupt the current action whenever we press a button (this would be more sensical to most users, though probably isn't what a real elevator would do)
To do that, we will keep track of something like a reverse debounce, where any other call will inform all previous ones to stop operating.
controller = nil
function callTo(ty)
local myControl = math.random()
controller = myControl
while controller == myControl and ty ~= y do
end
velocity = 0
end
Now, whenever callTo gets called, it changes controller, but it doesn't change myControl -- so controller == myControl becomes false and the old call stops working.
Single, Constant Loop
The final design that we have is essentially just one loop -- it just gets traded off between different calls to the function with a different ty variable.
With that in mind, we can make a much simpler system:
target = 0
function callTo(ty)
target = ty
end
while true do
wait()
if y == target then
velocity = 0
elseif y < target then
velocity = -1
else
velocity = 1
end
end
This is all we need. If we wanted to put some sort of "debounce", we could do that, too:
target = 0
function callTo(ty)
target = ty
end
local realTarget = 0
while true do
wait()
if y == realTarget then
velocity = 0
elseif y < realTarget then
velocity - 1
else
velocity = 1
end
if velocity == 0 then
realTarget = target
end
end
One interesting difference between this and the debounce above is that this will still hear when you press. It just waits until it's done, and then does it. (You could, with the above system, do this by instead repeat wait() until canCall, but this would be a problem if multiple buttons were pressed in that time -- since they might all start more or less at the same time but don't check the debounce -- or, worse, make a big stack of different locations to track to -- so the elevator would be "frozen" in an odd path for however many times people pressed buttons)
Real-er elevator?
I would like to think that real elevators aren't so dumb. I will write more about this shortly.
Here is what I would suggest a real elevator does:
Keeps a list of all floors that need to be visited. A floor needs to be visited because either it was called to that floor, or because that floor was indicated while inside the elevator. I am not going to make any distinction about priority between the two types of calls, though you could if you wanted to.
Whenever a floor that needs to be visited is passed, stop and open the doors -- then continue on.
Here is what it might look like:
function find(tab, val)
for i,v in pairs(tab) do
if v == val then
return i
end
end
end
local visits = {}
function callTo(ty)
if not find(visits, ty) then
table.insert(visits, ty)
end
end
local target = y
while true do
wait()
if find(visits, y) then
open = true
wait(1)
open = false
table.remove(visits, find(visits, y))
end
if y == target then
if #visits > 0 then
target = table.remove(1)
else
velocity = 0
end
end
end
2 comments
I haven't the faintest idea what you're problem is...
i want to know how to make a loop that will wait until the elevator is idle to run