Karya, built on Mon Jul 24 11:39:07 PDT 2017 (patch 33511aca01257b76b88de7c7a2763b7a965c084e)

Safe HaskellNone




This module is sister to Derive.Deriver.Lib, except that it contains functions which are normally only used by the built-in track derivation scheme, and are not used when writing most normal calls.


generic state access

local :: (Dynamic -> Dynamic) -> Deriver a -> Deriver a Source #

This is a little different from Reader.local because only a portion of the state is used Reader-style.

Note that this doesn't restore the state on an exception. I think this is ok because exceptions are always "caught" at the event evaluation level since it runs each one separately. Since the state dynamic state (i.e. except Collect) from the sub derivation is discarded, whatever state it's in after the exception shouldn't matter.

detached_local :: (Dynamic -> Dynamic) -> Deriver a -> Deriver (Either Error a) Source #

A version of local that catches exceptions and ignores any changes to Collect. This is appropriate for sub-calls that are below normal track derivation.


merge_collect :: Collect -> Deriver () Source #

Collect is only ever accumulated.

Direct modification would be potentially more efficient, but according to profiling it doesn't make a difference.

local_collect :: Deriver a -> Deriver (a, Collect) Source #

Run with an empty Collect, restore the original Collect, and return the sub-deriver's Collect.

trim_track_warps :: Maybe RealTime.RealTime -> Maybe RealTime.RealTime -> Deriver a -> Deriver a Source #

Modify the collect_warp_map to reduce the start and end by the given times. This is useful if you're going to clip off some events. The TrackWarps, and hence playback cursor, can't know you're going to do this, so you have to tell it.

with_collect :: (Collect -> Collect) -> Deriver a -> Deriver a Source #

Run the deriver and modify the Collect it returns.

modify_collect :: (Collect -> Collect) -> Deriver () Source #

TODO this is sketchy, you're supposed to use merge_collect.


record_track_dynamic :: Dynamic -> Maybe TrackDynamic Source #

Figure out the current block and track, and record the current environ in the Collect. It only needs to be recorded once per track.

record_track_dynamic_for :: BlockId -> TrackId -> Deriver () Source #

record_track_dynamic for when I already know BlockId and TrackId.

misc Dynamic state


ui state

get_track :: TrackId -> Deriver Track.Track Source #

Because Deriver is not a UiStateMonad.

TODO I suppose it could be, but then I'd be tempted to make a ReadOnlyUiStateMonad. And I'd have to merge the exceptions. Or just rethrow, right?

eval_ui :: Text -> Ui.StateId a -> Deriver a Source #

Evaluate a Ui.M computation, rethrowing any errors.

lookup_id :: (Ord k, Show k) => k -> Map k a -> Deriver a Source #

Lookup map!key, throwing if it doesn't exist.


with_stack_block :: BlockId -> Deriver a -> Deriver a Source #

Make a quick trick block stack.

with_stack_track :: TrackId -> Deriver a -> Deriver a Source #

Make a quick trick track stack.

add_stack_frame :: Stack.Frame -> Dynamic -> Dynamic Source #

Add a new stack frame and hash it with the random seed.


time and duration


place :: ScoreTime -> ScoreTime -> Deriver a -> Deriver a Source #

at and stretch in one. It's a little faster than using them separately. The order is stretch, then shift, as documented by Warp. TODO shouldn't the arguments go in the other order then?

warp :: Warp -> Deriver a -> Deriver a Source #

Low level warp function.

Previously, this would disallow <=0 stretch, but it turns out to be useful to stretch events to 0, and to negative durations.

is_root_block :: Deriver Bool Source #

Am I deriving the toplevel block?

track warp

add_new_track_warp :: Maybe TrackId -> Deriver () Source #

Start a new track warp for the current block_id.

This must be called for each block, and it must be called after the tempo is warped for that block so it can install the new warp.

block_logical_range :: BlockId -> Deriver (TrackTime, TrackTime) Source #

Sub-derived blocks are stretched according to their length, and this function defines the length of a block. This is therefore the logical duration of the block, which may be shorter or lorger than the end of the last event, or the ruler.

block_event_end :: BlockId -> Deriver ScoreTime Source #

Get the duration of the block according to the last event.


record_empty_tracks :: [TrackId] -> Deriver () Source #

The deriver strips out tracks that can't be derived because they have no notes. But that means the track warps and track dynamics aren't recorded, which means they don't have tempo or a playback monitor, which makes them annoying.


get_ruler :: Deriver Ruler.Marklists Source #

Get the Ruler.meter marklists, if there is a ruler track here. This is called in all contexts, due to control_at, so it has to be careful to not require a ruler.