ByRef for Activity

Penko

Active Member
Licensed User
Longtime User
Hello Erel :)

This post is kinda wish or a question if it is achievable with current B4A capabilities.

I'm writing something serious and as it's obvious from other topics of mine, I am aiming at reusability. But because I can't pass an Activity to a function by reference, I am copying the same code in every Activity.

Sample code which is copied:
addMenus() - a function in Activity modules.

B4X:
Sub addMenus()

   Dim i As Int
   
   Dim menus As Map
   menus.Initialize
   
   Dim thisKey As String
   Dim thisMenuItem As MENU_ITEM   
      
   ' get all menus depending on the activity
   menus = Common.getMenusByActivity(menu_prefix) ' E.g $$Main$$
   
   For i = 0 To menus.Size - 1
      
      thisKey = menus.GetKeyAt(i)
      thisMenuItem = menus.GetValueAt(i)
      
      Activity.AddMenuItem2(thisMenuItem.displayText, thisMenuItem.event, thisMenuItem.icon)
   Next
   
   'Activity.AddMenuItem("About","menu")
End Sub

Now, if it was possible to put the above method into a code module and do the following in Activity_Create

addMenus(ThisActivity) ' of course it can be the activity name too.
 

joseluis

Active Member
Licensed User
Longtime User
You can't pass an Activity by reference?
B4X:
Sub test(A as Activity, L as Label)

    L.Initialize("")
    A.AddView(L, 0, 0, 100, 100)
End Sub

I'm pretty sure that would work in a code module. Have you tried it with your code?
 

Penko

Active Member
Licensed User
Longtime User
I read that all Objects are passed by Value. Activity objects should not make an exception.

Haven't tried myself recently, just during the first 1-2 days tried something like that and it didn't work.

I tried it out and successfully broke the compiler. But even if it happens, I don't expect to get the result on the main activity but on its copy(the local function parameter).

Try yourself with the attached project.
 

Attachments

  • activity.zip
    6.2 KB · Views: 207

Penko

Active Member
Licensed User
Longtime User
That sounds interesting, my mistake. Therefore the example should work but it breaks.

Edit: @thedesolatesoul was right! I was reading an example of Erel's and noticed he used Activity as object which is pretty much correct. Therefore, I modified my above example and it is now:

module:
B4X:
Sub showMenu(act As Activity)

act.AddMenuItem("rarara", "ra")

act.Title = "Activity commanded by Module"

End Sub

Activity module ze - the key point here is to use the variable Activity rather than the name variable like in StartActivity(Main). E.g NOT Main, About, etc...
B4X:
Sub Activity_Create(FirstTime As Boolean)
module.showMenu(Activity)
End Sub

It is so cool. One minor bug is that Activity is shown in Red in the module but it compiles correctly.

Thank you both, it's much easier now.
 

HarryB

New Member
Licensed User
Longtime User
More instanstances of activity

Would this mean that something like:

Sub Globals
  • Dim act() As Activity
    act= Array As Activity ("Test","Test","Test")
End Sub

would also work? I am really interested in that.

I get a compiler error now.
 

agraham

Expert
Licensed User
Longtime User
All primitives are passed by value.
Everything else is passed by reference.
I'm afraid this is wrong, everything is passed by value. Note that what is being passed is the contents of a variable located in memory or a literal value. The contents (value) of a primitive is the actual primitive value. the contents (value) of an object variable is a reference to the location of that object.

Passing by reference passes the actual address of the value in memory which allows you to alter the value at address. i.e. change the value of a primitive variable or change the object referenced by an object variable.
 
Top