Tutorial07 autocount2 - MaxClock

This class will put the auto in autocount1 - whereas before an input bang was required to increase the count by one and output the result, in the class below we use the MaxClock class to create a clock that regularly calls the bang method with a period set by the user.

import com.cycling74.max.*;

public class autocount2 extends MaxObject implements Executable {

	private MaxClock clock;
	private int count=0;
	private float interval=400.f;
	
	public autocount2() {
		declareAttribute("count");
		declareAttribute("interval");
		clock = new MaxClock(this);
	}

	public void inlet(int i) {
		if (i==1)  
			clock.delay(0);
		else 
			clock.unset();
	}

	public void execute() {
		bang();
		clock.delay(interval);
	}

	protected void notifyDeleted() {
		clock.unset();
	}

	public void bang() {
		count++;
		outlet(0, count);
	}
}

The first thing to notice is that the autocount2 class not only extends MaxObject, it also implements the Executable interface. In Java an Interface is a device that unrelated objects use to interact with each other. You use an interface to define behaviour that can be implemented by any class. For a class to implement Executable the only requirement is that it define an execute() method.

In this case we use the fact that our class in an Executable in the constructor when we create a new MaxClock. The constructor for the MaxClock class requires an executable as an argument. Then, when it is time for the clock to execute, the MaxClock will call the execute method in the Executable object that it was passed at construction time. In this case we pass the keyword this, which is shorthand for "this object". In other words, a new autocount2 object passes itself as the Excutable to the MaxClock constructor, and when it's time for the MaxClock to do something it will call the autocount2 object's execute method.

A MaxClock can be told to execute at some time in the future by calling its delay(double) method, where the double represents the number of milliseconds the clock should wait before executing. In the case of the class above, the code calls clock.delay(0) if the mxj object receives a 1, as might happen if a toggle were connected to the inlet. The execute method will then be called almost immediately - it calls bang, which increases the count variable and outputs the result, and then calls clock.delay(interval), which will cause the execute method to be called again in 400 milliseconds. Note that 400 is the default value for the interval variable, but that we have declared it as an attribute so the user may set a new value with an interval message.

We introduce also in this class the notifyDeleted method. As you might have suspected, it is called when the mxj object that contains the Java class is deleted in the Max patch. The typical use of this method is to tie up all of the "loose ends" that the object may have created during its lifetime. In this case the only loose end to take care of is the MaxClock, which, if running, will continue to call the object's execute method over and over, perhaps with disastrous consequences when the outlet that the bang method requires no longer exists. The clock.unset call causes the MaxClock to stop any future execute calls it may have planned.

Example: