130 posts
Location
Here
Posted 20 March 2016 - 03:40 AM
OQ
Is there a way to detect a key combination for an interrupt similar to how CraftOS terminates a program with ctrl + T? This would be implemented in a program where the computer is left unattended and no events are being thrown while the program is running. (hence if yielding, the computer would hang)I have a completely isolated computer. a user can interact with this computer. the computer is running a program. the program will detect if a user enters a key sequence such as CTRL+D. if this sequence is detected, the program will call another function within the same program which is a CLI [aka console or shell]. once the user is finished with the CLI they will 'exit' the CLI and the loop which was running to detect the key sequence will again be running, as the CLI returned because it is simply a function.
How can I do this?
function console()
--console
end
function run()
while true do
if ([key sequence]) then
console()
else
--run program normally
end
end
end
ANSWER
function other()
print('Ctrl+D Detected!')
end
function run()
local counter = 0
while true do
local event, key = os.pullEvent()
if event == 'key' and key == keys.leftCtrl then
counter = 1
elseif event == 'key_up' and key == keys.leftCtrl then
counter = 0
end
if event == 'key' and key == keys.d and counter == 1 then
other()
end
end
end
run()
Credit: Bomb Bloke
Edited on 21 March 2016 - 09:01 PM
7083 posts
Location
Tasmania (AU)
Posted 20 March 2016 - 05:05 AM
You can't ever prevent events from being thrown - only from being caught. And if you're not catching events, then how would you catch Ctrl+T? That's putting aside that ComputerCraft will kill your script if it fails to yield regularly… the closest you could get would be to yield using an event filter set to something that can never occur.
Anyway, it's not so much CraftOS that handles Ctrl+T so much as it's os.pullEvent(). That function specifically looks out for "terminate" events in the queue and errors whenever it spots one. Compare os.pullEventRaw(), which is effectively the same other than the fact that it has no special handling for "terminate" events at all (meaning you can implement your own, or just ignore them entirely).
https://github.com/alekso56/ComputercraftLua/blob/master/bios.lua#L197
1080 posts
Location
In the Matrix
Posted 20 March 2016 - 08:00 AM
I'm assuming you want to basically hit a certain key, or any key to interrupt a running program? Depending on how your code is setup you could use just a normal while loop with a timer, or go for the parallel api.
130 posts
Location
Here
Posted 20 March 2016 - 05:48 PM
Yes, basically im looking to do what dragon says, sorry for the wording, when i say no events, i mean that no player is there to trigger events and i don't have the computer hooked up to anything that triggers events externally. its simply a standalone computer running my program. I'm trying to make a available an interrupt sequence not to 'stop' the program but to run another function.
function console()
--PROGRAM CONSOLE
end
function run()
if (KEY SEQUENCE) then
console()
end
end
7083 posts
Location
Tasmania (AU)
Posted 20 March 2016 - 09:37 PM
You've lost me. You want to detect the user pressing a certain combo even when there's no user there to enter the combo and generate the associated events…?
Well, let's say there IS a user present, they're holding eg Ctrl + I, and you want to detect that. First up, you'll ideally be using CC 1.74 or later, as that's the build that introduced key_up events.
The idea is that every time someone presses one of the keys that's involved in your combo, you'll get a "key" event, and you should increment a counter. Whenever they let go, you get a "key_up" event, and you should decrement your counter. If the counter reaches two, then both relevant keys are held, and you should go off and run your other function.
Under older CC builds (if memory serves), if Ctrl is held while a character key is pressed, a "char" event for that character will not be generated. So, on receiving a "key" event for your character of interest, you queue a random event, and if that gets pulled before the expected "char" event you know your combo is being held.
1080 posts
Location
In the Matrix
Posted 20 March 2016 - 09:57 PM
BB, you've got the concept wrong. He wants a script like this:
local timer = os.startTimer(0.1)
while true do
local event = {os.pullEvent()}
if event[1] == "timer" and event[2] == timer then
--#Normal code stuff
timer = os.startTimer(0.1)
elseif event[1] == "key" and event[2] == keys.w then
--#Other stuff
end
end
To be honest with you, the way he's describing it is that he wants basically the parallel api, however i think he also wants the normal program to pause while the other bit is executing. I believe a way to achieve that would be to override os.pullEvent to check if that key is pressed and then based on that run the appropriate function while also utilizing os.pullEventRaw or whatever.
130 posts
Location
Here
Posted 20 March 2016 - 11:12 PM
The only interaction with the user that the computer will have is when the user presses an interrupt sequence such as ctrl+T. otherwise the computer is left alone to run the program. When the user does press said sequence the running code will execute another function within the same file synchronously (NOT async aka parallel aka 'simultaneous').
130 posts
Location
Here
Posted 20 March 2016 - 11:24 PM
I'm obviously not making myself clear.
I have a completely isolated computer. a user can interact with this computer. the computer is running a program. the program will detect if a user enters a key sequence such as CTRL+D. if this sequence is detected, the program will call another function within the same program which is a CLI [aka console or shell]. once the user is finished with the CLI they will 'exit' the CLI and the loop which was running to detect the key sequence will again be running, as the CLI returned because it is simply a function.
function console()
--console
end
function run()
while true do
if ([key sequence]) then
console()
else
--run program normally
end
end
end
Edited on 20 March 2016 - 10:24 PM
7083 posts
Location
Tasmania (AU)
Posted 21 March 2016 - 06:54 AM
Ok, but… I assume you're already aware of how to detect standard keypresses, and I've explained above how pick up combinations.
So what's the problem?
130 posts
Location
Here
Posted 21 March 2016 - 09:40 PM
None, I've got it working now! :)/> Just wanted to restate because I was so unclear about it. Sorry :)/> hahaha