160 posts
Location
Netherlands
Posted 23 June 2013 - 03:48 PM
Is it possible to check for mouse clicks and handle keyboard input at the same time?
Let's say I have this code:
print("Type something")
input = read()
while true do
event = {os.pullEvent()}
if event[1] == "mouse_click" then
print("Mouse click")
end
end
How would I check for mouse clicks while it's waiting for the user to type something?
1522 posts
Location
The Netherlands
Posted 23 June 2013 - 04:02 PM
Of course, the only thing that makes it complex is that you have to write your own read function. This is very, very primitive:
local str = ""
while true do
local event = { os.pullEvent() }
if event[1] == "mouse_click" then
-- Do stuff with your mouse
elseif event[1] == "char" then
str = str .. event[2]
end
end
But like I said, you can take this to the next level and make it super complex if you really want. Only Im not doing that for you :P/>
504 posts
Location
Seattle, WA
Posted 23 June 2013 - 04:38 PM
Engineer gave a great example of how you might do what you're asking for.
Here's a similar way, but using coroutines:
local function mouseClickHandler (eventName, clickType, xClickPos, yClickPos)
local currentCursorPos = { term.getCursorPos() }
term.setCursorPos (1, currentCursorPos[2] + 1)
term.write ("Mouse click at: (" .. currentCursorPos[1] .. ", " .. currentCursorPos[2] .. ')')
term.setCursorPos (unpack (currentCursorPos))
end
local function modifiedRead()
local readCoroutine = coroutine.create (read)
coroutine.resume (readCoroutine)
local mouseClickHandlerCoroutine = coroutine.create (mouseClickHandler)
while coroutine.status (readCoroutine) ~= "dead" do
local eventData = { os.pullEvent() }
if eventData[1] == "mouse_click" then
coroutine.resume (mouseClickHandler, unpack (eventData))
else
coroutine.resume (readCoroutine, unpack (eventData))
end
end
end
160 posts
Location
Netherlands
Posted 23 June 2013 - 05:22 PM
Of course, the only thing that makes it complex is that you have to write your own read function. This is very, very primitive:
-snip-
But like I said, you can take this to the next level and make it super complex if you really want. Only Im not doing that for you :P/>
Engineer your example works great, that's the second time tonight :P/>
Engineer gave a great example of how you might do what you're asking for.
Here's a similar way, but using coroutines:
-snip-
Is there an advantage on using coroutines here? All I can think of is that you can actually click and type at the same time
1604 posts
Posted 23 June 2013 - 06:47 PM
Why would you write a coroutine manager when you have the parallel api? ;)/>
local input
local function getInput()
print("Type something:")
input = read()
end
local function getMouseInput()
while true do
local evt, btn, x, y = os.pullEvent("mouse_click")
-- Handle the mouse click here
end
end
parallel.waitForAny(getInput, getMouseInput)
160 posts
Location
Netherlands
Posted 24 June 2013 - 01:46 PM
Why would you write a coroutine manager when you have the parallel api? ;)/>
-snip-
If I use your method, and I click something that clears the screen, it still waits for an input. Is there way to stop that?
1522 posts
Location
The Netherlands
Posted 24 June 2013 - 01:54 PM
If I use your method, and I click something that clears the screen, it still waits for an input. Is there way to stop that?
Then you must have your own read function that checks continueusly if a boolean is true. If that is true it will break that loop it is in
160 posts
Location
Netherlands
Posted 24 June 2013 - 01:59 PM
If I use your method, and I click something that clears the screen, it still waits for an input. Is there way to stop that?
Then you must have your own read function that checks continueusly if a boolean is true. If that is true it will break that loop it is in
That'll work :P/>
1604 posts
Posted 24 June 2013 - 03:03 PM
The parallel.waitForAny call should return when one of the functions ends. So, you just have to make the mouse input function end and it will end the other one too. Example:
local input
local function getInput()
print("Type something:")
input = read()
end
local function getMouseInput()
while true do
local evt, btn, x, y = os.pullEvent("mouse_click")
break -- stop the loop when we get a mouse click
end
end
parallel.waitForAny(getInput, getMouseInput)
term.clear()
term.setCursorPos(1, 1)
if input then
print("Your input: ", input)
else
print("You clicked the screen!")
end
If this is not what you need, please explain what you are trying to do, so we can help.
160 posts
Location
Netherlands
Posted 24 June 2013 - 05:38 PM
The parallel.waitForAny call should return when one of the functions ends. So, you just have to make the mouse input function end and it will end the other one too. Example:
-snip-
If this is not what you need, please explain what you are trying to do, so we can help.
Your method combined with a custom read function and os.queueEvent() worked mostly fine, just when I clicked something, it executed the command from the click before it ended the keyboard input loop, causing buttons on the next screen to not-respond for some reason. I guess becouse there were multiple os.pullEvent()'s running
But i've just found that this method works perfect:
Spoiler
local data = {}
function main()
term.clear()
term.setCursorPos(1,1)
data[1] = 1
data[2] = 1
data[3] = ms
parallel.waitForAny(handleMouse, handleInput)
data[1] = 2
data[2] = 1
data[3] = ms
handleMouse()
end
function handleInput()
term.write("Input: ")
local inp = read()
if inp == "yes" then
kb()
end
end
function handleMouse()
while true do
local event = {os.pullEvent()}
if event[1] == "mouse_click" then
for k, v in ipairs(data) do
if event[3] == data[1] and event[4] == data[2] then
data[3]()
return
end
end
end
end
end
function ms()
print("Mouse got here")
end
function kb()
print("Keyboard got here")
end
main()
It's pretty much the same as your function but i've used return instead of break since the wiki states "stops when any of them returns."
7508 posts
Location
Australia
Posted 25 June 2013 - 12:44 AM
your code will error after you restart your computer. Move your functions above the parallel call to fix this future problem.
160 posts
Location
Netherlands
Posted 25 June 2013 - 05:10 AM
your code will error after you restart your computer. Move your functions above the parallel call to fix this future problem.
Thanks TOB
7508 posts
Location
Australia
Posted 25 June 2013 - 09:44 AM
Thanks TOB
No problems :)/> as always here to help…
Also, just a side note, if you want to shorten either BIT or TOBIT. I'd prefer former over latter. :)/>