B4J Question Wait for used as asyncstreams timeout

Chris2

Active Member
Licensed User
Longtime User
In the following code from here, can someone please explain to me why b needs to be an array (as opposed to a single boolean), and b(1) set as true at the end of the two subs?
b(1) doesn't appear to be actually used anywhere?

B4X:
'usage
ReadData(5000)
Wait For DataReceived (Success As Boolean, Data() As Byte)


Sub ReadData (Timeout As Int)
 Dim b() As Boolean = Array As Boolean(False)
 TimeOutImpl(Timeout, b)
 Wait For Astream_NewData(Data() As Byte)
 If b(0) = false Then CallSubDelayed3(Me, "DataReceived", True, Data)
 b(1) = true
End Sub

Sub TimeOutImpl(Duration As Int, b() As Boolean)
 Sleep(Duration)
 If b(0) = false Then CallSubDelayed3(Me, "DataReceived", False, Null)
 b(1) = true
End Sub
 
Solution
I think the b(1) references are a typo and they should be b(0) as b() is an array with a length of one. Here an array is used instead of a global flag to signal that one or other of the ReadData or TimeOutImpl waits has expired. As Java/B4X parameters are passed by value just using a boolean as a flag won't work as assignment to parameter values don't propagate back to the caller. However if an array value is passed as a parameter the parameter value is actually a reference to the array and so a change in a value in the array will be seen by the caller.

agraham

Expert
Licensed User
Longtime User
I think the b(1) references are a typo and they should be b(0) as b() is an array with a length of one. Here an array is used instead of a global flag to signal that one or other of the ReadData or TimeOutImpl waits has expired. As Java/B4X parameters are passed by value just using a boolean as a flag won't work as assignment to parameter values don't propagate back to the caller. However if an array value is passed as a parameter the parameter value is actually a reference to the array and so a change in a value in the array will be seen by the caller.
 
Upvote 0
Solution

Chris2

Active Member
Licensed User
Longtime User
OK, thanks.
So, just to help my understanding, would the following, using a global boolean flag be equivalent?
(albeit perhaps less elegant, and susceptible to problems if the global boolean b is changed somewhere else or ReadData is called more than once)

B4X:
Process_Globals
 Private b as Boolean
End Sub

'usage
ReadData(5000)
Wait For DataReceived (Success As Boolean, Data() As Byte)


Sub ReadData (Timeout As Int)
 b = False
 TimeOutImpl(Timeout, b)
 Wait For Astream_NewData(Data() As Byte)
 If b = false Then CallSubDelayed3(Me, "DataReceived", True, Data)
 b = true
End Sub

Sub TimeOutImpl(Duration As Int)
 Sleep(Duration)
 If b = false Then CallSubDelayed3(Me, "DataReceived", False, Null)
 b = true
End Sub
 
Last edited:
Upvote 0

OliverA

Expert
Licensed User
Longtime User
So, would the following, using a global boolean flag be equivalent?

Yes, but now you make both routines (ReadData and TimeOutImpl) dependent on a global variable, whereas before they were not.
 
Upvote 0
Top