From: Tomas Wenström <tomas.wenstrom@gmail.com>
Date: Sun, 1 Dec 2019 22:00:09 +0000 (+0100)
Subject: Push and pop modes
X-Git-Url: http://git.dolda2000.com/gitweb/?a=commitdiff_plain;h=c9edf58db4c00b7b95bb7f521063e5ecd79db262;p=kaka%2Fcakelight.git

Push and pop modes
---

diff --git a/src/kaka/cakelight/CakeLight.java b/src/kaka/cakelight/CakeLight.java
index 822e2ab..cd59362 100644
--- a/src/kaka/cakelight/CakeLight.java
+++ b/src/kaka/cakelight/CakeLight.java
@@ -28,7 +28,7 @@ public class CakeLight {
     }
 
     public void cleanup() {
-        while (popMode());
+        while (popMode() != null);
     }
 
     public void pushMode(Mode mode) {
@@ -41,16 +41,16 @@ public class CakeLight {
         // TODO: create a composite fading mode of top of stack and new mode
     }
 
-    public boolean popMode() {
+    public Mode popMode() {
         if (!modes.isEmpty()) {
             Mode mode = modes.pop();
             stopMode(mode);
             if (!modes.isEmpty()) {
                 resumeMode(modes.peek());
             }
-            return true;
+            return mode;
         }
-        return false;
+        return null;
         // TODO: create a composite fading mode of popped mode and top of stack, unless doing cleanup
     }
 
diff --git a/src/kaka/cakelight/Commands.java b/src/kaka/cakelight/Commands.java
index a5b612c..825ebe3 100644
--- a/src/kaka/cakelight/Commands.java
+++ b/src/kaka/cakelight/Commands.java
@@ -1,10 +1,6 @@
 package kaka.cakelight;
 
-import kaka.cakelight.mode.AmbientMode;
-import kaka.cakelight.mode.SingleColorMode;
-import kaka.cakelight.mode.SunriseMode;
-import kaka.cakelight.mode.TwoColorNoiseMode;
-import kaka.cakelight.mode.VideoMode;
+import kaka.cakelight.mode.*;
 
 import java.util.function.BiFunction;
 
@@ -17,10 +13,29 @@ class Commands {
 	    }
 
 	    @Override
-	    public void activate(Console console, String[] args) {
+	    public Object activate(Console console, String[] args) {
 		if (!activate.apply(console, args)) {
 		    console.out("did NOT run command");
 		}
+		return null;
+	    }
+	};
+    }
+
+    private static Console.Command modeCommand(String[] names, BiFunction<Console, String[], Mode> activate) {
+        return new Console.Command() {
+	    @Override
+	    public String[] getNames() {
+		return names;
+	    }
+
+	    @Override
+	    public Object activate(Console console, String[] args) {
+		Mode mode = activate.apply(console, args);
+		if (mode == null) {
+		    console.out("did NOT run command");
+		}
+		return mode;
 	    }
 	};
     }
@@ -42,15 +57,30 @@ class Commands {
 	});
     }
 
