• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mlange-42 / ark-pixel / 13719732838

07 Mar 2025 11:28AM CUT coverage: 29.148% (+8.1%) from 21.025%
13719732838

push

github

web-flow
Add entity inspector (#4)

76 of 103 new or added lines in 1 file covered. (73.79%)

195 of 669 relevant lines covered (29.15%)

31.42 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.79
/plot/inspector.go
1
package plot
2

3
import (
4
        "fmt"
5
        "io"
6
        "reflect"
7

8
        px "github.com/gopxl/pixel/v2"
9
        "github.com/gopxl/pixel/v2/backends/opengl"
10
        "github.com/gopxl/pixel/v2/ext/text"
11
        "github.com/mlange-42/ark-tools/resource"
12
        "github.com/mlange-42/ark/ecs"
13
)
14

15
// Inspector drawer for inspecting entities.
16
//
17
// Shows information of the entity indicated by the SelectedEntity resource ([github.com/mlange-42/arche-model/resource.SelectedEntity]).
18
// Entity selection is to be done by another system, e.g. by user input.
19
//
20
// Details can be adjusted using the HideXxx fields.
21
// Further, keys F, T, V and N can be used to toggle details during a running simulation.
22
// The view can be scrolled using arrow keys or the mouse wheel.
23
type Inspector struct {
24
        HideFields  bool // Hides components fields.
25
        HideTypes   bool // Hides field types.
26
        HideValues  bool // Hides field values.
27
        HideNames   bool // Hide field names of nested structs.
28
        scroll      int
29
        selectedRes ecs.Resource[resource.SelectedEntity]
30
        text        *text.Text
31
        helpText    *text.Text
32
}
33

34
// Initialize the system
35
func (i *Inspector) Initialize(w *ecs.World, win *opengl.Window) {
3✔
36
        i.selectedRes = ecs.NewResource[resource.SelectedEntity](w)
3✔
37

3✔
38
        i.text = text.New(px.V(0, 0), defaultFont)
3✔
39
        i.helpText = text.New(px.V(0, 0), defaultFont)
3✔
40

3✔
41
        i.text.AlignedTo(px.BottomRight)
3✔
42
        i.helpText.AlignedTo(px.BottomRight)
3✔
43

3✔
44
        fmt.Fprint(i.helpText, "Toggle [f]ields, [t]ypes, [v]alues or [n]ames, scroll with arrows or mouse wheel.")
3✔
45
}
3✔
46

47
// Update the drawer.
48
func (i *Inspector) Update(w *ecs.World) {}
300✔
49

50
// UpdateInputs handles input events of the previous frame update.
51
func (i *Inspector) UpdateInputs(w *ecs.World, win *opengl.Window) {
122✔
52
        if win.JustPressed(px.KeyF) {
122✔
NEW
53
                i.HideFields = !i.HideFields
×
NEW
54
                return
×
NEW
55
        }
×
56
        if win.JustPressed(px.KeyT) {
122✔
NEW
57
                i.HideTypes = !i.HideTypes
×
NEW
58
                return
×
NEW
59
        }
×
60
        if win.JustPressed(px.KeyV) {
122✔
NEW
61
                i.HideValues = !i.HideValues
×
NEW
62
                return
×
NEW
63
        }
×
64
        if win.JustPressed(px.KeyN) {
122✔
NEW
65
                i.HideNames = !i.HideNames
×
NEW
66
                return
×
NEW
67
        }
×
68
        if win.JustPressed(px.KeyDown) {
122✔
NEW
69
                i.scroll++
×
NEW
70
                return
×
NEW
71
        }
×
72
        if win.JustPressed(px.KeyUp) {
122✔
NEW
73
                if i.scroll > 0 {
×
NEW
74
                        i.scroll--
×
NEW
75
                }
×
NEW
76
                return
×
77
        }
78
        scr := win.MouseScroll()
122✔
79
        if scr.Y != 0 {
122✔
NEW
80
                i.scroll -= int(scr.Y)
×
NEW
81
                if i.scroll < 0 {
×
NEW
82
                        i.scroll = 0
×
NEW
83
                }
×
84
        }
85
}
86

87
// Draw the system
88
func (i *Inspector) Draw(w *ecs.World, win *opengl.Window) {
122✔
89
        i.helpText.Draw(win, px.IM.Moved(px.V(10, 20)))
122✔
90

122✔
91
        if !i.selectedRes.Has() {
122✔
NEW
92
                return
×
NEW
93
        }
×
94
        sel := i.selectedRes.Get().Selected
122✔
95
        if sel.IsZero() {
122✔
NEW
96
                return
×
NEW
97
        }
×
98

99
        height := win.Canvas().Bounds().H()
122✔
100
        x0 := 10.0
122✔
101
        y0 := height - 10.0
122✔
102

122✔
103
        i.text.Clear()
122✔
104
        fmt.Fprintf(i.text, "Entity %+v\n\n", sel)
122✔
105

122✔
106
        if !w.Alive(sel) {
133✔
107
                fmt.Fprint(i.text, "  dead entity")
11✔
108
                i.text.Draw(win, px.IM.Moved(px.V(x0, y0)))
11✔
109
                return
11✔
110
        }
11✔
111

112
        scroll := i.scroll
111✔
113
        ids := w.Unsafe().IDs(sel)
111✔
114
        for _, id := range ids {
333✔
115
                tp, _ := ecs.ComponentInfo(w, id)
222✔
116
                ptr := w.Unsafe().Get(sel, id)
222✔
117
                val := reflect.NewAt(tp.Type, ptr).Elem()
222✔
118

222✔
119
                if scroll <= 0 {
444✔
120
                        fmt.Fprintf(i.text, "  %s\n", tp.Type.Name())
222✔
121
                }
222✔
122
                scroll--
222✔
123

222✔
124
                if !i.HideFields {
444✔
125
                        for k := 0; k < val.NumField(); k++ {
666✔
126
                                field := tp.Type.Field(k)
444✔
127
                                if field.IsExported() {
888✔
128
                                        if scroll <= 0 {
888✔
129
                                                i.printField(i.text, tp.Type, field, val.Field(k))
444✔
130
                                        }
444✔
131
                                        scroll--
444✔
132
                                }
133
                        }
134
                        if scroll <= 0 {
444✔
135
                                fmt.Fprint(i.text, "\n")
222✔
136
                        }
222✔
137
                        scroll--
222✔
138
                }
139
        }
140

141
        i.text.Draw(win, px.IM.Moved(px.V(x0, y0)))
111✔
142
}
143

144
func (i *Inspector) printField(w io.Writer, tp reflect.Type, field reflect.StructField, value reflect.Value) {
444✔
145
        fmt.Fprintf(w, "    %-20s ", field.Name)
444✔
146
        if !i.HideTypes {
888✔
147
                fmt.Fprintf(w, "    %-16s ", value.Type())
444✔
148
        }
444✔
149
        if !i.HideValues {
888✔
150
                if i.HideNames {
488✔
151
                        fmt.Fprintf(w, "= %v", value.Interface())
44✔
152
                } else {
444✔
153
                        fmt.Fprintf(w, "= %+v", value.Interface())
400✔
154
                }
400✔
155
        }
156
        fmt.Fprint(i.text, "\n")
444✔
157
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc