B4J Question Using Wait For in an iterative sub

stevel05

Expert
Licensed User
Longtime 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

B4X founder
Staff member
Licensed User
Longtime 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: 86
Upvote 0

stevel05

Expert
Licensed User
Longtime 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