Android Question How to access properties of "unknown" object?

Discussion in 'Android Questions' started by Troberg, Mar 27, 2015.

  1. Troberg

    Troberg Well-Known Member Licensed User

    I have made a framework, where I can plug in GUI components by creating them as classes with a certain interface. Normally, I would do this using Implements, so that they would all appear to be the same class, but that option is not available in B4A.

    So, in my case, I have a bunch of different GUI components (in the framework terminology called SCR). These are different, but they all share some common properties and methods.

    So, for example, I want to do this:

    Code:
    Sub ShowSCR(SCR As Object)
      SCR.HostPanel.Visible = 
    True
    End Sub
    I know that SCR has a HostPanel property, which has a Visible property, but the compiler doesn't and reports an error.

    How do I solve this, without true object oriented interfaces? For methods, it's easy to simply use CallSub (at least as long as they don't have many arguments), but properties?
     
  2. JordiCP

    JordiCP Well-Known Member Licensed User

    Code:
    If SCR is Panel then
        
    Dim myP as Panel =SCR
        myP.HostPanel.Visible=
    True
    end if
     
    Troberg likes this.
  3. Troberg

    Troberg Well-Known Member Licensed User

    Ah, but SCR isn't a panel. SCR is not a single class, it's a bunch of different classes with a common interface, and one of the exposed properties in that interface is HostPanel.

    So, the code fails at the first dot, after SCR.
     
    JordiCP likes this.
  4. JordiCP

    JordiCP Well-Known Member Licensed User

    Then, this should work

    Code:
    If SCR is someSpecificClass then
       
    Dim myP someSpecificClass =SCR
       myP.HostPanel.Visible=
    True
    End if
     
    Troberg likes this.
  5. Troberg

    Troberg Well-Known Member Licensed User

    Yes, but it would kind of break the idea of having a framework where the host (where this code resides) don't have to know anything about the components it hosts, other than that they all share a certain interface.

    At the moment, I need one (or, if one is strict about counting, two) line of code to add a component. Example:

    Code:
    'Add About SCR
    Dim SCR As cSCRAbout :AddSCR(SCR)
    'Add Video SCR
    Dim SCR As cSCRVideo :AddSCR(SCR)
    That's the only place where I need to know the actual type. Form then on, I don't want to have to add any special handling at all for different SCRs. For example, if I do this the following, I shouldn't need any special handling depending on if it's cSCRAbout or cSCRVideo, I just need to know that since they have all the methods and properties that the SCR interface demands, they should have an Enabled-property.

    Code:
    Sub EnableSCR(SCR as object, Enabled as Boolean)
      SCR.Enabled=Enabled
    End Sub
    These are the very building blocks in my framework, and I'm going to use them a lot. I don't want to add specific code for each SCR (which may be dozens) in every specific place I access them.

    I understand (or, at least I think I do) why Erel has chosen to not go down the full object oriented path, and I support those reasons, but in this case, it would have been easy to just define an iSCR interface, then specify on all SCRs that they Implements iSCR. THat way, I could have been able to simply handle them all as iSCR.
     
  6. keirS

    keirS Well-Known Member Licensed User

    You could use the Reflection library to do it.

    Code:
    Sub EnableSCR(SCR as object, Enabled as Boolean)
     
    Dim r As Reflector
     r.Target =SCR
     r.SetPublicField2(
    "Enabled",Enabled)
     
    JordiCP, Troberg and thedesolatesoul like this.
  7. Troberg

    Troberg Well-Known Member Licensed User

    Ah, neat. I was going down a slightly similar path, using CallSub to directly call the getters and setters of the properties.

    Code:
    Dim hp As Panel=CallSub(SCR, "getHostPanel")
    hp.Visible = 
    True
    Your version is neater, though.
     
    keirS and thedesolatesoul like this.
  8. JordiCP

    JordiCP Well-Known Member Licensed User

    There is even a third method using classes. It will allow exactly the syntax you were initially looking for :)

    Define a generic class with all the common interface members, and methods if needed
    Code:
    'CI_class <-- Common interface class
    Sub Class_Globals
      
    Dim Property1 as Boolean
      
    Dim Property2 as Int
    end sub
    ...
    The classes which share this common interface will place the members in a CI_class instance
    Code:

    Sub Class_Globals
      ...
      
    Dim CI as CI_class 'place where all your common interface properties will be
    end sub
    ...
    and finally, your SCR object wouldn't have to be an object anymore, but a CI_class instance

    Code:
    'myClass1 and myClass2 have a CI_class
       Dim myClass1Var as myClass1
       
    Dim myClass2Var as myClass2
       myVar1Class.Initialize(...)
       myVar2Class.Initialize(...)

      
    Dim SCR1,SCR2 as CI_class
      SCR1=myClass1Var.CI
      SCR2=myClass2Var.CI

      
    'Then you can do
      SCR1.Property1=True
      SCR2.Property2=
    3
     
    keirS and Troberg like this.
  9. Troberg

    Troberg Well-Known Member Licensed User

    Neat, very neat, but it wouldn't be without problems either, as there would then be a discrepancy between myClass Me and SCR Me. I use messages to communicate between classes, and this would mean they ended up at the wrong class. All in all, it would be a bit backward to put myClass in control over the parent SCR if it's contained in it.

    I'm sure I could work around that (for example but adding an Owner property to SCR), but it would require a bit too much rebuild at this point.

    Just to clarify: Even though the SCRs share the same interface, they will be very different on the inside, and will have very different capabilities and responses. Getting a clean path through the interface to the inside might be a bit awkward.

    And, yes, I'm picky. I'm going to use this framework extensively in a large project, so I want it as smooth as possible to use. :)
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice