Jump to content




Making functions run several times while one works


  • You cannot reply to this topic
11 replies to this topic

#1 CCJJSax

  • Members
  • 262 posts

Posted 27 August 2016 - 07:49 AM

I've been messing around with coroutines and the parallel APIs and I can't figure out a good way to do this. I have a function that takes several seconds to get done, but I want to have it constantly updating the UI so I can have buttons and such on it.

this is my understanding of the APIs

Spoiler


#2 H4X0RZ

  • Members
  • 1,315 posts
  • LocationGermany

Posted 27 August 2016 - 07:54 AM

You could wrap the function inside an anonymous function which loops and executes the actual function.

parallel.waitForAny(func, function() for i=1,5 do func2() end end)

Edited by H4X0RZ, 27 August 2016 - 07:54 AM.


#3 CCJJSax

  • Members
  • 262 posts

Posted 27 August 2016 - 08:16 AM

View PostH4X0RZ, on 27 August 2016 - 07:54 AM, said:

You could wrap the function inside an anonymous function which loops and executes the actual function.

parallel.waitForAny(func, function() for i=1,5 do func2() end end)

with that is the long one func or func2?

#4 H4X0RZ

  • Members
  • 1,315 posts
  • LocationGermany

Posted 27 August 2016 - 08:52 AM

View PostCCJJSax, on 27 August 2016 - 08:16 AM, said:

View PostH4X0RZ, on 27 August 2016 - 07:54 AM, said:

You could wrap the function inside an anonymous function which loops and executes the actual function.

parallel.waitForAny(func, function() for i=1,5 do func2() end end)

with that is the long one func or func2?

func would be the long one. Also, you could/should replace the for loop with a while(true) do loop, so it really executes until the long function is done.

#5 CCJJSax

  • Members
  • 262 posts

Posted 27 August 2016 - 05:23 PM

Quote


--Snip

func would be the long one. Also, you could/should replace the for loop with a while(true) do loop, so it really executes until the long function is done.

I'll try it again. I thought that was the answer so I tested it out but it seemed to move forward then run the function2 while loop and waited for the while true do to get done, which is problematic

#6 CCJJSax

  • Members
  • 262 posts

Posted 27 August 2016 - 05:54 PM

I tried that and the turtle just acts really weird. It's not running through the full func. It seems like it randomly picks if it's going to go up or down instead of the full thing.

#7 valithor

  • Members
  • 1,053 posts

Posted 27 August 2016 - 07:25 PM

View PostCCJJSax, on 27 August 2016 - 05:23 PM, said:

I'll try it again. I thought that was the answer so I tested it out but it seemed to move forward then run the function2 while loop and waited for the while true do to get done, which is problematic

It doesn't actually run both functions at the same time. Anytime one of the two functions yield it will go on to the next one that you pass to parallel.waitForAny. So... if your second function never yields the first one will never get to run again.

Anytime you are using coroutines/parallel api make sure all of the functions you are using actually have coroutine.yield, os.pullEvent, or os.pullEventRaw inside of it somewhere.

#8 CCJJSax

  • Members
  • 262 posts

Posted 28 August 2016 - 02:10 AM

Quote


It doesn't actually run both functions at the same time. Anytime one of the two functions yield it will go on to the next one that you pass to parallel.waitForAny. So... if your second function never yields the first one will never get to run again.

Anytime you are using coroutines/parallel api make sure all of the functions you are using actually have coroutine.yield, os.pullEvent, or os.pullEventRaw inside of it somewhere.

Can that be put just anywhere in eacharge function? My longer one goes through a lot of steps. Do I have to put the yield after every step or is the end ok?


#9 valithor

  • Members
  • 1,053 posts

Posted 28 August 2016 - 03:37 AM

View PostCCJJSax, on 28 August 2016 - 02:10 AM, said:

Quote


It doesn't actually run both functions at the same time. Anytime one of the two functions yield it will go on to the next one that you pass to parallel.waitForAny. So... if your second function never yields the first one will never get to run again.

