【问题标题】:Simple Example for Scala ReactScala React 的简单示例
【发布时间】:2013-10-23 13:40:39
【问题描述】:

基于论文Deprecating the Observer Pattern with Scala.React我试图从论文中设置一个简单的例子,但是它抛出了一个异常Exception in thread "main" java.lang.AssertionError: assertion failed: This method must be run on its domain scala.react.NilDebug@1502c065

一个相关的问题是Running a simple Scala.React expression

如何设置一切以使用 scala react 库的强大功能?

除了库scala-react之外,我还使用了以下示例:

object MyFirstReact extends App {

  object MyDomain extends scala.react.Domain {
    protected val scheduler: Scheduler = new ManualScheduler
    protected val engine: Engine = new Engine
  }
  import MyDomain._

  case class MouseEvent(position: (Int, Int))
  class Path(var positions: Seq[(Int, Int)]) {
    def this(pos: (Int, Int)) = this(Seq(pos))
    def lineTo(pos: (Int, Int)) { positions = positions :+ pos }
    def close { positions = positions :+ positions.head }
  }

  val mouseDown: Events[MouseEvent] = Events.once(MouseEvent((0, 0)))
  val mouseMove: Events[MouseEvent] = Events.once(MouseEvent((1, 1)))
  val mouseUp: Events[MouseEvent] = Events.once(MouseEvent((2, 2)))
  def draw(path: Path) { /* ... */ }

  Reactor.loop { self =>
    // step 1
    val path = new Path((self await mouseDown).position)
    self.loopUntil(mouseUp) { // step 2
      val m = self awaitNext mouseMove
      path.lineTo(m.position)
      draw(path)
    }
    path.close // step 3
    draw(path)
  }

}

【问题讨论】:

    标签: scala reactive-programming frp


    【解决方案1】:

    您遇到了异常,因为 Reactor.loop 必须用 schedule { ... } 块包装。但解决这个问题还不够(我得到了一个 java.lang.StackOverflowError)。

    无论如何,我使用 scala-swing 准备了一个完整的工作示例,您实际上可以使用与您拥有的相同反应器代码绘制一条线。我将包含 scala-react 的 sbt-buildable 副本放入 github:https://github.com/zsoltdonca/scala-react-line-drawing

    package zsd
    
    import scala.swing._
    import java.awt.event.{MouseMotionAdapter, MouseEvent, MouseAdapter}
    import java.awt.{Color, Point}
    import scala.react.Domain
    
    object MyDomain extends Domain {
      val scheduler = new SwingScheduler()
      val engine = new Engine
    }
    
    import MyDomain._
    
    object ScalaReactLineDrawing extends SimpleSwingApplication with Observing {
    
      override def main(args: Array[String]) {
        schedule { startup(args) }
        start() // starts the scala-react engine
      }
    
      override def top: Frame = new MainFrame() {
        contents = new FlowPanel() {
          val mouseDown = EventSource[Point]
          val mouseMove = EventSource[Point]
          val mouseUp = EventSource[Point]
    
          val mainProgramFlow = Reactor.loop {
            self =>
            // step 1
              val path = new Path(self await mouseDown)
              self.loopUntil(mouseUp) {
                // step 2
                val m = self awaitNext mouseMove
                path.lineTo(m)
                draw(path)
              }
              path.close() // step 3
              draw(path)
          }
    
          peer.addMouseListener(new MouseAdapter {
            override def mousePressed(e: MouseEvent): Unit = mouseDown << e.getPoint
            override def mouseReleased(e: MouseEvent): Unit = mouseUp << e.getPoint
          })
          peer.addMouseMotionListener(new MouseMotionAdapter {
            override def mouseDragged(e: MouseEvent): Unit = mouseMove << e.getPoint
          })
    
          class Path(var positions: Seq[Point]) {
            def this(pos: Point) = this(Seq(pos))
    
            def lineTo(pos: Point) {
              positions = positions :+ pos
            }
    
            def close() {
              positions = positions :+ positions.head
            }
          }
    
          var pathDrawn = new Path(new Point(0, 0))
          def draw(path: Path) {
            pathDrawn = path
            repaint()
          }
    
          override protected def paintComponent(g: swing.Graphics2D): Unit = {
            super.paintComponent(g)
    
            val xPoints = pathDrawn.positions.map(pos => pos.x).toArray
            val yPoints = pathDrawn.positions.map(pos => pos.y).toArray
            g.setColor(Color.BLACK)
            g.drawPolyline(xPoints, yPoints, pathDrawn.positions.length)
          }
        }
        preferredSize = new Dimension(400, 300)
        pack()
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 2018-05-03
      • 2011-03-21
      • 2013-10-03
      • 2016-10-08
      • 1970-01-01
      相关资源
      最近更新 更多