aboutsummaryrefslogtreecommitdiff
path: root/src/java/com/cycling74/max/MaxQelem.java
blob: 100f671927070ecf6c188197586eeedd27355cf4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package com.cycling74.max;

/**
 * Background job utility class. This is used to execute code in the 
 * background that might take time to execute. Calling <code>set</code>
 * will trigger/execute the "job". If <code>set</code> is called while 
 * the "job" is running, the "job" won't be called again.
 * <p>On PDJ, a Qelem is simply a Java thread that wait to be triggered.
 * </p> 
 */
public class MaxQelem {
    Thread job;
	Executable exec;
	boolean incall;
	static int nbQelem = 0;
	boolean stopThread = true;
	
    /**
     * Constructs a Qelem that is bound the overriden class with method
     * name qfn.
     */
	public MaxQelem() {
		exec = new Callback(this, "qfn");
		do_init();
	}

    /**
     * Constructs a Qelem that is bound to an executable.
     * @param exec the executable to run
     */
	public MaxQelem(Executable exec) {
		this.exec = exec;
		do_init();
	}
	
    /**
     * Constructs a Qelem that is bound to a class with method name.
     * @param src the object that contains the method
     * @param method the method to execute
     */
	public MaxQelem(Object src, String method) {
		exec = new Callback(src, method);
		do_init();
	}
	
	private void do_init() {
	    job = new Thread(new Dispatcher(), "MaxQelem#" + (++nbQelem));
	    job.setPriority(Thread.MIN_PRIORITY);
	}
	
	/**
	 * Puts thread in front execution. <b>Does nothing on PDJ</b>
	 */
	public void front() {
	}

	/**
	 * The callback method, otherwise it calls the 'executable' method 
	 * provided in constructor.
	 */
	public void qfn() {	
	}
	
	/** 
	 * Ask qfn to execute. If it is already set, the qfn won't be called
	 * twice.
	 */
	public synchronized void set() {
	    if ( !incall ) {
	        job.notify();
	    }
	}
	
	/**
	 * Cancels execution of qelem. Use with caution since it will throw
	 * an InterruptedException on PDJ.
	 */
	public synchronized void unset() {
	    job.interrupt();
	}
	
	
    /**
     * Releases current Qelem and cancel the running thread.
     */
	public void release() {
		unset();
		stopThread = true;
	}

    /**
     * Returns the executable object.
     * @return the executble object that is bound to this Qelem
     */
	public Executable getExecutable() {
		return exec;
	}
	
	class Dispatcher implements Runnable {
	    public void run() {
	        while( !stopThread ) {
	            try {
	                incall = false;
	                job.wait();
	                incall = true;
	                exec.execute();
	            } catch (InterruptedException e) {
                   // TODO Auto-generated catch block
	                e.printStackTrace();
                }
		    }
	    }
	}
}