2012-05-28 29 views
7

我正在用反應香蕉在Haskell寫一個音樂播放器。我遇到的一個問題是使用fromPoll獲取最新值。我想要讓用戶在播放時選擇部分曲目。我的代碼看起來是這樣的:活性香蕉:來自fromPoll的最新值

makePlayNetworkDescr :: Player a => AddHandler Command -> a -> NetworkDescription t() 
makePlayNetworkDescr addCmdEvent player = do 
    bPosition <- fromPoll (getPosition player) 
    eCmds <- fromAddHandler addCmdEvent 

    let eSetStart = filterE (isJust) $ bPosition <@ filterE (==SetStart) eCmds 
     eSetEnd = filterE (isJust) $ bPosition <@ filterE (==SetEnd) eCmds 
     eClearRange = filterE (==ClearRange) eCmds 

     bStart = accumB Nothing ((const <$> eSetStart) `union` (const Nothing <$ eClearRange)) 
     bEnd = accumB Nothing ((const <$> eSetEnd) `union` (const Nothing <$ eClearRange)) 

以上,爲getPosition是部分函數,​​返回沒有實際開始播放之前。問題是,一旦addCmdEvent第一次火災,b地位仍然會保持一個沒有值。 eSetStart/End根據此計算它們的值。只有這樣bPosition得到更新,並且這是下次將用於該值的值,其中addCmdEvent火災。等等,價值永遠是「一個」,可以這麼說。

有一個相關SO question,但在這種情況下,存在一個「觸發」事件,可用於計算行爲的新值。 fromPoll有沒有這樣的可能?

+0

當你完成後,你應該把結果放在Hackage上。期待從哈斯克爾演奏我的音樂! – amindfv

+0

我打算把它放在Hackage上一次(哈)我完成了。然而,這是一種「搔自己癢」的音樂播放器,以幫助轉錄音樂,所以我不確定這對其他人有多有趣。 – oggy

回答

2

從響應香蕉-0.5和0.6開始,fromPoll函數會在外部事件觸發事件網絡時更新行爲。您可以通過使用

eUpdate <- changes bSomeBehavior 

但是訪問這些更新作爲一個事件,注意行爲表示不支持「更新事件」的一般概念連續隨時間變化的值。 changes函數將嘗試返回一個有用的近似值,但沒有正式的保證。

或者,您可以更改外部事件以包含玩家位置作爲addCmdEvent的一部分。在你的情況下,這意味着將更多的數據添加到SetStartSetEnd構造函數。然後,你可以使用

eSetStart = filterJust $ matchSetStart <$> eCmds 
    where 
    matchSetStart (SetStart pos) = Just pos 
    matchSetStart _    = Nothing 

兩種方案都要求你觀察最近的值作爲一個事件,而不是行爲。原因在於,使用stepper創建的行爲在更新時會始終返回舊值(它們「落後於1」),因爲這對於遞歸定義非常有用。

在任何情況下,潛在的問題是玩家位置外長addCmdEvent發生之前更新的,但問題是,這是該事件的網絡看到的不是什麼。相反,網絡認爲fromPoll返回的行爲與addCmdEvent同時更新。事實上,除非您有權訪問負責更新玩家位置的外部事件源,否則這是唯一可以考慮的事情。 (如果您確實有權訪問,則可以使用fromChanges函數。)

我知道fromPoll的這種行爲對於您的常見用例而言有點令人不滿意。但我不確定是否應該將其修復到我的庫中:在返回最新值的fromPoll和嘗試盡力而爲的changes函數之間進行權衡。如果返回最新值,那麼changes的行爲就像跳過一次更新(當外部更新值時)並且觸發了多餘的更新(當網絡更新值以匹配外部值時)。如果您對此有任何意見,請告訴我。


注意與應用性操作<*>合併行爲將結合最新的值就好了。

+0

感謝您的回覆。最後,我進行了外部輪詢位置數據並將其包括在事件中的路線。再想一想,我無法真正決定從獲得來自寶來的新鮮價值與從外部獲得新鮮價值相比,是否有任何概念上的好處,或者相反。另一方面,我並沒有完全解決Polling「blocking」的問題,直到讀取新值,然後才觸發實際觸發此評估的事件(與更改事件同時發生),但是您知道您的庫比我好得多 – oggy