diff --git a/ds/reactive/clock_test.go b/ds/reactive/clock_test.go index 45187f3c..a0d6d621 100644 --- a/ds/reactive/clock_test.go +++ b/ds/reactive/clock_test.go @@ -18,5 +18,5 @@ func TestClock(t *testing.T) { time.Sleep(time.Second) - require.Greater(t, tickCount, 10) + require.GreaterOrEqual(t, tickCount, 10) } diff --git a/ds/reactive/variable.go b/ds/reactive/variable.go index 69c484d9..44926ce4 100644 --- a/ds/reactive/variable.go +++ b/ds/reactive/variable.go @@ -105,69 +105,77 @@ type DerivedVariable[Type comparable] interface { } // NewDerivedVariable creates a DerivedVariable that transforms an input value into a different one. -func NewDerivedVariable[Type, InputType1 comparable, InputValueType1 ReadableVariable[InputType1]](compute func(InputType1) Type, input1 InputValueType1) DerivedVariable[Type] { +func NewDerivedVariable[Type, InputType1 comparable, InputValueType1 ReadableVariable[InputType1]](compute func(currentValue Type, inputValue1 InputType1) Type, input1 InputValueType1, initialValue ...Type) DerivedVariable[Type] { return newDerivedVariable[Type](func(d DerivedVariable[Type]) func() { return input1.OnUpdate(func(_, input1 InputType1) { - d.Compute(func(_ Type) Type { return compute(input1) }) + d.Compute(func(currentValue Type) Type { return compute(currentValue, input1) }) }, true) - }) + }, initialValue...) } // NewDerivedVariable2 creates a DerivedVariable that transforms two input values into a different one. -func NewDerivedVariable2[Type, InputType1, InputType2 comparable, InputValueType1 ReadableVariable[InputType1], InputValueType2 ReadableVariable[InputType2]](compute func(InputType1, InputType2) Type, input1 InputValueType1, input2 InputValueType2) DerivedVariable[Type] { +func NewDerivedVariable2[Type, InputType1, InputType2 comparable, InputValueType1 ReadableVariable[InputType1], InputValueType2 ReadableVariable[InputType2]](compute func(currentValue Type, inputValue1 InputType1, inputValue2 InputType2) Type, input1 InputValueType1, input2 InputValueType2, initialValue ...Type) DerivedVariable[Type] { return newDerivedVariable[Type](func(d DerivedVariable[Type]) func() { return lo.Batch( input1.OnUpdate(func(_, input1 InputType1) { - d.Compute(func(_ Type) Type { return compute(input1, input2.Get()) }) + d.Compute(func(currentValue Type) Type { return compute(currentValue, input1, input2.Get()) }) }, true), input2.OnUpdate(func(_, input2 InputType2) { - d.Compute(func(_ Type) Type { return compute(input1.Get(), input2) }) + d.Compute(func(currentValue Type) Type { return compute(currentValue, input1.Get(), input2) }) }, true), ) - }) + }, initialValue...) } // NewDerivedVariable3 creates a DerivedVariable that transforms three input values into a different one. -func NewDerivedVariable3[Type, InputType1, InputType2, InputType3 comparable, InputValueType1 ReadableVariable[InputType1], InputValueType2 ReadableVariable[InputType2], InputValueType3 ReadableVariable[InputType3]](compute func(InputType1, InputType2, InputType3) Type, input1 InputValueType1, input2 InputValueType2, input3 InputValueType3) DerivedVariable[Type] { +func NewDerivedVariable3[Type, InputType1, InputType2, InputType3 comparable, InputValueType1 ReadableVariable[InputType1], InputValueType2 ReadableVariable[InputType2], InputValueType3 ReadableVariable[InputType3]](compute func(currentValue Type, inputValue1 InputType1, inputValue2 InputType2, inputValue3 InputType3) Type, input1 InputValueType1, input2 InputValueType2, input3 InputValueType3, initialValue ...Type) DerivedVariable[Type] { return newDerivedVariable[Type](func(d DerivedVariable[Type]) func() { return lo.Batch( input1.OnUpdate(func(_, input1 InputType1) { - d.Compute(func(_ Type) Type { return compute(input1, input2.Get(), input3.Get()) }) + d.Compute(func(currentValue Type) Type { return compute(currentValue, input1, input2.Get(), input3.Get()) }) }, true), input2.OnUpdate(func(_, input2 InputType2) { - d.Compute(func(_ Type) Type { return compute(input1.Get(), input2, input3.Get()) }) + d.Compute(func(currentValue Type) Type { return compute(currentValue, input1.Get(), input2, input3.Get()) }) }, true), input3.OnUpdate(func(_, input3 InputType3) { - d.Compute(func(_ Type) Type { return compute(input1.Get(), input2.Get(), input3) }) + d.Compute(func(currentValue Type) Type { return compute(currentValue, input1.Get(), input2.Get(), input3) }) }, true), ) - }) + }, initialValue...) } // NewDerivedVariable4 creates a DerivedVariable that transforms four input values into a different one. -func NewDerivedVariable4[Type, InputType1, InputType2, InputType3, InputType4 comparable, InputValueType1 ReadableVariable[InputType1], InputValueType2 ReadableVariable[InputType2], InputValueType3 ReadableVariable[InputType3], InputValueType4 ReadableVariable[InputType4]](compute func(InputType1, InputType2, InputType3, InputType4) Type, input1 InputValueType1, input2 InputValueType2, input3 InputValueType3, input4 InputValueType4) DerivedVariable[Type] { +func NewDerivedVariable4[Type, InputType1, InputType2, InputType3, InputType4 comparable, InputValueType1 ReadableVariable[InputType1], InputValueType2 ReadableVariable[InputType2], InputValueType3 ReadableVariable[InputType3], InputValueType4 ReadableVariable[InputType4]](compute func(currentValue Type, inputValue1 InputType1, inputValue2 InputType2, inputValue3 InputType3, inputValue4 InputType4) Type, input1 InputValueType1, input2 InputValueType2, input3 InputValueType3, input4 InputValueType4, initialValue ...Type) DerivedVariable[Type] { return newDerivedVariable[Type](func(d DerivedVariable[Type]) func() { return lo.Batch( input1.OnUpdate(func(_, input1 InputType1) { - d.Compute(func(_ Type) Type { return compute(input1, input2.Get(), input3.Get(), input4.Get()) }) + d.Compute(func(currentValue Type) Type { + return compute(currentValue, input1, input2.Get(), input3.Get(), input4.Get()) + }) }, true), input2.OnUpdate(func(_, input2 InputType2) { - d.Compute(func(_ Type) Type { return compute(input1.Get(), input2, input3.Get(), input4.Get()) }) + d.Compute(func(currentValue Type) Type { + return compute(currentValue, input1.Get(), input2, input3.Get(), input4.Get()) + }) }, true), input3.OnUpdate(func(_, input3 InputType3) { - d.Compute(func(_ Type) Type { return compute(input1.Get(), input2.Get(), input3, input4.Get()) }) + d.Compute(func(currentValue Type) Type { + return compute(currentValue, input1.Get(), input2.Get(), input3, input4.Get()) + }) }, true), input4.OnUpdate(func(_, input4 InputType4) { - d.Compute(func(_ Type) Type { return compute(input1.Get(), input2.Get(), input3.Get(), input4) }) + d.Compute(func(currentValue Type) Type { + return compute(currentValue, input1.Get(), input2.Get(), input3.Get(), input4) + }) }, true), ) - }) + }, initialValue...) } // endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/ds/reactive/variable_impl.go b/ds/reactive/variable_impl.go index 43fbeefb..da1410cc 100644 --- a/ds/reactive/variable_impl.go +++ b/ds/reactive/variable_impl.go @@ -283,9 +283,9 @@ type derivedVariable[ValueType comparable] struct { } // newDerivedVariable creates a new derivedVariable instance. -func newDerivedVariable[ValueType comparable](subscribe func(DerivedVariable[ValueType]) func()) *derivedVariable[ValueType] { +func newDerivedVariable[ValueType comparable](subscribe func(DerivedVariable[ValueType]) func(), initialValue ...ValueType) *derivedVariable[ValueType] { d := &derivedVariable[ValueType]{ - Variable: NewVariable[ValueType](), + Variable: NewVariable[ValueType]().Init(lo.First(initialValue)), } d.unsubscribe = subscribe(d)