Shop OBEX P1 Docs P2 Docs Learn Events
How to store an object in an array (or similar data structures) — Parallax Forums

How to store an object in an array (or similar data structures)

Harry1Harry1 Posts: 29
edited 2007-01-05 22:45 in Propeller 1
I am trying to store a Point Object. Point is an object i created and takes two vars (xVal, yVal) as parameters. Is it possible this type of an object in an array or similar data structures? Any help will be appreciated [noparse]:)[/noparse]·

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-01-05 21:34
    If the range of xVal and yVal is such that you can store them in 8 bits or 16 bits, you can combine them to form a 16 bit or 32 bit word (or long word) which you could treat as a single item in SPIN, but quickly and easily dissect into pieces within your object's code. SPIN does have arrays of bytes, words, and longs as native structures. For example, if xVal and yVal range from -1000 to +1000, you could extract and combine values as:
    PUB xValOf(p)
       return p >> 16 - 32768
    
    PUB yValOf(p)
       return p & $FFFF - 32768
    
    PUB pointOf(x,y)
       return ((x + 32768) << 16) | (y + 32768)
    
    


    you could declare a point array as "VAR long pointArray[noparse][[/noparse]32]" and store items as "pointArray[noparse][[/noparse]z] := pointOf(x,y)" or reference them as "xValOf(pointArray[noparse][[/noparse]z])"
  • rokickirokicki Posts: 1,000
    edited 2007-01-05 21:36
    Unfortunately, spin "objects" are not the same what most people mean when they say "object-oriented programming".

    You can indeed have arrays of objects. But you cannot (at least not "easily") copy objects, create or use a pointer or
    reference to an object (other than in a purely static manner), subclass objects, etc.

    So you can do this:

    obj
    pointArray[noparse][[/noparse]100] : "point"

    which creates an array of 100 "pointArray" objects. (You can only create, I think, a maximum of 255 total
    subobjects + procedures in any one object, so that 100 cannot be 1000.)

    But it is probably far far more efficient (if not clean) to simply disassociate the data from the methods, so your
    "point" class would not actually have any data, and you would just use a memory area with two longs in it as
    data, and call those subroutines passing the pointer to the memory for the data. That is, use a C-style design
    rather than a C++-style design.
  • Harry1Harry1 Posts: 29
    edited 2007-01-05 21:36
    You are a genius [noparse]:)[/noparse]

    thank you!
  • Harry1Harry1 Posts: 29
    edited 2007-01-05 21:40
    rokicki said...
    Unfortunately, spin "objects" are not the same what most people mean when they say "object-oriented programming".

    You can indeed have arrays of objects. But you cannot (at least not "easily") copy objects, create or use a pointer or
    reference to an object (other than in a purely static manner), subclass objects, etc.

    So you can do this:

    obj
    pointArray[noparse][[/noparse]100] : "point"

    which creates an array of 100 "pointArray" objects. (You can only create, I think, a maximum of 255 total
    subobjects + procedures in any one object, so that 100 cannot be 1000.)

    But it is probably far far more efficient (if not clean) to simply disassociate the data from the methods, so your
    "point" class would not actually have any data, and you would just use a memory area with two longs in it as
    data, and call those subroutines passing the pointer to the memory for the data. That is, use a C-style design
    rather than a C++-style design.
    Sorry, i don't exactly understand what you mean. How do i disassociate data?
  • rokickirokicki Posts: 1,000
    edited 2007-01-05 21:40
    By the way if you do this, it's far better to use the (not very well known) byte-subfield and word-subfield access.
    So if you store a point as two words in a long, you can:

    sub hypot(pt) | x, y
    x := pt.word[noparse][[/noparse] 0 ]
    y := pt.word[noparse][[/noparse] 1 ]
    return ^^(x * x + y * y)

    Post Edited (rokicki) : 1/5/2007 9:45:33 PM GMT
  • rokickirokicki Posts: 1,000
    edited 2007-01-05 21:43
    Well, what I mean is instead of doing this:

    (point.spin)
    var long x, y
    pub hypot
       return ^^(x * x + y * y)
    
    



    where the data is *in* the object, you instead do what Mike Green suggested or something
    similar, so

    (point.spin)
    var ' empty!  no data *in* the object itself
    pub hypot(pt) | x, y ' data is passed in to all methods
       x := pt.byte[noparse][[/noparse] 0 ]
       y := pt.byte[noparse][[/noparse] 1 ]
       return ^^(x * x + y * y)
    
    



    So you simply separate the data and the procedures that operate on that data rather than having
    them in the same "object".
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-01-05 22:45
    Perhaps even better would be to have an array in the object (class) itself and a constructor for allocating objects in the array, something like this:

    [b]var[/b]
    
      [b]word[/b] point[noparse][[/noparse]200]
      [b]byte[/b] nextpoint
    
    [b]pub[/b] new(x, y)
    
      [b]if[/b] (nextpoint < 200)
        point[noparse][[/noparse]nextpoint++] := x
        point[noparse][[/noparse]nextpoint++] := y
        [b]return[/b] @point[noparse][[/noparse]nextpoint - 2]
      [b]else[/b]
        [b]return[/b] [b]false[/b]
    
    [b]pub[/b] hypot(self) | x, y
    
       x := self.[b]word[/b][noparse][[/noparse] 0 ]
       y := self.[b]word[/b][noparse][[/noparse] 1 ]
       [b]return[/b] ^^(x * x + y * y) 
    
    
    


    This has the advantage of keeping the object implementation details and their management hidden from the user. Of course, it doesn't make the most efficient use of memory and lacks an object destructor. This could be be improved by implementing some sort of dynamic memory management scheme, wherein destroyed objects could be reused.

    -Phil
Sign In or Register to comment.