Android Question Resumable subs cant return a value?

techknight

Well-Known Member
Licensed User
Longtime User
I have run into an issue that I am unsure how to get around.

I have a subroutine that shows the user a list of player numbers and names, and its supposed to return the player number of the player the user selects. But, it doesnt work. its complaining about unable to return a value on a resumable sub. Seems like a huge limitation. Any ideas?

Here is the code:

The code hasn't been debugged yet because I cant get past the limitation ATM, So I don't know if it even works.

B4X:
Sub ShowPlayerList(side As String) As Int
Dim I As Int
Dim A As Int   
Dim Index() As Int
Dim PlayerList As List
Dim Players() As String
PlayerList.Initialize
A = 0
For I = 0 To 14 Step 1
    If side = "home" Then
        If PlayerOnCourtHome(I) > 0 Then
            Index(A) = I
            Players(A) = PlayerNumberHome(I) & " - " & PlayerNameHome(I)
            A = A + 1
        End If
    Else
        If PlayerOnCourtGuest(I) > 0 Then
            Index(A) = I
            Players(A) = PlayerNumberGuest(I) & " - " & PlayerNameGuest(I)
            A = A + 1
        End If     
    End If
Next
If Players.Length = 0 Then Return 999 'No On-Court Players were found.
PlayerList.AddAll(Players)
InputListAsync(PlayerList, "Select a Player", -1, False)
Wait For InputList_Result (Ret As Int)
If Ret <> DialogResponse.CANCEL Then
    If side = "home" Then
        I = PlayerNumberHome(Index(Ret))
        Return I
    Else
        I = PlayerNumberGuest(Index(Ret))
    End If
Else
    Return 888 'User didn't select a player, or canceled. 
End If
End Sub
 

stevel05

Expert
Licensed User
Longtime User
The resumable sub returns when it executes the waitfor, the sub is then resumed when the result is received, so there is nowhere to return a result.

I would use callsub to send the process where I wanted when the result is received.
 
Last edited:
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
You know, I remember the old days, there was something called a Stack. all subroutine data was pushed onto it. So when things got diverted you could pop the stack and get the values needed to complete a subroutine from where it left off. You would think Wait For would push additional data on the Stack so when it resumed it can pick up exactly, state and all...

Sorry, thats the Low Level/Embedded side of me talking. I used to do that all the time, this higher level stuff is a bit over my head at times. But I digress...

I need to be able to return a value from here. However, I am drawing blanks as how to do it. I dont want global variables everywhere, thats just messy.
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
Since I am ignorant in this Wait For thing, That brings up another question. I have multiple Wait For instances in the same subroutine for each messagebox, I wonder if that will cause problems as well?
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
There is no problem with having multiple wait fors inside the same sub.

Ok, that answers my question. I was worried if a Wait For was encountered at a 2nd or 3rd prompt, it would resume back at the first prompt by mistake.

But, I still cant wrap my head around returning a value. Even if I use Call Sub Delayed at the end of a Resumable sub, Sure I can pass a value back to the parent sub, but guess what... That parent sub has a Wait For basically throwing me into an infinite nest of Catch 22 here.
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
Which means I still cant return a value. I need to figure out somehow to return a value.

The code I posted above is a user prompt lookup function that I am trying to write. Since its a resumable sub, I cant return a value, but I need to. Any thoughts?
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
It's difficult without seeing more of your code but I would suggest that you split the calling sub, the last statement being the call to showplayerlist. Then call a new sub to continue the process once a value is received.
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
Well its a commandbutton.

Goes like this:

Basically its supposed to call the PlayerList, and it returns back with the Player Number of the chosen player in the list, the list is built from the arrays that form the roster. (As seen in my list code). The Player Number is used in the HandleHomeFouls function to look up that particular player, count a foul against the player, and against the total team fouls score.

Its a basketball scoring app that controls an LED Video display.

The display itself is running my own B4J app which writes the graphics, overlays, and scoring data into a framebuffer using a modified LEDScape/Fadecandy driver but that isnt important here.

B4X:
Sub cmdHomeFoulsUp_Click
    Dim PlayerID as Int
    If HomeRosterLoaded = True Then
        'Get Player Number and Handle it.
         PlayerID = ShowPlayerList("home")
         If PlayerID > 888 then
             MsgBox("You didn't select a player, or no players were on the court!")
         Else
             HandleHomeFouls(PlayerID)
         End If
    Else
        PlayerFoulVisible = False
        lblPlayer.Visible = False
        If TeamFoulsHome < 10 Then
            TeamFoulsHome = TeamFoulsHome + 1
        End If
        lblFoulsHome.Text = TeamFoulsHome & " - " & TimeOutsHome
        If ServiceTxRx.connected = True Then
            If ServiceMain.ClockTimer.Enabled = False Then
                ServiceTxRx.EventID = 6               
                CallSub(ServiceTxRx, "PerformTxRxEvent")
            Else
                ServiceTxRx.Queued = True
            End If
        End If
    End If   
End Sub
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Tip: Don't use Msgbox. Replace it with MsgboxAsync.

It should be something like:
B4X:
If HomeResterLoaded = True Then
 ShowPlayerList("home")
 Wait For ShowPlayerList_Complete (PlayerId As Int)
 If PLayerID > 888 Then ...

In ShowPlayerList you need to call:
B4X:
CallSubDelayed2(Me, "ShowPlayerList_Complete", PlayerId)
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
Thank you. Now its clear to me.

Can I use multiple MsgBoxAsync and MsgBox2Async commands in the same subroutine? Given I have to use different senders, correct?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Can I use multiple MsgBoxAsync and MsgBox2Async commands in the same subroutine?
Yes.

Given I have to use different senders, correct?
It is always better to use the sender filter (when possible) though it will work without it as the next Msgbox2Async is only called after the first is returned.
 
Upvote 0
Top