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

Safe HaskellNone

Derive.Cache

Contents

Synopsis

Documentation

block :: (PassedArgs d -> NoteDeriver) -> PassedArgs d -> NoteDeriver Source #

If the given generator has a cache entry, relevant derivation context is the same as the cache entry's, and there is no damage under the generator, I can reuse the cached values for it. This is effectively a kind of memoization. If the generator is called, the results will be put in the cache before being returned.

track Source #

Arguments

:: Cacheable d 
=> TrackTree.Track 
-> Set TrackId

Children, as documented in Track.

-> Deriver (Stream.Stream d) 
-> Deriver (Stream.Stream d) 

Cache a track, but only if it's not sliced and has a TrackId.

get_control_damage Source #

Arguments

:: BlockId 
-> TrackId 
-> (ScoreTime, ScoreTime)

track_range must be passed explicitly because the event may have been sliced and shifted, but ControlDamage should be relative to the start of the track at ScoreTime 0.

-> Deriver ControlDamage 

ScoreDamage on the current track is converted into ControlDamage, and expanded to the neighbor events. This is because control calls emit samples between their previous or next events. Then this is merged with any ControlDamage inherited from callers.

If a block call is touched by control damage, the the control damage expands to cover the entire block.

Previously, this inherited damage would also be expanded to its neighbor events, under the rationale that controls can modify other controls. While this is true, it causes an annoying situation where a control track with a single call under (say) a tempo track will cause any edits to the tempo track to invalidate the entire score. This happens a lot in practice, and I've forgotten about this wrinkle a number of times

The downside, of course, is that control damage will not cause a control call that lies before its previous event to rederive, even if it should have. I'll have to see how annoying this is in practice.

get_tempo_damage :: BlockId -> TrackId -> TrackTime -> Events.Events -> Deriver ControlDamage Source #

Since the warp is the integral of the tempo track, damage on the tempo track will affect all events after it. Actually, the damage extends from the previous event to the end of the track, since interpolating calls extend from the previous event.

It would be simpler to have any edit invalidate the whole track, but it seems like editing a score at the end is a common case, and it would be a shame to rederive the entire score on each edit when only the very end has changed.

cache_hit_events :: Log.Msg -> Maybe.Maybe Int Source #

Get the number of cached events from a cache_hit_msg.

cache_miss_reason :: Log.Msg -> Maybe.Maybe Text Source #

Get the reason from a cache_miss_msg.

debugging

pretty_cache :: Cache -> Text Source #

Format the cache in a hopefully readable way.

find_generator_cache :: Cacheable d => Type -> CacheKey -> Ranges -> ScoreDamage -> ControlDamage -> Cache -> Either (Bool, Text) (Collect, Stream.Stream d) Source #

Find the cached value, or a reason why there is no cache entry. This is the function that determines whether you hit the cache or not.