use java.util.ServiceLoader to load applications and devices more or

less dynamically.
This commit is contained in:
2013-05-22 21:15:21 +02:00
parent 9d3eabb91c
commit ff4938a323
10 changed files with 434 additions and 412 deletions

View File

@@ -8,6 +8,7 @@
<classpathentry kind="lib" path="lib/jxinput.jar"/>
<classpathentry kind="lib" path="lib/log4j-1.2.16.jar"/>
<classpathentry kind="lib" path="wiiusej.jar"/>
<classpathentry kind="lib" path="lib/commons-collections-3.2.1.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="bin"/>
</classpath>

Binary file not shown.

View File

@@ -0,0 +1,8 @@
mimis.application.cmd.windows.gomplayer.GomPlayerApplication
mimis.application.cmd.windows.photoviewer.PhotoViewerApplication
mimis.application.cmd.windows.winamp.WinampApplication
mimis.application.cmd.windows.wmp.WMPApplication
mimis.application.itunes.iTunesApplication
mimis.application.lirc.ipod.iPodApplication
mimis.application.mpc.MPCApplication
mimis.application.vlc.VLCApplication

View File

@@ -0,0 +1,7 @@
mimis.device.javainput.extreme3d.Extreme3DDevice
mimis.device.javainput.rumblepad.RumblepadDevice
mimis.device.jintellitype.JIntellitypeDevice
mimis.device.lirc.LircDevice
mimis.device.network.NetworkDevice
mimis.device.panel.PanelDevice
mimis.device.wiimote.WiimoteDevice

View File

@@ -1,100 +1,104 @@
package mimis;
import javax.swing.UIManager;
import mimis.application.cmd.windows.gomplayer.GomPlayerApplication;
import mimis.application.cmd.windows.photoviewer.PhotoViewerApplication;
import mimis.application.cmd.windows.winamp.WinampApplication;
import mimis.application.cmd.windows.wmp.WMPApplication;
import mimis.application.itunes.iTunesApplication;
import mimis.application.lirc.ipod.iPodApplication;
import mimis.application.mpc.MPCApplication;
import mimis.application.vlc.VLCApplication;
import mimis.device.javainput.extreme3d.Extreme3DDevice;
import mimis.device.javainput.rumblepad.RumblepadDevice;
import mimis.device.jintellitype.JIntellitypeDevice;
import mimis.device.lirc.LircDevice;
import mimis.device.network.NetworkDevice;
import mimis.device.panel.PanelDevice;
import mimis.device.wiimote.WiimoteDevice;
import mimis.exception.worker.ActivateException;
import mimis.exception.worker.DeactivateException;
import mimis.input.Task;
import mimis.manager.ButtonManager;
import mimis.manager.CurrentButtonManager;
import mimis.value.Action;
public class Main extends Mimis {
protected CurrentButtonManager applicationManager;
protected ButtonManager deviceManager;
protected Gui gui;
static {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {}
}
public Main() {
super(
new WinampApplication(), new GomPlayerApplication(), new WMPApplication(), new MPCApplication(), // WindowsApplication
new VLCApplication(), // CMDApplication
new iPodApplication(), // LircApplication
new PhotoViewerApplication(), // RobotApplication
new iTunesApplication()); // Component
/* Create gui from application and device managers */
applicationManager = new CurrentButtonManager(router, componentCycle, "Applications", currentArray);
deviceManager = new ButtonManager("Devices", initialize(false,
new Extreme3DDevice(), new RumblepadDevice(), // JavaInputDevice
new JIntellitypeDevice(), new PanelDevice(), new LircDevice(), new WiimoteDevice(), new NetworkDevice())); // Component
gui = new Gui(this, applicationManager, deviceManager);
manager.add(initialize(false, gui));
}
public void activate() throws ActivateException {
super.activate();
listen(Task.class);
/* Start managers */
applicationManager.start();
deviceManager.start();
/* Force display of currenct component when gui started */
gui.start();
while (!gui.active());
end(Action.CURRENT);
}
protected void deactivate() throws DeactivateException {
super.deactivate();
log.debug("Stop managers");
applicationManager.stop();
deviceManager.stop();
}
public void exit() {
super.exit();
log.debug("Exit managers");
applicationManager.exit();
deviceManager.exit();
}
public void end(Action action) {
super.end(action);
switch (action) {
case CURRENT:
case NEXT:
case PREVIOUS:
applicationManager.currentChanged();
break;
}
}
public static void main(String[] args) {
new Main().start(false);
}
}
package mimis;
import java.util.ArrayList;
import java.util.ServiceLoader;
import javax.swing.UIManager;
import mimis.application.Application;
import mimis.device.Device;
import mimis.exception.worker.ActivateException;
import mimis.exception.worker.DeactivateException;
import mimis.input.Task;
import mimis.manager.ButtonManager;
import mimis.manager.CurrentButtonManager;
import mimis.value.Action;
import mimis.worker.Component;
public class Main extends Mimis {
protected CurrentButtonManager applicationManager;
protected ButtonManager deviceManager;
protected Gui gui;
static {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {}
}
public static Component[] getApplications() {
ArrayList<Component> componentList = new ArrayList<Component>();
for (Application application : ServiceLoader.load(mimis.application.Application.class)) {
if (application instanceof Component) {
componentList.add((Component) application);
}
}
return componentList.toArray(new Component[]{});
}
public static Component[] getDevices() {
ArrayList<Component> componentList = new ArrayList<Component>();
for (Device device : ServiceLoader.load(mimis.device.Device.class)) {
if (device instanceof Component) {
componentList.add((Component) device);
}
}
return componentList.toArray(new Component[]{});
}
public Main() {
super(getApplications());
/* Create gui from application and device managers */
applicationManager = new CurrentButtonManager(router, componentCycle, "Applications", currentArray);
deviceManager = new ButtonManager("Devices", initialize(false, getDevices()));
gui = new Gui(this, applicationManager, deviceManager);
manager.add(initialize(false, gui));
}
public void activate() throws ActivateException {
super.activate();
listen(Task.class);
/* Start managers */
applicationManager.start();
deviceManager.start();
/* Force display of current component when gui started */
gui.start();
while (!gui.active());
end(Action.CURRENT);
}
protected void deactivate() throws DeactivateException {
super.deactivate();
log.debug("Stop managers");
applicationManager.stop();
deviceManager.stop();
}
public void exit() {
super.exit();
log.debug("Exit managers");
applicationManager.exit();
deviceManager.exit();
}
public void end(Action action) {
super.end(action);
switch (action) {
case CURRENT:
case NEXT:
case PREVIOUS:
applicationManager.currentChanged();
break;
}
}
public static void main(String[] args) {
new Main().start(false);
}
}

