{-# OPTIONS_GHC -optc-D_LARGEFILE_SOURCE #-}
{-# OPTIONS_GHC -optc-D_LARGEFILE64_SOURCE #-}
{-# OPTIONS_GHC -optc-D_THREAD_SAFE #-}
{-# OPTIONS_GHC -optc-D_REENTRANT #-}
{-# OPTIONS_GHC -optc-DBUILD_DIR="build/debug" #-}
{-# OPTIONS_GHC -optc-DGHC_VERSION=90205 #-}
{-# OPTIONS_GHC -optc-D__APPLE__ #-}
{-# LINE 1 "Ui/Event.hsc" #-}
module Ui.Event (
Event
, Stack(..), IndexKey, event
, clear_integration
, start, duration, text, style, stack
, start_, duration_, text_, style_, stack_, end_
, set_text_raw
, end, range, overlaps, min, max
, orientation, orientation_of
, is_negative, is_positive
, unmodified
, set_start, set_end
, place, round
, intern_event
, EventStyle
) where
import Prelude hiding (round, min, max)
import qualified Prelude
import qualified Control.DeepSeq as DeepSeq
import qualified Data.Map as Map
import qualified Data.Text as Text
import qualified Util.FFI as FFI
import qualified Util.Lens as Lens
import qualified Util.Pretty as Pretty
import qualified Util.Serialize as Serialize
import Util.Serialize (get, put)
import qualified Ui.ScoreTime as ScoreTime
import qualified Ui.Style as Style
import qualified Ui.Types as Types
import qualified Derive.Stack as Stack
import qualified App.Config as Config
import ForeignC
import Global
import Types
data Event = Event {
_start :: !TrackTime
, _duration :: !TrackTime
, _text :: !Text
, _style :: !Style.StyleId
, _stack :: !(Maybe Stack)
} deriving (Eq, Show)
data Stack = Stack {
stack_stack :: !Stack.Stack
, stack_key :: !IndexKey
} deriving (Eq, Ord, Show)
instance DeepSeq.NFData Stack where
rnf = DeepSeq.rnf . stack_stack
type IndexKey = TrackTime
instance DeepSeq.NFData Event where
rnf = DeepSeq.rnf . stack
instance Pretty Event where
format (Event start dur bs _style stack) =
"Event" <> Pretty.format (start, dur, bs, stack)
instance Pretty Stack where
format (Stack stack key) =
Pretty.format (Pretty.format stack, Pretty.format key)
event :: ScoreTime -> ScoreTime -> Text -> Event
event start dur text = Event
{ _start = start
, _duration = dur
, _text = text
, _style = Config.default_style
, _stack = Nothing
}
clear_integration :: Event -> Event
clear_integration e = event (start e) (duration e) (text e)
start :: Event -> TrackTime
start = _start
duration :: Event -> TrackTime
duration = _duration
text :: Event -> Text
text = _text
style :: Event -> Style.StyleId
style = _style
stack :: Event -> Maybe Stack
stack = _stack
start_ :: Lens Event TrackTime
start_ = event_lens True _start (\val event -> event { _start = val })
duration_ :: Lens Event TrackTime
duration_ =
event_lens_eq eq True _duration (\val event -> event { _duration = val })
where eq a b = a == b && ScoreTime.is_negative a == ScoreTime.is_negative b
text_ :: Lens Event Text
text_ = event_lens True _text (\val event -> event { _text = val })
set_text_raw :: Text -> Event -> Event
set_text_raw t event = event { _text = t }
style_ :: Lens Event Style.StyleId
style_ = event_lens False _style (\val event -> event { _style = val })
stack_ :: Lens Event (Maybe Stack)
stack_ = event_lens False _stack (\val event -> event { _stack = val })
end :: Event -> ScoreTime
end e = start e + duration e
end_ :: Lens Event TrackTime
end_ = Lens.lens end update
where
update modify event = duration_ #= modify (end event) - start event $ event
range :: Event -> (ScoreTime, ScoreTime)
range e = (min e, max e)
overlaps :: ScoreTime -> Event -> Bool
overlaps p event
| start event == p = True
| is_positive event = start event <= p && p < end event
| otherwise = end event < p && p <= start event
min, max :: Event -> ScoreTime
min e = Prelude.min (start e) (end e)
max e = Prelude.max (start e) (end e)
event_lens :: Eq a => Bool -> (Event -> a) -> (a -> Event -> Event)
-> Lens.Lens Event a
event_lens = event_lens_eq (==)
event_lens_eq :: (a -> a -> Bool) -> Bool -> (Event -> a)
-> (a -> Event -> Event) -> Lens.Lens Event a
event_lens_eq eq set_modified field set = Lens.lens field update
where
update modify event
| field event `eq` val = event
| set_modified = modified (set val event)
| otherwise = set val event
where val = modify (field event)
orientation :: Event -> Types.Orientation
orientation = orientation_of . duration
orientation_of :: TrackTime -> Types.Orientation
orientation_of t
| ScoreTime.is_negative t = Types.Negative
| otherwise = Types.Positive
is_negative :: Event -> Bool
is_negative = ScoreTime.is_negative . duration
is_positive :: Event -> Bool
is_positive = not . is_negative
modified :: Event -> Event
modified = style_ %= Config.modified_style
unmodified :: Event -> Event
unmodified = style_ %= Config.unmodified_style
set_start :: ScoreTime -> Event -> Event
set_start p event = place p (end event - p) event
set_end :: ScoreTime -> Event -> Event
set_end = (end_ #=)
place :: ScoreTime -> ScoreTime -> Event -> Event
place start dur event = modified $ event { _start = start, _duration = dur }
round :: Event -> Event
round event = event
{ _start = ScoreTime.round (start event)
, _duration = ScoreTime.round (duration event)
}
intern_event :: Map.Map Text (Text, Int) -> Event
-> (Map.Map Text (Text, Int), Event)
intern_event table event = case Map.lookup (text event) table of
Nothing -> (Map.insert (text event) (text event, 1) table, event)
Just (interned, count) ->
( Map.insert interned (interned, count+1) table
, event { _text = interned }
)
type EventStyle = Text
-> Event -> Style.StyleId
instance Serialize.Serialize Event where
put (Event start dur text style stack) =
put start >> put dur >> put text >> put style >> put stack
get = do
start :: ScoreTime <- get
dur :: ScoreTime <- get
text :: Text <- get
style :: Style.StyleId <- get
stack :: Maybe Stack <- get
return $ Event start dur text style stack
instance Serialize.Serialize Stack where
put (Stack a b) = put a >> put b
get = do
stack :: Stack.Stack <- get
key :: IndexKey <- get
return $ Stack stack key
instance CStorable Event where
sizeOf _ = (32)
{-# LINE 316 "Ui/Event.hsc" #-}
alignment _ = alignment (0 :: CDouble)
poke = poke_event
peek = error "Event peek unimplemented"
poke_event :: Ptr Event -> Event -> IO ()
poke_event eventp (Event start dur text (Style.StyleId style_id) _) = do
textp <- if Text.null text
then return nullPtr else FFI.newCString0 text
((\hsc_ptr -> pokeByteOff hsc_ptr 0)) eventp start
{-# LINE 326 "Ui/Event.hsc" #-}
((\hsc_ptr -> pokeByteOff hsc_ptr 8)) eventp dur
{-# LINE 327 "Ui/Event.hsc" #-}
((\hsc_ptr -> pokeByteOff hsc_ptr 16)) eventp textp
{-# LINE 328 "Ui/Event.hsc" #-}
((\hsc_ptr -> pokeByteOff hsc_ptr 24)) eventp style_id
{-# LINE 329 "Ui/Event.hsc" #-}