From fdb815ec573495280d832538c54a4c1255d17655 Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Tue, 3 Sep 2019 10:21:08 -0500 Subject: [PATCH 01/22] Refactor some parts --- .../server/AnimatedLEDStripServer.kt | 60 ++++++++++++------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt b/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt index 9285fc5..41c116f 100644 --- a/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt +++ b/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt @@ -45,12 +45,17 @@ import java.util.* import kotlin.reflect.KClass import kotlin.reflect.full.primaryConstructor -class AnimatedLEDStripServer ( +class AnimatedLEDStripServer( args: Array, ledClass: KClass ) { + /** + * Is the server running + */ internal var running = false + /* Command line and properties file */ + private val options = Options().apply { addOption("d", "Enable debugging") addOption("t", "Enable trace debugging") @@ -58,44 +63,59 @@ class AnimatedLEDStripServer ( addOption("q", "Disable log outputs") addOption("E", "Emulate LED strip but do NOT launch emulator") addOption("f", true, "Specify properties file") + addOption("o", true, "Specify output file name for image debugging") + addOption("r", true, "Specify number of renders between saves") addOption("i", "Enable image debugging") addOption("T", "Run test") } private val cmdline = DefaultParser().parse(options, args) - var defaultPropertyFileName = "led.config" + private var propertyFileName = cmdline.getOptionValue("f") ?: "led.config" - var defaultOutputFileName: String? = null + private var outputFileName: String? = cmdline.getOptionValue("o") private val properties = Properties().apply { try { - load(FileInputStream(cmdline.getOptionValue("f") ?: defaultPropertyFileName)) + load(FileInputStream(propertyFileName)) } catch (e: FileNotFoundException) { - Logger.warn("File ${cmdline.getOptionValue("f") ?: defaultPropertyFileName} not found") + Logger.warn("File $propertyFileName not found") } } - val ports = mutableListOf().apply { - Logger.debug(properties.getProperty("ports")) + + /* Arguments for creating the AnimatedLEDStrip instance */ + + private val emulated: Boolean = cmdline.hasOption("e") || cmdline.hasOption("E") + + private val numLEDs: Int = properties.getProperty("numLEDs", "240").toInt() + + private val pin: Int = properties.getProperty("pin", "12").toInt() + + private val imageDebuggingEnabled: Boolean = cmdline.hasOption("i") + + private val ports = mutableListOf().apply { properties.getProperty("ports")?.split(' ')?.forEach { - Logger.debug(it) requireNotNull(it.toIntOrNull()) this.add(it.toInt()) } } - private val leds = when (cmdline.hasOption("e") || cmdline.hasOption("E")) { + private val rendersBeforeSave = + properties.getProperty("renders")?.toIntOrNull() ?: cmdline.getOptionValue("r")?.toIntOrNull() ?: 1000 + + private val leds = when (emulated) { false -> ledClass.primaryConstructor!!.call( - properties.getProperty("numLEDs", "240").toInt(), - properties.getProperty("pin", "12").toInt(), - cmdline.hasOption("i"), - cmdline.getOptionValue("o") ?: defaultOutputFileName + numLEDs, + pin, + imageDebuggingEnabled, + outputFileName, + rendersBeforeSave ) true -> EmulatedAnimatedLEDStrip( - properties.getProperty("numLEDs", "240").toInt(), - imageDebugging = cmdline.hasOption("i"), - fileName = cmdline.getOptionValue("o") ?: defaultOutputFileName + numLEDs, + imageDebugging = imageDebuggingEnabled, + fileName = outputFileName ) } @@ -105,11 +125,11 @@ class AnimatedLEDStripServer ( AnimationData().animation(Animation.COLOR).color(CCBlue) init { - val pattern = + val loggingPattern = if (cmdline.hasOption("v")) "{date:yyyy-MM-dd HH:mm:ss} [{thread}] {class}.{method}()\n{level}: {message}" else "{{level}:|min-size=8} {message}" - val level = + val loggingLevel = when { cmdline.hasOption("t") -> Level.TRACE cmdline.hasOption("d") -> Level.DEBUG @@ -117,14 +137,14 @@ class AnimatedLEDStripServer ( else -> Level.INFO } - Configurator.defaultConfig().formatPattern(pattern).level(level).activate() + Configurator.defaultConfig().formatPattern(loggingPattern).level(loggingLevel).activate() } fun start(): AnimatedLEDStripServer { running = true startLocalTerminalReader() - Logger.debug("Ports = $ports") + Logger.debug("Ports: $ports") ports.forEach { SocketConnections.add(it, server = this).open() } From b8e70e8c633cf8fe96d570d1d139e8cf2c3e2768 Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Tue, 3 Sep 2019 10:21:58 -0500 Subject: [PATCH 02/22] Move thread creation into ContinuousRunAnimation --- pom.xml | 4 +- .../server/AnimationHandler.kt | 59 +++++++++---------- .../server/ContinuousRunAnimation.kt | 49 +++++++++++---- .../server/SocketConnections.kt | 15 ++++- src/test/java/AnimationHandlerTest.kt | 5 +- 5 files changed, 82 insertions(+), 50 deletions(-) diff --git a/pom.xml b/pom.xml index 8c1fdbd..9c6e10e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.animatedledstrip animatedledstrip-server - 0.3 + 0.4-SNAPSHOT jar ${project.groupId}:${project.artifactId} @@ -69,7 +69,7 @@ io.github.animatedledstrip animatedledstrip-core - 0.3 + 0.4-SNAPSHOT org.jetbrains.kotlin diff --git a/src/main/java/animatedledstrip/server/AnimationHandler.kt b/src/main/java/animatedledstrip/server/AnimationHandler.kt index 0e87af3..8066b80 100644 --- a/src/main/java/animatedledstrip/server/AnimationHandler.kt +++ b/src/main/java/animatedledstrip/server/AnimationHandler.kt @@ -38,10 +38,10 @@ import java.lang.Math.random * An object that creates ContinuousRunAnimation instances for animations and * keeps track of currently running animations. */ -internal class AnimationHandler(private val leds: AnimatedLEDStrip) { +internal class AnimationHandler(private val leds: AnimatedLEDStrip, threadCount: Int = 100) { @Suppress("EXPERIMENTAL_API_USAGE") - val animationThreadPool = newFixedThreadPoolContext(100, "AnimationThreads") + val animationThreadPool = newFixedThreadPoolContext(threadCount, "AnimationThreads") /** * Map tracking what continuous animations are currently running @@ -67,44 +67,43 @@ internal class AnimationHandler(private val leds: AnimatedLEDStrip) { */ fun addAnimation(params: AnimationData) { - /* Special "Animation" type that the GUI sends to end an animation */ + /* Special "Animation" type that the client sends to end an animation */ if (params.animation == Animation.ENDANIMATION) { Logger.debug("Ending an animation") continuousAnimations[params.id]?.endAnimation() // End animation - ?: throw Exception("Animation ${params.id} not running") + ?: Logger.error("Animation ${params.id} not running") continuousAnimations.remove(params.id) // Remove it from the continuousAnimations map + return } - Logger.trace("Launching new thread for new animation") - GlobalScope.launch(animationThreadPool) { - Logger.debug(params) - - when (params.animation::class.java.fields[params.animation.ordinal].annotations.find { it is NonRepetitive } is NonRepetitive) { - /* Animations that are only run once because they change the color of the strip */ - true -> { - Logger.trace("Calling Single Run Animation") - leds.run(params) - Logger.trace("Single Run Animation on ${Thread.currentThread().name} complete") - } - /* Animations that can be run repeatedly */ - false -> { - if (params.continuous) { - Logger.trace("Calling Continuous Animation") - val id = random().toString().removePrefix("0.") - continuousAnimations[id] = - ContinuousRunAnimation(id, params, leds) - Logger.trace(continuousAnimations) - continuousAnimations[id]!!.startAnimation() - Logger.debug("$id complete") - } else { - Logger.trace("Calling Single Run Animation") - leds.run(params) - Logger.trace("Single Run Animation on ${Thread.currentThread().name} complete") - } + when (params.animation::class.java.fields[params.animation.ordinal].annotations.find { it is NonRepetitive } is NonRepetitive) { + /* Animations that are only run once because they change the color of the strip */ + true -> { + singleRunAnimation(params) + } + /* Animations that can be run repeatedly */ + false -> { + if (params.continuous) { + Logger.trace("Calling Continuous Animation") + val id = random().toString().removePrefix("0.") + continuousAnimations[id] = + ContinuousRunAnimation(id, params, leds, this) + Logger.trace(continuousAnimations) + continuousAnimations[id]!!.runAnimation() + } else { + singleRunAnimation(params) } } } } + + private fun singleRunAnimation(params: AnimationData) { + GlobalScope.launch(animationThreadPool) { + Logger.trace("Calling Single Run Animation") + leds.run(params) + Logger.trace("Single Run Animation on ${Thread.currentThread().name} complete") + } + } } diff --git a/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt b/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt index b5b91cc..5a8f405 100644 --- a/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt +++ b/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt @@ -23,8 +23,12 @@ package animatedledstrip.server */ +import animatedledstrip.animationutils.Animation import animatedledstrip.animationutils.AnimationData import animatedledstrip.leds.AnimatedLEDStrip +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch import org.pmw.tinylog.Logger /** @@ -34,43 +38,64 @@ import org.pmw.tinylog.Logger * @param params An AnimationData instance containing data about the animation * to be run */ -class ContinuousRunAnimation(private val id: String, private val params: AnimationData, private val leds: AnimatedLEDStrip) { +internal class ContinuousRunAnimation( + private val id: String, + private val params: AnimationData, + private val leds: AnimatedLEDStrip, + private val handler: AnimationHandler +) { /** - * Variable controlling while loops in animation functions. + * Variable controlling if the animation will repeat */ private var continueAnimation = true + private var job: Job? = null + init { - sendAnimation() // Send animation to GUI + sendStartAnimation() // Send animation to GUI } /** - * Determine which animation is being called and call the corresponding function. + * Run the animation in a new thread */ - fun startAnimation() { - Logger.trace("params: $params") - while (continueAnimation) leds.run(params) + fun runAnimation() { + job = GlobalScope.launch(handler.animationThreadPool) { + Logger.trace("params: $params") + while (continueAnimation) leds.run(params) + sendEndAnimation() + } } /** - * Stop animation by setting the loop guard to false. + * Stop animation by setting the loop guard to false */ fun endAnimation() { Logger.debug("Animation $id ending") - continueAnimation = false + if (continueAnimation) continueAnimation = false + else job?.cancel() } /** - * Send animation data to GUI. + * Send message to client(s) that animation has started */ - fun sendAnimation(connection: SocketConnections.Connection? = null) { - Logger.trace("Sending animation to GUI") + fun sendStartAnimation(connection: SocketConnections.Connection? = null) { + Logger.trace("Sending animation start to client(s)") SocketConnections.sendAnimation(params, id, connection) } + /** + * Send message to client(s) that animation has ended + * + * @param connection + */ + fun sendEndAnimation(connection: SocketConnections.Connection? = null) { + Logger.trace("Sending animation end to client(s)") + SocketConnections.sendAnimation(params.copy(animation = Animation.ENDANIMATION), id, connection) + } + } diff --git a/src/main/java/animatedledstrip/server/SocketConnections.kt b/src/main/java/animatedledstrip/server/SocketConnections.kt index 7ce4abb..d50cf94 100644 --- a/src/main/java/animatedledstrip/server/SocketConnections.kt +++ b/src/main/java/animatedledstrip/server/SocketConnections.kt @@ -23,6 +23,7 @@ package animatedledstrip.server */ +import animatedledstrip.animationutils.Animation import animatedledstrip.animationutils.AnimationData import animatedledstrip.animationutils.id import kotlinx.coroutines.* @@ -109,7 +110,7 @@ object SocketConnections { Logger.debug("Sending currently running animations to GUI") // Send all current running continuous animations to newly connected client server.animationHandler.continuousAnimations.forEach { - it.value.sendAnimation(this@Connection) + it.value.sendStartAnimation(this@Connection) } disconnected = false Logger.info("Connection on port $port Established") @@ -149,7 +150,17 @@ object SocketConnections { runBlocking { withTimeout(5000) { withContext(Dispatchers.IO) { - socOut?.writeObject(animation.id(if (animation.id == "") id else "${animation.id} $id")) + socOut?.writeObject( + animation + .id( + if ((animation.animation == Animation.CUSTOMANIMATION || + animation.animation == Animation.CUSTOMREPETITIVEANIMATION) && + animation.id.length == 1 + ) + "${animation.id} $id" + else id + ) + ) ?: Logger.debug("Could not send animation $id: Connection socket null") Logger.debug("Sent animation $id") } diff --git a/src/test/java/AnimationHandlerTest.kt b/src/test/java/AnimationHandlerTest.kt index 80d380d..b6ab6f5 100644 --- a/src/test/java/AnimationHandlerTest.kt +++ b/src/test/java/AnimationHandlerTest.kt @@ -32,7 +32,6 @@ import animatedledstrip.utils.delayBlocking import org.junit.Test import org.pmw.tinylog.Configurator import org.pmw.tinylog.Level -import kotlin.test.assertFails import kotlin.test.assertTrue class AnimationHandlerTest { @@ -92,9 +91,7 @@ class AnimationHandlerTest { @Test fun testRemoveNonExistentAnimation() { val handler = AnimationHandler(leds) - assertFails { - handler.addAnimation(AnimationData().animation(Animation.ENDANIMATION).id("TEST")) - } + handler.addAnimation(AnimationData().animation(Animation.ENDANIMATION).id("TEST")) } } \ No newline at end of file From 3fffcd03fb1c234a0a34ec744ebf939cc36d9860 Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Thu, 12 Sep 2019 11:45:57 -0500 Subject: [PATCH 03/22] Add local terminal thread --- .../server/AnimatedLEDStripServer.kt | 94 ++++++++++++++----- 1 file changed, 68 insertions(+), 26 deletions(-) diff --git a/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt b/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt index 41c116f..9def7e0 100644 --- a/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt +++ b/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt @@ -54,7 +54,7 @@ class AnimatedLEDStripServer( */ internal var running = false - /* Command line and properties file */ + /* Command line options and properties file */ private val options = Options().apply { addOption("d", "Enable debugging") @@ -83,6 +83,22 @@ class AnimatedLEDStripServer( } } + /* Set logging levels based on command line */ + init { + val loggingPattern = + if (cmdline.hasOption("v")) "{date:yyyy-MM-dd HH:mm:ss} [{thread}] {class}.{method}()\n{level}: {message}" + else "{{level}:|min-size=8} {message}" + + val loggingLevel = + when { + cmdline.hasOption("t") -> Level.TRACE + cmdline.hasOption("d") -> Level.DEBUG + cmdline.hasOption("q") -> Level.OFF + else -> Level.INFO + } + + Configurator.defaultConfig().formatPattern(loggingPattern).level(loggingLevel).activate() + } /* Arguments for creating the AnimatedLEDStrip instance */ @@ -124,22 +140,8 @@ class AnimatedLEDStripServer( var testAnimation: AnimationData = AnimationData().animation(Animation.COLOR).color(CCBlue) - init { - val loggingPattern = - if (cmdline.hasOption("v")) "{date:yyyy-MM-dd HH:mm:ss} [{thread}] {class}.{method}()\n{level}: {message}" - else "{{level}:|min-size=8} {message}" - - val loggingLevel = - when { - cmdline.hasOption("t") -> Level.TRACE - cmdline.hasOption("d") -> Level.DEBUG - cmdline.hasOption("q") -> Level.OFF - else -> Level.INFO - } - - Configurator.defaultConfig().formatPattern(loggingPattern).level(loggingLevel).activate() - } + /* Start and stop methods */ fun start(): AnimatedLEDStripServer { running = true @@ -152,12 +154,6 @@ class AnimatedLEDStripServer( return this } - fun waitUntilStop() { - while (running) { - delayBlocking(1) - } - } - fun stop() { leds.setStripColor(0) delayBlocking(500) @@ -166,6 +162,8 @@ class AnimatedLEDStripServer( running = false } + /* Local terminal thread */ + @Suppress("EXPERIMENTAL_API_USAGE") val localThread = newSingleThreadContext("Local Terminal") @@ -173,13 +171,57 @@ class AnimatedLEDStripServer( GlobalScope.launch(localThread) { while (this@AnimatedLEDStripServer.running) { Logger.trace("Local terminal waiting for input") - val strIn = readLine() + val strIn = readLine() ?: continue Logger.trace("Read line") - if (strIn?.toUpperCase() == "Q") { - Logger.trace("'Q' received, shutting down server") - stop() + val line = strIn.toUpperCase().split(" ") + when (line[0]) { + "QUIT", "Q", "EXIT" -> { + Logger.info("Shutting down server") + stop() + } + "DEBUG" -> { + setLoggingLevel(Level.DEBUG) + Logger.debug("Set logging level to debug") + } + "TRACE" -> { + setLoggingLevel(Level.TRACE) + Logger.trace("Set logging level to trace") + } + "INFO" -> { + setLoggingLevel(Level.INFO) + Logger.info("Set logging level to info") + } + "CLEAR" -> { + animationHandler.addAnimation(AnimationData().animation(Animation.COLOR)) + } + "SHOW" -> { + if (line.size > 1) Logger.info( + "${line[1]}: ${animationHandler.continuousAnimations[line[1]]?.params ?: "NOT FOUND"}" + ) + else Logger.info("Running Animations: ${animationHandler.continuousAnimations.keys}") + } + "END" -> { + if (line.size > 1) { + if (line[1].toUpperCase() == "ALL") { + val animations = animationHandler.continuousAnimations + animations.forEach { + animationHandler.endAnimation(it.value) + } + } else for (i in 1 until line.size) + animationHandler.endAnimation(animationHandler.continuousAnimations[line[i]]) + } else Logger.warn("Animation ID must be specified") + } + else -> Logger.warn("Not a valid command") } } } } + + /* Helper methods */ + + fun setLoggingLevel(level: Level) { + Configurator.currentConfig().level(level).activate() + } + + } \ No newline at end of file From 1814e9b7a3a2071dabb95bd3921ac6aca396bbe2 Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Thu, 12 Sep 2019 11:46:19 -0500 Subject: [PATCH 04/22] Add waitUntilStop() extension method --- src/main/java/animatedledstrip/server/ServerUtils.kt | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/main/java/animatedledstrip/server/ServerUtils.kt diff --git a/src/main/java/animatedledstrip/server/ServerUtils.kt b/src/main/java/animatedledstrip/server/ServerUtils.kt new file mode 100644 index 0000000..ef06da3 --- /dev/null +++ b/src/main/java/animatedledstrip/server/ServerUtils.kt @@ -0,0 +1,9 @@ +package animatedledstrip.server + +import animatedledstrip.utils.delayBlocking + +fun AnimatedLEDStripServer<*>.waitUntilStop() { + while (running) { + delayBlocking(1) + } +} \ No newline at end of file From 6b037aa61813252b790ba721f54b0c9e883ad8e6 Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Thu, 12 Sep 2019 11:46:54 -0500 Subject: [PATCH 05/22] Add endAnimation methods --- .../server/AnimationHandler.kt | 56 ++++++++++--------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/src/main/java/animatedledstrip/server/AnimationHandler.kt b/src/main/java/animatedledstrip/server/AnimationHandler.kt index 8066b80..d2823b3 100644 --- a/src/main/java/animatedledstrip/server/AnimationHandler.kt +++ b/src/main/java/animatedledstrip/server/AnimationHandler.kt @@ -68,34 +68,28 @@ internal class AnimationHandler(private val leds: AnimatedLEDStrip, threadCount: fun addAnimation(params: AnimationData) { /* Special "Animation" type that the client sends to end an animation */ - if (params.animation == Animation.ENDANIMATION) { - Logger.debug("Ending an animation") - continuousAnimations[params.id]?.endAnimation() // End animation - ?: Logger.error("Animation ${params.id} not running") - continuousAnimations.remove(params.id) // Remove it from the continuousAnimations map - - return - } - - when (params.animation::class.java.fields[params.animation.ordinal].annotations.find { it is NonRepetitive } is NonRepetitive) { - /* Animations that are only run once because they change the color of the strip */ - true -> { - singleRunAnimation(params) - } - /* Animations that can be run repeatedly */ - false -> { - if (params.continuous) { - Logger.trace("Calling Continuous Animation") - val id = random().toString().removePrefix("0.") - continuousAnimations[id] = - ContinuousRunAnimation(id, params, leds, this) - Logger.trace(continuousAnimations) - continuousAnimations[id]!!.runAnimation() - } else { + if (params.animation == Animation.ENDANIMATION) + endAnimation(params) + else + when (params.animation::class.java.fields[params.animation.ordinal].annotations.find { it is NonRepetitive } is NonRepetitive) { + /* Animations that are only run once because they change the color of the strip */ + true -> { singleRunAnimation(params) } + /* Animations that can be run repeatedly */ + false -> { + if (params.continuous) { + Logger.trace("Calling Continuous Animation") + val id = (random() * 100000000).toInt().toString() + continuousAnimations[id] = + ContinuousRunAnimation(id, params, leds, this) + Logger.trace(continuousAnimations) + continuousAnimations[id]!!.runAnimation() + } else { + singleRunAnimation(params) + } + } } - } } private fun singleRunAnimation(params: AnimationData) { @@ -105,5 +99,17 @@ internal class AnimationHandler(private val leds: AnimatedLEDStrip, threadCount: Logger.trace("Single Run Animation on ${Thread.currentThread().name} complete") } } + + fun endAnimation(params: AnimationData?) { + Logger.debug("Ending an animation") + continuousAnimations[params?.id ?: "NONE"]?.endAnimation() // End animation + ?: run { Logger.warn("Animation ${params?.id} not running"); return } +// continuousAnimations.remove(params?.id) // Remove it from the continuousAnimations map + } + + fun endAnimation(animation: ContinuousRunAnimation?) { + if (animation == null) return + else endAnimation(animation.params) + } } From 97d1c35f889de5cb2186e4deeff059bbd644d517 Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Thu, 12 Sep 2019 11:47:28 -0500 Subject: [PATCH 06/22] Make ContinuousRunAnimation params public --- .../java/animatedledstrip/server/ContinuousRunAnimation.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt b/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt index 5a8f405..39e3ac4 100644 --- a/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt +++ b/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt @@ -40,7 +40,7 @@ import org.pmw.tinylog.Logger */ internal class ContinuousRunAnimation( private val id: String, - private val params: AnimationData, + val params: AnimationData, private val leds: AnimatedLEDStrip, private val handler: AnimationHandler ) { @@ -66,6 +66,7 @@ internal class ContinuousRunAnimation( Logger.trace("params: $params") while (continueAnimation) leds.run(params) sendEndAnimation() + handler.continuousAnimations.remove(id) } } From 8fd718341df0e84442c846cd66fe7a1220b3821a Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Thu, 12 Sep 2019 11:48:03 -0500 Subject: [PATCH 07/22] Add q to emulated strip params --- src/test/java/SocketConnectionsTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/SocketConnectionsTest.kt b/src/test/java/SocketConnectionsTest.kt index 04534d9..64800be 100644 --- a/src/test/java/SocketConnectionsTest.kt +++ b/src/test/java/SocketConnectionsTest.kt @@ -46,7 +46,7 @@ class SocketConnectionsTest { @Test fun testAdd() { val server = - AnimatedLEDStripServer(arrayOf("-E"), EmulatedAnimatedLEDStrip::class) + AnimatedLEDStripServer(arrayOf("-Eq"), EmulatedAnimatedLEDStrip::class) SocketConnections.hostIP = "0.0.0.0" SocketConnections.add(1200, server) @@ -57,7 +57,7 @@ class SocketConnectionsTest { fun testOpenSocket() = runBlocking { withTimeout(60000) { val server = - AnimatedLEDStripServer(arrayOf("-E"), EmulatedAnimatedLEDStrip::class).start() + AnimatedLEDStripServer(arrayOf("-Eq"), EmulatedAnimatedLEDStrip::class).start() SocketConnections.hostIP = "0.0.0.0" val c = SocketConnections.add(1201, server) c.open() From c69d56dcf57d5bc23a913c417e76eac65fc5727f Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Thu, 12 Sep 2019 11:48:17 -0500 Subject: [PATCH 08/22] Show different message if ending an animation --- src/main/java/animatedledstrip/server/SocketConnections.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/animatedledstrip/server/SocketConnections.kt b/src/main/java/animatedledstrip/server/SocketConnections.kt index d50cf94..26937b2 100644 --- a/src/main/java/animatedledstrip/server/SocketConnections.kt +++ b/src/main/java/animatedledstrip/server/SocketConnections.kt @@ -162,7 +162,8 @@ object SocketConnections { ) ) ?: Logger.debug("Could not send animation $id: Connection socket null") - Logger.debug("Sent animation $id") + if (animation.animation == Animation.ENDANIMATION) Logger.debug("Sent end of animation $id") + else Logger.debug("Sent animation $id") } } } From 6609c2f75e41156b37022bb7a499997f8179ce57 Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Thu, 12 Sep 2019 22:17:52 -0500 Subject: [PATCH 09/22] Upgrade tinylog to v2.0.0 --- .../server/AnimatedLEDStripServer.kt | 43 ++++++------------- .../server/AnimationHandler.kt | 12 +++--- .../server/ContinuousRunAnimation.kt | 10 ++--- .../animatedledstrip/server/GlobalVars.kt | 19 ++++++++ .../server/SocketConnections.kt | 34 +++++++-------- src/test/java/AnimatedLEDStripServerTest.kt | 7 +-- src/test/java/AnimationHandlerTest.kt | 5 +-- src/test/java/SocketConnectionsTest.kt | 7 +-- 8 files changed, 69 insertions(+), 68 deletions(-) create mode 100644 src/main/java/animatedledstrip/server/GlobalVars.kt diff --git a/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt b/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt index 9def7e0..bbe9575 100644 --- a/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt +++ b/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt @@ -31,14 +31,9 @@ import animatedledstrip.colors.ccpresets.CCBlue import animatedledstrip.leds.AnimatedLEDStrip import animatedledstrip.leds.emulated.EmulatedAnimatedLEDStrip import animatedledstrip.utils.delayBlocking -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.newSingleThreadContext import org.apache.commons.cli.DefaultParser -import org.apache.commons.cli.Options -import org.pmw.tinylog.Configurator -import org.pmw.tinylog.Level -import org.pmw.tinylog.Logger +import org.tinylog.Logger +import org.tinylog.configuration.Configuration import java.io.FileInputStream import java.io.FileNotFoundException import java.util.* @@ -56,19 +51,6 @@ class AnimatedLEDStripServer( /* Command line options and properties file */ - private val options = Options().apply { - addOption("d", "Enable debugging") - addOption("t", "Enable trace debugging") - addOption("v", "Enable verbose log statements") - addOption("q", "Disable log outputs") - addOption("E", "Emulate LED strip but do NOT launch emulator") - addOption("f", true, "Specify properties file") - addOption("o", true, "Specify output file name for image debugging") - addOption("r", true, "Specify number of renders between saves") - addOption("i", "Enable image debugging") - addOption("T", "Run test") - } - private val cmdline = DefaultParser().parse(options, args) private var propertyFileName = cmdline.getOptionValue("f") ?: "led.config" @@ -79,7 +61,7 @@ class AnimatedLEDStripServer( try { load(FileInputStream(propertyFileName)) } catch (e: FileNotFoundException) { - Logger.warn("File $propertyFileName not found") + Logger.warn { "File $propertyFileName not found" } } } @@ -91,13 +73,14 @@ class AnimatedLEDStripServer( val loggingLevel = when { - cmdline.hasOption("t") -> Level.TRACE - cmdline.hasOption("d") -> Level.DEBUG - cmdline.hasOption("q") -> Level.OFF - else -> Level.INFO + cmdline.hasOption("t") -> "trace" + cmdline.hasOption("d") -> "debug" + cmdline.hasOption("q") -> "off" + else -> "info" } - Configurator.defaultConfig().formatPattern(loggingPattern).level(loggingLevel).activate() + Configuration.set("level", loggingLevel) + Configuration.set("format", loggingPattern) } /* Arguments for creating the AnimatedLEDStrip instance */ @@ -140,13 +123,11 @@ class AnimatedLEDStripServer( var testAnimation: AnimationData = AnimationData().animation(Animation.COLOR).color(CCBlue) - /* Start and stop methods */ fun start(): AnimatedLEDStripServer { running = true - startLocalTerminalReader() - Logger.debug("Ports: $ports") + Logger.debug { "Ports: $ports" } ports.forEach { SocketConnections.add(it, server = this).open() } @@ -219,8 +200,8 @@ class AnimatedLEDStripServer( /* Helper methods */ - fun setLoggingLevel(level: Level) { - Configurator.currentConfig().level(level).activate() + fun setLoggingLevel(level: String) { + Configuration.set("level", level) } diff --git a/src/main/java/animatedledstrip/server/AnimationHandler.kt b/src/main/java/animatedledstrip/server/AnimationHandler.kt index d2823b3..c3b6720 100644 --- a/src/main/java/animatedledstrip/server/AnimationHandler.kt +++ b/src/main/java/animatedledstrip/server/AnimationHandler.kt @@ -30,7 +30,7 @@ import animatedledstrip.leds.AnimatedLEDStrip import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.newFixedThreadPoolContext -import org.pmw.tinylog.Logger +import org.tinylog.Logger import java.lang.Math.random @@ -79,7 +79,7 @@ internal class AnimationHandler(private val leds: AnimatedLEDStrip, threadCount: /* Animations that can be run repeatedly */ false -> { if (params.continuous) { - Logger.trace("Calling Continuous Animation") + Logger.trace { "Calling Continuous Animation" } val id = (random() * 100000000).toInt().toString() continuousAnimations[id] = ContinuousRunAnimation(id, params, leds, this) @@ -94,16 +94,16 @@ internal class AnimationHandler(private val leds: AnimatedLEDStrip, threadCount: private fun singleRunAnimation(params: AnimationData) { GlobalScope.launch(animationThreadPool) { - Logger.trace("Calling Single Run Animation") + Logger.trace { "Calling Single Run Animation" } leds.run(params) - Logger.trace("Single Run Animation on ${Thread.currentThread().name} complete") + Logger.trace { "Single Run Animation on ${Thread.currentThread().name} complete" } } } fun endAnimation(params: AnimationData?) { - Logger.debug("Ending an animation") + Logger.debug { "Ending an animation" } continuousAnimations[params?.id ?: "NONE"]?.endAnimation() // End animation - ?: run { Logger.warn("Animation ${params?.id} not running"); return } + ?: run { Logger.warn { "Animation ${params?.id} not running" }; return } // continuousAnimations.remove(params?.id) // Remove it from the continuousAnimations map } diff --git a/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt b/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt index 39e3ac4..44b36a6 100644 --- a/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt +++ b/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt @@ -29,7 +29,7 @@ import animatedledstrip.leds.AnimatedLEDStrip import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.Job import kotlinx.coroutines.launch -import org.pmw.tinylog.Logger +import org.tinylog.Logger /** * Class for running an animation that repeats until stopped. @@ -63,7 +63,7 @@ internal class ContinuousRunAnimation( */ fun runAnimation() { job = GlobalScope.launch(handler.animationThreadPool) { - Logger.trace("params: $params") + Logger.trace { "params: $params" } while (continueAnimation) leds.run(params) sendEndAnimation() handler.continuousAnimations.remove(id) @@ -75,7 +75,7 @@ internal class ContinuousRunAnimation( * Stop animation by setting the loop guard to false */ fun endAnimation() { - Logger.debug("Animation $id ending") + Logger.debug { "Animation $id ending" } if (continueAnimation) continueAnimation = false else job?.cancel() } @@ -85,7 +85,7 @@ internal class ContinuousRunAnimation( * Send message to client(s) that animation has started */ fun sendStartAnimation(connection: SocketConnections.Connection? = null) { - Logger.trace("Sending animation start to client(s)") + Logger.trace { "Sending animation start to client(s)" } SocketConnections.sendAnimation(params, id, connection) } @@ -95,7 +95,7 @@ internal class ContinuousRunAnimation( * @param connection */ fun sendEndAnimation(connection: SocketConnections.Connection? = null) { - Logger.trace("Sending animation end to client(s)") + Logger.trace { "Sending animation end to client(s)" } SocketConnections.sendAnimation(params.copy(animation = Animation.ENDANIMATION), id, connection) } diff --git a/src/main/java/animatedledstrip/server/GlobalVars.kt b/src/main/java/animatedledstrip/server/GlobalVars.kt new file mode 100644 index 0000000..db5243f --- /dev/null +++ b/src/main/java/animatedledstrip/server/GlobalVars.kt @@ -0,0 +1,19 @@ +package animatedledstrip.server + +import org.apache.commons.cli.Options + +var server: AnimatedLEDStripServer<*>? = null + +val options = Options().apply { + addOption("d", "Enable debugging") + addOption("t", "Enable trace debugging") + addOption("v", "Enable verbose log statements") + addOption("q", "Disable log outputs") + addOption("E", "Emulate LED strip but do NOT launch emulator") + addOption("f", true, "Specify properties file") + addOption("o", true, "Specify output file name for image debugging") + addOption("r", true, "Specify number of renders between saves") + addOption("i", "Enable image debugging") + addOption("T", "Run test") + addOption("C", "Connect to a running server with a command line") +} \ No newline at end of file diff --git a/src/main/java/animatedledstrip/server/SocketConnections.kt b/src/main/java/animatedledstrip/server/SocketConnections.kt index 26937b2..2fbc047 100644 --- a/src/main/java/animatedledstrip/server/SocketConnections.kt +++ b/src/main/java/animatedledstrip/server/SocketConnections.kt @@ -27,7 +27,7 @@ import animatedledstrip.animationutils.Animation import animatedledstrip.animationutils.AnimationData import animatedledstrip.animationutils.id import kotlinx.coroutines.* -import org.pmw.tinylog.Logger +import org.tinylog.Logger import java.io.EOFException import java.io.ObjectInputStream import java.io.ObjectOutputStream @@ -83,7 +83,7 @@ object SocketConnections { */ fun open() { GlobalScope.launch(connectionThreadPool) { - Logger.debug("Starting port $port") + Logger.debug { "Starting port $port" } openSocket() } } @@ -98,40 +98,40 @@ object SocketConnections { */ private suspend fun openSocket() { withContext(Dispatchers.IO) { - Logger.debug("Socket at port $port started") + Logger.debug { "Socket at port $port started" } while (server.running) { try { clientSocket = serverSocket.accept() - Logger.trace("Accepted new connection on port $port") - Logger.trace("Initializing input stream") + Logger.trace { "Accepted new connection on port $port" } + Logger.trace { "Initializing input stream" } val socIn = ObjectInputStream(clientSocket!!.getInputStream()) - Logger.trace("Initializing output stream") + Logger.trace { "Initializing output stream" } socOut = ObjectOutputStream(clientSocket!!.getOutputStream()) - Logger.debug("Sending currently running animations to GUI") + Logger.debug { "Sending currently running animations to GUI" } // Send all current running continuous animations to newly connected client server.animationHandler.continuousAnimations.forEach { it.value.sendStartAnimation(this@Connection) } disconnected = false - Logger.info("Connection on port $port Established") + Logger.info { "Connection on port $port Established" } var input: Any? while (!disconnected) { - Logger.trace("Waiting for input") + Logger.trace { "Waiting for input" } try { input = socIn.readObject() as AnimationData Logger.trace("Input received") server.animationHandler.addAnimation(input) } catch (e: ClassCastException) { - Logger.error("Could not cast input to AnimationData") + Logger.error { "Could not cast input to ${if (port == 1118) "String" else "AnimationData"}" } continue } } } catch (e: SocketException) { // Catch disconnections - Logger.warn("Connection on port $port Lost: $e") + Logger.warn { "Connection on port $port ${if (port == 1118) "(Local) " else ""}Lost: $e" } disconnected = true } catch (e: EOFException) { - Logger.warn("Connection on port $port Lost: $e") + Logger.warn { "Connection on port $port ${if (port == 1118) "(Local) " else ""}Lost: $e" } disconnected = true } } @@ -146,7 +146,7 @@ object SocketConnections { */ fun sendAnimation(animation: AnimationData, id: String) { if (!isDisconnected) { - Logger.trace("Animation to send: $animation") + Logger.trace { "Animation to send: $animation" } runBlocking { withTimeout(5000) { withContext(Dispatchers.IO) { @@ -161,9 +161,9 @@ object SocketConnections { else id ) ) - ?: Logger.debug("Could not send animation $id: Connection socket null") - if (animation.animation == Animation.ENDANIMATION) Logger.debug("Sent end of animation $id") - else Logger.debug("Sent animation $id") + ?: Logger.debug { "Could not send animation $id: Connection socket null" } + if (animation.animation == Animation.ENDANIMATION) Logger.debug { "Sent end of animation $id" } + else Logger.debug { "Sent animation $id" } } } } @@ -189,7 +189,7 @@ object SocketConnections { if (client != null) client.sendAnimation(animation, id) else connections.forEach { it.value.sendAnimation(animation, id) - Logger.trace("Sent animation to client on port ${it.key}") + Logger.trace { "Sent animation to client on port ${it.key}" } } } diff --git a/src/test/java/AnimatedLEDStripServerTest.kt b/src/test/java/AnimatedLEDStripServerTest.kt index 6171570..c32ebc3 100644 --- a/src/test/java/AnimatedLEDStripServerTest.kt +++ b/src/test/java/AnimatedLEDStripServerTest.kt @@ -27,16 +27,16 @@ import animatedledstrip.leds.emulated.EmulatedAnimatedLEDStrip import animatedledstrip.server.AnimatedLEDStripServer import animatedledstrip.server.SocketConnections import kotlinx.coroutines.* +import org.junit.Ignore import org.junit.Test -import org.pmw.tinylog.Configurator -import org.pmw.tinylog.Level +import org.tinylog.configuration.Configuration import java.io.ByteArrayInputStream class AnimatedLEDStripServerTest { init { SocketConnections.hostIP = "0.0.0.0" - Configurator.defaultConfig().level(Level.OFF).activate() + Configuration.set("level", "off") } val leds = EmulatedAnimatedLEDStrip(50) @@ -59,6 +59,7 @@ class AnimatedLEDStripServerTest { } @Test + @Ignore fun testLocalTerminalThread() = runBlocking { withTimeout(60000) { val stream = ByteArrayInputStream("q".toByteArray()) diff --git a/src/test/java/AnimationHandlerTest.kt b/src/test/java/AnimationHandlerTest.kt index b6ab6f5..e069cae 100644 --- a/src/test/java/AnimationHandlerTest.kt +++ b/src/test/java/AnimationHandlerTest.kt @@ -30,15 +30,14 @@ import animatedledstrip.server.AnimationHandler import animatedledstrip.server.SocketConnections import animatedledstrip.utils.delayBlocking import org.junit.Test -import org.pmw.tinylog.Configurator -import org.pmw.tinylog.Level +import org.tinylog.configuration.Configuration import kotlin.test.assertTrue class AnimationHandlerTest { init { - Configurator.defaultConfig().level(Level.OFF).activate() + Configuration.set("level", "off") SocketConnections.connections.clear() } diff --git a/src/test/java/SocketConnectionsTest.kt b/src/test/java/SocketConnectionsTest.kt index 64800be..58b72b1 100644 --- a/src/test/java/SocketConnectionsTest.kt +++ b/src/test/java/SocketConnectionsTest.kt @@ -28,9 +28,9 @@ import animatedledstrip.server.AnimatedLEDStripServer import animatedledstrip.server.SocketConnections import animatedledstrip.utils.delayBlocking import kotlinx.coroutines.* +import org.junit.Ignore import org.junit.Test -import org.pmw.tinylog.Configurator -import org.pmw.tinylog.Level +import org.tinylog.configuration.Configuration import java.io.BufferedInputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream @@ -40,7 +40,7 @@ import kotlin.test.assertTrue class SocketConnectionsTest { init { - Configurator.defaultConfig().level(Level.OFF).activate() + Configuration.set("level", "off") } @Test @@ -54,6 +54,7 @@ class SocketConnectionsTest { } @Test + @Ignore fun testOpenSocket() = runBlocking { withTimeout(60000) { val server = From fa0485c9890794091389308009878412b1cedd9a Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Thu, 12 Sep 2019 22:18:09 -0500 Subject: [PATCH 10/22] Start to add local command line --- .../animatedledstrip/cmdline/CommandLine.kt | 51 +++++++++++ .../server/AnimatedLEDStripServer.kt | 90 +++++++++---------- .../server/SocketConnections.kt | 40 +++++++-- .../server/SocketLogWriter.kt | 30 +++++++ .../services/org.tinylog.writers.Writer | 1 + src/main/resources/tinylog.properties | 3 + 6 files changed, 160 insertions(+), 55 deletions(-) create mode 100644 src/main/java/animatedledstrip/cmdline/CommandLine.kt create mode 100644 src/main/java/animatedledstrip/server/SocketLogWriter.kt create mode 100644 src/main/resources/META-INF/services/org.tinylog.writers.Writer create mode 100644 src/main/resources/tinylog.properties diff --git a/src/main/java/animatedledstrip/cmdline/CommandLine.kt b/src/main/java/animatedledstrip/cmdline/CommandLine.kt new file mode 100644 index 0000000..aba8c76 --- /dev/null +++ b/src/main/java/animatedledstrip/cmdline/CommandLine.kt @@ -0,0 +1,51 @@ +package animatedledstrip.cmdline + +import kotlinx.coroutines.* +import java.io.ObjectInputStream +import java.io.ObjectOutputStream +import java.net.InetSocketAddress +import java.net.Socket + +class CommandLine { + + private val socket = Socket() + + private var endCmdLine = false + + private var readerJob: Job? = null + + fun loop() { + println("Welcome to the AnimatedLEDStrip Server console") + while (!endCmdLine) { + try { + socket.connect(InetSocketAddress("localhost", 1118), 5000) + } catch (e: Exception) { + continue + } + println("Connected") + try { + val socOut = ObjectOutputStream(socket.getOutputStream()) + val socIn = ObjectInputStream(socket.getInputStream()) + readerJob = GlobalScope.launch { + withContext(Dispatchers.IO) { + while (!endCmdLine) { + println(socIn.readObject() as String? ?: continue) + } + } + } + + while (!endCmdLine) { + print("> ") + val str = readLine() ?: continue + socOut.writeObject(str) + when (str.toUpperCase()) { + "Q", "QUIT" -> endCmdLine = true + } + } + + } catch (e: Exception) { + readerJob?.cancel() + } + } + } +} \ No newline at end of file diff --git a/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt b/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt index bbe9575..09d5766 100644 --- a/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt +++ b/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt @@ -98,6 +98,7 @@ class AnimatedLEDStripServer( requireNotNull(it.toIntOrNull()) this.add(it.toInt()) } + this += 1118 // local port } private val rendersBeforeSave = @@ -143,58 +144,47 @@ class AnimatedLEDStripServer( running = false } - /* Local terminal thread */ - - @Suppress("EXPERIMENTAL_API_USAGE") - val localThread = newSingleThreadContext("Local Terminal") - - private fun startLocalTerminalReader() { - GlobalScope.launch(localThread) { - while (this@AnimatedLEDStripServer.running) { - Logger.trace("Local terminal waiting for input") - val strIn = readLine() ?: continue - Logger.trace("Read line") - val line = strIn.toUpperCase().split(" ") - when (line[0]) { - "QUIT", "Q", "EXIT" -> { - Logger.info("Shutting down server") - stop() - } - "DEBUG" -> { - setLoggingLevel(Level.DEBUG) - Logger.debug("Set logging level to debug") - } - "TRACE" -> { - setLoggingLevel(Level.TRACE) - Logger.trace("Set logging level to trace") - } - "INFO" -> { - setLoggingLevel(Level.INFO) - Logger.info("Set logging level to info") - } - "CLEAR" -> { - animationHandler.addAnimation(AnimationData().animation(Animation.COLOR)) - } - "SHOW" -> { - if (line.size > 1) Logger.info( - "${line[1]}: ${animationHandler.continuousAnimations[line[1]]?.params ?: "NOT FOUND"}" - ) - else Logger.info("Running Animations: ${animationHandler.continuousAnimations.keys}") - } - "END" -> { - if (line.size > 1) { - if (line[1].toUpperCase() == "ALL") { - val animations = animationHandler.continuousAnimations - animations.forEach { - animationHandler.endAnimation(it.value) - } - } else for (i in 1 until line.size) - animationHandler.endAnimation(animationHandler.continuousAnimations[line[i]]) - } else Logger.warn("Animation ID must be specified") - } - else -> Logger.warn("Not a valid command") + internal fun parseTextCommand(command: String) { + Logger.info { command } + val line = command.toUpperCase().split(" ") + return when (line[0]) { + "QUIT", "Q", "EXIT" -> { + Logger.info { "Shutting down server" } + stop() + } + "DEBUG" -> { + setLoggingLevel("debug") + Logger.debug { "Set logging level to debug" } + } + "TRACE" -> { + setLoggingLevel("trace") + Logger.trace { "Set logging level to trace" } + } + "INFO" -> { + setLoggingLevel("info") + Logger.info { "Set logging level to info" } + } + "CLEAR" -> { + animationHandler.addAnimation(AnimationData().animation(Animation.COLOR)) + } + "SHOW" -> { + if (line.size > 1) Logger.info { + "${line[1]}: ${animationHandler.continuousAnimations[line[1]]?.params ?: "NOT FOUND"}" } + else Logger.info { "Running Animations: ${animationHandler.continuousAnimations.keys}" } + } + "END" -> { + if (line.size > 1) { + if (line[1].toUpperCase() == "ALL") { + val animations = animationHandler.continuousAnimations + animations.forEach { + animationHandler.endAnimation(it.value) + } + } else for (i in 1 until line.size) + animationHandler.endAnimation(animationHandler.continuousAnimations[line[i]]) + } else Logger.warn { "Animation ID must be specified" } } + else -> Logger.warn { "Not a valid command" } } } diff --git a/src/main/java/animatedledstrip/server/SocketConnections.kt b/src/main/java/animatedledstrip/server/SocketConnections.kt index 2fbc047..5186774 100644 --- a/src/main/java/animatedledstrip/server/SocketConnections.kt +++ b/src/main/java/animatedledstrip/server/SocketConnections.kt @@ -47,6 +47,8 @@ object SocketConnections { */ val connections = mutableMapOf() + var localConnection: Connection? = null + /** * Initialize a new connection. Creates a Connection instance with the * specified port, then adds the port and Connection instance to @@ -57,7 +59,8 @@ object SocketConnections { */ fun add(port: Int, server: AnimatedLEDStripServer<*>): Connection { val connection = Connection(port, server) - connections[port] = connection + if (port == 1118) localConnection = connection + else connections[port] = connection return connection } @@ -118,9 +121,15 @@ object SocketConnections { while (!disconnected) { Logger.trace { "Waiting for input" } try { - input = socIn.readObject() as AnimationData - Logger.trace("Input received") - server.animationHandler.addAnimation(input) + input = when (port) { + 1118 -> socIn.readObject() as String + else -> socIn.readObject() as AnimationData + } + Logger.trace { "Input received" } + when (input) { + is AnimationData -> server.animationHandler.addAnimation(input) + is String -> server.parseTextCommand(input) + } } catch (e: ClassCastException) { Logger.error { "Could not cast input to ${if (port == 1118) "String" else "AnimationData"}" } continue @@ -139,12 +148,14 @@ object SocketConnections { } /** - * Send animation data to the GUI along with an ID + * Send animation data to the client along with an ID. + * Does not work for port 1118 (local connection). * * @param animation An AnimationData containing data about the animation * @param id The ID for the animation */ fun sendAnimation(animation: AnimationData, id: String) { + check(port != 1118) { "Cannot send animation to local port" } if (!isDisconnected) { Logger.trace { "Animation to send: $animation" } runBlocking { @@ -170,6 +181,25 @@ object SocketConnections { } } + /** + * Send a string to the local port. + * Only works for a connection with port 1118 (local connection) + */ + fun sendString(str: String) { + check(port == 1118) { "Cannot send string to non-local port" } + if (!isDisconnected) { + Logger.trace { "String to send: $str" } + runBlocking { + withTimeout(5000) { + withContext(Dispatchers.IO) { + socOut?.writeObject(str) + ?: Logger.debug { "Could not send string $str: Connection socket null" } + } + } + } + } + } + override fun toString(): String { return "Connection@${serverSocket.inetAddress.toString().removePrefix("/")}:$port" diff --git a/src/main/java/animatedledstrip/server/SocketLogWriter.kt b/src/main/java/animatedledstrip/server/SocketLogWriter.kt new file mode 100644 index 0000000..205467c --- /dev/null +++ b/src/main/java/animatedledstrip/server/SocketLogWriter.kt @@ -0,0 +1,30 @@ +package animatedledstrip.server + +import org.tinylog.Logger +import org.tinylog.core.LogEntry +import org.tinylog.core.LogEntryValue +import org.tinylog.writers.AbstractFormatPatternWriter + +class SocketLogWriter(properties: Map) : AbstractFormatPatternWriter(properties) { + + val delimiter = properties.getOrDefault("delimiter", ":") + + override fun getRequiredLogEntryValues(): MutableSet { + return mutableSetOf(LogEntryValue.LEVEL, LogEntryValue.MESSAGE) + } + + override fun write(log: LogEntry?) { + Logger.debug { log?.message } + SocketConnections.localConnection?.sendString( + "${log?.level.toString()}$delimiter".padEnd(8, ' ') + + "${log?.message}" + ) + } + + override fun flush() { + } + + override fun close() { + } + +} \ No newline at end of file diff --git a/src/main/resources/META-INF/services/org.tinylog.writers.Writer b/src/main/resources/META-INF/services/org.tinylog.writers.Writer new file mode 100644 index 0000000..ceff9d1 --- /dev/null +++ b/src/main/resources/META-INF/services/org.tinylog.writers.Writer @@ -0,0 +1 @@ +animatedledstrip.server.SocketLogWriter \ No newline at end of file diff --git a/src/main/resources/tinylog.properties b/src/main/resources/tinylog.properties new file mode 100644 index 0000000..efeae32 --- /dev/null +++ b/src/main/resources/tinylog.properties @@ -0,0 +1,3 @@ +writer1 = console + +writer2 = socket log \ No newline at end of file From 96e32d72975962441bdc6f0abc3a92fd86d19fce Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Thu, 12 Sep 2019 23:26:59 -0500 Subject: [PATCH 11/22] Add socket logger --- .../server/AnimatedLEDStripServer.kt | 31 +++++-------------- .../{SocketLogWriter.kt => SocketWriter.kt} | 4 +-- .../services/org.tinylog.writers.Writer | 2 +- src/main/resources/tinylog.properties | 3 +- 4 files changed, 13 insertions(+), 27 deletions(-) rename src/main/java/animatedledstrip/server/{SocketLogWriter.kt => SocketWriter.kt} (81%) diff --git a/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt b/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt index 09d5766..04b12ec 100644 --- a/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt +++ b/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt @@ -57,14 +57,6 @@ class AnimatedLEDStripServer( private var outputFileName: String? = cmdline.getOptionValue("o") - private val properties = Properties().apply { - try { - load(FileInputStream(propertyFileName)) - } catch (e: FileNotFoundException) { - Logger.warn { "File $propertyFileName not found" } - } - } - /* Set logging levels based on command line */ init { val loggingPattern = @@ -82,6 +74,13 @@ class AnimatedLEDStripServer( Configuration.set("level", loggingLevel) Configuration.set("format", loggingPattern) } + private val properties = Properties().apply { + try { + load(FileInputStream(propertyFileName)) + } catch (e: FileNotFoundException) { + Logger.warn { "File $propertyFileName not found" } + } + } /* Arguments for creating the AnimatedLEDStrip instance */ @@ -152,18 +151,6 @@ class AnimatedLEDStripServer( Logger.info { "Shutting down server" } stop() } - "DEBUG" -> { - setLoggingLevel("debug") - Logger.debug { "Set logging level to debug" } - } - "TRACE" -> { - setLoggingLevel("trace") - Logger.trace { "Set logging level to trace" } - } - "INFO" -> { - setLoggingLevel("info") - Logger.info { "Set logging level to info" } - } "CLEAR" -> { animationHandler.addAnimation(AnimationData().animation(Animation.COLOR)) } @@ -190,9 +177,7 @@ class AnimatedLEDStripServer( /* Helper methods */ - fun setLoggingLevel(level: String) { - Configuration.set("level", level) - } + } \ No newline at end of file diff --git a/src/main/java/animatedledstrip/server/SocketLogWriter.kt b/src/main/java/animatedledstrip/server/SocketWriter.kt similarity index 81% rename from src/main/java/animatedledstrip/server/SocketLogWriter.kt rename to src/main/java/animatedledstrip/server/SocketWriter.kt index 205467c..7425c25 100644 --- a/src/main/java/animatedledstrip/server/SocketLogWriter.kt +++ b/src/main/java/animatedledstrip/server/SocketWriter.kt @@ -3,9 +3,9 @@ package animatedledstrip.server import org.tinylog.Logger import org.tinylog.core.LogEntry import org.tinylog.core.LogEntryValue -import org.tinylog.writers.AbstractFormatPatternWriter +import org.tinylog.writers.Writer -class SocketLogWriter(properties: Map) : AbstractFormatPatternWriter(properties) { +class SocketWriter(properties: Map) : Writer { val delimiter = properties.getOrDefault("delimiter", ":") diff --git a/src/main/resources/META-INF/services/org.tinylog.writers.Writer b/src/main/resources/META-INF/services/org.tinylog.writers.Writer index ceff9d1..ec529fc 100644 --- a/src/main/resources/META-INF/services/org.tinylog.writers.Writer +++ b/src/main/resources/META-INF/services/org.tinylog.writers.Writer @@ -1 +1 @@ -animatedledstrip.server.SocketLogWriter \ No newline at end of file +animatedledstrip.server.SocketWriter \ No newline at end of file diff --git a/src/main/resources/tinylog.properties b/src/main/resources/tinylog.properties index efeae32..ff3fbc2 100644 --- a/src/main/resources/tinylog.properties +++ b/src/main/resources/tinylog.properties @@ -1,3 +1,4 @@ writer1 = console +writer1.format = {{level}:|min-size=8} {message} -writer2 = socket log \ No newline at end of file +writer2 = socket \ No newline at end of file From af834341b7228c629a57b0a8ac7e13b246cf1de9 Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Thu, 12 Sep 2019 23:40:17 -0500 Subject: [PATCH 12/22] Update tinylog.properties --- src/main/resources/tinylog.properties | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/resources/tinylog.properties b/src/main/resources/tinylog.properties index ff3fbc2..c118d78 100644 --- a/src/main/resources/tinylog.properties +++ b/src/main/resources/tinylog.properties @@ -1,4 +1,3 @@ -writer1 = console -writer1.format = {{level}:|min-size=8} {message} - -writer2 = socket \ No newline at end of file +writer2 = socket +writer2.format = {{level}:|min-size=8} {message} +writer2.level = info \ No newline at end of file From 5b43fe4d7a95bfaab0edf6a9a9601760a709f780 Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Fri, 13 Sep 2019 10:27:40 -0500 Subject: [PATCH 13/22] Use java.util.map for SocketWriter --- .../java/animatedledstrip/server/AnimatedLEDStripServer.kt | 2 +- src/main/java/animatedledstrip/server/SocketConnections.kt | 3 ++- src/main/java/animatedledstrip/server/SocketWriter.kt | 6 +++--- src/test/java/SocketConnectionsTest.kt | 2 -- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt b/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt index 04b12ec..34f49cf 100644 --- a/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt +++ b/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt @@ -97,7 +97,7 @@ class AnimatedLEDStripServer( requireNotNull(it.toIntOrNull()) this.add(it.toInt()) } - this += 1118 // local port + if (!emulated) this += 1118 // local port } private val rendersBeforeSave = diff --git a/src/main/java/animatedledstrip/server/SocketConnections.kt b/src/main/java/animatedledstrip/server/SocketConnections.kt index 5186774..33c3c51 100644 --- a/src/main/java/animatedledstrip/server/SocketConnections.kt +++ b/src/main/java/animatedledstrip/server/SocketConnections.kt @@ -186,9 +186,10 @@ object SocketConnections { * Only works for a connection with port 1118 (local connection) */ fun sendString(str: String) { + println("Send") check(port == 1118) { "Cannot send string to non-local port" } if (!isDisconnected) { - Logger.trace { "String to send: $str" } + Logger.info { "String to send: $str" } runBlocking { withTimeout(5000) { withContext(Dispatchers.IO) { diff --git a/src/main/java/animatedledstrip/server/SocketWriter.kt b/src/main/java/animatedledstrip/server/SocketWriter.kt index 7425c25..1493fcb 100644 --- a/src/main/java/animatedledstrip/server/SocketWriter.kt +++ b/src/main/java/animatedledstrip/server/SocketWriter.kt @@ -1,11 +1,11 @@ package animatedledstrip.server -import org.tinylog.Logger import org.tinylog.core.LogEntry import org.tinylog.core.LogEntryValue import org.tinylog.writers.Writer -class SocketWriter(properties: Map) : Writer { +@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") +class SocketWriter(properties: java.util.Map) : Writer { val delimiter = properties.getOrDefault("delimiter", ":") @@ -14,7 +14,7 @@ class SocketWriter(properties: Map) : Writer { } override fun write(log: LogEntry?) { - Logger.debug { log?.message } + println(log?.message) SocketConnections.localConnection?.sendString( "${log?.level.toString()}$delimiter".padEnd(8, ' ') + "${log?.message}" diff --git a/src/test/java/SocketConnectionsTest.kt b/src/test/java/SocketConnectionsTest.kt index 58b72b1..a9c6474 100644 --- a/src/test/java/SocketConnectionsTest.kt +++ b/src/test/java/SocketConnectionsTest.kt @@ -28,7 +28,6 @@ import animatedledstrip.server.AnimatedLEDStripServer import animatedledstrip.server.SocketConnections import animatedledstrip.utils.delayBlocking import kotlinx.coroutines.* -import org.junit.Ignore import org.junit.Test import org.tinylog.configuration.Configuration import java.io.BufferedInputStream @@ -54,7 +53,6 @@ class SocketConnectionsTest { } @Test - @Ignore fun testOpenSocket() = runBlocking { withTimeout(60000) { val server = From 2b9bbb3e50a9cf5abf6a6fd2b22b1bc94b19afe9 Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Fri, 13 Sep 2019 15:21:48 -0500 Subject: [PATCH 14/22] Update travis config --- .travis.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 18929a1..b29687a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ branches: stages: - name: test - name: deploy - if: branch = master AND type != pull_request + if: (branch = master OR branch =~ /^v.*/) AND type != pull_request jobs: include: @@ -34,13 +34,9 @@ jobs: keep-history: true verbose: true local_dir: ./dokka - on: - branch: master - stage: deploy install: - "" deploy: - provider: script script: mvn deploy --settings .maven.xml -DskipTests=true -B - on: - branch: master From da73bf8fd9b8ab0022f83419333a1a621d109f6f Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Fri, 13 Sep 2019 17:14:46 -0500 Subject: [PATCH 15/22] Speed up travis build --- .travis.yml | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index b29687a..4f24ffb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,10 @@ language: java jdk: openjdk9 +cache: + directories: + - $HOME/.m2 + before_install: - echo $GPG_SECRET_KEYS | base64 --decode | $GPG_EXECUTABLE --import - echo $GPG_OWNERTRUST | base64 --decode | $GPG_EXECUTABLE --import-ownertrust @@ -20,23 +24,29 @@ stages: jobs: include: - stage: test - install: "" + install: skip after_success: bash <(curl -s https://codecov.io/bash) - stage: deploy - install: "" - test: "" + script: skip + install: skip deploy: - provider: script script: mvn --settings .maven.xml site -DskipTests=true -B && git add dokka + on: + all_branches: true - provider: pages skip-cleanup: true github-token: $GITHUB_TOKEN keep-history: true verbose: true local_dir: ./dokka + on: + all_branches: true - stage: deploy - install: - - "" + script: skip + install: skip deploy: - provider: script script: mvn deploy --settings .maven.xml -DskipTests=true -B + on: + all_branches: true \ No newline at end of file From 500ece824a506105c3681d3080f5f7b1e2b8746f Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Sat, 14 Sep 2019 16:23:41 -0500 Subject: [PATCH 16/22] Fix sending animations on connection --- src/main/java/animatedledstrip/cmdline/CommandLine.kt | 2 +- .../java/animatedledstrip/server/SocketConnections.kt | 9 ++++----- src/main/java/animatedledstrip/server/SocketWriter.kt | 1 - src/main/resources/tinylog.properties | 4 ++++ 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/animatedledstrip/cmdline/CommandLine.kt b/src/main/java/animatedledstrip/cmdline/CommandLine.kt index aba8c76..f318796 100644 --- a/src/main/java/animatedledstrip/cmdline/CommandLine.kt +++ b/src/main/java/animatedledstrip/cmdline/CommandLine.kt @@ -29,7 +29,7 @@ class CommandLine { readerJob = GlobalScope.launch { withContext(Dispatchers.IO) { while (!endCmdLine) { - println(socIn.readObject() as String? ?: continue) + println(socIn.readObject() as String? ?: "ERROR") } } } diff --git a/src/main/java/animatedledstrip/server/SocketConnections.kt b/src/main/java/animatedledstrip/server/SocketConnections.kt index 33c3c51..a18affc 100644 --- a/src/main/java/animatedledstrip/server/SocketConnections.kt +++ b/src/main/java/animatedledstrip/server/SocketConnections.kt @@ -110,13 +110,14 @@ object SocketConnections { val socIn = ObjectInputStream(clientSocket!!.getInputStream()) Logger.trace { "Initializing output stream" } socOut = ObjectOutputStream(clientSocket!!.getOutputStream()) + Logger.info { "Connection on port $port Established" } + disconnected = false Logger.debug { "Sending currently running animations to GUI" } // Send all current running continuous animations to newly connected client server.animationHandler.continuousAnimations.forEach { + Logger.info { "Sending ${it.value}"} it.value.sendStartAnimation(this@Connection) } - disconnected = false - Logger.info { "Connection on port $port Established" } var input: Any? while (!disconnected) { Logger.trace { "Waiting for input" } @@ -186,15 +187,13 @@ object SocketConnections { * Only works for a connection with port 1118 (local connection) */ fun sendString(str: String) { - println("Send") check(port == 1118) { "Cannot send string to non-local port" } if (!isDisconnected) { - Logger.info { "String to send: $str" } runBlocking { withTimeout(5000) { withContext(Dispatchers.IO) { socOut?.writeObject(str) - ?: Logger.debug { "Could not send string $str: Connection socket null" } +// ?: Logger.debug { "Could not send string $str: Connection socket null" } } } } diff --git a/src/main/java/animatedledstrip/server/SocketWriter.kt b/src/main/java/animatedledstrip/server/SocketWriter.kt index 1493fcb..accca5b 100644 --- a/src/main/java/animatedledstrip/server/SocketWriter.kt +++ b/src/main/java/animatedledstrip/server/SocketWriter.kt @@ -14,7 +14,6 @@ class SocketWriter(properties: java.util.Map) : Writer { } override fun write(log: LogEntry?) { - println(log?.message) SocketConnections.localConnection?.sendString( "${log?.level.toString()}$delimiter".padEnd(8, ' ') + "${log?.message}" diff --git a/src/main/resources/tinylog.properties b/src/main/resources/tinylog.properties index c118d78..9d18946 100644 --- a/src/main/resources/tinylog.properties +++ b/src/main/resources/tinylog.properties @@ -1,3 +1,7 @@ +writer = console +writer.format = {{level}:|min-size=8} {message} +writer.level = info + writer2 = socket writer2.format = {{level}:|min-size=8} {message} writer2.level = info \ No newline at end of file From a854652ef2c9744c0602f28c3946af26b3659630 Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Sat, 14 Sep 2019 16:33:48 -0500 Subject: [PATCH 17/22] Improve command line --- .../java/animatedledstrip/cmdline/CommandLine.kt | 12 +++++++++--- .../server/AnimatedLEDStripServer.kt | 10 ++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/animatedledstrip/cmdline/CommandLine.kt b/src/main/java/animatedledstrip/cmdline/CommandLine.kt index f318796..ef0dd1d 100644 --- a/src/main/java/animatedledstrip/cmdline/CommandLine.kt +++ b/src/main/java/animatedledstrip/cmdline/CommandLine.kt @@ -5,6 +5,7 @@ import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.net.InetSocketAddress import java.net.Socket +import kotlin.system.exitProcess class CommandLine { @@ -34,12 +35,17 @@ class CommandLine { } } - while (!endCmdLine) { + input@ while (!endCmdLine) { print("> ") val str = readLine() ?: continue - socOut.writeObject(str) when (str.toUpperCase()) { - "Q", "QUIT" -> endCmdLine = true + "" -> continue@input + "EXIT" -> exitProcess(0) + "Q", "QUIT" -> { + socOut.writeObject(str) + exitProcess(0) + } + else -> socOut.writeObject(str) } } diff --git a/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt b/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt index 34f49cf..1a8250a 100644 --- a/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt +++ b/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt @@ -144,10 +144,9 @@ class AnimatedLEDStripServer( } internal fun parseTextCommand(command: String) { - Logger.info { command } val line = command.toUpperCase().split(" ") return when (line[0]) { - "QUIT", "Q", "EXIT" -> { + "QUIT", "Q" -> { Logger.info { "Shutting down server" } stop() } @@ -171,13 +170,8 @@ class AnimatedLEDStripServer( animationHandler.endAnimation(animationHandler.continuousAnimations[line[i]]) } else Logger.warn { "Animation ID must be specified" } } - else -> Logger.warn { "Not a valid command" } + else -> Logger.warn { "$command is not a valid command" } } } - /* Helper methods */ - - - - } \ No newline at end of file From a5e1a69ec35fbb71c00986be32cb0eef24565f9d Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Sat, 14 Sep 2019 16:36:35 -0500 Subject: [PATCH 18/22] Limit command line exceptions --- .../animatedledstrip/cmdline/CommandLine.kt | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/main/java/animatedledstrip/cmdline/CommandLine.kt b/src/main/java/animatedledstrip/cmdline/CommandLine.kt index ef0dd1d..9c3c7eb 100644 --- a/src/main/java/animatedledstrip/cmdline/CommandLine.kt +++ b/src/main/java/animatedledstrip/cmdline/CommandLine.kt @@ -1,10 +1,12 @@ package animatedledstrip.cmdline import kotlinx.coroutines.* +import java.io.EOFException import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.net.InetSocketAddress import java.net.Socket +import java.net.SocketException import kotlin.system.exitProcess class CommandLine { @@ -29,8 +31,14 @@ class CommandLine { val socIn = ObjectInputStream(socket.getInputStream()) readerJob = GlobalScope.launch { withContext(Dispatchers.IO) { - while (!endCmdLine) { - println(socIn.readObject() as String? ?: "ERROR") + try { + while (!endCmdLine) { + println(socIn.readObject() as String? ?: "ERROR") + } + } catch (e: SocketException) { + println("Connection lost: $e") + } catch (e: EOFException) { + println("Connection lost: $e") } } } @@ -49,7 +57,11 @@ class CommandLine { } } - } catch (e: Exception) { + } catch (e: SocketException) { + println("Connection lost: $e") + readerJob?.cancel() + } catch (e: EOFException) { + println("Connection lost: $e") readerJob?.cancel() } } From d856a30a43603173896b6990f6055bde1f979ccc Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Sat, 14 Sep 2019 17:18:42 -0500 Subject: [PATCH 19/22] Rename disconnected to connected and remove isDisconnected --- .../server/SocketConnections.kt | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/main/java/animatedledstrip/server/SocketConnections.kt b/src/main/java/animatedledstrip/server/SocketConnections.kt index a18affc..3bf8359 100644 --- a/src/main/java/animatedledstrip/server/SocketConnections.kt +++ b/src/main/java/animatedledstrip/server/SocketConnections.kt @@ -74,13 +74,11 @@ object SocketConnections { if (hostIP == null) null else InetAddress.getByName(hostIP) ) var clientSocket: Socket? = null - private var disconnected = true + var connected = false + private set private var socOut: ObjectOutputStream? = null var textBased = false - val isDisconnected: Boolean - get() = disconnected - /** * Open the connection */ @@ -111,7 +109,7 @@ object SocketConnections { Logger.trace { "Initializing output stream" } socOut = ObjectOutputStream(clientSocket!!.getOutputStream()) Logger.info { "Connection on port $port Established" } - disconnected = false + connected = true Logger.debug { "Sending currently running animations to GUI" } // Send all current running continuous animations to newly connected client server.animationHandler.continuousAnimations.forEach { @@ -119,7 +117,7 @@ object SocketConnections { it.value.sendStartAnimation(this@Connection) } var input: Any? - while (!disconnected) { + while (connected) { Logger.trace { "Waiting for input" } try { input = when (port) { @@ -139,10 +137,10 @@ object SocketConnections { } catch (e: SocketException) { // Catch disconnections Logger.warn { "Connection on port $port ${if (port == 1118) "(Local) " else ""}Lost: $e" } - disconnected = true + connected = false } catch (e: EOFException) { Logger.warn { "Connection on port $port ${if (port == 1118) "(Local) " else ""}Lost: $e" } - disconnected = true + connected = false } } } @@ -157,7 +155,7 @@ object SocketConnections { */ fun sendAnimation(animation: AnimationData, id: String) { check(port != 1118) { "Cannot send animation to local port" } - if (!isDisconnected) { + if (connected) { Logger.trace { "Animation to send: $animation" } runBlocking { withTimeout(5000) { @@ -188,7 +186,7 @@ object SocketConnections { */ fun sendString(str: String) { check(port == 1118) { "Cannot send string to non-local port" } - if (!isDisconnected) { + if (connected) { runBlocking { withTimeout(5000) { withContext(Dispatchers.IO) { From f9d9d4b964ff2926144ffdfa997ea692219b19c4 Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Sun, 15 Sep 2019 14:58:19 -0500 Subject: [PATCH 20/22] Save running animations to files to read in on restart --- .../server/AnimatedLEDStripServer.kt | 5 +++++ .../server/AnimationHandler.kt | 18 ++++++++++++++++ .../server/ContinuousRunAnimation.kt | 21 ++++++++++++++++--- .../server/SocketConnections.kt | 1 - 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt b/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt index 1a8250a..64eaebc 100644 --- a/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt +++ b/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt @@ -34,6 +34,7 @@ import animatedledstrip.utils.delayBlocking import org.apache.commons.cli.DefaultParser import org.tinylog.Logger import org.tinylog.configuration.Configuration +import java.io.File import java.io.FileInputStream import java.io.FileNotFoundException import java.util.* @@ -126,6 +127,10 @@ class AnimatedLEDStripServer( /* Start and stop methods */ fun start(): AnimatedLEDStripServer { + val dir = File(".animations") + if (!dir.isDirectory) + dir.mkdirs() + running = true Logger.debug { "Ports: $ports" } ports.forEach { diff --git a/src/main/java/animatedledstrip/server/AnimationHandler.kt b/src/main/java/animatedledstrip/server/AnimationHandler.kt index c3b6720..88962e9 100644 --- a/src/main/java/animatedledstrip/server/AnimationHandler.kt +++ b/src/main/java/animatedledstrip/server/AnimationHandler.kt @@ -31,6 +31,9 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.newFixedThreadPoolContext import org.tinylog.Logger +import java.io.File +import java.io.FileInputStream +import java.io.ObjectInputStream import java.lang.Math.random @@ -52,6 +55,21 @@ internal class AnimationHandler(private val leds: AnimatedLEDStrip, threadCount: val continuousAnimations = mutableMapOf() + init { + GlobalScope.launch { + File(".animations/").walk().forEach { + if (!it.isDirectory && it.name.endsWith(".anim")) try { + ObjectInputStream(FileInputStream(it)).apply { + val obj = readObject() as AnimationData + addAnimation(obj) + close() + } + } catch (e: ClassCastException) { + } + } + } + } + /** * Adds a new animation. * diff --git a/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt b/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt index 44b36a6..181827d 100644 --- a/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt +++ b/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt @@ -26,10 +26,13 @@ package animatedledstrip.server import animatedledstrip.animationutils.Animation import animatedledstrip.animationutils.AnimationData import animatedledstrip.leds.AnimatedLEDStrip -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.Job -import kotlinx.coroutines.launch +import kotlinx.coroutines.* import org.tinylog.Logger +import java.io.File +import java.io.FileOutputStream +import java.io.ObjectOutputStream +import java.nio.file.Files +import java.nio.file.Paths /** * Class for running an animation that repeats until stopped. @@ -52,6 +55,8 @@ internal class ContinuousRunAnimation( private var job: Job? = null + private val fileName = "$id.anim" + init { sendStartAnimation() // Send animation to GUI @@ -63,6 +68,14 @@ internal class ContinuousRunAnimation( */ fun runAnimation() { job = GlobalScope.launch(handler.animationThreadPool) { + launch { + withContext(Dispatchers.IO) { + ObjectOutputStream(FileOutputStream(".animations/$fileName")).apply { + writeObject(params) + close() + } + } + } Logger.trace { "params: $params" } while (continueAnimation) leds.run(params) sendEndAnimation() @@ -78,6 +91,8 @@ internal class ContinuousRunAnimation( Logger.debug { "Animation $id ending" } if (continueAnimation) continueAnimation = false else job?.cancel() + if (File(".animations/$id").exists()) + Files.delete(Paths.get(".animations/$fileName")) } diff --git a/src/main/java/animatedledstrip/server/SocketConnections.kt b/src/main/java/animatedledstrip/server/SocketConnections.kt index 3bf8359..22dfc9a 100644 --- a/src/main/java/animatedledstrip/server/SocketConnections.kt +++ b/src/main/java/animatedledstrip/server/SocketConnections.kt @@ -77,7 +77,6 @@ object SocketConnections { var connected = false private set private var socOut: ObjectOutputStream? = null - var textBased = false /** * Open the connection From 58db48e5ac93dd84bf82372d75a3ce99fce7baa9 Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Thu, 19 Sep 2019 12:34:26 -0500 Subject: [PATCH 21/22] Revert to tinylog 1.3 --- .../animatedledstrip/cmdline/CommandLine.kt | 1 - .../server/AnimatedLEDStripServer.kt | 51 ++++++++++++++----- .../server/AnimationHandler.kt | 17 ++++--- .../server/ContinuousRunAnimation.kt | 31 +++++------ .../animatedledstrip/server/GlobalVars.kt | 1 + .../server/SocketConnections.kt | 2 +- .../animatedledstrip/server/SocketWriter.kt | 22 +++++--- .../services/org.tinylog.writers.Writer | 1 - src/main/resources/tinylog.properties | 12 ++--- src/test/java/AnimatedLEDStripServerTest.kt | 2 - src/test/java/AnimationHandlerTest.kt | 2 - src/test/java/SocketConnectionsTest.kt | 5 -- src/test/resources/tinylog.properties | 5 ++ 13 files changed, 87 insertions(+), 65 deletions(-) delete mode 100644 src/main/resources/META-INF/services/org.tinylog.writers.Writer create mode 100644 src/test/resources/tinylog.properties diff --git a/src/main/java/animatedledstrip/cmdline/CommandLine.kt b/src/main/java/animatedledstrip/cmdline/CommandLine.kt index 9c3c7eb..f09e590 100644 --- a/src/main/java/animatedledstrip/cmdline/CommandLine.kt +++ b/src/main/java/animatedledstrip/cmdline/CommandLine.kt @@ -44,7 +44,6 @@ class CommandLine { } input@ while (!endCmdLine) { - print("> ") val str = readLine() ?: continue when (str.toUpperCase()) { "" -> continue@input diff --git a/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt b/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt index 64eaebc..3393f01 100644 --- a/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt +++ b/src/main/java/animatedledstrip/server/AnimatedLEDStripServer.kt @@ -32,8 +32,9 @@ import animatedledstrip.leds.AnimatedLEDStrip import animatedledstrip.leds.emulated.EmulatedAnimatedLEDStrip import animatedledstrip.utils.delayBlocking import org.apache.commons.cli.DefaultParser -import org.tinylog.Logger -import org.tinylog.configuration.Configuration +import org.pmw.tinylog.Configurator +import org.pmw.tinylog.Level +import org.pmw.tinylog.Logger import java.io.File import java.io.FileInputStream import java.io.FileNotFoundException @@ -66,16 +67,19 @@ class AnimatedLEDStripServer( val loggingLevel = when { - cmdline.hasOption("t") -> "trace" - cmdline.hasOption("d") -> "debug" - cmdline.hasOption("q") -> "off" - else -> "info" + cmdline.hasOption("t") -> Level.TRACE + cmdline.hasOption("d") -> Level.DEBUG + cmdline.hasOption("q") -> Level.OFF + else -> Level.INFO } - Configuration.set("level", loggingLevel) - Configuration.set("format", loggingPattern) + Configurator.defaultConfig().formatPattern(loggingPattern).level(loggingLevel).addWriter(SocketWriter()) + .activate() + + } - private val properties = Properties().apply { + + private val properties: Properties? = Properties().apply { try { load(FileInputStream(propertyFileName)) } catch (e: FileNotFoundException) { @@ -87,14 +91,14 @@ class AnimatedLEDStripServer( private val emulated: Boolean = cmdline.hasOption("e") || cmdline.hasOption("E") - private val numLEDs: Int = properties.getProperty("numLEDs", "240").toInt() + private val numLEDs: Int = properties?.getProperty("numLEDs", "240")?.toInt() ?: 240 - private val pin: Int = properties.getProperty("pin", "12").toInt() + private val pin: Int = properties?.getProperty("pin", "12")?.toInt() ?: 12 private val imageDebuggingEnabled: Boolean = cmdline.hasOption("i") private val ports = mutableListOf().apply { - properties.getProperty("ports")?.split(' ')?.forEach { + properties?.getProperty("ports")?.split(' ')?.forEach { requireNotNull(it.toIntOrNull()) this.add(it.toInt()) } @@ -102,7 +106,7 @@ class AnimatedLEDStripServer( } private val rendersBeforeSave = - properties.getProperty("renders")?.toIntOrNull() ?: cmdline.getOptionValue("r")?.toIntOrNull() ?: 1000 + properties?.getProperty("renders")?.toIntOrNull() ?: cmdline.getOptionValue("r")?.toIntOrNull() ?: 1000 private val leds = when (emulated) { false -> ledClass.primaryConstructor!!.call( @@ -119,7 +123,10 @@ class AnimatedLEDStripServer( ) } - internal val animationHandler = AnimationHandler(leds) + private val persistAnimations = + properties?.getProperty("persist", "false")?.toBoolean() ?: cmdline.hasOption("P") + + internal val animationHandler = AnimationHandler(leds, persistAnimations = persistAnimations) var testAnimation: AnimationData = AnimationData().animation(Animation.COLOR).color(CCBlue) @@ -155,6 +162,18 @@ class AnimatedLEDStripServer( Logger.info { "Shutting down server" } stop() } + "DEBUG" -> { + setLoggingLevel(Level.DEBUG) + Logger.debug("Set logging level to debug") + } + "TRACE" -> { + setLoggingLevel(Level.TRACE) + Logger.trace("Set logging level to trace") + } + "INFO" -> { + setLoggingLevel(Level.INFO) + Logger.info("Set logging level to info") + } "CLEAR" -> { animationHandler.addAnimation(AnimationData().animation(Animation.COLOR)) } @@ -179,4 +198,8 @@ class AnimatedLEDStripServer( } } + private fun setLoggingLevel(level: Level) { + Configurator.currentConfig().level(level).activate() + } + } \ No newline at end of file diff --git a/src/main/java/animatedledstrip/server/AnimationHandler.kt b/src/main/java/animatedledstrip/server/AnimationHandler.kt index 88962e9..bd17429 100644 --- a/src/main/java/animatedledstrip/server/AnimationHandler.kt +++ b/src/main/java/animatedledstrip/server/AnimationHandler.kt @@ -30,9 +30,10 @@ import animatedledstrip.leds.AnimatedLEDStrip import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.newFixedThreadPoolContext -import org.tinylog.Logger +import org.pmw.tinylog.Logger import java.io.File import java.io.FileInputStream +import java.io.InvalidClassException import java.io.ObjectInputStream import java.lang.Math.random @@ -41,7 +42,11 @@ import java.lang.Math.random * An object that creates ContinuousRunAnimation instances for animations and * keeps track of currently running animations. */ -internal class AnimationHandler(private val leds: AnimatedLEDStrip, threadCount: Int = 100) { +internal class AnimationHandler( + private val leds: AnimatedLEDStrip, + threadCount: Int = 100, + internal val persistAnimations: Boolean = false +) { @Suppress("EXPERIMENTAL_API_USAGE") val animationThreadPool = newFixedThreadPoolContext(threadCount, "AnimationThreads") @@ -65,6 +70,9 @@ internal class AnimationHandler(private val leds: AnimatedLEDStrip, threadCount: close() } } catch (e: ClassCastException) { + it.delete() + } catch (e: InvalidClassException) { + it.delete() } } } @@ -97,7 +105,6 @@ internal class AnimationHandler(private val leds: AnimatedLEDStrip, threadCount: /* Animations that can be run repeatedly */ false -> { if (params.continuous) { - Logger.trace { "Calling Continuous Animation" } val id = (random() * 100000000).toInt().toString() continuousAnimations[id] = ContinuousRunAnimation(id, params, leds, this) @@ -112,17 +119,13 @@ internal class AnimationHandler(private val leds: AnimatedLEDStrip, threadCount: private fun singleRunAnimation(params: AnimationData) { GlobalScope.launch(animationThreadPool) { - Logger.trace { "Calling Single Run Animation" } leds.run(params) - Logger.trace { "Single Run Animation on ${Thread.currentThread().name} complete" } } } fun endAnimation(params: AnimationData?) { - Logger.debug { "Ending an animation" } continuousAnimations[params?.id ?: "NONE"]?.endAnimation() // End animation ?: run { Logger.warn { "Animation ${params?.id} not running" }; return } -// continuousAnimations.remove(params?.id) // Remove it from the continuousAnimations map } fun endAnimation(animation: ContinuousRunAnimation?) { diff --git a/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt b/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt index 181827d..1fbd4c8 100644 --- a/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt +++ b/src/main/java/animatedledstrip/server/ContinuousRunAnimation.kt @@ -27,7 +27,7 @@ import animatedledstrip.animationutils.Animation import animatedledstrip.animationutils.AnimationData import animatedledstrip.leds.AnimatedLEDStrip import kotlinx.coroutines.* -import org.tinylog.Logger +import org.pmw.tinylog.Logger import java.io.File import java.io.FileOutputStream import java.io.ObjectOutputStream @@ -58,25 +58,13 @@ internal class ContinuousRunAnimation( private val fileName = "$id.anim" - init { - sendStartAnimation() // Send animation to GUI - } - - /** * Run the animation in a new thread */ fun runAnimation() { job = GlobalScope.launch(handler.animationThreadPool) { - launch { - withContext(Dispatchers.IO) { - ObjectOutputStream(FileOutputStream(".animations/$fileName")).apply { - writeObject(params) - close() - } - } - } - Logger.trace { "params: $params" } + if (handler.persistAnimations) launch { saveAnimationToDisk() } + sendStartAnimation() while (continueAnimation) leds.run(params) sendEndAnimation() handler.continuousAnimations.remove(id) @@ -91,7 +79,7 @@ internal class ContinuousRunAnimation( Logger.debug { "Animation $id ending" } if (continueAnimation) continueAnimation = false else job?.cancel() - if (File(".animations/$id").exists()) + if (File(".animations/$fileName").exists()) Files.delete(Paths.get(".animations/$fileName")) } @@ -100,7 +88,6 @@ internal class ContinuousRunAnimation( * Send message to client(s) that animation has started */ fun sendStartAnimation(connection: SocketConnections.Connection? = null) { - Logger.trace { "Sending animation start to client(s)" } SocketConnections.sendAnimation(params, id, connection) } @@ -110,8 +97,16 @@ internal class ContinuousRunAnimation( * @param connection */ fun sendEndAnimation(connection: SocketConnections.Connection? = null) { - Logger.trace { "Sending animation end to client(s)" } SocketConnections.sendAnimation(params.copy(animation = Animation.ENDANIMATION), id, connection) } + private suspend fun saveAnimationToDisk() { + withContext(Dispatchers.IO) { + ObjectOutputStream(FileOutputStream(".animations/$fileName")).apply { + writeObject(params) + close() + } + } + } + } diff --git a/src/main/java/animatedledstrip/server/GlobalVars.kt b/src/main/java/animatedledstrip/server/GlobalVars.kt index db5243f..2c9ed04 100644 --- a/src/main/java/animatedledstrip/server/GlobalVars.kt +++ b/src/main/java/animatedledstrip/server/GlobalVars.kt @@ -14,6 +14,7 @@ val options = Options().apply { addOption("o", true, "Specify output file name for image debugging") addOption("r", true, "Specify number of renders between saves") addOption("i", "Enable image debugging") + addOption("P", "Persist animations across restarts") addOption("T", "Run test") addOption("C", "Connect to a running server with a command line") } \ No newline at end of file diff --git a/src/main/java/animatedledstrip/server/SocketConnections.kt b/src/main/java/animatedledstrip/server/SocketConnections.kt index 22dfc9a..edcc91d 100644 --- a/src/main/java/animatedledstrip/server/SocketConnections.kt +++ b/src/main/java/animatedledstrip/server/SocketConnections.kt @@ -27,7 +27,7 @@ import animatedledstrip.animationutils.Animation import animatedledstrip.animationutils.AnimationData import animatedledstrip.animationutils.id import kotlinx.coroutines.* -import org.tinylog.Logger +import org.pmw.tinylog.Logger import java.io.EOFException import java.io.ObjectInputStream import java.io.ObjectOutputStream diff --git a/src/main/java/animatedledstrip/server/SocketWriter.kt b/src/main/java/animatedledstrip/server/SocketWriter.kt index accca5b..b4edff1 100644 --- a/src/main/java/animatedledstrip/server/SocketWriter.kt +++ b/src/main/java/animatedledstrip/server/SocketWriter.kt @@ -1,13 +1,19 @@ package animatedledstrip.server -import org.tinylog.core.LogEntry -import org.tinylog.core.LogEntryValue -import org.tinylog.writers.Writer +import org.pmw.tinylog.Configuration +import org.pmw.tinylog.LogEntry +import org.pmw.tinylog.writers.LogEntryValue +import org.pmw.tinylog.writers.PropertiesSupport +import org.pmw.tinylog.writers.Writer @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") -class SocketWriter(properties: java.util.Map) : Writer { +@PropertiesSupport(name = "socket", properties = []) +class SocketWriter : Writer { - val delimiter = properties.getOrDefault("delimiter", ":") + val delimiter = ":" + + override fun init(p0: Configuration?) { + } override fun getRequiredLogEntryValues(): MutableSet { return mutableSetOf(LogEntryValue.LEVEL, LogEntryValue.MESSAGE) @@ -15,9 +21,9 @@ class SocketWriter(properties: java.util.Map) : Writer { override fun write(log: LogEntry?) { SocketConnections.localConnection?.sendString( - "${log?.level.toString()}$delimiter".padEnd(8, ' ') + - "${log?.message}" - ) + "${log?.level.toString()}$delimiter".padEnd(8, ' ') + + "${log?.message}" + ) } override fun flush() { diff --git a/src/main/resources/META-INF/services/org.tinylog.writers.Writer b/src/main/resources/META-INF/services/org.tinylog.writers.Writer deleted file mode 100644 index ec529fc..0000000 --- a/src/main/resources/META-INF/services/org.tinylog.writers.Writer +++ /dev/null @@ -1 +0,0 @@ -animatedledstrip.server.SocketWriter \ No newline at end of file diff --git a/src/main/resources/tinylog.properties b/src/main/resources/tinylog.properties index 9d18946..3d0fa89 100644 --- a/src/main/resources/tinylog.properties +++ b/src/main/resources/tinylog.properties @@ -1,7 +1,7 @@ -writer = console -writer.format = {{level}:|min-size=8} {message} -writer.level = info +tinylog.writer1 = console +tinylog.writer1.format = {{level}:|min-size=8} {message} +tinylog.writer1.level = info -writer2 = socket -writer2.format = {{level}:|min-size=8} {message} -writer2.level = info \ No newline at end of file +tinylog.writer2 = socket +tinylog.writer2.format = {{level}:|min-size=8} {message} +tinylog.writer2.level = info \ No newline at end of file diff --git a/src/test/java/AnimatedLEDStripServerTest.kt b/src/test/java/AnimatedLEDStripServerTest.kt index c32ebc3..29ed327 100644 --- a/src/test/java/AnimatedLEDStripServerTest.kt +++ b/src/test/java/AnimatedLEDStripServerTest.kt @@ -29,14 +29,12 @@ import animatedledstrip.server.SocketConnections import kotlinx.coroutines.* import org.junit.Ignore import org.junit.Test -import org.tinylog.configuration.Configuration import java.io.ByteArrayInputStream class AnimatedLEDStripServerTest { init { SocketConnections.hostIP = "0.0.0.0" - Configuration.set("level", "off") } val leds = EmulatedAnimatedLEDStrip(50) diff --git a/src/test/java/AnimationHandlerTest.kt b/src/test/java/AnimationHandlerTest.kt index e069cae..67667fc 100644 --- a/src/test/java/AnimationHandlerTest.kt +++ b/src/test/java/AnimationHandlerTest.kt @@ -30,14 +30,12 @@ import animatedledstrip.server.AnimationHandler import animatedledstrip.server.SocketConnections import animatedledstrip.utils.delayBlocking import org.junit.Test -import org.tinylog.configuration.Configuration import kotlin.test.assertTrue class AnimationHandlerTest { init { - Configuration.set("level", "off") SocketConnections.connections.clear() } diff --git a/src/test/java/SocketConnectionsTest.kt b/src/test/java/SocketConnectionsTest.kt index a9c6474..1ea9be9 100644 --- a/src/test/java/SocketConnectionsTest.kt +++ b/src/test/java/SocketConnectionsTest.kt @@ -29,7 +29,6 @@ import animatedledstrip.server.SocketConnections import animatedledstrip.utils.delayBlocking import kotlinx.coroutines.* import org.junit.Test -import org.tinylog.configuration.Configuration import java.io.BufferedInputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream @@ -38,10 +37,6 @@ import kotlin.test.assertTrue class SocketConnectionsTest { - init { - Configuration.set("level", "off") - } - @Test fun testAdd() { val server = diff --git a/src/test/resources/tinylog.properties b/src/test/resources/tinylog.properties new file mode 100644 index 0000000..b006e0c --- /dev/null +++ b/src/test/resources/tinylog.properties @@ -0,0 +1,5 @@ +tinylog.writer1 = console +tinylog.writer1.level = off + +tinylog.writer2 = socket +tinylog.writer2.level = off \ No newline at end of file From 803e40785ac431fe8e29af69687d14d1c2f1e598 Mon Sep 17 00:00:00 2001 From: Max Narvaez Date: Thu, 19 Sep 2019 20:48:47 -0500 Subject: [PATCH 22/22] Fix loading animations from file with wrong ID Fix connection trying to send running animations to local connection --- .../java/animatedledstrip/cmdline/CommandLine.kt | 6 ++++++ .../animatedledstrip/server/AnimationHandler.kt | 6 +++--- .../animatedledstrip/server/SocketConnections.kt | 13 ++++--------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main/java/animatedledstrip/cmdline/CommandLine.kt b/src/main/java/animatedledstrip/cmdline/CommandLine.kt index f09e590..944071f 100644 --- a/src/main/java/animatedledstrip/cmdline/CommandLine.kt +++ b/src/main/java/animatedledstrip/cmdline/CommandLine.kt @@ -1,6 +1,8 @@ package animatedledstrip.cmdline import kotlinx.coroutines.* +import org.pmw.tinylog.Configurator +import org.pmw.tinylog.Level import java.io.EOFException import java.io.ObjectInputStream import java.io.ObjectOutputStream @@ -17,6 +19,10 @@ class CommandLine { private var readerJob: Job? = null + init { + Configurator.defaultConfig().level(Level.OFF).activate() + } + fun loop() { println("Welcome to the AnimatedLEDStrip Server console") while (!endCmdLine) { diff --git a/src/main/java/animatedledstrip/server/AnimationHandler.kt b/src/main/java/animatedledstrip/server/AnimationHandler.kt index bd17429..158bba4 100644 --- a/src/main/java/animatedledstrip/server/AnimationHandler.kt +++ b/src/main/java/animatedledstrip/server/AnimationHandler.kt @@ -66,7 +66,7 @@ internal class AnimationHandler( if (!it.isDirectory && it.name.endsWith(".anim")) try { ObjectInputStream(FileInputStream(it)).apply { val obj = readObject() as AnimationData - addAnimation(obj) + addAnimation(obj, obj.id) close() } } catch (e: ClassCastException) { @@ -91,7 +91,7 @@ internal class AnimationHandler( * * @param params An AnimationData instance containing data about the animation to be run */ - fun addAnimation(params: AnimationData) { + fun addAnimation(params: AnimationData, animId: String? = null) { /* Special "Animation" type that the client sends to end an animation */ if (params.animation == Animation.ENDANIMATION) @@ -105,7 +105,7 @@ internal class AnimationHandler( /* Animations that can be run repeatedly */ false -> { if (params.continuous) { - val id = (random() * 100000000).toInt().toString() + val id = animId ?: (random() * 100000000).toInt().toString() continuousAnimations[id] = ContinuousRunAnimation(id, params, leds, this) Logger.trace(continuousAnimations) diff --git a/src/main/java/animatedledstrip/server/SocketConnections.kt b/src/main/java/animatedledstrip/server/SocketConnections.kt index edcc91d..af2ac6f 100644 --- a/src/main/java/animatedledstrip/server/SocketConnections.kt +++ b/src/main/java/animatedledstrip/server/SocketConnections.kt @@ -102,19 +102,15 @@ object SocketConnections { while (server.running) { try { clientSocket = serverSocket.accept() - Logger.trace { "Accepted new connection on port $port" } - Logger.trace { "Initializing input stream" } val socIn = ObjectInputStream(clientSocket!!.getInputStream()) - Logger.trace { "Initializing output stream" } socOut = ObjectOutputStream(clientSocket!!.getOutputStream()) Logger.info { "Connection on port $port Established" } connected = true - Logger.debug { "Sending currently running animations to GUI" } // Send all current running continuous animations to newly connected client - server.animationHandler.continuousAnimations.forEach { - Logger.info { "Sending ${it.value}"} - it.value.sendStartAnimation(this@Connection) - } + if (port != 1118) + server.animationHandler.continuousAnimations.forEach { + it.value.sendStartAnimation(this@Connection) + } var input: Any? while (connected) { Logger.trace { "Waiting for input" } @@ -190,7 +186,6 @@ object SocketConnections { withTimeout(5000) { withContext(Dispatchers.IO) { socOut?.writeObject(str) -// ?: Logger.debug { "Could not send string $str: Connection socket null" } } } }