View File

@@ -1,6 +1,6 @@
package mimis.application;
public interface Application {
}
package mimis.application;
public interface Application {
}

View File

@@ -1,79 +1,80 @@
package mimis.application.cmd;
import java.io.IOException;
import java.util.Map;
import mimis.exception.worker.ActivateException;
import mimis.exception.worker.DeactivateException;
import mimis.util.Native;
import mimis.value.Registry;
import mimis.worker.Component;
public abstract class CMDApplication extends Component {
protected final static Registry REGISTRY = Registry.LOCAL_MACHINE;
protected final static String KEY = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths";
protected String program;
protected String title;
protected Process process;
protected boolean detect, running;
public CMDApplication(String program, String title) {
super(title);
this.program = program;
this.title = title;
detect = true;
}
protected void activate() throws ActivateException {
detect = true;
if (!running) {
String path = getPath();
if (path == null) {
throw new ActivateException();
}
try {
String command = path.startsWith("\"") ? path : String.format("\"%s\"", path);
command = replaceVariables(command);
process = Runtime.getRuntime().exec(command);
} catch (IOException e) {
log.error(e);
throw new ActivateException();
}
}
super.activate();
}
public boolean active() {
if (detect) {
running = Native.isRunning(program);
if (!active && running) {
active = true;
start();
}
}
return active;
}
protected synchronized void deactivate() throws DeactivateException {
detect = false;
super.deactivate();
if (process != null) {
process.destroy();
}
}
public String getPath() {
String key = String.format("%s\\%s", KEY, program);
System.out.println(Native.getValue(REGISTRY, key));
return Native.getValue(REGISTRY, key);
}
public static String replaceVariables(String string) {
Map<String, String> env = System.getenv();
for (String key : env.keySet()) {
string = string.replace(String.format("%%%s%%", key), env.get(key));
}
return string;
}
}
package mimis.application.cmd;
import java.io.IOException;
import java.util.Map;
import mimis.application.Application;
import mimis.exception.worker.ActivateException;
import mimis.exception.worker.DeactivateException;
import mimis.util.Native;
import mimis.value.Registry;
import mimis.worker.Component;
public abstract class CMDApplication extends Component implements Application {
protected final static Registry REGISTRY = Registry.LOCAL_MACHINE;
protected final static String KEY = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths";
protected String program;
protected String title;
protected Process process;
protected boolean detect, running;
public CMDApplication(String program, String title) {
super(title);
this.program = program;
this.title = title;
detect = true;
}
protected void activate() throws ActivateException {
detect = true;
if (!running) {
String path = getPath();
if (path == null) {
throw new ActivateException();
}
try {
String command = path.startsWith("\"") ? path : String.format("\"%s\"", path);
command = replaceVariables(command);
process = Runtime.getRuntime().exec(command);
} catch (IOException e) {
log.error(e);
throw new ActivateException();
}
}
super.activate();
}
public boolean active() {
if (detect) {
running = Native.isRunning(program);
if (!active && running) {
active = true;
start();
}
}
return active;
}
protected synchronized void deactivate() throws DeactivateException {
detect = false;
super.deactivate();
if (process != null) {
process.destroy();
}
}
public String getPath() {
String key = String.format("%s\\%s", KEY, program);
System.out.println(Native.getValue(REGISTRY, key));
return Native.getValue(REGISTRY, key);
}
public static String replaceVariables(String string) {
Map<String, String> env = System.getenv();
for (String key : env.keySet()) {
string = string.replace(String.format("%%%s%%", key), env.get(key));
}
return string;
}
}

