aboutsummaryrefslogtreecommitdiff
path: root/vfd-uav/src/main/scala/vfd/uav/Connection.scala
blob: 223a787ce35ea3dbd4b40aa4e6c3c41c3b5a96cc (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
package vfd.uav

import scala.collection.mutable.ArrayBuffer

import akka.actor.Actor
import akka.actor.ActorRef
import akka.actor.Terminated
import akka.actor.actorRef2Scala
import akka.util.ByteString

/** Protocol definition. */
object Connection {
  trait Event
  trait Command

  /** Received data from the uav (or any other systems on the link) */
  case class Received(bstr: ByteString) extends Event

  /** The connection closed or could not be opened */
  case class Closed(message: String) extends Event

  /** Register the sender to be notified on events */
  case object Register extends Command

  /** Send given bytes out to the uav (or any other systems on the link) */
  case class Send(bstr: ByteString) extends Command
}

/** Common behavior of connection actors. */
trait Connection { myself: Actor =>

  /** Current clients that should be notified on incoming messages. */
  private val _clients = new ArrayBuffer[ActorRef]
  def clients = _clients.toSeq

  /** Adds a client to the client list and acquires a deathwatch. */
  protected def register(client: ActorRef) = {
    _clients += client
    myself.context.watch(client)
  }

  /** Remove client and release deathwatch. */
  protected def unregister(client: ActorRef) = {
    _clients -= client
    myself.context.unwatch(client)
  }

  /** Sends a message to all registered clients. */
  protected def sendAll(msg: Any) = clients foreach (_ ! msg)

  /**
   * Common registration behavior. Manages the events `Register` and `Terminated` by
   * registering and unregistering clients.
   */
  protected def registration: Receive = {
    case Connection.Register => register(sender)
    case Terminated(client) if clients contains client => unregister(client)
  }
}