-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathwait.go
54 lines (50 loc) · 1.35 KB
/
wait.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package bus
import (
"context"
"github.com/aperturerobotics/controllerbus/directive"
)
// ExecWaitValue executes a directive and waits for a value matching the cb.
//
// valDisposeCallback can be nil, will be called if the value is disposed.
// If cb returns true, nil, returns the value.
// If checkCb is nil, returns first value.
//
// idleCb is called when idle with the list of resolver errors.
// idleCb should return (wait, error): if wait=true, continues to wait.
// if idleCb is nil: continues to wait when the directive becomes idle
// errs is the list of errors from the resolvers (if any)
func ExecWaitValue[T directive.Value](
ctx context.Context,
b Bus,
dir directive.Directive,
idleCb func(isIdle bool, errs []error) (bool, error),
valDisposeCallback func(),
checkCb func(val T) (bool, error),
) (T, directive.Instance, directive.Reference, error) {
av, avDi, avRef, err := ExecOneOffWithFilter(
ctx,
b,
dir,
idleCb,
valDisposeCallback,
func(val directive.AttachedValue) (bool, error) {
v, vOk := val.GetValue().(T)
if !vOk {
return false, nil
}
if checkCb == nil {
return true, nil
}
return checkCb(v)
},
)
if err != nil || av == nil {
if avRef != nil {
avRef.Release()
}
var empty T
return empty, nil, nil, err
}
// note: type is already asserted above
return av.GetValue().(T), avDi, avRef, nil
}