Passing .spin object for use in another object ?
jazzed
Posts: 11,803
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
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
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
multiple cogs. Take a look here:
http://forums.parallax.com/showthread.php?p=695493
regards peter
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.
Steven
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
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
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
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
Don't suppose you have hash table or tree modules yet ? [noparse];)[/noparse]
jazzed ...·by your urge to use·doxygen markup.
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
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