
On Sat, 18 Dec 2004 20:24:47 -0500, Robert Dockins
Well that shouldn't affect the functionality. The weak pointer was only a way of attatching a finalizer to the Playback object. It is true that I should probably wrap up the the SoundPlaybackRaw inside the SoundPlayback as well, to save CPU, but it shouldn't matter for the core functionality.
I'm not sure I understand.
Well not including the SamplePlaybackRaw in the SamplePlayback datatype means that the SamplePlaybackRaw might get prematurely GC'd, but if the finalizer had worked that wouldn't have mattered, it would've only meant that the keep-alive loop might have been started earlier. Anyway, the reason for not wanting to do polling-loops was simply a performance issue. FMOD is one of the fastest, if not THE fastest, sound libraries out there so I didn't want to "ruin it" by attatching too much extra "fluff". That's why I wanted to start a polling loop ony when it was absolutely necessary, ie only when the Playback object was being GC'd (which meant that GC'ing of the sound data might be imminent). But anyway, I decided to bite the bullet and do it "the easy way". Here's the final, short-n-sweet (albeit slightly inefficient), solution: -- A playback of a sample resource newtype SamplePlayback = SP (MVar CInt) -- play, and keep data alive until playback is done samplePlay' :: MVar CInt -> SoundSample -> IO () samplePlay' var s = do ch <- withForeignPtr s (fsound_PlaySound (-1)) putMVar var ch let loop = do b <- isPlaying (SP var) case b of True -> do touchForeignPtr s threadDelay 1000000 -- wait one second loop False -> return () loop -- asynchronous playback action samplePlay :: SoundSample -> IO SamplePlayback samplePlay s = do var <- newEmptyMVar -- spawn a new playback thread forkIO (samplePlay' var s) -- wait for the MVar to get filled in let loop = do yield b <- isEmptyMVar var if b then loop else return () loop return (SP var) isPlaying :: SamplePlayback -> IO Bool isPlaying (SP var) = do b <- withMVar var (fsound_IsPlaying) return (cscharToBool b) -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862