Shop OBEX P1 Docs P2 Docs Learn Events
Passing .spin object for use in another object ? — Parallax Forums

Passing .spin object for use in another object ?

jazzedjazzed Posts: 11,803
edited 2008-01-13 05:13 in Propeller 1
Hi. Been working with .spin for a while now, and find that I would
like to pass my defined console object from the top object to another
object for "printf debugging". Is there a way to do this? I've tried it,
but the compiler doesn't know the incoming variable is an object.
Could use a little language type-casting here [noparse]:)[/noparse]

TIA

Comments

  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-01-07 10:33
    Hi jazzed and welcome to the forum.

    Spin can't officially do that (ie supported by parallax) but I am working on an object that will you to do this kind of thing. Have a look in the "Spin feature request" thread. Doing it involves including a dummy object and then playing around with the pointers that spin generates. Its not all that easy, but I think I can do it.

    Steven
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-01-07 17:04
    I think the callback object I wrote may help you. Be sure to read all the caveats...

    -Phil
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2008-01-07 18:05
    It is possible to use one object that does debug printing, even from
    multiple cogs. Take a look here:
    http://forums.parallax.com/showthread.php?p=695493

    regards peter
  • jazzedjazzed Posts: 11,803
    edited 2008-01-07 21:29
    Thanks for warmly welcoming me to this forum and offering these very interesting code examples.

    This is enough to chew on for now .. of course more inputs to the problem will be happily considered.
    I will certainly be using some of the concepts and examples provided.

    Phil's callback appears the closest answer to my question although it seems a little stack heavy. It does show a reasonable example of how to implement features callable by other modules. Is this reentrant ?

    Peter and Phil, these print formatting code bits look very useful ... I guess a generic var_args printf is out of the question with spin. Adding some vt100 compatible cursor positioning would be great for creating a generic ascii system monitor don't you think ? I'm using some of the codes for display found in a big list at:
    http://pegasus.cs.csubak.edu/Tables_Charts/VT100_Escape_Codes.html

    Steven your loadable object idea is quite intriguing. Have you considered a layer that would allow loading over an interface that can be specified at cog-start time (serial, IR, disk, whateve)? One of my applications could benefit greatly from this. Of course passing the driver object handle having well defined API into the load layer would make new devices easy to add. Seems like Phil's callback approach could be employed for passing the handle.

    Thanks again.
    --jazzed ... by your answers.
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-01-08 06:38
    @jazzed: No I hadn't thought of that yet. I hadn't seen Phils callback object before so I will have to have a look at that. I'll start thinking about other interfaces when I get DOL working properly.

    Steven
  • simonlsimonl Posts: 866
    edited 2008-01-08 14:44
    Steven: jazzed's request has got me thinking - could be a way to call 'services' hosted by another Prop' (or even a PC!). Might even pave the way for PropClusters?! Especially given Beau's high-speed comm's objects...

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheers,

    Simon
    www.norfolkhelicopterclub.co.uk
    You'll always have as many take-offs as landings, the trick is to be sure you can take-off again ;-)
    BTW: I type as I'm thinking, so please don't take any offense at my writing style smile.gif
  • hippyhippy Posts: 1,981
    edited 2008-01-08 19:11
    There are three design decisions with the Spin architecture which makes what's needed difficult.

    The first decision was to implement a 'method pointer table', a jump vector table which leads to where methods and objects are, which means calling a method is a matter of indexing through these tables rather than by being a direct call to the address of the executable code of a method.

    This is why 'function pointers' could not be a simple case of '@MyFunction'.

    Secondly, methods do not allocate their own stack space for local variables upon entry. That needs to be done before entering the method and uses information in the 'method pointer table'. Even if function pointers existed, calling direct with them would not work if the method used any local variables.

    Thirdly, inter-object method calls also need to manipulate 'Object Base' and 'Variable Base' pointers, again done before calling an object's method, because there's no means to do that once the method is entered. Unless the pointers are updated as required, the method cannot use VAR variables the object has defined ( any references to them would be to the wrong place in hub memory ).

    Once 'Variable Base' gets out of kilter, it stays that way for any calls made from the called method.

    This all adds up to complications and especially so when it's a call to an arbitrary method in an arbitrary object, it's unfortunately not just a simple case of passing the address of where the desired method to call or call-back is or the address of an object to use.

    More deep-down details : propeller.wikispaces.com/Method+Calls
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2008-01-10 15:21
    I am currently writing a double linked list object that uses my heap object
    for dynamic memory allocation. I want to pass the heap object that a list uses
    for memory allocation. Since that is not possible I thought of the next best way:
    pass the·heap object properties. This could be the properties of the main heap
    or the properties for a completely new heap.
    Example:
    The main program
    OBJ
    · mem:·· "heap"················ 'dynamic memory control
    · hp2: "heap"·
    · list: "list"
    VAR
    · byte heapArray[noparse][[/noparse]1024] 'byte array to serve as heap
    · word block
    PUB main
    · mem.create(@heapArray,1024) 'this defines the main heap
    · block := mem.allocate(600) 'this block is to be used for list
    ··hp2.create(block,600) 'this creates a new heap (inside an existing heap) from which main and list can allocate
    · list.setHeapObjectProperties(block,600) 'pass the heap object properties

    The list object:
    OBJ
    · heap: "heap"
    VAR
    · word listStart '//address of listBlock
    PUB setHeapObjectProperties(base,size)
    · '/**
    · ' * Defines the heap this list will use to allocate blocks from.
    · ' * This could be the main heap, but just as well a completely new heap.
    · ' *
    · ' * @param base Start address of heap
    · ' * @param size Size of heap in bytes (size => 7 bytes)
    · ' */
    · heap.create(base,size)

    setHeapObjectProperties sets the private heapStart and heapEnd parameters
    of object heap in object list. To prevent overwriting an existing heap structure,
    the method create in object heap must not create a heap structure if the
    integrity test for the passed parameters returns true, which would be the case
    if I had passed @heapArray and 1024, because the heap structure for those
    values is already done by the main program.

    This is I think the best workaround for passing objects to objects. Mandatory is in that
    case that objects have an initialization method that can check it is initialized prior
    to setting its parameters or initializing used structures.

    Please comment on this approach. The big plus is that I can simply call·method names
    that are·defined public in the object.

    regards peter


    Post Edited (Peter Verkaik) : 1/10/2008 3:27:54 PM GMT
  • jazzedjazzed Posts: 11,803
    edited 2008-01-10 18:07
    Peter do you have a repository or demo code for this example ?
    Don't suppose you have hash table or tree modules yet ? [noparse];)[/noparse]

    jazzed ...·by your urge to use·doxygen markup.
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2008-01-10 18:31
    No demo code yet, but I think this approach will work.
    Basically I create a new object instance (in this case a heap object)
    that accesses the same datastructure as set by hp2 in the main program.
    So it is as if hp2 was passed to list.

    regards peter
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2008-01-13 05:13
    Attached are my latest results regarding passing objects.
    I have put the methods required for the pointer manipulations
    in a seperate object. This keeps the application objects clean.

    The important part of the test program is
    · obj1.init(string("ABCD"))·· 'this sets up text in obj1 and prints "ABCD"
    · obj2.init·················· 'this sets up text in d and prints "PQRS"
    · handle := po.getObjectHandle(2,1,TotalObjects,@endOfObjects,@firstVariable) 'get handle for obj1 to call from obj2
    · obj2.run(handle)··········· 'this prints the text array from d, but because d gets redirected it prints "ABCD"
    · obj2.run(0)················ 'and it prints "PQRS" again

    The debug output is as described by the comments.

    regards peter
Sign In or Register to comment.