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

Strange PullEvent Quirk

Started by atomroflman, 30 June 2016 - 07:48 PM
atomroflman #1
Posted 30 June 2016 - 09:48 PM
Hey guys,

I have a quite strange behavior in my code:

function showSelector(text, values, textFunc)
  local isSelected = false
  local cursor = 1
  local selectedValue = nil
  while not isSelected do
	local counter = 1
	clear()
print("Select " .. text .. ":")
	for i, v in pairs(values) do
	  local cursorText = "   "
	  if cursor == counter then
		cursorText = " > "
		selectedValue = v
	  end
	  counter = counter + 1
   if textFunc ~= nil then
	 print(cursorText..textFunc(v))
   else
		print(cursorText .. v)
   end
	end
glb = glb + 1
print("wait for key"..glb)
	local event, key = os.pullEvent("key")
print("key done"..glb)
	if key == keys.up then
	  if cursor > 1 then
		cursor = cursor - 1
	  end
	elseif key == keys.down then
	  if cursor < #values then
		cursor = cursor + 1
	  end
	elseif key == keys.enter then
	  isSelected = true
	end
  end
  clear()
  return selectedValue
end
When I try to execute it from one point in my program it works fine, from another it does not.
It just stops moving the cursor, as if the value of keys is not valid anymore. So I thought i've overwritten the keys table, but i didn't.

Find the full code here:

Spoiler

sides = { "front", "back", "right", "left", "top", "bottom" }
glb = 0
function map(array, func)
  local new_array = {}
  for i,v in ipairs(array) do
	new_array[i] = func(v)
  end
  return new_array
end

function copy(src, target)
  print("Copying: "..src.." => "..target.."...")
  if fs.exists(src) then
	fs.copy(src, target)
  else
	print("404: Not found!")
  end
end

function clear()
  term.clear()
  term.setCursorPos(1, 1)
end

function showSelector(text, values, textFunc)
  local isSelected = false
  local cursor = 1
  local selectedValue = nil
  while not isSelected do
	local counter = 1
	clear()
print("Select " .. text .. ":")
	for i, v in pairs(values) do
	  local cursorText = "   "
	  if cursor == counter then
		cursorText = " > "
		selectedValue = v
	  end
	  counter = counter + 1
   if textFunc ~= nil then
	 print(cursorText..textFunc(v))
   else
		print(cursorText .. v)
   end
	end
glb = glb + 1
print("wait for key"..glb)
	local event, key = os.pullEvent("key")
print("key done"..glb)
	if key == keys.up then
	  if cursor > 1 then
		cursor = cursor - 1
	  end
	elseif key == keys.down then
	  if cursor < #values then
		cursor = cursor + 1
	  end
	elseif key == keys.enter then
	  isSelected = true
	end
  end
  clear()
  return selectedValue
end
function getFilesFrom()
  for i, v in pairs(installFiles.client) do
	-- get from bitbucket
	-- get from disk
	copy("/disk/"..v.name, "/"..v.name)
  end
end
function split(s)
  local result = {}
  local index = 0
  for word in string.gmatch(s, "%a+") do
	 result[index] = word
  index = index + 1
  end
  return result
end
function debugPrint(obj)
  if obj == nil then
	print("nil")
return
  end
  for i, v in obj do
	print(i.."-"..v)
  end
end
installFiles = {}
installFiles.common = {}
installFiles.client = {}
installFiles.server = {}
local values = { ["back"] = { text = "Back...", value = nil, name = nil } }
values["render"] = {text = "test", value="awesomeness", name = "render", x = 0, y = 0, maxLength = 11 }
local menues = { { text="Move Values", fn = moveValues }, { text = "Run", fn = nil } }
function moveValues()
  --[[
  showSelector does not work fine here
  --]]
  local selectedValue = showSelector("Value to move", values, function(v) return v.text end)
  while selectedValue.name ~= nil do
	local monitor = term
if selectedValue.monitor ~= nil then
   monitor = selectedValue.monitor
end
local w, h = monitor.getSize()
renderMonitor(selectedValue, monitor)
	local ready = false
