I want my external to behave in a [grab]-like fashion
- that is, I want it to send a value to an arbitrary object connected to one of its outlets, have that object perform its calculation upon the value and be able to retrieve the result from its outlet – that is, to prevent the outlet from sending out the result, intercepting it from within my calling method instead…
Maybe the answer is obvious, or maybe it’s not but it lies somewhere in the sdk, but I can’t find it… can anyone point me into the right direction?
Thank you very much!
There isn’t anything the SDK to demonstrate how the grab object works. Maybe you could share a little more about your project? Some context might be helpful in offering different ways of thinking about the solution(s).
Oh, I see…
In fact, I am working upon a bundle of objects operating upon lists, and I was fancying about implementing a sort of a lisp-like "mapcar" thing – where the lambda function would be an object box connected to an outlet.
Of course it’s a trivial thing to do in max, I was just thinking it would have been cool…
But any suggestion is welcome, anyway!
Sounds cool! The techniques of the grab object open up many cans of worms, and its some trouble from which I’m to save you :-). I was thinking of two things.
If you wanted to do this, you could have an additional inlet and outlet and then feed your values to the new outlet and receive the calculations at the new inlet. This is one additional patch cord in the patcher, but it preserves the normal flow of messages through patchers and would even allow users to chain several objects together instead of being restricted to a single object.
Another alternative, if you were creating your own objects for this purpose, is that you could send a message from the main object to the worker object and that message would have an argument that is the pointer value of the main object. Then, upon completion of its task, the worker object could communicate back to the main object by using a call to object_method() and the pointer it was passed.
Hope that all makes sense!
Yes, it definitely makes sense.
In fact, your first solution was my backup plan from the beginning, and I could smell that it was much more reasonable than a grab-like hack! I just have the feeling that thread-safety will require some special care…
The second solution is very cool, but I don’t want this mechanism to be limited to especially-made objects, so it’s not what I’m looking for.
Thank you for your help!
… and of course you made me utterly curious about the innards of grab!
No way to have a peek inside? ;)
i am not a C programmer, but if i wouwld have to guess, i would say it is not that
easy to implement the grabby thing.
it will probably require different methods for different target objects and is maybe
even runtime version dependent.
also, it may be, that the starship captains dont really want us to create externals
beside grab to brake the blackbox paradigm of maxmsp patching.
@roman: i have the feeling that grab somehow tweaks the worker’s object "outlet" field, in the t_object structure. i’d guess it doesn’t require different methods for different objects – maybe it does for different outlet types – but i’m just taking a guess…
@pizza: your solution sounds interesting, but i don’t really get it – can you show me a somewhat more detailed scenario?
thank you guys!
Looks cool! I don’t actually think it will be my kind of solution, but I like the thing anyway – thank you!
About safety, I have two remarks:
- it works fine as long as everything is in the same thread. If there is some deferring/scheduling between [walkie] and [talkie], the result might not be consistent; but as far as I can see this should not cause more problems than this.
- I wonder if there is a thread-safety problem if a [talkie] is freed just before its "get" method is called (but after the "if" has been passed). Maybe a locking system should be implemented, to mutually exclude the "get" method call in [walkie] and the free method in [talkie]. But I’m not too sure about either the problem (shouldn’t it arise in one thousand other normal max situations? is there a locking mechanism in max to prevent such things?), or the solution (would a mutex in the free method actually prevent an undesired freeing?). – if you or some other max guru have an idea about this it would be of great interest to me; thread-safety is becoming a personal obsession…