Anytime you are using coroutines/parallel api make sure all of the functions you are using actually have coroutine.yield, os.pullEvent, or os.pullEventRaw inside of it somewhere.

Can that be put just anywhere in eacharge function? My longer one goes through a lot of steps. Do I have to put the yield after every step or is the end ok?

I would need to see the function to give more specific advice, but after each individual step would be a little overkill. You would definitely want at least one yield/sleep in the while loop of the second function. If the first one doesn't have any yields in it, then you could space them out (assuming you are doing a lot of looping in that function), like every thousand loops or something.

Edited by valithor, 28 August 2016 - 03:50 AM.


#10 CCJJSax

  • Members
  • 262 posts

Posted 28 August 2016 - 07:06 AM

Quote


-- snip --

I would need to see the function to give more specific advice, but after each individual step would be a little overkill. You would definitely want at least one yield/sleep in the while loop of the second function. If the first one doesn't have any yields in it, then you could space them out (assuming you are doing a lot of looping in that function), like every thousand loops or something.

Makes sense. I will try what you said as well. Just so you can see my test program, I'll post it.
Spoiler


#11 valithor

  • Members
  • 1,053 posts

Posted 28 August 2016 - 07:28 AM

View PostCCJJSax, on 28 August 2016 - 07:06 AM, said:

-snip
There is a handful of problems with the test code posted, mostly having to do with the use of coroutines.
coroutine.create(func) -- This function will return what I am going to call a thread. I will touch on threads in a second.
coroutine.resume(thread, arg1, arg2, etc...) -- This function will resume a thread. It will run the passed thread until it reaches a coroutine.yield (os.pullEvent and os.pullEventRaw both call coroutine.yield). The arguments passed after the thread in coroutine.resume will be what will be received by coroutine.yield.
coroutine.yield(filter) -- This will cause the thread to yield allowing you to come back to it later without the requested information in the filter. The filter is returned by the coroutine.resume that resumed the thread.
example for create, resume, and yield:
function hello()
print("hi")
coroutine.yield("filter example")
print("hello")
coroutine.yield("hello")
print("another message")
end
local co = coroutine.create(hello)
local filter = coroutine.resume(co) --# the first time you resume a coroutine it starts from the very beginning, it doesn't need args.
print(filter) --# will print "filter example"
filter = coroutine.resume(co,"filter") --# this is resuming at the point of the first yield
print(filter) --# will print("hello")
coroutine.resume(co,"hello")
print(coroutine.status(co)) --# will print dead because it is at the end of the function
For what you are wanting though, it would be easier to just use parallel api, as you would need to make a full coroutine manager to do it.
Try something like this as a test:
function testLoop()
term.setCursorPos(1,1)
term.write(math.random(1, 50))
end
function loopMe(n)
lm = true
term.setCursorPos(1,2)
turtle.forward()
turtle.up()
turtle.down()
turtle.down()
turtle.turnLeft()
turtle.turnRight()
turtle.turnRight()
turtle.turnLeft()
turtle.up()
term.setCursorPos(1,2)
if i == n then lm = true end
str = str + 1
end
parallel.waitForAny(function() loopMe(3) end,function() while true do testLoop() sleep(.05) end)
I haven't tested that but I believe it should work for what you are wanting.

Edited by valithor, 28 August 2016 - 07:34 AM.


#12 CCJJSax

  • Members
  • 262 posts

Posted 28 August 2016 - 07:44 AM

That code has some unexpected symbol on the parallel line... I'm not sure where though. as far as I can tell it looks good.

edit: it just needed another end at the end

edit 2: That actually works great. so it seems like H4x0rz 's code wasn't working just because of the sleep? Such a small difference.

Edited by CCJJSax, 28 August 2016 - 07:48 AM.






2 user(s) are reading this topic

0 members, 2 guests, 0 anonymous users