Bug/limitation: outlet() does not work in the constructor

Adam Murray's icon

As demonstrated in the included external and patch, any calls to outlet() inside the constructor seem to be ignored.

Here is my problem. I have a custom attribute getter/setter, similar to the example external, and I really need the value to be sent out ANYTIME the attribute is set, which includes not only via max messages (that works fine), but also when using attributes to construct the object (mxj AttributeTest @myattr 2). The latter case does not work because of the limitation with outlet() in the constructor.

Any suggestions for how I can send out the attribute values in this situation? I thought I might be able to use the loadbang() method, but the APIs say "Note that you do not get the loadbang message when the user creates a new instance of your object in the Patcher window, only when a Max file containing your class is loaded from disk." I also need it to work when a new instance is created.

Adam

Java external:
[code]
import com.cycling74.max.Atom;
import com.cycling74.max.MaxObject;

public class AttributeTest extends MaxObject {

    private int myattr = 0;

    public AttributeTest(Atom[] args) {
        declareIO(1, 1);
        declareAttribute("myattr", "getmyattr", "myattr");
        outlet(0, "finished the constructor"); // doesn't do anything
    }

    public int getmyattr() {
        return myattr;
    }

    public void myattr(int myattr) {
        post("In myattr()");
        this.myattr = myattr;
        outlet(0, myattr); // only works when receiving myattr messages via the inlet
    }
}
[/code]

**********
Max patch:

Max Patch
Copy patch and select New From Clipboard in Max.

Adam Murray's icon

And off topic: why doesn't [code] [/code] work in my post? The forum FAQ seems to indicate it should.

Owen Green's icon

Adam Murray wrote:
> As demonstrated in the included external and patch, any calls to
> outlet() inside the constructor seem to be ignored.

The object doesn't, strictly speaking, exist until the constructor has
completed, so this isn't surprising.

I think you'll need something to run asynchronously, after the
constructor has finished:

new MaxQelem(new Executable() {
public void execute(){
outlet(0, myattr);
}
}).set();

This works here - don't know how reliable it is without building some
sort of delay into it though. So YMMV.

--
O

Emmanuel Jourdan's icon

On 7 sept. 07, at 11:12, Owen Green wrote:

> The object doesn't, strictly speaking, exist until the constructor
> has completed, so this isn't surprising.
>
> I think you'll need something to run asynchronously, after the
> constructor has finished:
>
> new MaxQelem(new Executable() {
> public void execute(){
> outlet(0, myattr);
> }
> }).set();
>
> This works here - don't know how reliable it is without building
> some sort of delay into it though. So YMMV.

You could also use the loadbang() method.

ej

Owen Green's icon

That was my first thought, but check the last paragraph of the OP's
message :)

--
O

Emmanuel Jourdan wrote:
> You could also use the loadbang() method.

Emmanuel Jourdan's icon
Adam Murray's icon

Quote: owen wrote on Fri, 07 September 2007 02:12
----------------------------------------------------
>
> I think you'll need something to run asynchronously, after the
> constructor has finished:
>
> new MaxQelem(new Executable() {
> public void execute(){
> outlet(0, myattr);
> }
> }).set();
>
> This works here - don't know how reliable it is without building some
> sort of delay into it though. So YMMV.
>

Thanks Owen, I'll give this a shot.

You mentioned reliability - I'll keep this in mind if things stop working as my patch gets more complex. If that's potentailly going to be a problem, I'd like to make a feature request to have a new overridable method in MaxObject that's like loadbang(), but will be called after the object is initialized. This would be useful for any who is patching on-the-fly with mxj externals.

I'll post another message if I actually do run into any reliability problems with this MaxQelem approach.

-Adam

Owen Green's icon

Adam Murray wrote:

> You mentioned reliability - I'll keep this in mind if things stop
> working as my patch gets more complex.

It'll be an issue of whatever lag there may be between the constructor
exiting and there actually being an outlet available to use - if it does
stop working, try putting a Thread.sleep() for some short amount of time
at the beginning of execute().

--
Owen