I have a UI app which reads in serial data and updates a label (GameClock) based on a certain element in that data stream. In part the code is:
B4X:
Sub btnOpen_Action
sp.Open(cmbPort.Value)
sp.SetParams(115200,8,1,0)
ast.Initialize(Me, "ast", sp.GetInputStream, sp.GetOutputStream)
btnOpen.Enabled = False
lblStatus.Text = "Status: Open"
End Sub
Sub ast_NewText(Text As String)
Select js.left(Text,1)
Case "T"
GameClock.Text = js.Mid(Text,2,5)
End Select
End Sub
My problem is that I need to delay each label update by say 150ms, however given the nature of the data stream, ast_NewText may be called every 100ms. So it seems I can't just simply put a 150ms delay ahead of the label update:
B4X:
GameClock.Text = js.Mid(Text,2,5)
but instead need to put the updates into a queue and execute each update 150ms after it has entered the queue.
No, I don't want to skip any updates. I want to queue them and update at the same rate, but with just a fixed delay of 150ms. I may want to adjust the fixed delay to between 100 and 200ms, and that would mean there would only be up to say three updates in the queue.
As background, my UI app is displaying a sports game clock as well as other scoreboard details and when I mix it with video from a venue camera, it is around 150ms ahead of the camera video due to delay induced by the camera capture digital processing path.
Sub UpdateLabel
Do While True
If ListOfMessages.Size > 0 Then
Label1.Text = ListOfMessages.Get(0)
ListOfMessages.RemoveAt(0)
End If
Sleep (UpdateInterval) 'global variable set to 150. You can change it whenever you want.
Loop
End Sub
Call UpdateLabel once when the program starts.
Add messages to ListOfMessages from ast_NewText.
Now I've gone to implement it I realise I may need to deal with a couple of other related issues, but the principle of your suggestion will remain the basis for the solution.