Shop OBEX P1 Docs P2 Docs Learn Events
Pointer to Object Instance — Parallax Forums

Pointer to Object Instance

computer guycomputer guy Posts: 1,113
edited 2012-08-02 21:08 in Propeller 1
Lets say I have 3 objects (OBJA, OBJB and OBJC).

OBJA includes OBJB and OBJC

e.g.
OBJA
OBJ
  OBJB : "OBJB"
  OBJC : "OBJC"

The problem is, OBJC needs to access a variables value in OBJB.
At the moment I am declaring the variable in OBJA and passing OBJB and OBJC a pointer to the variable.

Is there a better way to do this? Can you have a pointer to an object?



Thanks :)

Comments

  • Heater.Heater. Posts: 21,230
    edited 2012-08-02 03:56
    No and no.
  • computer guycomputer guy Posts: 1,113
    edited 2012-08-02 04:06
    Thanks Heater.

    So is this standard practice then?
  • Heater.Heater. Posts: 21,230
    edited 2012-08-02 04:19
    As far as I can tell.

    Unlike C++ Spin does not allow you to take the address of an object and then pass that around to other objects so that they can access its methods and properties.

    Of course if the data area in question more logically belongs in object B or C, then perhaps it makes sense to define it in B or C and provide a method to get it's address that can be called by A. That address can then be passed to the other object that needs it.
  • n_ermoshn_ermosh Posts: 294
    edited 2012-08-02 07:18
    As heater said, you can't pass variables between objects. One thing i have often times done is create an object calls pointers, which contains and empty PUB main method and a CON section where i declare "global" variables that can be accessed by all objects in my project that reference it. Or have a method in OBJB that returns the address of the variable in OBJB to any other object, but from what i can tell, it would require a method for every variable that might be passed, which can get messy.
  • Heater.Heater. Posts: 21,230
    edited 2012-08-02 07:42
    There is a way out...possibly.

    1) Define the data you want to share in some object.
    2) Put all the data in a DAT section.
    3) Give that object some PUB methods that set and get that data.
    4) Include that object in any other objects you like with the normal obj syntax.
    5) Have those objects use the shared data by calling the accessor methods.
    6) For complicated structures the set and get methods will need to implement locks.

    This relies on the fact that there is only ever one DAT section created in the final program no matter how many instances of the object are created. In contrast to VAR variables where every instances gets it's own copy.

    You could, for example, have just a single get and stet method for your data object that takes a parameter indicating what is to be read or updated.
  • n_ermoshn_ermosh Posts: 294
    edited 2012-08-02 11:07
    That's one way of doing it, but it seems tedious and redundant. If you specify you "global variables" in the CON block, starting at say, $6000, you have plenty of space after your program and plenty more for your variables. Then include the object and reference those address constants by a name instead of and address.

    I haven't tried this, but what might work is declaring all your variables in a DAT block in a separate object, then in the CON block of that object declare constants equal to the address of the variables in the DAT block, and when in the main object, reference [pointers#varA] where pointers is the object where everything is stored. This would remove the possibility of accidentally writing over used memory space. Correct me if I'm wrong, please.
  • computer guycomputer guy Posts: 1,113
    edited 2012-08-02 18:01
    Thank you all for your suggestions. Unfortunately constants won't work as the data changes.

    OBJA initialises the other objects and then sleeps (waitcnt) for long periods of time, only waking up to do small tasks.
    OBJB is a Bluetooth driver object that holds a variable called "conState" which can have three values (0=disconnected, 1=connecting, 2=connected)
    OBJC is an object that contains drawing routines for displaying icons and text on a uOLED-128-G1 screen. So it needs to know the value in "conState" so that is knows if it should display the BT logo.

    There are other variables that OBJB and OBJC share. Such as the RSSI value.

    I was hoping to get away from having pointer accessors/setters defined in both OBJB and OBJC, but it appears this is the only way.

    OBJB will have "pointerForConState"
    OBJC will have "setPointerForConState"

    OBJA will use both methods to give OBJC the pointer from OBJB.
  • jazzedjazzed Posts: 11,803
    edited 2012-08-02 18:31
    Thank you all for your suggestions. Unfortunately constants won't work as the data changes.

    I think he meant using constants as address offsets which you can add to a base address to get/set the data (in a dat section - var sections reorganize things for you). You can pass addresses anywhere; just can't pass objects.
  • computer guycomputer guy Posts: 1,113
    edited 2012-08-02 18:34
    So explicitly specifying the address location of the variables? I'm not sure I follow.
  • jazzedjazzed Posts: 11,803
    edited 2012-08-02 19:09
    So explicitly specifying the address location of the variables? I'm not sure I follow.

    Just the offsets. Get/Set methods would be easier to read. Example:
    {{
     * @file objectref.spin
     * This is the main objectref program start point.
    }} 
    
    
    obj
        ob2 : "object2"
        ob3 : "object3"
        odat: "objectdat"    
    {{
     * Main program function.
    }}
    pub main | sum2, sum3
    
    
        ob2.start( odat.base)
        ob3.start( odat.base)
        sum2 := ob2.sum
        sum3 := ob3.sum
        
        repeat
    
    ' object2.spin
    obj
        odat : "objectdat"
    
    
    var
        word vp
    
    
    pub start(vptr)
        vp := vptr
        
    pub sum
        return long[vp+odat#v1p] + long[vp+odat#v2p]
    
    ' object3
    obj
        odat : "objectdat"
    
    
    var
        word vp
    
    
    pub start(vptr)
        vp := vptr
        
    pub sum
        return long[vp+odat#v1p] + long[vp+odat#v2p]
    
    ' object dat
    con
        v1p = 0
        v2p = v1p + 4
        v3p = v2p + 4  
    
    
    dat
        var1 long 0
        var2 long 0
        var3 long 0
    
    
    pub base
        return @var1
    
  • msrobotsmsrobots Posts: 3,709
    edited 2012-08-02 21:08
    computer guy

    There was a thread here in this Forum about Dynamic Linking of Objects (DOL link here)

    Not simple but possible...

    Enjoy!

    Mie
Sign In or Register to comment.