diff options
Diffstat (limited to 'flow-main/src/main/scala/com/github/jodersky/flow/SerialOperator.scala')
-rw-r--r-- | flow-main/src/main/scala/com/github/jodersky/flow/SerialOperator.scala | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/flow-main/src/main/scala/com/github/jodersky/flow/SerialOperator.scala b/flow-main/src/main/scala/com/github/jodersky/flow/SerialOperator.scala new file mode 100644 index 0000000..5524125 --- /dev/null +++ b/flow-main/src/main/scala/com/github/jodersky/flow/SerialOperator.scala @@ -0,0 +1,68 @@ +package com.github.jodersky.flow + +import java.nio.ByteBuffer + +import com.github.jodersky.flow.internal.Reader +import com.github.jodersky.flow.internal.ReaderDied +import com.github.jodersky.flow.internal.SerialConnection + +import Serial.Close +import Serial.Closed +import Serial.NoAck +import Serial.Opened +import Serial.Write +import akka.actor.Actor +import akka.actor.ActorLogging +import akka.actor.ActorRef +import akka.actor.Props +import akka.actor.Terminated +import akka.actor.actorRef2Scala + +/** + * 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 ! Opened(connection.port) + reader.start() + + override def postStop = { + connection.close() + } + + def receive: Receive = { + + case Write(data, ack) => { + writeBuffer.clear() + data.copyToBuffer(writeBuffer) + val sent = connection.write(writeBuffer) + if (ack != NoAck) sender ! ack(sent) + } + + case Close => { + client ! Closed + context stop self + } + + case Terminated(`client`) => { + context stop self + } + + //go down with reader thread + case ReaderDied(ex) => throw ex + + } + +} + +object SerialOperator { + def apply(connection: SerialConnection, bufferSize: Int, client: ActorRef) = Props(classOf[SerialOperator], connection, bufferSize, client) +}
\ No newline at end of file |