View File

@@ -1,181 +1,181 @@
package mimis.application.cmd.windows.winamp;
import mimis.application.cmd.windows.WindowsApplication;
import mimis.exception.worker.DeactivateException;
import mimis.value.Action;
import mimis.value.Command;
import mimis.worker.Worker;
public class WinampApplication extends WindowsApplication {
protected final static String PROGRAM = "winamp.exe";
protected final static String TITLE = "Winamp";
protected final static String WINDOW = "Winamp v1.x";
protected final static int STATUS_PLAYING = 1;
protected final static int STATUS_PAUSED = 3;
protected final static int STATUS_STOPPED = 0;
protected final static int IPC_ISPLAYING = 104;
protected final static int IPC_GETOUTPUTTIME = 105;
protected final static int IPC_SETVOLUME = 122;
protected final static int WINAMP_FILE_QUIT = 40001;
protected final static int WINAMP_FILE_REPEAT = 40022;
protected final static int WINAMP_FILE_SHUFFLE = 40023;
protected final static int WINAMP_BUTTON1 = 40044;
protected final static int WINAMP_BUTTON2 = 40045;
protected final static int WINAMP_BUTTON3 = 40046;
protected final static int WINAMP_BUTTON5 = 40048;
protected final static int WINAMP_VOLUMEUP = 40058;
protected final static int WINAMP_VOLUMEDOWN = 40059;
protected final static int WINAMP_FFWD5S = 40060;
protected final static int WINAMP_REW5S = 40061;
protected final static int WINAMP_BUTTON4_SHIFT = 40147;
protected final static int WINAMP_VISPLUGIN = 40192;
protected static final int VOLUME_SLEEP = 50;
protected static final int SEEK_SLEEP = 100;
protected VolumeWorker volumeWorker;
protected SeekWorker seekWorker;
protected double volume;
protected boolean muted;
public WinampApplication() {
super(PROGRAM, TITLE, WINDOW);
volume = getVolume();
muted = volume == 0;
volumeWorker = new VolumeWorker();
seekWorker = new SeekWorker();
}
public void deactivate() throws DeactivateException {
super.deactivate();
volumeWorker.stop();
seekWorker.stop();
}
public void exit() {
super.exit();
volumeWorker.exit();
seekWorker.exit();
}
public void begin(Action action) {
log.trace("WinampApplication begin: " + action);
switch (action) {
case VOLUME_UP:
volumeWorker.start(1);
break;
case VOLUME_DOWN:
volumeWorker.start(-1);
break;
case FORWARD:
seekWorker.start(1);
break;
case REWIND:
seekWorker.start(-1);
break;
}
}
public void end(Action action) {
log.trace("WinampApplication end: " + action);
switch (action) {
case PLAY:
log.debug("play");
switch (user(0, IPC_ISPLAYING)) {
case STATUS_STOPPED:
command(WINAMP_BUTTON2);
break;
default:
command(WINAMP_BUTTON3);
break;
}
break;
case NEXT:
command(WINAMP_BUTTON5);
break;
case PREVIOUS:
command(WINAMP_BUTTON1);
break;
case FORWARD:
case REWIND:
seekWorker.stop();
break;
case MUTE:
if (muted) {
setVolume(volume);
} else {
volume = getVolume();
setVolume(0);
}
muted = !muted;
break;
case VOLUME_UP:
case VOLUME_DOWN:
volumeWorker.stop();
break;
case SHUFFLE:
command(WINAMP_FILE_SHUFFLE);
break;
case REPEAT:
command(WINAMP_FILE_REPEAT);
break;
case FADEOUT:
command(WINAMP_BUTTON4_SHIFT);
break;
case QUIT:
command(WINAMP_FILE_QUIT);
break;
case VISUALISER:
system(Command.System.MAXIMIZE);
command(WINAMP_VISPLUGIN);
break;
}
}
public double getVolume() {
return user(-666, IPC_SETVOLUME) / 255f;
}
public void setVolume(double volume) {
user((int) Math.ceil(volume * 255), IPC_SETVOLUME);
}
public int getDuration() {
return user(1, IPC_GETOUTPUTTIME);
}
public int getElapsed() {
return user(0, IPC_GETOUTPUTTIME) / 1000;
}
protected class VolumeWorker extends Worker {
protected int volumeChangeSign;
public void start(int volumeChangeSign) {
super.start();
this.volumeChangeSign = volumeChangeSign;
}
public void work() {
command(volumeChangeSign > 0 ? WINAMP_VOLUMEUP : WINAMP_VOLUMEDOWN);
sleep(VOLUME_SLEEP);
}
};
protected class SeekWorker extends Worker {
protected int seekDirection;
public void start(int seekDirection) {
super.start();
this.seekDirection = seekDirection;
}
public void work() {
command(seekDirection > 0 ? WINAMP_FFWD5S : WINAMP_REW5S);
sleep(SEEK_SLEEP);
}
};
}
package mimis.application.cmd.windows.winamp;
import mimis.application.cmd.windows.WindowsApplication;
import mimis.exception.worker.DeactivateException;
import mimis.value.Action;
import mimis.value.Command;
import mimis.worker.Worker;
public class WinampApplication extends WindowsApplication {
protected final static String PROGRAM = "winamp.exe";
protected final static String TITLE = "Winamp";
protected final static String WINDOW = "Winamp v1.x";
protected final static int STATUS_PLAYING = 1;
protected final static int STATUS_PAUSED = 3;
protected final static int STATUS_STOPPED = 0;
protected final static int IPC_ISPLAYING = 104;
protected final static int IPC_GETOUTPUTTIME = 105;
protected final static int IPC_SETVOLUME = 122;
protected final static int WINAMP_FILE_QUIT = 40001;
protected final static int WINAMP_FILE_REPEAT = 40022;
protected final static int WINAMP_FILE_SHUFFLE = 40023;
protected final static int WINAMP_BUTTON1 = 40044;
protected final static int WINAMP_BUTTON2 = 40045;
protected final static int WINAMP_BUTTON3 = 40046;
protected final static int WINAMP_BUTTON5 = 40048;
protected final static int WINAMP_VOLUMEUP = 40058;
protected final static int WINAMP_VOLUMEDOWN = 40059;
protected final static int WINAMP_FFWD5S = 40060;
protected final static int WINAMP_REW5S = 40061;
protected final static int WINAMP_BUTTON4_SHIFT = 40147;
protected final static int WINAMP_VISPLUGIN = 40192;
protected static final int VOLUME_SLEEP = 50;
protected static final int SEEK_SLEEP = 100;
protected VolumeWorker volumeWorker;
protected SeekWorker seekWorker;
protected double volume;
protected boolean muted;
public WinampApplication() {
super(PROGRAM, TITLE, WINDOW);
volume = getVolume();
muted = volume == 0;
volumeWorker = new VolumeWorker();
seekWorker = new SeekWorker();
}
public void deactivate() throws DeactivateException {
super.deactivate();
volumeWorker.stop();
seekWorker.stop();
}
public void exit() {
super.exit();
volumeWorker.exit();
seekWorker.exit();
}
public void begin(Action action) {
log.trace("WinampApplication begin: " + action);
switch (action) {
case VOLUME_UP:
volumeWorker.start(1);
break;
case VOLUME_DOWN:
volumeWorker.start(-1);
break;
case FORWARD:
seekWorker.start(1);
break;
case REWIND:
seekWorker.start(-1);
break;
}
}
public void end(Action action) {
log.trace("WinampApplication end: " + action);
switch (action) {
case PLAY:
log.debug("play");
switch (user(0, IPC_ISPLAYING)) {
case STATUS_STOPPED:
command(WINAMP_BUTTON2);
break;
default:
command(WINAMP_BUTTON3);
break;
}
break;
case NEXT:
command(WINAMP_BUTTON5);
break;
case PREVIOUS:
command(WINAMP_BUTTON1);
break;
case FORWARD:
case REWIND:
seekWorker.stop();
break;
case MUTE:
if (muted) {
setVolume(volume);
} else {
volume = getVolume();
setVolume(0);
}
muted = !muted;
break;
case VOLUME_UP:
case VOLUME_DOWN:
volumeWorker.stop();
break;
case SHUFFLE:
command(WINAMP_FILE_SHUFFLE);
break;
case REPEAT:
command(WINAMP_FILE_REPEAT);
break;
case FADEOUT:
command(WINAMP_BUTTON4_SHIFT);
break;
case QUIT:
command(WINAMP_FILE_QUIT);
break;
case VISUALISER:
system(Command.System.MAXIMIZE);
command(WINAMP_VISPLUGIN);
break;
}
}
public double getVolume() {
return user(-666, IPC_SETVOLUME) / 255f;
}
public void setVolume(double volume) {
user((int) Math.ceil(volume * 255), IPC_SETVOLUME);
}
public int getDuration() {
return user(1, IPC_GETOUTPUTTIME);
}
public int getElapsed() {
return user(0, IPC_GETOUTPUTTIME) / 1000;
}
protected class VolumeWorker extends Worker {
protected int volumeChangeSign;
public void start(int volumeChangeSign) {
super.start();
this.volumeChangeSign = volumeChangeSign;
}
public void work() {
command(volumeChangeSign > 0 ? WINAMP_VOLUMEUP : WINAMP_VOLUMEDOWN);
sleep(VOLUME_SLEEP);
}
};
protected class SeekWorker extends Worker {
protected int seekDirection;
public void start(int seekDirection) {
super.start();
this.seekDirection = seekDirection;
}
public void work() {
command(seekDirection > 0 ? WINAMP_FFWD5S : WINAMP_REW5S);
sleep(SEEK_SLEEP);
}
};
}

