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

Problem with my PlotMe Border Program

Started by Lion4ever, 23 August 2015 - 08:40 PM
Lion4ever #1
Posted 23 August 2015 - 10:40 PM
In the past few days i was looking back at my PlotMe Boder Program which startet as a temporary fix to the turtles region bypassing.

And it is basically wrapping the turtle funcitons in new functions to check if they are allowed to move or dig there.


local function checkIfMoved(move,fm,ym)
if isInBounds(fm,ym) then
  local stime = oc()
  local o,r,r2=pc(move)
  if not o then
   print("reached")
   ost(2)
   repeat
	cy("timer")
   until oc()-stime >= 2
  end
  local o2,fl = pc(gfl)
  if not o2 then
   checkGps(true)
  end
  if fl < lfl then
   x=x+fx*fm
   y=y+ym
   z=z+fz*fm
   lfl = fl
  end
  if o then
   return r,r2
  else
   error(r,0)
  end
end
sleep(0.2)
return false,"Can not move out of the plot"
end

function turtle.back()
return checkIfMoved(bk,-1,0)
end
function turtle.forward()
return checkIfMoved(fd,1,0)
end
Full Code here

And that does work well unless the current thread calling that function does never return…


coroutine.wrap(turtle.forward)()


If called like this, the upper code does never return from the pcall (pc) in the fourth line, but the turtle does move forward. print("reached") is not executed here and coordinates are not updated

Is there a better way than overwriting coroutine.yield and let all turtle movements be executed by the coroutine created in bios:787 (the main thread) or do you even know a situation where the main thread is not resumed except on system restart?

Thanks for your help :)/>
Edited on 23 August 2015 - 08:42 PM
Bomb Bloke #2
Posted 24 August 2015 - 01:31 AM
How exactly are you handling the coroutine generated by wrap?
Lion4ever #3
Posted 24 August 2015 - 08:38 AM
In this example where it does where the turtles moves, but the coordinates are not updated: I am only calling/resuming the coroutine once. Only the code which is before the first yield of the wrapped function has ran and that is:

if isInBounds(fm,ym) then
  local stime = oc()
  local o,r,r2=pc(move)
where "move" is the native turtle function, causing the turtle to move and yield.
So i am not handling it at all yet…

The coroutine.yield overwrite would look something like this:

local moveReqest
local mainThread = coroutine.current()
local oy = coroutine.yield
turtle.forward = function()
if coroutine.coroutine() ~= mainThread then
  moveReqest = fd
  oy("turtle_request_executed")
end
end

coroutine.yield = function(...)
if coroutine.current() == mainThread and moveReqest then
  local move = moveReqest
  moveReqest = nil
  makeMove(move)
  os.queueEvent("turtle_request_executed")
end
return oq(...)
end
But this is really ugly code in my opinion…
Lion4ever #4
Posted 24 August 2015 - 10:46 PM
Solved. Found a better way: Execute everything before the first yield.

local function waitUntilLastMoveEnded()
if oc()-lastTime < 0.4 then
  local tmr = ost(0.4+lastTime-oc())
  repeat
   local e = {os.pullEvent("timer")}
   if e[1] == "timer" and e[2] == tmr then
    tmr = ost(0.4+lastTime-oc())
   end
  until oc()-lastTime >= 0.4
end
local fl = gfl()
if fl < lfl then
  x=x+fx*lastForwardM
  y=y+lastYM
  z=z+fz*lastForwardM
  lfl = fl
end
end
local function checkIfMoved(move,fm,ym)
waitUntilLastMoveEnded()
if isInBounds(fm,ym) then
  lastTime = oc()
  lastForwardM = fm
  lastYM = ym
  return move()
end
return returnV"Can not move out of the plot"
end