我正在使用reactive-banana
- 构建一个多模式编辑器,并且在大多数情况下它会很完美。为了扩展我的场景,编辑器是一些绘图软件,或者您可以将其视为一个非常简单的矢量图形编辑器。它目前有两种状态——选择模式和多边形创建模式。在选择模式下,用户可以用鼠标右键选择以前创建的多边形(理论上这会带你进入一个新的选择模式),或者他们可以用鼠标左键开始创建一个新的多边形。
目的是,当按下鼠标左键时,我们从选择模式切换到多边形创建模式。在这种模式下,鼠标左键意味着“添加一个新的顶点”,直到用户返回到原来的顶点。此时,他们已经关闭了多边形,所以我们返回选择模式。
我已经用几种不同的方式实现了这一点,最近注意到事件切换几乎使它非常优雅。我可以有:
defaultMode :: Frameworks t => HadoomGUI -> Moment t (Behavior t Diagram)
defaultMode gui@HadoomGUI{..} =
do mouseMoved <- registerMotionNotify guiMap
mouseClicked <- registerMouseClicked guiMap
let lmbClicked = ...
gridCoords = ...
diagram = ...
switchToCreateSector <- execute ((\m ->
FrameworksMoment
(=<< trimB =<< createSectorMode gui emptySectorBuilder m)) <$>
(gridCoords <@ lmbClicked))
return (switchB diagram switchToCreateSector)
随着
createSectorMode :: Frameworks t
=> HadoomGUI
-> SectorBuilder
-> Point V2 Double
-> Moment t (Behavior t Diagram)
createSectorMode HadoomGUI{..} initialSectorBuilder firstVertex =
do mouseClicked <- registerMouseClicked guiMap
...
这当然有效 - 只需单击鼠标。如果我在地图上单击一次,我会从刚才的状态切换到扇区创建模式。但是,如果我再次单击,defaultMode
接收到单击事件并切换到新的多边形创建模式,丢弃我之前的状态。
我想做的就是切换defaultMode
一次,再也没有回来的可能。本质上,我想Behavior t Diagram
用defaultMode
.createSectorMode
我知道reactive-banana
动态事件的垃圾收集存在问题,但我现在愿意接受。上面的公式比我迄今为止写的任何其他公式都要精确得多——比如有一个CurrentState
变量并根据它的内容过滤各种事件。我遇到的问题是它太大了,给我留下了太多的空间来搞砸事情。通过切换,我只能在范围内处理我可以处理的事件。