Commits

Pavel Kozlov  committed 784f8a0

remove scopt command line parser, run server from GUI

  • Participants
  • Parent commits bfdebba

Comments (0)

Files changed (6)

File qcp-sim-p2p/build.sbt

 
 libraryDependencies ++= Seq(
   "org.scala-lang" % "scala-swing" % "2.10.2",
-  "com.github.scopt" %% "scopt" % "3.2.0",
   "com.typesafe.akka" %% "akka-actor" % "2.3.0",
   "com.typesafe" %% "scalalogging-slf4j" % "1.1.0",
   "org.slf4j" % "slf4j-log4j12" % "1.7.6"

File qcp-sim-p2p/src/main/scala/qcp/sim/p2p/MessageReceived.scala

-package qcp.sim.p2p
-
-import java.net.InetSocketAddress
-import scala.swing.event.Event
-
-case class MessageReceived(address: InetSocketAddress, message: String) extends Event

File qcp-sim-p2p/src/main/scala/qcp/sim/p2p/QcpP2PSimulator.scala

 import akka.actor.{Props, ActorSystem}
 import java.net.InetSocketAddress
 import qcp.sim.p2p.Client.SendTo
-import scopt._
 import java.util.Calendar
 import java.text.SimpleDateFormat
+import akka.io.Tcp.Unbind
 
 object QcpP2PSimulator extends SimpleSwingApplication with Logging {
 
   val timeFormat = new SimpleDateFormat("HH:mm:ss.SSS")
 
   // GUI elements
-  val textArea = new TextArea(15,10) {
+  val textArea = new TextArea(15, 10) {
     lineWrap = true
     wordWrap = true
     editable = false
   val client = system.actorOf(Props[Client], "client")
   val server = system.actorOf(Server.props(textArea), "server")
 
+  val bindPortLabel = new Label("Port")
+  val bindPortField = new TextField(5)
+  val bindButton = new Button("Bind")
+
   val hostnameLabel = new Label("Hostname")
   val hostnameField = new TextField(15) {
     text = "localhost"
     system.shutdown()
   }
 
-  override def main(args: Array[String]) {
-    new OptionParser[Config]("qcp-sim-p2p") {
-      head("")
-      opt[Int]('p', "port") action {
-        (p, c) => c.copy(p)
-      }
-    }.parse(args, Config()) map {
-      config =>
-        portField.text = config.port.toString
-        server ! config.port
-    }
-    Swing.onEDT {
-      startup(args)
-    }
-  }
-
   override def top = new MainFrame {
     title = "QCP P2P Simulator"
 
     contents = new BorderPanel {
+      layout(new BoxPanel(Orientation.Horizontal) {
+        contents += new FlowPanel(bindPortLabel, bindPortField)
+        contents += bindButton
+      }) = North
       layout(new ScrollPane(textArea)) = Center
       layout(new BoxPanel(Orientation.Horizontal) {
         contents += new FlowPanel(hostnameLabel, hostnameField)
       }) = South
     }
 
-    listenTo(sendButton, textArea)
+    listenTo(sendButton, bindButton, textArea)
 
     reactions += {
+
       case ButtonClicked(`sendButton`) =>
         val address = new InetSocketAddress(hostnameField.text, portField.text.toInt)
         val message = messageField.text
         client ! SendTo(message, address)
         val time = timeFormat.format(Calendar.getInstance().getTime)
         textArea append s"$time: $address <= $message\n"
-      case MessageReceived(address, message) =>
+
+      case ButtonClicked(`bindButton`) =>
+        server ! (bindButton.text match {
+          case "Bind" => bindPortField.text.toInt
+          case "Unbind" => Unbind
+        })
+        bindButton.enabled = false
+
+      case BoundEvent(_) =>
+        bindButton.enabled = true
+        bindButton.text = "Unbind"
+
+      case UnboundEvent(_) =>
+        bindButton.enabled = true
+        bindButton.text = "Bind"
+
+      case BindFailedEvent(_) =>
+        bindButton.enabled = true
+        Dialog.showMessage(bindButton, "Fail to bind", "Error", Dialog.Message.Error)
+
+      case MessageEvent(address, message) =>
         val time = timeFormat.format(Calendar.getInstance().getTime)
         textArea append s"$time: $address => $message\n"
+
     }
 
   }

File qcp-sim-p2p/src/main/scala/qcp/sim/p2p/Receiver.scala

       val cypher = deserialize(data, classOf[Array[Char]])
       log.info("Received encrypted message, decrypting")
       val message = (for ((b, k) <- cypher zip key) yield (b ^ k).toChar).mkString
-      publisher.publish(MessageReceived(address, message))
+      publisher.publish(MessageEvent(address, message))
       log.info(s"Decrypted message '$message'")
 
     case c: ConnectionClosed =>

File qcp-sim-p2p/src/main/scala/qcp/sim/p2p/Server.scala

 
     case b@Bound(localAddress) =>
       log.info(s"Bound address $localAddress")
+      publisher.publish(BoundEvent(b))
       context.become(running(sender()), discardOld = false)
 
-    case CommandFailed(b: Bind) => log.error(s"Bind $b failed")
+    case CommandFailed(b: Bind) =>
+      log.error(s"Bind $b failed")
+      publisher.publish(BindFailedEvent(b))
   }
 
   def running(socket: ActorRef): Receive = {
 
     case Unbind => socket ! Unbind
 
-    case Unbound => context.unbecome()
+    case Unbound =>
+      log.info("Unbound")
+      publisher.publish(UnboundEvent(Unbound))
+      context.unbecome()
 
   }
 
 
 object Server {
 
-  def props(publisher: Publisher = new Publisher {}) = Props(new Server(publisher))
+  def props(publisher: Publisher) = Props(new Server(publisher))
 
 }

File qcp-sim-p2p/src/main/scala/qcp/sim/p2p/package.scala

 import scala.util.Random
 import akka.util.ByteString
 import akka.serialization.Serialization
+import akka.io.Tcp._
+import scala.swing.event.Event
+import java.net.InetSocketAddress
 
 package object p2p {
 
+  case class BoundEvent(bound: Bound) extends Event
+  case class UnboundEvent(unbound: Unbound) extends Event
+  case class BindFailedEvent(b: Bind) extends Event
+  case class MessageEvent(address: InetSocketAddress, message: String) extends Event
+
   implicit class RandomOps(rand: Random) {
     def booleans(size: Int): IndexedSeq[Boolean] = for (i <- 1 to size) yield rand.nextBoolean()
   }