diff options
Diffstat (limited to 'flow-core/src/main/scala/com/github/jodersky/flow/SerialOperator.scala')
-rw-r--r-- | flow-core/src/main/scala/com/github/jodersky/flow/SerialOperator.scala | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/flow-core/src/main/scala/com/github/jodersky/flow/SerialOperator.scala b/flow-core/src/main/scala/com/github/jodersky/flow/SerialOperator.scala new file mode 100644 index 0000000..ec0ee27 --- /dev/null +++ b/flow-core/src/main/scala/com/github/jodersky/flow/SerialOperator.scala @@ -0,0 +1,54 @@ +package com.github.jodersky.flow + +import akka.actor.{ Actor, ActorLogging, ActorRef, Props, Terminated, actorRef2Scala } +import internal.{ Reader, SerialConnection, ThreadDied } +import java.nio.ByteBuffer + +/** + * Operator associated to an open serial port. All communication with a port is done via an operator. Operators are created though the serial manager. + * @see SerialManager + */ +class SerialOperator(connection: SerialConnection, bufferSize: Int, client: ActorRef) extends Actor with ActorLogging { + import SerialOperator._ + import context._ + + val readBuffer = ByteBuffer.allocateDirect(bufferSize) + val reader = new Reader(connection, readBuffer, self, client) + val writeBuffer = ByteBuffer.allocateDirect(bufferSize) + + context.watch(client) + client ! Serial.Opened(connection.port) + reader.start() + + override def postStop = { + connection.close() + } + + def receive: Receive = { + + case Serial.Write(data, ack) => { + writeBuffer.clear() + data.copyToBuffer(writeBuffer) + val sent = connection.write(writeBuffer) + if (ack != Serial.NoAck) sender ! ack(sent) + } + + case Serial.Close => { + client ! Serial.Closed + context stop self + } + + case Terminated(`client`) => { + context stop self + } + + //go down with reader thread + case ThreadDied(`reader`, ex) => throw ex + + } + +} + +object SerialOperator { + def apply(connection: SerialConnection, bufferSize: Int, client: ActorRef) = Props(classOf[SerialOperator], connection, bufferSize, client) +} |