我正在使用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将接收click事件并切换到新的多边形创建模式,从而丢弃以前的状态。
我想做的是在defaultMode中切换一次,再也不可能回来了。本质上,我想将defaultMode生成的defaultMode与createSectorMode的结果进行“交换”。
我知道reactive-banana在动态事件的垃圾收集方面有问题,但我现在愿意接受这个问题。上面的公式比我到目前为止所写的任何东西都要精确得多--比如有一个CurrentState变量,并根据该变量的内容过滤各种事件。我的问题是它太大了,给我留下了太多的空间去搞砸事情。通过切换,我只知道我能做的事情。
发布于 2015-01-10 17:18:06
这个问题有点开放,所以我不能给出一个明确的答案。但我当然可以给出我的意见。;-)
但是,我可能要做的是将模式之间的切换与模式内的行为分开。如果我们暂时忘记了FRP,您的程序看起来有点像一对递归调用自己的函数:
defaultMode = ... `andthen` sectorMode
sectorMode = ... `andthen` defaultMode它写得有点像一个“顺序”程序,“先做这个模式,然后再做那个模式”。我认为这没有什么问题,尽管默认的API反应性香蕉(特别是switchB )并不支持这种风格。你(私下)提到你可以写一个
once :: Event t a -> Event t acombinator,它允许一个事件的第一次出现,但放弃其余的事件。这确实是顺序样式所需要的。
但是,由于您总是返回到默认模式,所以我可能会尝试一种不同的方法,在这种方法中,每种模式都有一个事件,表示它希望被切换。切换本身由“外部”实体处理。这样做的目的是避免上述程序中由高阶组合器显式递归。在伪代码中,这看起来如下所示:
modeManager = switchB initialMode changeMode
changeMode = defaultModeSwitch `union` sectorModeSwitch虽然我对细节有点不确定。事实上,我不完全确定它是否有效,您可能仍然需要once组合器。
总之,这只是一个关于如何进行切换的想法。我完全同意转换是处理不同模式的正确方法。
https://stackoverflow.com/questions/27816012
复制相似问题