2018-02-15 17:26:30 +08:00
|
|
|
package vars
|
|
|
|
|
|
|
|
import (
|
|
|
|
"reflect"
|
2018-11-18 22:13:03 +08:00
|
|
|
"sync"
|
2018-02-15 17:26:30 +08:00
|
|
|
|
2019-12-24 04:00:59 +08:00
|
|
|
"github.com/elves/elvish/pkg/eval/vals"
|
2018-02-15 17:26:30 +08:00
|
|
|
)
|
|
|
|
|
2019-08-27 16:55:12 +08:00
|
|
|
type PtrVar struct {
|
2018-11-18 22:13:03 +08:00
|
|
|
ptr interface{}
|
|
|
|
mutex *sync.RWMutex
|
2018-02-15 17:26:30 +08:00
|
|
|
}
|
|
|
|
|
2019-04-20 02:44:11 +08:00
|
|
|
// FromPtrWithMutex creates a variable from a pointer. The variable is kept in
|
|
|
|
// sync with the value the pointer points to, converting with vals.ScanToGo and
|
|
|
|
// vals.FromGo when Get and Set. Its access is guarded by the supplied mutex.
|
2019-08-27 16:55:12 +08:00
|
|
|
func FromPtrWithMutex(p interface{}, m *sync.RWMutex) PtrVar {
|
|
|
|
return PtrVar{p, m}
|
2018-11-18 22:13:03 +08:00
|
|
|
}
|
|
|
|
|
2019-04-20 02:44:11 +08:00
|
|
|
// FromPtr creates a variable from a pointer. The variable is kept in sync with
|
|
|
|
// the value the pointer points to, converting with vals.ScanToGo and
|
|
|
|
// vals.FromGo when Get and Set. Its access is guarded by a new mutex.
|
2019-08-27 16:55:12 +08:00
|
|
|
func FromPtr(p interface{}) PtrVar {
|
2018-11-18 22:13:03 +08:00
|
|
|
return FromPtrWithMutex(p, new(sync.RWMutex))
|
|
|
|
}
|
|
|
|
|
|
|
|
// FromInit creates a variable with an initial value. The variable created
|
|
|
|
// can be assigned values of any type.
|
|
|
|
func FromInit(v interface{}) Var {
|
|
|
|
return FromPtr(&v)
|
2018-02-15 17:26:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get returns the value pointed by the pointer, after conversion using FromGo.
|
2019-08-27 16:55:12 +08:00
|
|
|
func (v PtrVar) Get() interface{} {
|
|
|
|
return vals.FromGo(v.GetRaw())
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetRaw returns the value pointed by the pointer without any conversion.
|
|
|
|
func (v PtrVar) GetRaw() interface{} {
|
2018-11-18 22:13:03 +08:00
|
|
|
v.mutex.RLock()
|
|
|
|
defer v.mutex.RUnlock()
|
2019-08-27 16:55:12 +08:00
|
|
|
return reflect.Indirect(reflect.ValueOf(v.ptr)).Interface()
|
2018-02-15 17:26:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get sets the value pointed by the pointer, after conversion using ScanToGo.
|
2019-08-27 16:55:12 +08:00
|
|
|
func (v PtrVar) Set(val interface{}) error {
|
2018-11-18 22:13:03 +08:00
|
|
|
v.mutex.Lock()
|
|
|
|
defer v.mutex.Unlock()
|
2018-02-15 17:26:30 +08:00
|
|
|
return vals.ScanToGo(val, v.ptr)
|
|
|
|
}
|