PureScript를 사용하여 캔버스 게임을 만들고 있는데, 특히 이벤트 모으기를 처리하는 가장 좋은 방법은 무엇인지, 특히 맞춤형 모나드 스택 내에서 콜백을 실행하는 것이 궁금합니다. 이(PureScript) Eff 이외의 모나 딕 (monadic) 컨텍스트 내에서 DOM 이벤트 리스너 콜백을 실행하려면 어떻게해야합니까?
type BaseEffect e = Eff (canvas :: CANVAS, dom :: DOM, console :: CONSOLE | e)
type GameState = { canvas :: CanvasElement, context :: Context2D, angle :: Number }
type GameEffect e a = StateT GameState (BaseEffect e) a
는 내가 뭘하려는 어떤 키를 누를 때 GameState에서 "각도"속성을 변경입니다 ... 내 게임 스택이다 (개발 목적은 그래서 그래픽을 조정할 수 있습니다 단지에 대한). 이것은 내 콜백 함수 ... 그러나 addEventListener 그들이 다음 확인을 입력하지 않도록 만 EFF의와 함께 사용되는 의미있는 것처럼 eventListener 보기
changeState :: forall e. Event -> GameEffect e Unit
changeState a = do
modify \s -> s { angle = s.angle + 1.0 }
liftEff $ log "keypress"
pure unit
입니다 ...
addEventListener
(EventType "keypress")
(eventListener changeState)
false
((elementToEventTarget <<< htmlElementToElement) bodyHtmlElement)
addEventListener 및 eventListener를 직접 정의 할 수 있고 외부 함수 인터페이스 (GameEffect로 Eff 변경)를 사용하여 가져올 수 있다고 생각했습니다. 그 입력 된 체크하지만 브라우저에서 실행하려고 할 때 콘솔 오류가 발생했습니다.
foreign import addEventListener :: forall e. EventType -> EventListener e -> Boolean -> EventTarget -> GameEffect e Unit
foreign import eventListener :: forall e. (Event -> GameEffect e Unit) -> EventListener e
모나드 스택 내에서 콜백을 실행하는 가장 좋은 방법은 무엇입니까?
나는 그것을 작동시킬 수 있었지만, 오직 하나의 키 누르기와 keypress가 그래픽 렌더링을 막는 것처럼 보였다. 첫 번째 키를 누르면 소비자가 닫히고 그래픽이 렌더링됩니다. 나는'CR.runProcess $ connect producer consumer'를 사용할 수 있도록 GameEffect (newtype로 래핑 된)에 대한'Parallel' 인스턴스를 생성해야한다고 생각합니다. 나는 옳은 길에있는 것처럼 들리는가? – Albtzrly
죄송합니다. 'consumer'는 다음과 같이 정의되어야합니다 :'forever $ lift <<< changeState = << CR.await','Control.Monad.Rec.Class'에서 영원히옵니다. –
쉬운 대답은 [ "just fork it"] (https://github.com/slamdata/purescript-fork)이 될 수 있기 때문에 블로킹은 조금 까다 롭습니다. 그러나 'StateT'를 포크하는 인스턴스는 없습니다. 당신은 아마도'GameEffect'를위한'newtype'을 가지고 뭔가를 생각해 낼 수 있습니다. 렌더링 루프에서'setupListener'를 호출하는 것이 좋습니다. 설치가 끝나면 한 번만 할 수 있어야합니다. 근본적으로 나는이 비트를 위해 좋은 대답을 가지지 않고있다, 미안하다! –