Forums > Dev

How to uniquely identify a t_patcher?

February 27, 2008 | 4:04 am

Possibly my last obscure question for now:

Is there any way I can uniquely identify a t_patcher? Something in the struct that will be unique to that patcher only, or a method I can call that will return a uid (and return the same uid if called on the same t_patcher)?

I know this will only work for the Max 4 t_patcher struct, and that’s fine, but I will also need an equivalent for Max 5, when the SDK is out.


February 27, 2008 | 4:32 am

Why not the patcher pointer itself? It is certainly unique for the
lifetime of the patcher. Jeremy’s the expert, but I think this is
something pattr uses.

Otherwise you can keep a hashtab with values keyed to the pointer
value (casting t_patcher * to a t_symbol * is fine, as we don’t look
at the t_symbol), you can even cast anything to t_object * for the
value too. YOu just need to use hashtab_chuckkey() to delete a value
and/or hashtab_chuck to delete the hashtab so it doesn’t try to call
freeobject on the value.

Hope this helps.

-Joshua

>


February 27, 2008 | 5:04 am

Quote: jkc wrote on Wed, 27 February 2008 17:32
—————————————————-
> Why not the patcher pointer itself?

I was thinking that, but wasn’t sure that it was necessarily a good idea given possible VM swapping etc. I don’t know enough about how that sort of thing is handled.

Yep, I will be maintaining a hashtab indexed against patchers (the stored item will be a custom struct dealing with the patcher’s oo properties), and if the pointer’s good enough for you, it’s good enough for me…


February 27, 2008 | 6:23 am

On Feb 26, 2008, at 9:04 PM, John Pitcairn wrote:

> Quote: jkc wrote on Wed, 27 February 2008 17:32
> —————————————————-
>> Why not the patcher pointer itself?
>
> I was thinking that, but wasn’t sure that it was necessarily a good
> idea given possible VM swapping etc. I don’t know enough about how
> that sort of thing is handled.

You don’t need to worry about pointers being swapped in and out of
actual ram. The pointer address itself doesn’t change.

> Yep, I will be maintaining a hashtab indexed against patchers (the
> stored item will be a custom struct dealing with the patcher’s oo
> properties), and if the pointer’s good enough for you, it’s good
> enough for me…

Sounds groovy. The only thing you need to pay attention to is when
the object is freed.

FWIW, in Max 5 everything supports storing arbitrary in the obex
hashtab, but conceptually it’s no different than storing your own
structure in a global hash for associated objects. The nice thing in
Max 5 is that it will be easier to manage when the object frees
itself. The obex entries will be freed as well as a notification sent
out to any objects who have attached to it.

Have fun!

-Joshua


February 27, 2008 | 9:56 pm

Quote: jkc wrote on Wed, 27 February 2008 19:23
—————————————————-
> FWIW, in Max 5 everything supports storing arbitrary in the
> obex hashtab

Excellent news!

That suggests another conceptually similar approach for Max 4, which is to stash a pointer to my struct in the patcher’s p_lineunused field. OK, it’s hacky, but if the field is indeed unused as DDZ notes, then I should be safe unless some other external is trying to use it (and I hope they’d check to see if anything is there beforehand).

With regard to freeing the struct, at present when one of my objects is freed it checks the parentpatcher’s p_freed field, and if the patcher is also being freed the object will free the related patcherinfo struct (recursively upwards for all parentpatchers as needed). At quit I run a final cleanup on the global hashtab via quittask.

I guess if I use p_lineunused for the struct, I’ll need to keep track of how many instances of my objects are remaining in the patcher, and when the last one is freed check the patcher p_freed and do my upward-free then. Otherwise I’ll wind up leaking the struct memory at quit for any patchers that don’t contain one of my objects.

Hmmm … I do have some older code that worked this way, but given the global hashtab approach works fine, p_lineunused might just be more trouble than it’s worth…


February 27, 2008 | 10:04 pm

Or just add the structs to a global hashtab or linklist, AND store a pointer in p_lineunused. So finding the struct for an existing patcher will be a simple pointer-check, and freeing orphaned structs at quit will involve walking the hashtab or linklist. I already have a magic number check in the struct so previously-freed structs won’t be freed again. Hmmm…


February 27, 2008 | 10:27 pm

Quote: johnpitcairn wrote on Wed, 27 February 2008 22:56
> That suggests another conceptually similar approach for Max 4, which is to stash a pointer to my struct in the patcher’s p_lineunused field. OK, it’s hacky, but if the field is indeed unused as DDZ notes, then I should be safe unless some other external is trying to use it (and I hope they’d check to see if anything is there beforehand).

I have no evidence to indicate the p_lineunused is in fact used, but I wouldn’t risk storing stuff in a structure that you don’t have any control over, unless you don’t really mind when your pointer gets overwritten.

jb


February 27, 2008 | 10:30 pm

Well, a quick test loading 65536 oo-patchers reveals that the pointer-check using p_lineunused has no meaningful speed advantage compared to a hashtab lookup … so the less hacky hashtab solution wins.


Viewing 8 posts - 1 through 8 (of 8 total)