The reason why your programs can be terminated is because you're either using os.pullEvent() somewhere, or because you're calling an external function and that uses os.pullEvent().
os.pullEvent() is the reason why your program will stop execution on pressing CTRL+T:
If you press CTRL+T then the 'terminate' event is created.
os.pullEvent() listens for that event and will throw the error message 'Terminated', which in turn will stop your program.
There are two ways you can prevent CTRL+T from stopping your programs:
- Catch the error thrown by os.pullEvent() by making use of the pcall() function. Quote from lua.org's manual:
- Use os.pullEventRaw() instead of os.pullEvent() If you take a closer look at how os.pullEvent() is implemented ("bios.lua"), then you can see that it calls os.pullEventRaw() to receive an event and in addition to that throws an error if the event was 'terminate'. That means instead of using os.pullEvent() in your program, you can just replace it with os.pullEventRaw() to prevent CTRL+T to throw an error. Now, os.pullEventRaw() itself simply wraps coroutine.yield(), but that is not necessary knowledge for this tutorial and deserves its own topic. So if your program is something like this…
So let's say you have this code:pcall (f, arg1, …)
Calls function f with the given arguments in protected mode. This means that any error inside f is not propagated; instead, pcall catches the error and returns a status code. Its first result is the status code (a boolean), which is true if the call succeeds without errors. In such case, pcall also returns all results from the call, after this first result. In case of any error, pcall returns false plus the error message.
local password = "secret"
local input
repeat
write("Password: ")
input = read()
until input == password
Since read() is using os.pullEvent(), instead of directly calling read() we can call it via pcall() instead:
local password = "secret"
local status, input
repeat
write("Password: ")
status, input = pcall(read)
until input == password
while true do
local sEvent, param = os.pullEvent()
if sEvent == "key" and param == 28 then
print("You pressed ENTER")
end
end
… then simply replace the os.pullEvent() with os.pullEventRaw() to prevent CTRL+T from stopping your program:
while true do
local sEvent, param = os.pullEventRaw()
if sEvent == "key" and param == 28 then
print("You pressed ENTER")
end
end
The only way to stop this program now would be to reboot the (ingame-) computer.But which of all the CC-functions make use of os.pullEvent() ?
As of CC version 1.2 the functions making use of os.pullEvent() either directly or indirectly are:
- sleep
- read
- rednet
To prevent that, call them via pcall (as described further up)
The number of functions using os.pullEvent() or the functions themselves might change in the future though.
Therefore it's always a good idea to check them for yourself. All the functions should either be in "bios.lua" or the API files.
Location of "bios.lua": .minecraft\mods\ComputerCraft\lua\
Location of the API files: .minecraft\mods\ComputerCraft\lua\rom\apis\
Example: Does read() make use of os.pullEvent() ?
- read() is defined within "bios.lua", so we open that file.
- We search for os.pullEvent() within the read() function and find this line:
local sEvent, param = os.pullEvent()
- So yes, CC's read() does use os.pullEvent() and if we'd use it in our program it could be terminated with CTRL+T.
Further Information:
- From the Lua Manual: Error Handling pcall() Definition
- From Programming in Lua: Error Handling and Exceptions
I hope everything was easy to follow and not too complicated.
If you have any further questions or suggestions, feel free to ask.
Cheers! ;)/>/>