This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
MentalHamburger's profile picture

Max Length Input Bug

Started by MentalHamburger, 29 October 2015 - 06:31 PM
MentalHamburger #1
Posted 29 October 2015 - 07:31 PM
Hey i'm using code i found on the forums in my code to limit the length of an input, the code is causing bugs in my program. When i switch between the Register and Login screen then try to type something it will type multiple characters, I believe this is because it is running more that one of the custom read function. Any help is appreciated!

Read Function Code:


function limitRead(nLimit, replaceChar)
	term.setCursorBlink(true)
	local cX, cY = term.getCursorPos()
	local rString = ""
	if replaceChar == "" then replaceChar = nil end
	repeat
		local event, p1 = os.pullEvent()
		if event == "char" then
			-- Character event
			if #rString + 1 <= nLimit then
				rString = rString .. p1
				write(replaceChar or p1)
			end
		elseif event == "key" and p1 == keys.backspace and #rString >= 1 then
			-- Backspace
			rString = string.sub(rString, 1, #rString-1)
			xPos, yPos = term.getCursorPos()
			term.setCursorPos(xPos-1, yPos)
			write(" ")
			term.setCursorPos(xPos-1, yPos)
		end
	until event == "key" and p1 == keys.enter
	term.setCursorBlink(false)
	print() -- Skip to the next line after clicking enter.
	return rString
-- And you call it like this
	--input = limitRead(10)
	-- If you want to replace it with a char, like read("*") then
	--password = limitRead(10, "*")
end

Program Code:


shell.run("Startup/Main")
boot(0.1)
local function LoginBoot()
  clear()
  paintutils.drawImage(UsernameScreen,1,1)
  term.setCursorPos(17,11)
  term.setBackgroundColour(colors.lightGray)
  term.setTextColor(colors.white)
  print("Account Username:")
  term.setCursorPos(39,17)
  print("Register")
  term.setCursorPos(17,13)
  term.setBackgroundColour(colors.white)
  term.setTextColor(colors.blue)
  username = limitRead(17)
  sleep(0.5)
end
local function Register()
  endRead = "true"
  clear()
  paintutils.drawImage(RegisterScreen,1,1)
  term.setCursorPos(21,2)
  term.setBackgroundColour(colors.lightGray)
  term.setTextColor(colors.white)
  print("Register")
  term.setCursorPos(12,5)
  print("Username")
  term.setCursorPos(39,17)
  print("LoginScrn")
  term.setCursorPos(12,8)
  print("Password")
  term.setCursorPos(12,12)
  print("Password")
  term.setCursorPos(21,5)
  term.setBackgroundColour(colors.white)
  term.setTextColor(colors.blue)
  username = limitRead(17)
  sleep(1)
  term.setCursorPos(21,8)
  pass1 = limitRead(17)
  sleep(1)
  term.setCursorPos(21,12)
  pass2 = limitRead(17)
  sleep(1)
end
function UsernameScreenButtons()
  local s = "false"
  local event = nil
  local button = nil
  local x = nil
  local y = nil
  repeat
	local event, button, x, y = os.pullEvent( "mouse_click" )
if event == "mouse_click" and x >= 38 and x <= 50 and y == 17 then
   parallel.waitForAll(Register, RegisterScreenButtons)
   s = "true"
end
  until s == "true"
end
function RegisterScreenButtons()
  local s = "false"
  local event = nil
  local button = nil
  local x = nil
  local y = nil
  repeat
	local event, button, x, y = os.pullEvent( "mouse_click" )
if event == "mouse_click" and x >= 38 and x <= 50 and y == 17 then
   parallel.waitForAll(LoginBoot, UsernameScreenButtons)
   s = "true"
end
  until s == "true"
end
parallel.waitForAll(LoginBoot, UsernameScreenButtons)
Edited on 29 October 2015 - 06:39 PM
MentalHamburger #2
Posted 29 October 2015 - 09:16 PM
Any Help Is Welcome
Lupus590 #3
Posted 29 October 2015 - 10:09 PM
What are the bugs? it will help us identify the cause of the problem.
Bomb Bloke #4
Posted 29 October 2015 - 10:20 PM
Hey i'm using code i found on the forums in my code to limit the length of an input, the code is causing bugs in my program. When i switch between the Register and Login screen then try to type something it will type multiple characters, I believe this is because it is running more that one of the custom read function

Sort of, it's not the limitRead() function causing the bugs - you're the one calling it multiple times at once (via the parallel API), so the short answer is "don't do that"! "parallel" will send a copy of every character typed to every function it's managing, so if you have more than one "read" going at a time, then it's got no way of knowing which one the characters are actually intended for. The limitRead() function itself isn't equipped to deal with another coroutine moving the text cursor around, either.

The simple way to re-organise things would be to ditch the parallel API and instead access all text fields via buttons. For example, the user gets either the login text boxes or the registration text boxes depending on whether they click the login or register buttons: But you'd never offer both at once. Right now it looks like it's possible to have multiple LoginBoot instances running at the same time, which you certainly wouldn't want to happen.

The complex way is to write a "read" function that can handle multiple text fields at once, perhaps by listening for events which indicate where the new text fields should be, and generating events with their content when the user finishes typing into them. This would involve a fair bit more code, as you'd need to incorporate a mechanism for switching between the active text fields, managing the cursor location, etc, and is probably overkill for your purposes.