B4J Question Using Wait For in an iterative sub

stevel05

Expert
Licensed User
The sub that does the main work in my mineXML app is iterative. I would like to update a progress bar when importing larger files, but can't for the life of me work out how to use the wait for to achieve this when the sub calls itself.

I did try creating it in it's own class and creating new instances as needed and waited on the a complete call from the class, it worked, but the tree can be hundreds of levels deep and it added a long time to the process.

This is the sub, any ideas gratefully received.

B4X:
Private Sub XMLMapToDataDo(M As Map, Indent As Int, TagList As List)
    
    For Each K As Object In M.Keys
        Dim JO As JavaObject = ""                                                            'Ignore
        Dim Key As String = JO.RunMethod("join",Array(",",TagList))
        Key = Key & "," & K
        Dim FN As String = FriendlyNames.GetDefault(Key,"")
        If M.Get(K) Is Map Then
            Dim TL1 As List
            TL1.Initialize
            TL1.AddAll(TagList)
            If TL1.Size = 0 Or TL1.Get(TL1.Size - 1) <> K Then TL1.Add(K)
            XMLMapToDataDo(M.Get(K), Indent + 1, TL1)
        Else If M.Get(K) Is List Then
            Dim L As List = M.Get(K)
            For Each O As Object In L
                If O Is Map Then
                    Dim TL1 As List
                    TL1.Initialize
                    TL1.AddAll(TagList)
                    If TL1.Size = 0 Or TL1.Get(TL1.Size - 1) <> K Then TL1.Add(K)
                    XMLMapToDataDo(O,Indent + 1, TL1)
                Else
                    If DataSaveMap.ContainsKey(Key) = False Then
                        Dim DS As DataSaveType1 = NewDataSaveType1(Key,"Str1",K,FN,O,False)
                        DataSaveMap.Put(Key,DS)
                        DataSaveKeyList.Add(Key)
                    Else
                        DS = DataSaveMap.Get(Key)
                        DS.Values.Add(O)
                    End If
                End If
            Next
        Else
            If DataSaveMap.ContainsKey(Key) = False Then
                Dim DS As DataSaveType1 = NewDataSaveType1(Key,"Str2",K,FN,M.Get(K),False)
                DataSaveMap.Put(Key,DS)
                DataSaveKeyList.Add(Key)
            Else
                DS = DataSaveMap.Get(Key)
                DS.Values.Add(M.Get(K))
            End If
        End If
    Next
    
End Sub
 

Erel

Administrator
Staff member
Licensed User
It can be tricky. Easier to use an indeterminate progress bar.

See the attached example.

B4X:
Sub AppStart (Form1 As Form, Args() As String)
   MainForm = Form1
   MainForm.RootPane.LoadLayout("1") 'Load the layout file.
   MainForm.Show
   MaxValue = 5
   AnotherProgressBar1.SetValueNoAnimation(0)
   Wait For (Factorial(MaxValue)) Complete (Result As Int)
   Log(Result)
End Sub


Sub Factorial(n As Int) As ResumableSub
   AnotherProgressBar1.Value = 100 / MaxValue * (MaxValue - (n - 1))
   Sleep(1000)
   If n = 1 Then Return 1
   Wait For (Factorial(n - 1)) Complete (Result As Int)
   Return n * Result
End Sub
 

Attachments

  • 1.zip
    3 KB · Views: 62
Upvote 0

stevel05

Expert
Licensed User
Great, thanks Erel. That did occur to me but I thought I'd ask this question first. How to create an indeterminate progress bar would have been my next question.
 
Upvote 0
Top