-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathid.go
71 lines (63 loc) · 1.68 KB
/
id.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
62
63
64
65
66
67
68
69
70
71
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
package debugui
import (
"fmt"
"runtime"
"slices"
)
// caller returns a program counter of the caller.
func caller() uintptr {
pc, _, _, ok := runtime.Caller(2)
if !ok {
return 0
}
return pc
}
// IDScope creates a new scope for widget IDs.
// IDScope creates a unique scope based on the caller's position and the given name string.
//
// IDScope is useful when you want to create multiple widgets at the same position e.g. in a for loop.
func (c *Context) IDScope(name string, f func()) {
pc := caller()
c.idStack = append(c.idStack, widgetID(fmt.Sprintf("caller:%d", pc)))
c.idStack = append(c.idStack, widgetID(fmt.Sprintf("string:%q", name)))
defer func() {
c.idStack = slices.Delete(c.idStack, len(c.idStack)-2, len(c.idStack))
}()
f()
}
func (c *Context) idScopeFromID(id widgetID, f func()) {
c.idStack = append(c.idStack, id)
defer func() {
c.idStack = slices.Delete(c.idStack, len(c.idStack)-1, len(c.idStack))
}()
f()
}
func (c *Context) idScopeToWidgetID() widgetID {
var newID widgetID
for _, id := range c.idStack {
if len(newID) > 0 {
newID += ":"
}
newID += "[" + id + "]"
}
return newID
}
func (c *Context) idFromString(str string) widgetID {
newID := c.idScopeToWidgetID()
if len(newID) > 0 {
newID += ":"
}
newID += widgetID(fmt.Sprintf("string:%q", str))
return newID
}
// idFromCaller returns a hash value based on the caller's file and line number.
func (c *Context) idFromCaller(callerPC uintptr) widgetID {
newID := c.idScopeToWidgetID()
if len(newID) > 0 {
newID += ":"
}
newID += widgetID(fmt.Sprintf("caller:%d", callerPC))
return newID
}