matedledstrip.animatedledstrip-android-client.1.0.source-code.AndroidAnimationSenderFactory.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of animatedledstrip-android-client Show documentation
Show all versions of animatedledstrip-android-client Show documentation
An android helper library for communicating with an AnimatedLEDStripServer
The newest version!
package animatedledstrip.androidclient
/*
* Copyright (c) 2019 AnimatedLEDStrip
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.newSingleThreadContext
import org.pmw.tinylog.Logger
import java.io.BufferedInputStream
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import java.net.InetSocketAddress
import java.net.Socket
object AndroidAnimationSenderFactory {
var defaultSenderAndroid: AndroidAnimationSender? = null
get() {
return field ?: throw NullPointerException()
}
fun create(ipAddress: String = "10.0.0.254", port: Int = 5, connectAttemptLimit: Int = 5): AndroidAnimationSender {
return AndroidAnimationSender(ipAddress, port, connectAttemptLimit)
}
class AndroidAnimationSender(val ipAddress: String, val port: Int, val connectAttemptLimit: Int) {
private var socket: Socket = Socket()
private var out: ObjectOutputStream? = null
private var socIn: ObjectInputStream? = null
private var disconnected = true
private var connectionTries = 0
private var action: ((Map<*, *>) -> Any?)? = null
private var stopSocket = false
private var started = false
private var loopThread: Job? = null
fun setOnReceiveCallback(action: (Map<*, *>) -> R): AndroidAnimationSender {
this.action = action
return this
}
fun setAsDefaultSender(): AndroidAnimationSender {
defaultSenderAndroid = this
return this
}
fun start(): AndroidAnimationSender {
if (!started) {
loopThread = GlobalScope.launch(newSingleThreadContext("AndroidAnimationSender")) {
loop()
}
started = true
}
return this
}
fun end() {
loopThread?.cancel()
}
private suspend fun loop() {
while (!stopSocket) {
connect()
try {
out = ObjectOutputStream(socket.getOutputStream())
socIn = ObjectInputStream(BufferedInputStream(socket.getInputStream()))
var input: Map<*, *>
while (true) {
input = socIn!!.readObject() as Map<*, *>
Logger.debug("Received: $input")
action?.invoke(input)
}
} catch (e: Exception) {
socket = Socket()
disconnected = true
}
}
}
private suspend fun connect() {
try {
socket.connect(InetSocketAddress(ipAddress, port), 5000)
Logger.info("Connected to server at $ipAddress")
disconnected = false
connectionTries = 0
} catch (e: Exception) {
connectionTries++
Logger.warn("Connection attempt $connectionTries: Server not found at $ipAddress: $e")
Thread.sleep(10000)
if (connectionTries <= connectAttemptLimit) {
socket = Socket()
connect()
} else {
Logger.error("Could not locate server at $ipAddress after $connectionTries tries")
}
}
}
fun send(args: Map<*, *>) {
try {
out!!.writeObject(args)
} catch (e: Exception) {
Logger.error("Error sending animation: $e")
}
}
fun isDisconnected() = disconnected
}
}