Files
alda-mirror/client/model/event_sequence.go
Dave Yarwood e0d11b1ec2 include source context EVERYWHERE
This provides filename/line/column context for any error I could possibly find.
To achieve this, I made it so that all ScoreUpdates have source context, so when
updating the score results in an error, we can print out the line and column
number corresponding to the error.

It's a bit more complicated than that, because score updates are nestable (e.g.
event sequences can contain cram expressions can contain chords, etc.), which
essentially gives us a stacktrace whenever a score update results in an error. I
punted on giving the user the full stacktrace, in favor of doing something
simpler and just showing the bottom-most error, because that's probably going to
be the line and column number that's the most helpful.
2020-11-14 20:34:04 -05:00

68 lines
1.7 KiB
Go

package model
import (
"alda.io/client/json"
"github.com/mohae/deepcopy"
)
// An EventSequence is an ordered sequence of events.
type EventSequence struct {
SourceContext AldaSourceContext
Events []ScoreUpdate
}
// GetSourceContext implements HasSourceContext.GetSourceContext.
func (es EventSequence) GetSourceContext() AldaSourceContext {
return es.SourceContext
}
// JSON implements RepresentableAsJSON.JSON.
func (es EventSequence) JSON() *json.Container {
events := json.Array()
for _, event := range es.Events {
events.ArrayAppend(event.JSON())
}
return json.Object(
"type", "event-sequence",
"value", json.Object("events", events),
)
}
// UpdateScore implements ScoreUpdate.UpdateScore by updating the score with
// each event in the sequence, in order.
func (es EventSequence) UpdateScore(score *Score) error {
return score.Update(es.Events...)
}
// DurationMs implements ScoreUpdate.DurationMs by returning the total duration
// of the events in the sequence.
func (es EventSequence) DurationMs(part *Part) float64 {
durationMs := 0.0
for _, event := range es.Events {
durationMs += event.DurationMs(part)
}
return durationMs
}
// VariableValue implements ScoreUpdate.VariableValue by returning a version of
// the event sequence where each event is the captured value of that event.
func (es EventSequence) VariableValue(score *Score) (ScoreUpdate, error) {
result := deepcopy.Copy(es).(EventSequence)
result.Events = []ScoreUpdate{}
for _, event := range es.Events {
eventValue, err := event.VariableValue(score)
if err != nil {
return nil, err
}
result.Events = append(result.Events, eventValue)
}
return result, nil
}