-
Notifications
You must be signed in to change notification settings - Fork 402
/
dependency.go
61 lines (53 loc) · 1.5 KB
/
dependency.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
55
56
57
58
59
60
61
// Copyright (C) 2024 Storj Labs, Inc.
// See LICENSE for copying information.
package mud
import (
"fmt"
"reflect"
)
// Optional tag is used to mark components which may not required.
type Optional struct{}
// Find selects components matching the selector.
func Find(ball *Ball, selector ComponentSelector) (result []*Component) {
for _, c := range ball.registry {
if selector(c) {
result = append(result, c)
}
}
return result
}
// FindSelectedWithDependencies selects components matching the selector, together with all the dependencies.
func FindSelectedWithDependencies(ball *Ball, selector ComponentSelector) (result []*Component) {
dependencies := map[reflect.Type]struct{}{}
for _, component := range ball.registry {
if selector(component) {
collectDependencies(ball, component, dependencies)
}
}
for k := range dependencies {
result = append(result, mustLookupByType(ball, k))
}
return filterComponents(sortedComponents(ball), result)
}
func collectDependencies(ball *Ball, c *Component, result map[reflect.Type]struct{}) {
// don't check it again
for k := range result {
if c.target == k {
return
}
}
// don't check it again
result[c.target] = struct{}{}
for _, dep := range c.requirements {
// ignore if optional
dc, found := lookupByType(ball, dep)
if !found {
panic(fmt.Sprintf("Dependency %s for %s is missing", dep, c.ID()))
}
_, optional := findTag[Optional](dc)
if optional {
continue
}
collectDependencies(ball, mustLookupByType(ball, dep), result)
}
}