View File

@@ -1,41 +1,42 @@
package mimis.application.lirc;
import mimis.device.lirc.LircButton;
import mimis.device.lirc.LircService;
import mimis.device.lirc.remote.WC02IPOButton;
import mimis.exception.worker.ActivateException;
import mimis.exception.worker.DeactivateException;
import mimis.worker.Component;
public class LircApplication extends Component {
protected LircService lircService;
public LircApplication(String title) {
super(title);
lircService = new LircService();
lircService.put(WC02IPOButton.NAME, WC02IPOButton.values());
}
public void activate() throws ActivateException {
lircService.activate();
super.activate();
}
public boolean active() {
return active = lircService.active();
}
protected void deactivate() throws DeactivateException {
super.deactivate();
lircService.stop();
}
public void exit() {
super.exit();
lircService.exit();
}
public void send(LircButton button) {
lircService.send(button);
}
}
package mimis.application.lirc;
import mimis.application.Application;
import mimis.device.lirc.LircButton;
import mimis.device.lirc.LircService;
import mimis.device.lirc.remote.WC02IPOButton;
import mimis.exception.worker.ActivateException;
import mimis.exception.worker.DeactivateException;
import mimis.worker.Component;
public class LircApplication extends Component implements Application {
protected LircService lircService;
public LircApplication(String title) {
super(title);
lircService = new LircService();
lircService.put(WC02IPOButton.NAME, WC02IPOButton.values());
}
public void activate() throws ActivateException {
lircService.activate();
super.activate();
}
public boolean active() {
return active = lircService.active();
}
protected void deactivate() throws DeactivateException {
super.deactivate();
lircService.stop();
}
public void exit() {
super.exit();
lircService.exit();
}
public void send(LircButton button) {
lircService.send(button);
}
}

View File

@@ -1,5 +1,5 @@
package mimis.device;
public interface Device {
}
package mimis.device;
public interface Device {
}