while ready do
   local e, key = os.pullEvent("key")
   if key == keys.left then
	 if selectedValue.x > 1 then
	   selectedValue.x = selectedValue.x - 1
  end
   elseif key == keys.right then
	 if selectedValue.maxLength + selectedValue.x < w then
	selectedValue.x = selectedValue.x + 1
  end
   elseif key == keys.up then
	 if selectedValue.y > 1 then
	selectedValue.y = selectedValue.y - 1
  end
   elseif key == keys.down then
	 if selectedValue.y < h then
	selectedValue.y = selectedValue.y + 1
  end
   elseif key == keys.backspace then
	 ready = true
   end
   renderMonitor(selectedValue, monitor)  
end
selectedValue = showSelector("Value to move", values, function(v) return v.text end)
  end
end
function renderMonitor(movedItem, monitor)
  if monitor == nil then
	monitor = term
  end
  monitor.clear()
  print("whatever")
  for i,v in pairs(values) do
	if v.name ~=nil then
   local printChar = " "
   if movedItem then
	 printchar = "x"
   end
   monitor.setCursorPos(v.x, v.y)
   for l=1, v.maxLength do
		monitor.write(printChar)
	  end
   if not movedItem then
	 monitor.setCursorPos(v.x, v.y)
	 monitor.write(v.value)
   end
end
  end
end
function handleCommand(cmd, sender)
  if message == "server-find" then
	local label = os.getComputerLabel()
	local t = "computer"
	if turtle ~= nil then
	  t = "turtle"
	end
	if label == nil then
	  label = t..os.getComputerID()
	end
	return label
  else
	local cnf = split(line)
	if cnf[0] == "update" then
   if values[cnf[1]] == nil then
	 values[cnf[1]] = {}
  values[cnf[1]].x = 0
  values[cnf[1]].y = 0
  values[cnf[1]].visible = false
  values[cnf[1]].name = cnf[1]
  values[cnf[1]].maxLength = 0
   end
   values[cnf[1]].value = cnf[2]
   if string.len(cnf[2]) > values[cnf[1]].maxLength then
	 values[cnf[1]].maxLength = string.len(cnf[2].value)
   end
	end
  end
end
function handleKey(key)
  if key == keys.m then
  --[[
  showSelector works fine here
  --]]

	local selected = showSelector("Function", menues, function(m) return m.text end)
while selected.fn ~= nil do
   selected.fn()
   selected = showSelector("Function", menues, function(m) return m.text end)
end
  end
end
local serverConfig = {}
if fs.exists("/config") then
  local configFile = fs.open("/config", "r")
  local line = configFile.readLine()
  while line do
	local cnf = split(line)
	term.write("Reading: "..line)
	local type = cnf[0]
print(type)
if type == "modem" then
   serverConfig.modemSide = cnf[1]
end
	line = configFile.readLine()
  end
end
rednet.open(serverConfig.modemSide)
while (true) do
  event, param1, param2, param3 = os.pullEvent()
  if event == "rednet_message" then
	local sender, message, distance = param1, param2, param3
	print(message .. " from " .. sender)
	rednet.send(sender, handleCommand(message, sender))
  elseif event == "key" then
	handleKey(param1)
  end
end
Edited on 20 August 2016 - 11:09 PM
BrunoZockt #2
Posted 20 August 2016 - 05:25 PM
Hey,
I'd like to help you but I don't understand what your problem is.
Are you getting an Error? If yes then post it please.
Or doesn't the program do what you want? If that's the case please describe what you want it to do and what it actually does.
If you don't need help anymore, edit your post and write that you don't need help anymore or add a "[solved]" to your title.

Bruno
KingofGamesYami #3
Posted 20 August 2016 - 07:22 PM
He described his problem adequetly in the post and comments. I can't address it because I am on mobile, but the information is there.
BrunoZockt #4
Posted 20 August 2016 - 09:42 PM
He described his problem adequetly in the post and comments. I can't address it because I am on mobile, but the information is there.
Oh, sorry!
I didn't see the text between the codes yet. It helps a bit, but however I don't know what his code should do.
I try to read myself through the code when I know what I am looking for and what it should do because otherwise it's really hard, but for now, maybe it's because of my bad english, I don't know what should happen.
So please tell me what should happen and I will work on it.

Bruno