Wish Include module

Jack Cole

Well-Known Member
Licensed User
Longtime User
It would be nice to be able to include all of the functions in a module directly into another module. Consider doing it like:

#IncludeModule: ExtraFunctionsCodeModule

This would be a real time saver for me, because there are some projects where I have to copy and paste particular code into every module. It would improve the ability to maintain, change, and develop code that is repeated across many modules.
 

LucaMs

Expert
Licensed User
Longtime User
:eek:

Add the module to the project!

upload_2019-10-22_19-15-34.png
 

Jack Cole

Well-Known Member
Licensed User
Longtime User
Here's an examples of where this would be very helpful. It would also be helpful to have some way to add variables to Globals or Process_Globals through this type of module.

#IncludeModule: RewardAdEventsAndFunctions

Content of RewardAdEventsAndFunctions
B4X:
Sub RewardAdPrompt(AllowInterstitial As Boolean)
    Dim ShowInterstitial=AllowInterstitial As Boolean
    If Round(Starter.Db.RewardMins)>0 And _
            Starter.RewardedVideoPromptCount<Starter.Db.RewardedVideoPromptCountMax And _
            gamereturncount>=Starter.Db.RewardedVideoShowAfterPlayNumber And _
            statemanagertemp.GetSetting2("returning",False)=True And _
            Starter.Db.rewardedvideoshowprompt Then
        ShowVideoOnLoaded=False

        If Main.adsenabled And DateTime.Now-Starter.Db.RewardAdLastBuggedAt>Starter.Db.RewardAdBuggerIntervalMin*DateTime.TicksPerMinute Then
            Starter.Db.RewardAdLastBuggedAt=DateTime.Now
            Starter.RewardedVideoPromptCount=Starter.RewardedVideoPromptCount+1
            Msgbox2Async(Starter.Db.translate("Would you like to watch a short video advertisement to enable %s minutes of full access without ads?").Replace("%s",Round(Starter.Db.RewardMins)), _
                Starter.Db.translate("Mind Games Pro"), _           
                Starter.Db.translate("Watch video ad"),Starter.Db.translate("Cancel"),Starter.Db.translate("Subscribe"),LoadBitmap(File.dirassets,"iconpro100.png") ,True)
            Wait For Msgbox_Result (Result As Int)
            If Result = DialogResponse.POSITIVE Then
                ShowInterstitial=False
                If RewardAd.Ready Then
                    RewardAd.Show
                Else
                    RewardAdLoad
                    ShowWhenLoaded
                End If
            End If
            If Result = DialogResponse.NEGATIVE Then
                ShowInterstitial=False
                misc.ProApp("Vid Ad Dialog")
            End If
            Starter.Db.RewardAdLastBuggedAt=DateTime.Now
        End If
    End If
    If statemanagertemp.GetSetting2("returning",False)=True Then gamereturncount=gamereturncount+1
    If ShowInterstitial Then Check_Show_Interstitial
End Sub

Sub RewardAdLoad
#if debug
    RewardAd.LoadAd("ca-app-pub-3940256099942544/5224354917")
#else
                    RewardAd.LoadAd("ca-app-pub-9667959996137118/4784545368")
#End If   
End Sub

Sub ShowWhenLoaded
    ShowVideoOnLoaded=True
    ProgressDialogShow2(Starter.Db.translate("Loading"),True)
End Sub


Sub RewardAd_ReceiveAd
    ProgressDialogHide
    If ShowVideoOnLoaded And RewardAd.Ready Then RewardAd.Show
    ShowVideoOnLoaded=False
    Log("Ad received. Now wait for the right moment to show the ad.")
End Sub

Sub RewardAd_Rewarded (Item As Object)
    LogColor("RewardAd_Rewarded",Colors.Green)
    Starter.firebaseanalytics.SendEvent("rewarded_video",Null)
    CallSubDelayed2(Starter,"Reward",Me)
'    ToastMessageShow("You are rewarded!!!", True)
End Sub

'called from starter service
Sub RewardAd_AfterProEnabled
    Activity.RemoveAllViews
    MsgboxAsync(Starter.Db.translate("You can now play for free for %s minutes.").Replace("%s",Round(Starter.Db.rewardmins)),Starter.Db.translate("Congratulations"))
End Sub

Sub RewardAd_FailedToReceiveAd (ErrorCode As String)
    LogColor("Failed: " & ErrorCode,Colors.Yellow)
End Sub

Sub RewardAd_AdClosed
    LogColor("RewardAd_AdClosed",Colors.Green)

End Sub

Sub RewardAd_AdOpened
    Log("Opened")
End Sub
 

Jack Cole

Well-Known Member
Licensed User
Longtime User
There is never a good reason to copy code. Why can't you implement the relevant code in a class?

Sometimes you need the events and subs to be in the activity module. Like above with the rewarded video ad. There are many other times when this is needed (consider for example repeated UI elements like with back buttons). Even Activity_Keypress can have the same content within several activities or even across apps. In my ActivityClass for b4i, I had to copy code to each Activity module to be available to be called in that module to preserve the event context for views. When I make a change to the repeated code, I have to do it in every module that uses it.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
You can and should implement the rewarded ads in the class. Handle the events inside the class.

If there is any specific event that must be in the activity (there are very few such events) then delegate the event from the Activity to the class.
B4X:
Activity_Resume
 YourClass.Resume
