Jump to content




Parallel Api


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

#1 Alerith

  • Members
  • 36 posts

Posted 22 April 2013 - 01:20 AM

Hello there! I've been reading in the wiki but I still don't get it, I mean, I understand both apis (ForAny and ForAll) but I don't know how to use it and when.

I'm making a new program, is a countdown and I want when the countdown is close to 0 min, like 2 min, I can write something but the countdown must don't stop. So ---> countdown ---> 2min---> write something while the countdown is still on ----> if the words are correct, like a password then something happens, if not, otherwise. I think I can use the Parallel Api for this, but I don't know how..

I don't want the entire code, I just want a little jog :P

Thank you very much in advance :3

#2 Espen

    Curious Explorer

  • Members
  • 708 posts

Posted 22 April 2013 - 03:32 AM

I wouldn't recommend to do it with the parallel API.
When you start a counter in one part of your code, you'll have to yield and wait until there is an event that tells you that the amount of time has passed.
But in order for some other part of your code to know how how much time has passed UNTIL that event occurs, you'd have to set up another timer in parallel.
The problem with that is that you'd have to make sure to start up these timers at the same time and even then they might not be fully in synch.
IMO a better solution would be to not use parallel at all and instead use a one-second timer, which you'd restart in a loop and count the passed time with a counter variable.
Example:
local printTime  = 3  -- Time at which to print a message
local endTime	= 6  -- Time after which to stop the countdown
local timePassed = 0  -- Counts the seconds that have passed
local countdown  = os.startTimer(1)  -- Starts a one second timer

write("Progress: ")
while timePassed < endTime do
  -- Wait until our second has passed, i.e. when we are told about it via an event.
  local _, timer = os.pullEvent("timer")

  write(".")
  if timer == countdown then
	timePassed = timePassed + 1

	-- If printTime seconds have passed, we will write 'FOO'
	if timePassed == printTime then
	  write("FOO")
	end

	-- Restart the timer
	countdown = os.startTimer(1)
  end
end

print()


#3 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 22 April 2013 - 03:43 AM

In addition to what Espen just said...

Since you want to also allow user input you will need to slightly modify how his code works, like so

This line
local _, timer = os.pullEvent("timer")
would need to become
local event, param1 = os.pullEvent()

and then you would need to check the events and go from there, essentially you are making your own read function
if event == 'timer' then
  -- Espens code here
elseif event == 'char' then
  -- add the char to the input string
elseif event == 'key' then
  -- check for backspace and enter here
end

you would then need a string at the top of your code like this
local input = ""
and this is what you append to
if event == 'char' then
  input = input..param1
elseif event == 'key' then
  if param1 == keys.backspace then
    input = string.sub( input, 1, string.len(input) - 1 )
  elseif param1 == keys.enter then
    -- ok check the password here and do whatever you want the program to do when it is correct, when false just input = "" again
  end
end


#4 Espen

    Curious Explorer

  • Members
  • 708 posts

Posted 22 April 2013 - 04:49 AM

Oh, I thought he just wanted to print something after x amount of time.
Totally overlooked him wanting to do input as well. :wacko:

In that case I take back what I said about the use of the parallel API.
Because in order not having to write your own complete read() function, it's much more comfortable to use the parallel API.
In this particular case I'd suggest a combination of the one-second timer with manual counting and parallel, like so:
function login()
  local pwd = "secret"
  local input
  term.clear()
  term.setCursorPos( 1, 2 )

  while input ~= pwd do
    write("Password: ")
    input = read("*")
    if input == pwd then
      print("Correct!")
    end
  end
end

function countdown()
  local printTime  = 4  -- Time at which to print a message
  local endTime    = 8  -- Time after which to stop the countdown
  local timePassed = 0  -- Counts the seconds that have passed
  local countdown  = os.startTimer(1)

  while timePassed < endTime do
    local _, timer = os.pullEvent("timer")

    if timer == countdown then
      timePassed = timePassed + 1

      if timePassed == printTime then
        local currX, currY = term.getCursorPos()    -- Note current cursor position.
        term.setCursorPos( 1, 1 )
        term.clearLine()

        write( printTime .. " seconds left..." )
        term.setCursorPos( currX, currY )   -- Reset cursor position to where it was before.
      end

      countdown = os.startTimer(1)
    end
  end
  print()
end

parallel.waitForAny( login, countdown )

Edit: Added some comments.

Edited by Espen, 22 April 2013 - 04:52 AM.


#5 Alerith

  • Members
  • 36 posts

Posted 22 April 2013 - 06:29 AM

Whoa, thanks for the response guys! I will analize that :3 If I have any questions, I will post them here :D
I'm not in my PC right now, so later :P

#6 Alerith

  • Members
  • 36 posts

Posted 23 April 2013 - 09:22 AM

Just a little question, what is the "_" variable?

#7 remiX

  • Members
  • 2,076 posts
  • LocationSouth Africa

Posted 23 April 2013 - 09:26 AM

When you pull an event, even if you put a 'filter' within the function call, the event still gets returned with the first variable.
People use any short character like _ to just 'ignore' that returned variable by putting it it's place because you won't be using it.

Not sure If i explained it properly xD

#8 Alerith

  • Members
  • 36 posts

Posted 23 April 2013 - 09:30 AM

View PostremiX, on 23 April 2013 - 09:26 AM, said:

When you pull an event, even if you put a 'filter' within the function call, the event still gets returned with the first variable.
People use any short character like _ to just 'ignore' that returned variable by putting it it's place because you won't be using it.

Not sure If i explained it properly xD

I get it.. something, is like drop that value right?

#9 remiX

  • Members
  • 2,076 posts
  • LocationSouth Africa

Posted 23 April 2013 - 09:32 AM

Yeah just to ignore it because you won't be using it

#10 Espen

    Curious Explorer

  • Members
  • 708 posts

Posted 23 April 2013 - 09:43 AM

View PostAlerith, on 23 April 2013 - 09:30 AM, said:

I get it.. something, is like drop that value right?
Yep, exactly as remiX has explained it already.
But to put any misunderstanding out of the way, I would explicitly add that Lua doesn't do anything special for _
It's a valid variable name like any other and it's just a convention of many programmers to show their intentions with that variable, i.e. that they don't use its content at all. But it stores the content nontheless and can be used like any other variable.

#11 Alerith

  • Members
  • 36 posts

Posted 23 April 2013 - 09:44 AM

Perfect. Thank you both :3





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users