Shop OBEX P1 Docs P2 Docs Learn Events
Accessing an object instance by reference — Parallax Forums

Accessing an object instance by reference

Matt1024Matt1024 Posts: 1
edited 2007-12-03 18:09 in Propeller 1
How can I access an instance of an object by reference in SPIN?· I’m sure it’s possible but cannot seem to figure out the syntax or find any useful reference in the Propeller docs.· Since there’s no way to have a truly ‘global’ object/variable, I’m okay passing a pointer to the global instance in the INIT method of objects which need to use it (so they can use a local reference), but the correct syntax for dereferencing·those pointers·eludes me.
I know you can ‘fake it’ by creating multiple instances of an ‘all –method’ object (in which case ‘same’ or ‘other’ instance is irrelevant), or by declaring object-scope variables as Data instead of Vars (so all instances reference the same variables), but I’m looking for a more elegant solution which doesn’t presume·all instances are to be ‘global’.
One case which serves as a good example:· I’m trying to develop a general framework, and would like all of my library code to have access to a single global instance of a “Debug” object.· This object internally references other objects so ‘faking it’ will not suffice·
An example of what I’d like to do (using Spin syntax) might look something like:
·
{{Debugger}}
PUB Init
··········· Yadda
··········· Yadda
PUB ShowError(TextPTR)
··········· Yadda
··········· Yadda
·
{{SomeLibraryModule}}
Var Long DebugInstance
PUB Init(DebuggerPTR)
··········· DebugInstance:=DebuggerPTR
PUB DoSomething(param)
··········· If (param<0) or (Param>MaxValid)
··········· ·· DebugiInstance^.ShowError(string(“Out of range&#8221[noparse];)[/noparse])
·
{{Main App}}
OBJ
Debug : Debugger
SomeMod : SomeLibraryModule
Pub Main
··········· Debug.init
··········· SomeMod.Init(@Debug)
··········· Yadda…
·
Any ideas?
·
Thanks for any help,
Matt

p.s.· Is this group mirrored on any actual Usenet server?· It would be nice to be able to use Usenet search tools [noparse]:)[/noparse]

·

Comments

  • AleAle Posts: 2,363
    edited 2007-12-03 12:39
    There are no instances, because there are no objects. Just their absolute addresses in memory, where their first "method" is and where their last. IFAIK, there is no way to know, because the compiler does not provide information about the compiled source (I asked for it). But, you can use a decompiler like hippy's to know where to look.

    Have a look at ariba's in-circuit debugger, it may give you an idea. OTOH a video driver text or graphics can help you debug. As HUB memory is shared, you can monitor variables with another COG and thus see what happens without disturbing or interrupting the running code.
  • Mike GreenMike Green Posts: 23,101
    edited 2007-12-03 15:31
    You can't have a reference to an object. There's simply no mechanism to do it. Someone posted some routines that "faked out" the various internal tables at run time by copying different values into them, but there are major limitations to that method.

    You might have a look at the "Propeller OS". There's a link in the "sticky threads" in Graham Stabler's good links list. This provides for persistent assembly routines with a common work area dynamically allocated in high RAM and accessed through small APIs that are compiled with programs running under the OS. For example (and this was only done in an unreleased version) you could have two display drivers, one for TV and the other for VGA, that are compatible in terms of their work areas with things like screen size provided in the work areas as parameters. You could have a single API that would work with either driver and they'd communicate through this common work area. The proper driver would be loaded by some initialization phase and subsequent overlays would reference the running driver's work area.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-12-03 17:35
    Mike might have been referring to my callback object, which provides said "fake-outs" and a way to pass a pointer to a procedure. It comes with a number of caveats and may or may not work for what you're trying to do. So use at your own risk. If it doesn't work, I can't help you.

    I found Chip's comment on the subject most intriquing:
    Chip Gracey (Parallax) said...
    To me, Spin's biggest shortcoming is lack of indirect calls and mixed data structures. This will get addressed in the future.
    Now that (the inidirect calls) will be something worth waiting for!

    -Phil
  • deSilvadeSilva Posts: 2,967
    edited 2007-12-03 18:09
    @Matt: There are - as generally smile.gif - some misconceptions here...

    (a) A "static instance" of a SPIN object consists of
    - code ("methods")
    - constants
    - DAT variables
    - VAR variables

    in multiple instantiations only VAR variables are multiplied!
    DAT variables are single and truly global ("class variables")

    (b) You can access constants (objalias#constname) and PUB-methods objalias.methodname); no class variables, no objct variables - this is a somewhat restricting scope rule.

    (c) Getting access to METHODs is only possible by statically knowing the object's true name, so you have to include this in your OBJ section. Note this does not do anything at all as lonmg you do not use VAR variables in it. In fact there is no reason to use VAR variables at all (other than just WANTING to dublicate that data set)

    (d)Getting access to DATA is only possible by calling getters, or - as you try - to implant pointers through INIT calls.

    I think what is one of your problems is the awkward way to dereference pointers: It is:
    X := LONG[noparse][[/noparse]thePointer]  ' or BYTE or WORD
    


    Accessing a vector-element is:
    X := LONG[noparse][[/noparse]thePointer][noparse][[/noparse]pos]  ' or BYTE or WORD
    



    Hope this helped a little bit
Sign In or Register to comment.