Use stack of modes instead of just one
[kaka/cakelight.git] / src / kaka / cakelight / CakeLight.java
index 8156833..0c1aa1a 100644 (file)
@@ -8,9 +8,12 @@ import org.jnativehook.keyboard.NativeKeyEvent;
 import org.jnativehook.mouse.NativeMouseEvent;
 import org.jnativehook.mouse.NativeMouseMotionAdapter;
 
+import java.util.Objects;
+import java.util.Stack;
+
 public class CakeLight {
     private Configuration config;
-    private Mode mode;
+    private Stack<Mode> modes = new Stack<>();
     private LedController ledController;
 
     public CakeLight(Configuration config, LedController ledController) {
@@ -21,16 +24,44 @@ public class CakeLight {
 
     public void setMode(Mode mode) {
         cleanup();
-        this.mode = mode;
-        mode.setFrameListener(ledController::onFrame);
-        mode.enter(config);
+        pushMode(mode);
     }
 
     public void cleanup() {
-        if (this.mode != null) {
-           this.mode.setFrameListener(ledFrame -> {}); // To avoid any frame being sent to the controller while the thread is exiting
-            this.mode.exit();
+        while (popMode());
+    }
+
+    public void pushMode(Mode mode) {
+        Objects.requireNonNull(mode);
+        if (!modes.isEmpty()) {
+            stopMode(modes.peek());
+        }
+        modes.push(mode);
+        startMode(mode);
+        // TODO: create a composite fading mode of top of stack and new mode
+    }
+
+    public boolean popMode() {
+        if (!modes.isEmpty()) {
+            Mode mode = modes.pop();
+            stopMode(mode);
+            if (!modes.isEmpty()) {
+                startMode(modes.peek());
+            }
+            return true;
         }
+        return false;
+        // TODO: create a composite fading mode of popped mode and top of stack, unless doing cleanup
+    }
+
+    private void startMode(Mode mode) {
+        mode.setFrameListener(ledController::onFrame);
+        mode.enter(config);
+    }
+
+    private void stopMode(Mode mode) {
+        mode.setFrameListener(ledFrame -> {}); // To avoid any frame being sent to the controller while the thread is exiting
+        mode.exit();
     }
 
     public void startLoop() {