End Sub

You should never duplicate code. There is no reason for that and the correct solution is to use classes, not to let the compiler duplicate the code for you.
 

Jack Cole

Well-Known Member
Licensed User
Longtime User
You should never duplicate code. There is no reason for that and the correct solution is to use classes, not to let the compiler duplicate the code for you.

That is my aspiration as well, but there are times when I can't seem to get around it. I just realized that I can do this myself by writing a pre-compiler that runs before your compiler runs. I have some large projects that have many activities that need the repeated code in every activity module to make it compatible with how I share code between b4i and b4a. It is really quite exciting to be able to share almost the entire code base.

I can see where you would not want to promote the practice by making it a feature. Thanks for your time and a great product.
 

stevel05

Expert
Licensed User
Longtime User
I may well be missing something, but can you not put the code in 1 module in a separate project and compile it to a library, you can use either a class or a code module (class if you are handling events). Then include the library in the project and maintain the code in the library projects - 1 for Android, 1 for IOS.
 
Last edited:

advansis

Active Member
Licensed User
Longtime User
I think using classes is usually the best solution, but it is not if you cannot have inheritance and cannot make more instances of activities. If you have similar activities to develop, "includes" would be a nice workaround to the fact you cannot duplicate them... Probably B4X has grown too much despite of its structure (for example, using b4xviews is much different from standard views, and forces to use several workarounds to work)
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
f you have similar activities to develop, "includes" would be a nice workaround to the fact you cannot duplicate them
I don't agree. You should implement all of the shared code in a class. In the worst case you will need to duplicate a single line that is called from one of the activities events.

Probably B4X has grown too much despite of its structure (for example, using b4xviews is much different from standard views, and forces to use several workarounds to work)
Using B4XViews is very similar to using the standard views.
B4X hasn't grown too much.
B4X structure is simple and powerful. A simple structure is a good base for further growth.
 

advansis

Active Member
Licensed User
Longtime User
I don't agree. You should implement all of the shared code in a class. In the worst case you will need to duplicate a single line that is called from one of the activities events.
Erel, probably, I didn't understand very well what you mean, but this is my case:
- I have an app with several activities managing database records, each of them is similar to others, but obviuosly data fields could very different
- Each activity has a "find part": a listview and some others (buttons and fields) to filter the data
- Each activity has a "detail part": a panel containing views to view/modify the data searched
- There are some common functions such: activity_keypress, activity_resume, data_loading, data_saving, data_erasing, that have the same code
- Several times I build the detail layout dinamically, to reuse activities that are very similar
- I need (ALWAYS) to navigate between activities: say, from the invoice, I want to open the customer's detail, the product's detail or some other linked documents and then return to the invoice detail: I should use the same activity, but saving context and replacing is quite slow if you have several views to destroy and recreate. So I use one activity for each and need to duplicate a lot of code

Using B4XViews is very similar to using the standard views.
B4X hasn't grown too much.
B4X structure is simple and powerful. A simple structure is a good base for further growth.
Don't agree:
- Create a simple B4XPlusMinus (or other B4x) at runtime, as if they were standard views: quite difficult, there is a workaround (if I remember well from LucaMs, creating a layout). I tried to create AddToParent sub in library, but without luck
- Try to cast a GetAllViewsRecursively result to a B4XView (as in my question, some days ago): the B4XView is hidden in the Tag property. I know there is a reason for this, but using BX4Views is not the same than using standard ones: I lost a lot of time to convert my old Apps...
- Try to change B4XSeekbar bounds at runtime...

Erel, I appreciate your great job: BX4 is a wonderful tool, and love it, but it changes quickly and very often is difficult to follow...
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
- Each activity has a "find part": a listview and some others (buttons and fields) to filter the data
- Each activity has a "detail part": a panel containing views to view/modify the data searched
I would create a CustomListView (xCustomListView) - clvSearchFilter & clvDetails

There are some common functions such: activity_keypress, activity_resume, data_loading, data_saving, data_erasing, that have the same code
I woud create a class for data loading, saving, erasing, etc.

Activity's events... create and save a code module :eek:, import it in your project, copy its routines (Activity's events), remove the code module.


I haven't read the rest of your post :).
 

advansis

Active Member
Licensed User
Longtime User
I woud create a class for data loading, saving, erasing, etc.

Activity's events... create and save a code module :eek:, import it in your project, copy its routines (Activity's events), remove the code module.

Thanks LucaMs, it is more or less what I do, I have little difficulties in mainteining common changes (for example if you want to add a common functionality).
The real missings, in my own opinion, are: 1) Inheritance for classes and 2) multiple instances of activities. Includes could be a "dirty" workaround
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Create a simple B4XPlusMinus (or other B4x) at runtime, as if they were standard views: quite difficult, there is a workaround (if I remember well from LucaMs, creating a layout). I tried to create AddToParent sub in library, but without luck
- Try to cast a GetAllViewsRecursively result to a B4XView (as in my question, some days ago): the B4XView is hidden in the Tag property. I know there is a reason for this, but using BX4Views is not the same than using standard ones: I lost a lot of time to convert my old Apps...
- Try to change B4XSeekbar bounds at runtime...
This is not the correct place to further discuss it however you are confusing different and unrelated things. B4XPlusMinus has nothing to do with B4XView.
CustomView <> B4XView.
B4XView behaves similar to other views.
 
Top