github.com/enbility/spine-go@v0.7.0/spine/function_data.go (about) 1 package spine 2 3 import ( 4 "fmt" 5 "sync" 6 7 "github.com/enbility/ship-go/logging" 8 "github.com/enbility/spine-go/api" 9 "github.com/enbility/spine-go/model" 10 "github.com/enbility/spine-go/util" 11 ) 12 13 type FunctionData[T any] struct { 14 functionType model.FunctionType 15 data *T 16 17 mux sync.Mutex 18 } 19 20 func NewFunctionData[T any](function model.FunctionType) *FunctionData[T] { 21 return &FunctionData[T]{ 22 functionType: function, 23 } 24 } 25 26 var _ api.FunctionDataInterface = (*FunctionData[int])(nil) 27 28 /* FunctionDataInterface */ 29 30 func (r *FunctionData[T]) FunctionType() model.FunctionType { 31 return r.functionType 32 } 33 34 func (r *FunctionData[T]) SupportsPartialWrite() bool { 35 return util.Implements[T, model.Updater]() 36 } 37 38 func (r *FunctionData[T]) DataCopy() *T { 39 r.mux.Lock() 40 defer r.mux.Unlock() 41 42 // copy the data and return it as the data can be updated 43 // and newly assigned at any time otherwise we run into panics 44 // because of invalid memory address or nil pointer dereference 45 var copiedData T 46 if r.data == nil { 47 return nil 48 } 49 50 copiedData = *r.data 51 52 return &copiedData 53 } 54 55 func (r *FunctionData[T]) UpdateData(remoteWrite, persist bool, newData *T, filterPartial *model.FilterType, filterDelete *model.FilterType) (any, *model.ErrorType) { 56 r.mux.Lock() 57 defer r.mux.Unlock() 58 59 if filterPartial == nil && filterDelete == nil && persist { 60 // just set the data 61 r.data = newData 62 return r.data, nil 63 } 64 65 if !r.SupportsPartialWrite() { 66 return nil, model.NewErrorTypeFromString(fmt.Sprintf("partial updates are not supported for type '%s'", util.Type[T]().Name())) 67 } 68 69 if r.data == nil { 70 r.data = new(T) 71 } 72 73 updater := any(r.data).(model.Updater) 74 data, success := updater.UpdateList(remoteWrite, persist, newData, filterPartial, filterDelete) 75 if !success { 76 return nil, model.NewErrorTypeFromString("update failed, likely not allowed to write") 77 } 78 79 return data, nil 80 } 81 82 func (r *FunctionData[T]) DataCopyAny() any { 83 return r.DataCopy() 84 } 85 86 func (r *FunctionData[T]) UpdateDataAny(remoteWrite, persist bool, newData any, filterPartial *model.FilterType, filterDelete *model.FilterType) (any, *model.ErrorType) { 87 data, err := r.UpdateData(remoteWrite, persist, newData.(*T), filterPartial, filterDelete) 88 if err != nil { 89 logging.Log().Debug(err.String()) 90 } 91 92 return data, err 93 }