-    static Console.Command video() {
-        return command(new String[] {"v", "video"}, (console, args) -> {
-	    console.getCakelight().setMode(new VideoMode());
-	    return true;
+    static Console.Command push() {
+        return command(new String[] {"push"}, (console, args) -> {
+            Object obj = console.handleInput(String.join(" ", args));
+	    if (obj instanceof Mode) { // obj could be anything, which should be fixed
+		console.out("pushing mode " + obj.getClass().getSimpleName());
+		console.getCakelight().pushMode((Mode) obj);
+	    }
+            return true;
 	});
     }
 
+    static Console.Command pop() {
+        return command(new String[] {"pop"}, (console, args) -> {
+            console.out("popping mode " + console.getCakelight().popMode().getClass().getSimpleName());
+            return true;
+	});
+    }
+
+    static Console.Command video() {
+        return modeCommand(new String[] {"v", "video"}, (console, args) -> new VideoMode());
+    }
+
     static Console.Command color() {
-        return command(new String[] {"c", "col", "color"}, (console, args) -> {
+        return modeCommand(new String[] {"c", "col", "color"}, (console, args) -> {
             Color c = null;
             if (args.length == 1) {
 		c = console.parseColor(args[0]);
@@ -62,12 +92,10 @@ class Commands {
 		);
 	    }
             if (c != null) {
-		console.getCakelight().setMode(new SingleColorMode(c));
 		console.out("setting color to " + c);
-		return true;
-            } else {
-		return false;
+		return new SingleColorMode(c);
 	    }
+	    return null;
 	});
     }
 
@@ -117,42 +145,36 @@ class Commands {
     }
 
     static Console.Command ambientMode() {
-        return command(new String[] {"m", "mode"}, (console, args) -> {
+        return modeCommand(new String[] {"m", "mode"}, (console, args) -> {
 	    if (args.length == 1) {
-		console.getCakelight().setMode(new AmbientMode(new String[] {args[0]}));
 		console.out("setting ambient mode to " + args[0]);
-		return true;
-	    } else {
-	        return false;
+		return new AmbientMode(new String[]{args[0]});
 	    }
+	    return null;
 	});
     }
 
     static Console.Command twoColorNoiseMode() {
-        return command(new String[] {"n", "noise"}, (console, args) -> {
+        return modeCommand(new String[] {"n", "noise"}, (console, args) -> {
 	    if (args.length == 2) {
-		console.getCakelight().setMode(new TwoColorNoiseMode(
+		console.out("setting two-color noise mode");
+		return new TwoColorNoiseMode(
 			console.parseColor(args[0]),
 			console.parseColor(args[1])
-		));
-		console.out("setting two-color noise mode");
-		return true;
-	    } else {
-	        return false;
+		);
 	    }
+	    return null;
 	});
     }
 
     static Console.Command sunriseMode() {
-        return command(new String[] {"sunrise"}, (console, args) -> {
+        return modeCommand(new String[] {"sunrise"}, (console, args) -> {
 	    if (args.length == 1) {
 		int durationSeconds = Integer.parseInt(args[0]);
-		console.getCakelight().setMode(new SunriseMode(durationSeconds));
 		console.out("setting sunrise mode with duration " + durationSeconds);
-		return true;
-	    } else {
-	        return false;
+		return new SunriseMode(durationSeconds);
 	    }
+	    return null;
 	});
     }
 }
diff --git a/src/kaka/cakelight/Console.java b/src/kaka/cakelight/Console.java
index 3f9bce9..5dfe091 100644
--- a/src/kaka/cakelight/Console.java
+++ b/src/kaka/cakelight/Console.java
@@ -1,5 +1,7 @@
 package kaka.cakelight;
 
+import kaka.cakelight.mode.Mode;
+
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
@@ -26,6 +28,8 @@ public class Console extends Thread {
 	this.config = config;
 	register(Commands.help());
 	register(Commands.quit());
+	register(Commands.push());
+	register(Commands.pop());
 	register(Commands.video());
 	register(Commands.color());
 	register(Commands.brightness());
@@ -71,14 +75,21 @@ public class Console extends Thread {
 	    while (running) {
 		System.out.print("> ");
 		String input = reader.readLine();
-		handleInput(input);
+		internalHandleInput(input);
 	    }
 	} catch (IOException e) {
 	    System.out.println("Error reading from command line");
 	}
     }
 
-    void handleInput(String input) {
+    private void internalHandleInput(String input) {
+	Object obj = handleInput(input);
+	if (obj instanceof Mode) {
+	    cakelight.setMode((Mode) obj);
+	}
+    }
+
+    Object handleInput(String input) {
 	String[] splitInput = input.split("\\s+", 2);
 	String name = splitInput[0];
 	String[] args = splitInput.length == 2
@@ -87,10 +98,11 @@ public class Console extends Thread {
 
 	Command cmd = commands.get(name);
 	if (cmd != null) {
-	    cmd.activate(this, args);
+	    return cmd.activate(this, args);
 	} else {
 	    out("no command named '" + name + "'");
 	}
+	return null;
     }
 
     void out(String text) {
@@ -126,6 +138,6 @@ public class Console extends Thread {
 
     public interface Command {
         String[] getNames();
-        void activate(Console console, String[] args);
+        Object activate(Console console, String[] args);
     }
 }