mirror of
https://github.com/alda-lang/alda.git
synced 2026-02-27 18:24:13 +01:00
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.
68 lines
1.7 KiB
Go
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
|
|
}
|