OpenAL-1.4.0.0: Sound/OpenAL/ALC/Errors.hs
--------------------------------------------------------------------------------
-- |
-- Module : Sound.OpenAL.ALC.Errors
-- Copyright : (c) Sven Panne 2003-2009
-- License : BSD-style (see the file LICENSE)
--
-- Maintainer : sven.panne@aedion.de
-- Stability : stable
-- Portability : portable
--
-- This module corresponds to section 6.3.6 (Query for Error Conditions) of the
-- OpenAL Specification and Reference (version 1.1).
--
--------------------------------------------------------------------------------
module Sound.OpenAL.ALC.Errors (
ALCError(..), ALCErrorCategory(..), alcErrors
) where
import Data.StateVar
import Sound.OpenAL.ALC.BasicTypes ( ALCenum )
import Sound.OpenAL.ALC.Device ( Device )
import Sound.OpenAL.ALC.QueryUtils ( StringQuery(..), getString )
import Sound.OpenAL.Constants (
alc_NO_ERROR, alc_INVALID_DEVICE, alc_INVALID_CONTEXT, alc_INVALID_ENUM,
alc_INVALID_VALUE, alc_OUT_OF_MEMORY, alc_INVALID_OPERATION )
import Sound.OpenAL.Config ( ALCdevice, marshalDevice )
--------------------------------------------------------------------------------
-- | ALC errors consist of a general error category and a description of what
-- went wrong.
data ALCError = ALCError ALCErrorCategory String
deriving ( Eq, Ord, Show )
--------------------------------------------------------------------------------
-- | General ALC error categories.
data ALCErrorCategory =
ALCInvalidEnum
| ALCInvalidValue
| ALCInvalidOperation
| ALCInvalidDevice
| ALCInvalidContext
| ALCOutOfMemory
deriving ( Eq, Ord, Show )
unmarshalALCErrorCategory :: ALCenum -> ALCErrorCategory
unmarshalALCErrorCategory x
| x == alc_INVALID_ENUM = ALCInvalidEnum
| x == alc_INVALID_VALUE = ALCInvalidValue
| x == alc_INVALID_OPERATION = ALCInvalidOperation
| x == alc_INVALID_DEVICE = ALCInvalidDevice
| x == alc_INVALID_CONTEXT = ALCInvalidContext
| x == alc_OUT_OF_MEMORY = ALCOutOfMemory
| otherwise = error ("unmarshalALCErrorCategory: illegal value " ++ show x)
--------------------------------------------------------------------------------
-- | OpenAL detects only a subset of those conditions that could be considered
-- errors. This is because in many cases error checking would adversely impact
-- the performance of an error-free program. The state variable 'alcErrors' is
-- used to obtain error information. When an error is detected by ALC, a flag is
-- set and the error code is recorded. Further errors, if they occur, do not
-- affect this recorded code. When 'alcErrors' is read, the error for the given
-- device is returned and the flag is cleared, so that a further error will
-- again record its code. If reading 'alcErrors' returns @\[\]@ then there has
-- been no detectable error since the last time 'alcErrors' (or since the ALC
-- was initialized).
--
-- When an error flag is set, results of ALC operations are undefined only if
-- 'ALCOutOfMemory' has occurred. In other cases, the command generating the
-- error is ignored so that it has no effect on ALC state or output buffer
-- contents. If the error generating command returns a value, it returns zero.
-- If the generating command modifies values through a pointer argument, no
-- change is made to these values. These error semantics apply only to ALC
-- errors, not to system errors such as memory access errors.
alcErrors :: Device -> GettableStateVar [ALCError]
alcErrors device =
makeGettableStateVar $ do
c <- alcGetError (marshalDevice device)
if c == alc_NO_ERROR
then return []
else do
s <- getString (Just device) (ALCErrorCategory c)
return [ ALCError (unmarshalALCErrorCategory c) s ]
foreign import CALLCONV unsafe "alcGetError"
alcGetError :: ALCdevice -> IO ALCenum