Use stack of modes instead of just one
[kaka/cakelight.git] / src / kaka / cakelight / mode / VideoMode.java
... / ...
CommitLineData
1package kaka.cakelight.mode;
2
3import kaka.cakelight.Configuration;
4import kaka.cakelight.FrameGrabber;
5import kaka.cakelight.VideoDeviceListener;
6import kaka.cakelight.VideoFrame;
7
8import java.io.File;
9import java.io.IOException;
10import java.util.Optional;
11import java.util.function.Consumer;
12
13public class VideoMode extends Mode {
14 private Configuration config;
15 private Thread grabberThread;
16 private Consumer<VideoFrame> frameConsumer;
17 private VideoDeviceListener deviceListener;
18
19 public VideoMode() {
20 deviceListener = new VideoDeviceListener();
21 deviceListener.onVideoDeviceChange(this::onVideoDeviceChange);
22 }
23
24 @Override
25 public void enter(Configuration config) {
26 this.config = config;
27 deviceListener.startListening();
28 }
29
30 @Override
31 public void exit() {
32 grabberThread.interrupt();
33 deviceListener.stopListening();
34 }
35
36 private void startGrabberThread(File videoDevice) {
37 assert frameConsumer != null;
38 grabberThread = new Thread() {
39 public void run() {
40 try (FrameGrabber grabber = FrameGrabber.from(videoDevice, config)) {
41 while (!isInterrupted()) {
42 Optional<VideoFrame> frame = grabber.grabFrame();
43 if (frameConsumer != null) frame.ifPresent(frameConsumer);
44 frame.ifPresent(VideoMode.this::onVideoFrame);
45// timeIt("frame", grabber::grabFrame);
46 }
47 } catch (IOException e) {
48 e.printStackTrace();
49 }
50 }
51 };
52 grabberThread.start();
53 }
54
55 public void onVideoFrame(Consumer<VideoFrame> consumer) {
56 frameConsumer = consumer;
57 }
58
59 private void onVideoFrame(VideoFrame frame) {
60 updateWithFrame(frame.getLedFrame());
61 }
62
63 public void onVideoDeviceChange(Optional<File> videoDevice) {
64 // Should only happen when this mode is active!
65 if (grabberThread != null) {
66 grabberThread.interrupt();
67 }
68 videoDevice.ifPresent(this::startGrabberThread);
69 }
70}