Shop OBEX P1 Docs P2 Docs Learn Events
Separating a Spin Program into Multiple Objects — Parallax Forums

Separating a Spin Program into Multiple Objects

CassLanCassLan Posts: 586
edited 2009-04-28 18:41 in Propeller 1
Hello,

In writing PrEditor (http://forums.parallax.com/showthread.php?p=802392) I have written a DropDownMenu Function which I think·by itself·is pretty cool and useful.
The End result of the DropDownMenu Function is to ultimately update 1 byte sized variable of the index of the chosen menu option (defined in DAT).
I'm trying to separate it into its own object so that it can be used outside of PrEditor and also be improved upon·outside of·PrEditor. I believed when writing it I had taken precautions to make this process simple.

As it turns out this process is not how I expected it would be, I thought when you included Objects it just pasted that code at the end of your main object....how very wrong I was. I'm not sure where I got that notion.

So I have a couple of questions and I would be grateful for any help on this matter:

(1) Objects...If DropDownMenu prints characters on screen, and so does my main object...does this mean I have to include TV_Text twice?
If not, and its included only in the DropDownMenu object, how do I access it from my main object..or if its included only in my main object how do I access it from within my DropDownMenu object?

(2) Variables...Is there any way to access Variables that only exist (are defined) inside of DropDownMenu from my main object?
Is there any kind of Variable that is Global Across all objects within the Top level object?

(3) DAT...Can DAT addresses from one object be used in another? Ideally I would like someone to define DAT in their main program filled with Menu Data using a certain label, and have the DropDownMenu object be able to utilize that, this way people would not have to change the DropDownMenu Object when they wanted to change a menu's contents.

I know this is a lot of questions, but this is the first large program that I have written for the Prop.
Thanks in advance,

Rick
·

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2009-04-28 15:38
    1) This is one aspect of object use that doesn't work the way objects are done in Spin. You can't pass other objects like TV_Text or parts of them to something like DropDownMenu without cheating (using Spin interpreter internal tables). If you have an object with the whole menu system in it, you can include TV_Text in the Menu System object and have "wrapper" methods in the Menu System object that just call the same methods in TV_Text. In other words, all access to TV_Text goes through the Menu System.

    2) No, not really. You can define methods in DropDownMenu that set or get the values of the variables. Usually you have a set and get method for each variable.

    3) See #2. The difference between VAR variables and DAT variables is mostly that there's a separate copy of each VAR variable for each declared instance of the object. There's only one copy of the DAT variables across all instances of the object.

    4) It's possible to include something like TV_Text in several objects and share the functionality with only a few bytes' overhead per include. You have to not use VAR and only use DAT for the variables. There's a serial driver in the OBEX that works this way and the Propeller OS that I wrote long ago works this way. All the I/O drivers were written using work areas in high memory and no VAR or DAT variables. Different objects could each include the base drivers (objects) and the Spin compiler took care of only including a single copy of the compiled code for the object.
  • jazzedjazzed Posts: 11,803
    edited 2009-04-28 15:56
    Just to add a bit to Mike's response:

    It will not hurt to include an object in many objects most of the time (one exception is an object that has a large data buffer ... don't know why). Mike mentions using DAT vs VAR in the TV_Text driver ... this works fine given the usage of the TV driver; other objects that may have multiple instances should not use DAT data.

    I feel your pain on sharing data ... no such thing as a public variable. One approach to solve this would be to make the user define the variables and pass them by reference to your object. If the user gets it wrong, it can be frustrating. You can still use private variables in the object if you like. Having to provide get/set accessors for every variable consumes valuable memory but does allow you control over the data.

    One thing to do for reducing memory size is to make sure to use 'constant' where possible in your program.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Steve


    Propalyzer: Propeller PC Logic Analyzer
    http://forums.parallax.com/showthread.php?p=788230
  • CassLanCassLan Posts: 586
    edited 2009-04-28 16:08
    Mike,

    Thanks for your reply, and the information.

    About #1, I had considered the wrapper option..this would mean all KB, Mouse and Text would all have to go through DropDownMenu..I think thats a lot to ask of someone who may want to try it out in an existing program. I'm gonna think about these options for a bit.

    Following along·to your answers 2 & 3, in the webinar clip:[url=http://www.parallax.com/Portals/0/Downloads/mm/video/Webinar/2009-03-17-4p-Webinar-[07].wmv]http://www.parallax.com/Portals/0/Downloads/mm/video/Webinar/2009-03-17-4p-Webinar-[noparse][[/noparse]07].wmv[/url], Chip says about DAT "so its a good way to do some kind of persistant state storage that all·objects need to see".
    So if I setup the DropDownMenu function so that upon being called it gets passed @MenuData (MenuData being a DAT label in the Main Object) then it can look up the data at that address?
    Is that what you mean by a "set and get method"? Using known memory locations for data that is to be shared among multiple objects?

    About #4, I see how that could work.

    Steve,

    I think I'm leaning toward a "helper"·method in the Main Object which would facilitate the single includes of kb, Mouse, TV_Text.


    Post Edited (CassLan) : 4/28/2009 4:15:36 PM GMT
  • jazzedjazzed Posts: 11,803
    edited 2009-04-28 16:29
    Rick,

    I know what you mean by "helper method", but I'm not sure that's possible.

    In one of my GUI projects, I use a common display driver. I plan to make it more generic by having a "wrapper interface". Using a wrapper will slow execution, but will make the code portable.

    Here's an example of a GUI label using an LCD spi driver:

    {{
    gui_label.spin: Defines a gui label
    Copyright (c) 2009 John Steven Denson
    All Rights Reserved
    }}
    
    var
      long textptr                  '' pointer to label text
      word left                     '' left pixel position of element
      word top                      '' top pixel position of element
      word width                    '' pixel width of element -- set to 0 for default or auto size
      word height                   '' pixel height of element -- set to 0 for default or auto size
      word border                   '' border width - 0 for no border
      word bocolor                  '' bocolor for label border
      word bgcolor                  '' bgcolor for label
      word fgcolor                  '' fgcolor for label
    
    obj
        d: "spiasm-lcd-65k"    ' replace with "wrapper interface" object
        g: "gui_common"
      
    pub init(textp,x,y,w,h)
    {{
      label constructor - creates a label element
      @param textp  - pointer to text
      @param x  - left
      @param y  - top
      @param w  - width  use 0 for default size
      @param h  - height use 0 for default size
    }}
      textptr := textp
      left  := x
      top   := y
      width := w
      ifnot h
        height := constant(g#DHEIGHT-1)
      else
        height:= h
      setBorder(0)
      setBorderColor(d#LIGHT_GRAY)
      setbgcolor(d#TRANSPARENT)
      setfgcolor(d#BLACK)
    
    ... much get/set code skipped ....
    
    pub paint | n, h
      d.setbgcolor(bgcolor)
      d.setfgcolor(fgcolor)
      if bgcolor
        d.fillRectangle(bgcolor,left,top,width,height)
      if border
        d.drawRectangle(bocolor,left,top,width,height,border)
      if textptr
        d.drawString(textptr,left+constant(d#FONTWIDTH*1/5),top+constant(d#FONTHEIGHT*2/3))
    
    
    



    User calls init, changes parameters with get/set, changes text which the user owns, and calls paint for display.
    Hope this helps in some way.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Steve


    Propalyzer: Propeller PC Logic Analyzer
    http://forums.parallax.com/showthread.php?p=788230
  • CassLanCassLan Posts: 586
    edited 2009-04-28 16:30
    You know what, I had originally thought that including objects got that objects code "Pasted" onto the bottom of your code, and thats how I wrote DropDownMenu.
    Since you can have Multiple CON, VAR, and DAT sections and they don't all have to be at the top, I'm just going to leave the DropDownMenu Function as a "pasteable" set of functions. If someone wants to simply play with it, they can paste it to the bottom of their existing program and call the functions from thier Main Object.
    After playing with it, if someone decides they like it, (I'm sure they will modify it anyway) they can work it into their program anyway they want.

    Maybe another solution will present itself in the future...but for now thats how I'm going to treat the DropDownMenu Functions and release them that way.

    Rick
  • BaggersBaggers Posts: 3,019
    edited 2009-04-28 16:43
    good call Rick, saves adding extra wrapping code, especially when you're trying to save space [noparse]:)[/noparse]

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    http://www.propgfx.co.uk/forum/·home of the PropGFX Lite

    ·
  • jazzedjazzed Posts: 11,803
    edited 2009-04-28 16:46
    That's a fair idea Rick. I have a PC application I've been writing to make that kind of GUI code copy/paste easier. It would be simple enough to include a code snippet definition for actually drawing the GUI elements. Spin source license would be open of course.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Steve


    Propalyzer: Propeller PC Logic Analyzer
    http://forums.parallax.com/showthread.php?p=788230
  • CassLanCassLan Posts: 586
    edited 2009-04-28 18:41
    Not to bump the thread but the DropDownMenu code mentioned above has been posted: http://forums.parallax.com/showthread.php?p=803515

    Rick
Sign In or Register to comment.