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

os.queueEvent wait for changes in true/false

Started by XSturb, 11 June 2013 - 06:49 PM
XSturb #1
Posted 11 June 2013 - 08:49 PM
Hi.

I am trying to make a program with the bee analyzer in MiscPeripherals and since the block doesn't give any events when there is a bee inside or not or if there is a different bee, I need to make that event my self.

I am trying to make the program wait for a variable that is true to be false. No it only loops all the time saying the variable is true over and over again.




bee = peripheral.wrap("left")


t = bee.analyze()
--print(t)
isbee = bee.isBee()
test = 1
check = true
while true do
if isbee == true and check == true then
check = false
print(check)
for key,value in pairs(t) do
  print(key,value)
end
elseif isbee == false and check == false then
check = true
print("Setting Check to TRUE!!")
elseif isbee == true and check == false then
else
end

--print(test)
--test = test + 1
--print("Effects: "..t["effect"])
--sleep(2)
os.queueEvent("isbee",isbee)
event, p1,p2,p3 = os.pullEvent("isbee")
print(event)
print(p1)
print(p2)
print(p3)
end

Thanks :)/>
Lyqyd #2
Posted 12 June 2013 - 02:22 AM
Split into new topic.
LBPHacker #3
Posted 12 June 2013 - 02:44 AM
Either you have to use the parallel API - something I don't recommend, - or you have to use this:
local bee = peripheral.wrap("left")

local t = bee.analyze()
--print(t)
local isbee = bee.isBee()
local lastbee = isbee
local test = 1
local check = true
while true do
    if isbee == true and check == true then
        check = false
        print(check)
        for key,value in pairs(t) do
            print(key,value)
        end
    elseif isbee == false and check == false then
        check = true
        print("Setting Check to TRUE!!")
    elseif isbee == true and check == false then
    else
    end

    if isbee ~= lastbee then
        isbee = lastbee
        --print(test)
        --test = test + 1
        --print("Effects: "..t["effect"])
        --sleep(2)

        print(event)
        print(p1)
        print(p2)
        print(p3)
    end
end
That will print "Changed" only if isbee really changed.
theoriginalbit #4
Posted 12 June 2013 - 02:51 AM
As LBPHacker showed you have to track the last state of the bee, this is a solution I put together using the parallel api. The program will go into the `main` function, and the checker will check the bees every 0.5 seconds and if it is different from the last time it will queue an event which the `main` function will receive so that it may continue execution.


function checker()
  local bee = peripheral.wrap("left")
  bee.analyze()
  local lastState = bee.isBee()
  while true do
    local currState = bee.isBee()
    if currState ~= lastState then
      lastState = currState
      os.queueEvent( "bee_change", currState ) -- this will be triggered when a be is added or removed and will also queue if the bee is present
    end
    sleep(0.5)
  end
end

function main()
  while true do
    local event, p = os.pullEvent("bee_change")
    if p then
      print("A bee was added.")
    else
      print("A bee was removed")
    end
  end
end

parallel.waitForAll( main, checker )
LBPHacker #5
Posted 12 June 2013 - 02:53 AM
+1 for bothering to explain the solution with parallel API…
theoriginalbit #6
Posted 12 June 2013 - 03:05 AM
+1 for bothering to explain the solution with parallel API…
Well you actually ninja'd me on this one, so I figured I'd do what you didn't :P/>


Oh also OP, here is some info/a suggestion with your if statements… in particular these ones:


if isbee == true and check == true then
elseif isbee == false and check == false then
elseif isbee == true and check == false then
you can also do them this way


if isbee and check then
elseif not (isbee or check) then
elseif isbee and not check then
now if statements require a boolean (true/false) to be able to run, now if you have a boolean true, what you're doing is you're saying `true == true`, which is very redundant, also `false == true` is also redundant. So in this case when we are wanting to check for true, we just use the boolean variable, if we're wanting to check for false, we use the `not` operator, this inverts the result
not true = false
not false = true
This makes readability a little better, and also reduces the time (even though its tiny) it takes to evaluate as no comparison is required.

Now one other thing you may notice is I changed the `var1 == false and var2 == false` to `not (var1 or var2)` and you may be wondering why. Well this is why.
Logical AND

true AND true = true
true AND false = false
false AND true = false
false AND false = false
Logical OR

true OR true = true
true OR false = true
false OR true = true
false OR false = false
So as you can see here, if I kept the `and` in the situation making it this `not (var1 and var2)` then it would be equivalent of doing this

if (var1 == true and var2 == false) or (var1 == false and var2 == false) or (var1 == false and var2 == true) then
So obviously it was needed to be changed to OR instead of AND
GopherAtl #7
Posted 12 June 2013 - 10:40 AM
just a note, in theoriginalbit's parallel solution, it should probably be waitForAny, not waitForAll. Neither of the two functions will exit unless it errors out, but if one does error out, you generally want the whole program to stop so it can be restarted, rather than letting it appear to still be working properly.
XSturb #8
Posted 12 June 2013 - 07:12 PM
The code that theoriginalbit posted worked perfectly just like what I wanted :D/> Thank you very much.
theoriginalbit #9
Posted 12 June 2013 - 10:16 PM
he is correct though, I had a momentary lapse in judgement and used the wrong function call, using waitForAny would be better to use here rather than waitForAll, but I'm glad it works as you needed.
XSturb #10
Posted 12 June 2013 - 11:39 PM
I have changed it to waitForAny now. Thank you for explaining that if statements checks for true and also about logical and and or. Im still fresh in Lua but still learning so thanks alot. This will help me make cleaner code as well :)/>