sointu/tracker/optional_int.go

82 lines
2.0 KiB
Go

package tracker
import "github.com/vsariola/sointu/tracker/types"
type (
// OptionalInt tries to follow the same convention as e.g. Int{...} or Bool{...}
// Do not confuse with types.OptionalInteger, which you might use as a model,
// but don't necessarily have to.
OptionalInt struct {
optionalIntData
}
optionalIntData interface {
Unpack() (int, bool)
Value() int
Range() intRange
setValue(int)
unsetValue()
change(kind string) func()
}
TrackMidiVelIn Model
)
func (v OptionalInt) Set(value int, present bool) (ok bool) {
if !present {
v.unsetValue()
return true
}
// TODO: can we deduplicate this by referencing Int{...}.Set(value) ?
r := v.Range()
if v.Equals(value, present) || value < r.Min || value > r.Max {
return false
}
defer v.change("Set")()
v.setValue(value)
return true
}
func (v OptionalInt) Equals(value int, present bool) bool {
oldValue, oldPresent := v.Unpack()
return value == oldValue && present == oldPresent
}
// Model methods
func (m *Model) TrackForMidiVelIn() *TrackMidiVelIn { return (*TrackMidiVelIn)(m) }
// TrackForMidiVelIn - to record Velocity in the track with given number (-1 = off)
func (m *TrackMidiVelIn) OptionalInt() OptionalInt { return OptionalInt{m} }
func (m *TrackMidiVelIn) Range() intRange { return intRange{0, len(m.d.Song.Score.Tracks) - 1} }
func (m *TrackMidiVelIn) change(string) func() { return func() {} }
func (m *TrackMidiVelIn) setValue(val int) {
m.trackForMidiVelIn = types.NewOptionalInteger(val, val >= 0)
}
func (m *TrackMidiVelIn) unsetValue() {
m.trackForMidiVelIn = types.NewEmptyOptionalInteger()
}
func (m *TrackMidiVelIn) Unpack() (int, bool) {
return m.trackForMidiVelIn.Unpack()
}
func (m *TrackMidiVelIn) Value() int {
return m.trackForMidiVelIn.Value()
}
func (m *TrackMidiVelIn) IsValid() bool {
if m.trackForMidiVelIn.Empty() {
return true
}
return (*Model)(m).CanUseTrackForMidiVelInput(m.trackForMidiVelIn.Value())
}
func (m *TrackMidiVelIn) Equals(value int) bool {
return m.trackForMidiVelIn.Equals(value)
}