package lejos.nxt; /** * Utility class for dispatching events to button, sensor and serial listeners. * * @author Paul Andrews */ class ListenerThread extends Thread { static ListenerThread singleton = new ListenerThread(); private static final int MAX_LISTENER_CALLERS = 7; private static int [] masks; private static ListenerCaller [] listenerCallers; private static int numLC = 0; int mask; Poll poller = new Poll(); static ListenerThread get() { synchronized (singleton) { if (!singleton.isAlive()) { masks = new int[MAX_LISTENER_CALLERS]; listenerCallers = new ListenerCaller[MAX_LISTENER_CALLERS]; singleton.setDaemon(true); singleton.setPriority(Thread.MAX_PRIORITY); singleton.start(); } } return singleton; } void addToMask(int mask, ListenerCaller lc) { int i; this.mask |= mask; for(i=0;i<numLC;i++) if (listenerCallers[i] == lc) break; if (i == numLC) { masks[numLC] = mask; listenerCallers[numLC++] = lc; } // Interrupt the polling thread, not the current one! interrupt(); } void addButtonToMask(int id, ListenerCaller lc) { addToMask(id << Poll.BUTTON_MASK_SHIFT, lc); } void addSensorToMask(int id, ListenerCaller lc) { addToMask(1 << id, lc); } void addSerialToMask(ListenerCaller lc) { addToMask(1 << Poll.SERIAL_SHIFT, lc); } public void run() { for (;;) { singleton.setPriority(Thread.MAX_PRIORITY); try { int changed = poller.poll(mask, 0); // Run events at normal priority so they can use Thread.yield() singleton.setPriority(Thread.NORM_PRIORITY); for(int i=0;i<numLC;i++) if ((changed & masks[i]) != 0) listenerCallers[i].callListeners(); } catch (InterruptedException ie) { } } } }