From 4eeb221ea07ba07f1d4d7074116a7a7534b2782a Mon Sep 17 00:00:00 2001 From: Azureyjt Date: Thu, 17 Oct 2019 17:37:55 +0800 Subject: [PATCH 1/7] Basic implementation --- double-buffer/pom.xml | 38 +++++++++++ .../java/com/iluwatar/doublebuffer/App.java | 35 ++++++++++ .../com/iluwatar/doublebuffer/Buffer.java | 56 ++++++++++++++++ .../iluwatar/doublebuffer/FrameBuffer.java | 65 +++++++++++++++++++ .../java/com/iluwatar/doublebuffer/Pixel.java | 43 ++++++++++++ .../java/com/iluwatar/doublebuffer/Scene.java | 62 ++++++++++++++++++ pom.xml | 1 + 7 files changed, 300 insertions(+) create mode 100644 double-buffer/pom.xml create mode 100644 double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java create mode 100644 double-buffer/src/main/java/com/iluwatar/doublebuffer/Buffer.java create mode 100644 double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java create mode 100644 double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java create mode 100644 double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java diff --git a/double-buffer/pom.xml b/double-buffer/pom.xml new file mode 100644 index 000000000000..0c398c70e452 --- /dev/null +++ b/double-buffer/pom.xml @@ -0,0 +1,38 @@ + + + + + java-design-patterns + com.iluwatar + 1.22.0-SNAPSHOT + + 4.0.0 + + double-buffer + + \ No newline at end of file diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java new file mode 100644 index 000000000000..87ff075118cb --- /dev/null +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java @@ -0,0 +1,35 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.doublebuffer; + +/** + * + */ +public class App { + + public static void main(String[] args) { + + } + +} diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Buffer.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Buffer.java new file mode 100644 index 000000000000..b8c15a914e35 --- /dev/null +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Buffer.java @@ -0,0 +1,56 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.doublebuffer; + +/** + * Buffer interface. + */ +public interface Buffer { + + /** + * Clear the pixel in (x, y). + * @param x X coordinate + * @param y Y coordinate + */ + void clear(int x, int y); + + /** + * Draw the pixel in (x, y). + * @param x X coordinate + * @param y Y coordinate + */ + void draw(int x, int y); + + /** + * Clear all the pixels. + */ + void clearAll(); + + /** + * Get all the pixels. + * @return pixel list + */ + Pixel[] getPixels(); + +} diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java new file mode 100644 index 000000000000..f78908866e99 --- /dev/null +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java @@ -0,0 +1,65 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.doublebuffer; + +/** + * + */ +public class FrameBuffer implements Buffer { + + private static final int WIDTH = 192; + private static final int HEIGHT = 168; + + private Pixel[] pixels = new Pixel[WIDTH * HEIGHT]; + + public FrameBuffer() { + clearAll(); + } + + @Override + public void clear(int x, int y) { + pixels[getIndex(x, y)] = Pixel.WHITE; + } + + @Override + public void draw(int x, int y) { + pixels[getIndex(x, y)] = Pixel.BLACK; + } + + @Override + public void clearAll() { + for (var i = 0; i < pixels.length; ++i) { + pixels[i] = Pixel.WHITE; + } + } + + @Override + public Pixel[] getPixels() { + return pixels; + } + + private int getIndex(int x, int y) { + return x + WIDTH * y; + } +} diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java new file mode 100644 index 000000000000..916bd9a0fda2 --- /dev/null +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java @@ -0,0 +1,43 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.doublebuffer; + +/** + * + */ +public enum Pixel { + + WHITE(0), + BLACK(1); + + private int color; + + Pixel(int color) { + this.color = color; + } + + public int getColor() { + return color; + } +} diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java new file mode 100644 index 000000000000..09e19a7007a0 --- /dev/null +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java @@ -0,0 +1,62 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.doublebuffer; + +import java.util.List; +import java.util.Map; + +/** + * + */ +public class Scene { + + private Buffer[] frameBuffers; + + private int current; + + private int next; + + public Scene() { + frameBuffers = new FrameBuffer[2]; + current = 0; + next = 1; + } + + public void draw(List> coordinateList) { + frameBuffers[next].clearAll(); + for (Map.Entry coordinate : coordinateList) { + int x = coordinate.getKey(); + int y = coordinate.getValue(); + frameBuffers[next].draw(x, y); + } + swap(); + } + + private void swap() { + current = current ^ next; + next = current ^ next; + current = current ^ next; + } + +} diff --git a/pom.xml b/pom.xml index 020c784c62fd..9dce921df85e 100644 --- a/pom.xml +++ b/pom.xml @@ -183,6 +183,7 @@ data-locality subclass-sandbox circuit-breaker + double-buffer From 7b9ad920a31f151fdbd203ccd8e64c64154bdee9 Mon Sep 17 00:00:00 2001 From: Azureyjt Date: Fri, 18 Oct 2019 17:07:43 +0800 Subject: [PATCH 2/7] implement double buffer --- double-buffer/pom.xml | 7 +++ .../java/com/iluwatar/doublebuffer/App.java | 52 ++++++++++++++++++- .../iluwatar/doublebuffer/FrameBuffer.java | 12 +++-- .../java/com/iluwatar/doublebuffer/Pixel.java | 2 +- .../java/com/iluwatar/doublebuffer/Scene.java | 29 ++++++++--- 5 files changed, 91 insertions(+), 11 deletions(-) diff --git a/double-buffer/pom.xml b/double-buffer/pom.xml index 0c398c70e452..d6c358463f28 100644 --- a/double-buffer/pom.xml +++ b/double-buffer/pom.xml @@ -35,4 +35,11 @@ double-buffer + + + org.apache.commons + commons-lang3 + + + \ No newline at end of file diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java index 87ff075118cb..27e9a4af7d9f 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java @@ -23,13 +23,63 @@ package com.iluwatar.doublebuffer; +import org.apache.commons.lang3.tuple.MutablePair; +import org.apache.commons.lang3.tuple.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + /** - * + * Double buffering is a term used to describe a device that has two buffers. + * The usage of multiple buffers increases the overall throughput of a device + * and helps prevents bottlenecks. This example shows using double buffer pattern + * on graphics. It is used to show one image or frame while a separate frame + * is being buffered to be shown next. This method makes animations and games + * look more realistic than the same done in a single buffer mode. */ public class App { + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + + /** + * Program main entry point. + * @param args runtime arguments + */ public static void main(String[] args) { + var scene = new Scene(); + List> drawPixels = new ArrayList<>(); + Pair pixel1 = new MutablePair<>(1, 1); + Pair pixel2 = new MutablePair<>(5, 6); + Pair pixel3 = new MutablePair<>(3, 2); + drawPixels.add(pixel1); + drawPixels.add(pixel2); + drawPixels.add(pixel3); + scene.draw(drawPixels); + Buffer buffer1 = scene.getBuffer(); + printBlackPixelCoordinate(buffer1); + drawPixels.clear(); + Pair pixel4 = new MutablePair<>(3, 7); + Pair pixel5 = new MutablePair<>(6, 1); + drawPixels.add(pixel4); + drawPixels.add(pixel5); + scene.draw(drawPixels); + Buffer buffer2 = scene.getBuffer(); + printBlackPixelCoordinate(buffer2); } + private static void printBlackPixelCoordinate(Buffer buffer) { + String log = "Black Pixels: "; + Pixel[] pixels = buffer.getPixels(); + for (int i = 0; i < pixels.length; ++i) { + if (pixels[i] == Pixel.BLACK) { + int y = i / FrameBuffer.WIDTH; + int x = i % FrameBuffer.WIDTH; + log += " (" + x + ", " + y + ")"; + } + } + LOGGER.info(log); + } } diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java index f78908866e99..6724ac6ae89b 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java @@ -23,13 +23,18 @@ package com.iluwatar.doublebuffer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** - * + * FrameBuffer implementation class. */ public class FrameBuffer implements Buffer { - private static final int WIDTH = 192; - private static final int HEIGHT = 168; + private static final Logger LOGGER = LoggerFactory.getLogger(FrameBuffer.class); + + public static final int WIDTH = 10; + public static final int HEIGHT = 8; private Pixel[] pixels = new Pixel[WIDTH * HEIGHT]; @@ -62,4 +67,5 @@ public Pixel[] getPixels() { private int getIndex(int x, int y) { return x + WIDTH * y; } + } diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java index 916bd9a0fda2..b6b7890c7be4 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java @@ -24,7 +24,7 @@ package com.iluwatar.doublebuffer; /** - * + * Pixel enum. Each pixel can be white (not drawn) or black (drawn). */ public enum Pixel { diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java index 09e19a7007a0..1672c0aeae74 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java @@ -23,14 +23,19 @@ package com.iluwatar.doublebuffer; +import org.apache.commons.lang3.tuple.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.List; -import java.util.Map; /** - * + * Scene class. Render the output frame. */ public class Scene { + private static final Logger LOGGER = LoggerFactory.getLogger(Scene.class); + private Buffer[] frameBuffers; private int current; @@ -39,18 +44,30 @@ public class Scene { public Scene() { frameBuffers = new FrameBuffer[2]; + frameBuffers[0] = new FrameBuffer(); + frameBuffers[1] = new FrameBuffer(); current = 0; next = 1; } - public void draw(List> coordinateList) { + public void draw(List> coordinateList) { + LOGGER.info("Start drawing next frame"); + LOGGER.info("Current buffer: " + current + " Next buffer: " + next); frameBuffers[next].clearAll(); - for (Map.Entry coordinate : coordinateList) { - int x = coordinate.getKey(); - int y = coordinate.getValue(); + for (Pair coordinate : coordinateList) { + var x = coordinate.getKey(); + var y = coordinate.getValue(); frameBuffers[next].draw(x, y); } + LOGGER.info("Swap current and next buffer"); swap(); + LOGGER.info("Finish swapping"); + LOGGER.info("Current buffer: " + current + " Next buffer: " + next); + } + + public Buffer getBuffer() { + LOGGER.info("Get current buffer: " + current); + return frameBuffers[current]; } private void swap() { From 55f8bcfcffb0bac6635670eabbd12c52c759177d Mon Sep 17 00:00:00 2001 From: Azureyjt Date: Fri, 18 Oct 2019 17:54:28 +0800 Subject: [PATCH 3/7] add unit test --- double-buffer/pom.xml | 4 ++ .../java/com/iluwatar/doublebuffer/App.java | 10 ++-- .../com/iluwatar/doublebuffer/AppTest.java | 39 +++++++++++++++ .../doublebuffer/FrameBufferTest.java | 48 +++++++++++++++++++ .../com/iluwatar/doublebuffer/SceneTest.java | 30 ++++++++++++ 5 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 double-buffer/src/test/java/com/iluwatar/doublebuffer/AppTest.java create mode 100644 double-buffer/src/test/java/com/iluwatar/doublebuffer/FrameBufferTest.java create mode 100644 double-buffer/src/test/java/com/iluwatar/doublebuffer/SceneTest.java diff --git a/double-buffer/pom.xml b/double-buffer/pom.xml index d6c358463f28..a904c58842ef 100644 --- a/double-buffer/pom.xml +++ b/double-buffer/pom.xml @@ -36,6 +36,10 @@ double-buffer + + junit + junit + org.apache.commons commons-lang3 diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java index 27e9a4af7d9f..78c4a747a867 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java @@ -57,7 +57,7 @@ public static void main(String[] args) { drawPixels.add(pixel2); drawPixels.add(pixel3); scene.draw(drawPixels); - Buffer buffer1 = scene.getBuffer(); + var buffer1 = scene.getBuffer(); printBlackPixelCoordinate(buffer1); drawPixels.clear(); @@ -71,12 +71,12 @@ public static void main(String[] args) { } private static void printBlackPixelCoordinate(Buffer buffer) { - String log = "Black Pixels: "; + var log = "Black Pixels: "; Pixel[] pixels = buffer.getPixels(); - for (int i = 0; i < pixels.length; ++i) { + for (var i = 0; i < pixels.length; ++i) { if (pixels[i] == Pixel.BLACK) { - int y = i / FrameBuffer.WIDTH; - int x = i % FrameBuffer.WIDTH; + var y = i / FrameBuffer.WIDTH; + var x = i % FrameBuffer.WIDTH; log += " (" + x + ", " + y + ")"; } } diff --git a/double-buffer/src/test/java/com/iluwatar/doublebuffer/AppTest.java b/double-buffer/src/test/java/com/iluwatar/doublebuffer/AppTest.java new file mode 100644 index 000000000000..ebbabf980476 --- /dev/null +++ b/double-buffer/src/test/java/com/iluwatar/doublebuffer/AppTest.java @@ -0,0 +1,39 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.doublebuffer; + +import org.junit.Test; + +/** + * App unit test. + */ +public class AppTest { + + @Test + public void testMain() { + String[] args = {}; + App.main(args); + } + +} diff --git a/double-buffer/src/test/java/com/iluwatar/doublebuffer/FrameBufferTest.java b/double-buffer/src/test/java/com/iluwatar/doublebuffer/FrameBufferTest.java new file mode 100644 index 000000000000..c09f53d5f04a --- /dev/null +++ b/double-buffer/src/test/java/com/iluwatar/doublebuffer/FrameBufferTest.java @@ -0,0 +1,48 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.doublebuffer; + +import org.junit.Assert; +import org.junit.Test; + +/** + * FrameBuffer unit test. + */ +public class FrameBufferTest { + + @Test + public void testClear() { + try { + var field = FrameBuffer.class.getDeclaredField("pixels"); + + FrameBuffer frameBuffer = new FrameBuffer(); + field.setAccessible(true); + field.set(frameBuffer, ); + } catch (NoSuchFieldException e) { + Assert.fail("Fail to modify field access."); + } + + } + +} diff --git a/double-buffer/src/test/java/com/iluwatar/doublebuffer/SceneTest.java b/double-buffer/src/test/java/com/iluwatar/doublebuffer/SceneTest.java new file mode 100644 index 000000000000..94476f7b4ad4 --- /dev/null +++ b/double-buffer/src/test/java/com/iluwatar/doublebuffer/SceneTest.java @@ -0,0 +1,30 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.doublebuffer; + +/** + * Scene unit tests. + */ +public class SceneTest { +} From e67ff858b46ba1b2a2d7db6b19962ed89a02db0e Mon Sep 17 00:00:00 2001 From: Azureyjt Date: Fri, 18 Oct 2019 17:54:28 +0800 Subject: [PATCH 4/7] add unit test --- double-buffer/pom.xml | 4 + .../java/com/iluwatar/doublebuffer/App.java | 10 +- .../iluwatar/doublebuffer/FrameBuffer.java | 1 - .../java/com/iluwatar/doublebuffer/Scene.java | 7 ++ .../com/iluwatar/doublebuffer/AppTest.java | 39 ++++++++ .../doublebuffer/FrameBufferTest.java | 97 +++++++++++++++++++ .../com/iluwatar/doublebuffer/SceneTest.java | 74 ++++++++++++++ 7 files changed, 226 insertions(+), 6 deletions(-) create mode 100644 double-buffer/src/test/java/com/iluwatar/doublebuffer/AppTest.java create mode 100644 double-buffer/src/test/java/com/iluwatar/doublebuffer/FrameBufferTest.java create mode 100644 double-buffer/src/test/java/com/iluwatar/doublebuffer/SceneTest.java diff --git a/double-buffer/pom.xml b/double-buffer/pom.xml index d6c358463f28..a904c58842ef 100644 --- a/double-buffer/pom.xml +++ b/double-buffer/pom.xml @@ -36,6 +36,10 @@ double-buffer + + junit + junit + org.apache.commons commons-lang3 diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java index 27e9a4af7d9f..78c4a747a867 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java @@ -57,7 +57,7 @@ public static void main(String[] args) { drawPixels.add(pixel2); drawPixels.add(pixel3); scene.draw(drawPixels); - Buffer buffer1 = scene.getBuffer(); + var buffer1 = scene.getBuffer(); printBlackPixelCoordinate(buffer1); drawPixels.clear(); @@ -71,12 +71,12 @@ public static void main(String[] args) { } private static void printBlackPixelCoordinate(Buffer buffer) { - String log = "Black Pixels: "; + var log = "Black Pixels: "; Pixel[] pixels = buffer.getPixels(); - for (int i = 0; i < pixels.length; ++i) { + for (var i = 0; i < pixels.length; ++i) { if (pixels[i] == Pixel.BLACK) { - int y = i / FrameBuffer.WIDTH; - int x = i % FrameBuffer.WIDTH; + var y = i / FrameBuffer.WIDTH; + var x = i % FrameBuffer.WIDTH; log += " (" + x + ", " + y + ")"; } } diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java index 6724ac6ae89b..2df1ebd40ce7 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java @@ -67,5 +67,4 @@ public Pixel[] getPixels() { private int getIndex(int x, int y) { return x + WIDTH * y; } - } diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java index 1672c0aeae74..2f5b668e2ac0 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java @@ -42,6 +42,9 @@ public class Scene { private int next; + /** + * Constructor of Scene. + */ public Scene() { frameBuffers = new FrameBuffer[2]; frameBuffers[0] = new FrameBuffer(); @@ -50,6 +53,10 @@ public Scene() { next = 1; } + /** + * Draw the next frame. + * @param coordinateList list of pixels of which the color should be black + */ public void draw(List> coordinateList) { LOGGER.info("Start drawing next frame"); LOGGER.info("Current buffer: " + current + " Next buffer: " + next); diff --git a/double-buffer/src/test/java/com/iluwatar/doublebuffer/AppTest.java b/double-buffer/src/test/java/com/iluwatar/doublebuffer/AppTest.java new file mode 100644 index 000000000000..ebbabf980476 --- /dev/null +++ b/double-buffer/src/test/java/com/iluwatar/doublebuffer/AppTest.java @@ -0,0 +1,39 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.doublebuffer; + +import org.junit.Test; + +/** + * App unit test. + */ +public class AppTest { + + @Test + public void testMain() { + String[] args = {}; + App.main(args); + } + +} diff --git a/double-buffer/src/test/java/com/iluwatar/doublebuffer/FrameBufferTest.java b/double-buffer/src/test/java/com/iluwatar/doublebuffer/FrameBufferTest.java new file mode 100644 index 000000000000..689af2919e9f --- /dev/null +++ b/double-buffer/src/test/java/com/iluwatar/doublebuffer/FrameBufferTest.java @@ -0,0 +1,97 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.doublebuffer; + +import org.junit.Assert; +import org.junit.Test; + +/** + * FrameBuffer unit test. + */ +public class FrameBufferTest { + + @Test + public void testClearAll() { + try { + var field = FrameBuffer.class.getDeclaredField("pixels"); + Pixel[] pixels = new Pixel[FrameBuffer.HEIGHT * FrameBuffer.WIDTH]; + for (int i = 0; i < pixels.length; ++i) { + pixels[i] = Pixel.WHITE; + } + pixels[0] = Pixel.BLACK; + var frameBuffer = new FrameBuffer(); + field.setAccessible(true); + field.set(frameBuffer, pixels); + frameBuffer.clearAll(); + Assert.assertEquals(Pixel.WHITE, frameBuffer.getPixels()[0]); + } catch (NoSuchFieldException | IllegalAccessException e) { + Assert.fail("Fail to modify field access."); + } + } + + @Test + public void testClear() { + try { + var field = FrameBuffer.class.getDeclaredField("pixels"); + Pixel[] pixels = new Pixel[FrameBuffer.HEIGHT * FrameBuffer.WIDTH]; + for (int i = 0; i < pixels.length; ++i) { + pixels[i] = Pixel.WHITE; + } + pixels[0] = Pixel.BLACK; + var frameBuffer = new FrameBuffer(); + field.setAccessible(true); + field.set(frameBuffer, pixels); + frameBuffer.clear(0, 0); + Assert.assertEquals(Pixel.WHITE, frameBuffer.getPixels()[0]); + } catch (NoSuchFieldException | IllegalAccessException e) { + Assert.fail("Fail to modify field access."); + } + } + + @Test + public void testDraw() { + var frameBuffer = new FrameBuffer(); + frameBuffer.draw(0, 0); + Assert.assertEquals(Pixel.BLACK, frameBuffer.getPixels()[0]); + } + + @Test + public void testGetPixels() { + try { + var field = FrameBuffer.class.getDeclaredField("pixels"); + Pixel[] pixels = new Pixel[FrameBuffer.HEIGHT * FrameBuffer.WIDTH]; + for (int i = 0; i < pixels.length; ++i) { + pixels[i] = Pixel.WHITE; + } + pixels[0] = Pixel.BLACK; + var frameBuffer = new FrameBuffer(); + field.setAccessible(true); + field.set(frameBuffer, pixels); + Assert.assertEquals(pixels, frameBuffer.getPixels()); + } catch (NoSuchFieldException | IllegalAccessException e) { + Assert.fail("Fail to modify field access."); + } + } + +} diff --git a/double-buffer/src/test/java/com/iluwatar/doublebuffer/SceneTest.java b/double-buffer/src/test/java/com/iluwatar/doublebuffer/SceneTest.java new file mode 100644 index 000000000000..6de0c23a9ea9 --- /dev/null +++ b/double-buffer/src/test/java/com/iluwatar/doublebuffer/SceneTest.java @@ -0,0 +1,74 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.iluwatar.doublebuffer; + +import org.junit.Assert; +import org.junit.Test; + +import java.lang.reflect.Field; +import java.util.ArrayList; + +/** + * Scene unit tests. + */ +public class SceneTest { + + @Test + public void testGetBuffer() { + try { + var scene = new Scene(); + Field field1 = Scene.class.getDeclaredField("current"); + field1.setAccessible(true); + field1.set(scene, 0); + FrameBuffer[] frameBuffers = new FrameBuffer[2]; + FrameBuffer frameBuffer = new FrameBuffer(); + frameBuffer.draw(0, 0); + frameBuffers[0] = frameBuffer; + Field field2 = Scene.class.getDeclaredField("frameBuffers"); + field2.setAccessible(true); + field2.set(scene, frameBuffers); + Assert.assertEquals(frameBuffer, scene.getBuffer()); + } catch (NoSuchFieldException | IllegalAccessException e) { + Assert.fail("Fail to access private field."); + } + } + + @Test + public void testDraw() { + try { + var scene = new Scene(); + Field field1 = Scene.class.getDeclaredField("current"); + Field field2 = Scene.class.getDeclaredField("next"); + field1.setAccessible(true); + field1.set(scene, 0); + field2.setAccessible(true); + field2.set(scene, 1); + scene.draw(new ArrayList<>()); + Assert.assertEquals(1, field1.get(scene)); + Assert.assertEquals(0, field2.get(scene)); + } catch (NoSuchFieldException | IllegalAccessException e) { + Assert.fail("Fail to access private field"); + } + } +} From e0955ce04ba2eb58ff733b393e71d90a62bf27bc Mon Sep 17 00:00:00 2001 From: Azureyjt Date: Sun, 20 Oct 2019 16:13:31 +0800 Subject: [PATCH 5/7] Add Readme --- double-buffer/README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 double-buffer/README.md diff --git a/double-buffer/README.md b/double-buffer/README.md new file mode 100644 index 000000000000..8e8e7acf6bfd --- /dev/null +++ b/double-buffer/README.md @@ -0,0 +1,29 @@ + +--- +layout: pattern +title: Double Buffer +folder: double-buffer +permalink: /patterns/double-buffer/ +categories: Other +tags: + - Java + - Difficulty-Beginner +--- + +## Intent +Double buffering is a term used to describe a device that has two buffers. The usage of multiple buffers increases the overall throughput of a device and helps prevents bottlenecks. This example shows using double buffer pattern on graphics. It is used to show one image or frame while a separate frame is being buffered to be shown next. This method makes animations and games look more realistic than the same done in a single buffer mode. + +## Applicability +This pattern is one of those ones where you’ll know when you need it. If you have a system that lacks double buffering, it will probably look visibly wrong (tearing, etc.) or will behave incorrectly. But saying, “you’ll know when you need it” doesn’t give you much to go on. More specifically, this pattern is appropriate when all of these are true: + +- We have some state that is being modified incrementally. + +- That same state may be accessed in the middle of modification. + +- We want to prevent the code that’s accessing the state from seeing the work in progress. + +- We want to be able to read the state and we don’t want to have to wait while it’s being written. + +## Credits + +* [Game Programming Patterns - Double Buffer]([http://gameprogrammingpatterns.com/double-buffer.html](http://gameprogrammingpatterns.com/double-buffer.html)) \ No newline at end of file From 50f4c66804c6fee639fdb088ea87c66a06d12697 Mon Sep 17 00:00:00 2001 From: Azureyjt Date: Sun, 20 Oct 2019 16:14:54 +0800 Subject: [PATCH 6/7] Change local value declaration to var --- .../test/java/com/iluwatar/doublebuffer/SceneTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/double-buffer/src/test/java/com/iluwatar/doublebuffer/SceneTest.java b/double-buffer/src/test/java/com/iluwatar/doublebuffer/SceneTest.java index 6de0c23a9ea9..ab332aa22360 100644 --- a/double-buffer/src/test/java/com/iluwatar/doublebuffer/SceneTest.java +++ b/double-buffer/src/test/java/com/iluwatar/doublebuffer/SceneTest.java @@ -38,14 +38,14 @@ public class SceneTest { public void testGetBuffer() { try { var scene = new Scene(); - Field field1 = Scene.class.getDeclaredField("current"); + var field1 = Scene.class.getDeclaredField("current"); field1.setAccessible(true); field1.set(scene, 0); FrameBuffer[] frameBuffers = new FrameBuffer[2]; FrameBuffer frameBuffer = new FrameBuffer(); frameBuffer.draw(0, 0); frameBuffers[0] = frameBuffer; - Field field2 = Scene.class.getDeclaredField("frameBuffers"); + var field2 = Scene.class.getDeclaredField("frameBuffers"); field2.setAccessible(true); field2.set(scene, frameBuffers); Assert.assertEquals(frameBuffer, scene.getBuffer()); @@ -58,8 +58,8 @@ public void testGetBuffer() { public void testDraw() { try { var scene = new Scene(); - Field field1 = Scene.class.getDeclaredField("current"); - Field field2 = Scene.class.getDeclaredField("next"); + var field1 = Scene.class.getDeclaredField("current"); + var field2 = Scene.class.getDeclaredField("next"); field1.setAccessible(true); field1.set(scene, 0); field2.setAccessible(true); From d4950211e62f347d2ce7610c0d5f3371c6a6019f Mon Sep 17 00:00:00 2001 From: Azureyjt Date: Sun, 20 Oct 2019 16:26:33 +0800 Subject: [PATCH 7/7] Remove unused fields --- .../src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java | 2 -- .../src/main/java/com/iluwatar/doublebuffer/Pixel.java | 4 ---- 2 files changed, 6 deletions(-) diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java index 2df1ebd40ce7..2730140a3d99 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java @@ -31,8 +31,6 @@ */ public class FrameBuffer implements Buffer { - private static final Logger LOGGER = LoggerFactory.getLogger(FrameBuffer.class); - public static final int WIDTH = 10; public static final int HEIGHT = 8; diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java index b6b7890c7be4..d693f4e2801c 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java @@ -36,8 +36,4 @@ public enum Pixel { Pixel(int color) { this.color = color; } - - public int getColor() { - return color; - } }