blob: 5524125d424796118b91f881916d6701202266e5 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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)
}
|