Skip to content

Commit 5ffbcd7

Browse files
committed
debugui: stop using pointers as identifiers
Closes #24
1 parent 24733b2 commit 5ffbcd7

File tree

4 files changed

+40
-47
lines changed

4 files changed

+40
-47
lines changed

control.go

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"fmt"
88
"image"
99
"math"
10-
"unsafe"
1110

1211
"github.com/hajimehoshi/ebiten/v2"
1312
"github.com/hajimehoshi/ebiten/v2/inpututil"
@@ -198,14 +197,14 @@ func (c *Context) button(label string, opt option, callerPC uintptr) (controlID,
198197

199198
// Checkbox creates a checkbox with the given boolean state and text label.
200199
//
201-
// The identifier for a Checkbox is the pointer value of its state.
202-
// Checkbox objects with different pointers are considered distinct.
203-
// Therefore, for example, you should not provide a pointer to a local variable;
204-
// instead, you should provide a pointer to a member variable of a struct or a pointer to a global variable.
200+
// A Checkbox control is uniquely determined by its call location.
201+
// Function calls made in different locations will create different controls.
202+
// If you want to generate different controls with the same function call in a loop (such as a for loop), use [IDScope].
205203
func (c *Context) Checkbox(state *bool, label string) bool {
204+
pc := caller()
205+
id := c.idFromCaller(pc)
206206
var res bool
207207
c.wrapError(func() error {
208-
id := c.idFromPointer(unsafe.Pointer(state))
209208
var err error
210209
res, err = c.control(id, 0, func(bounds image.Rectangle, wasFocused bool) (bool, error) {
211210
var res bool
@@ -233,10 +232,9 @@ func (c *Context) Checkbox(state *bool, label string) bool {
233232
return res
234233
}
235234

236-
func (c *Context) slider(value *int, low, high, step int, opt option) (bool, error) {
235+
func (c *Context) slider(value *int, low, high, step int, id controlID, opt option) (bool, error) {
237236
last := *value
238237
v := last
239-
id := c.idFromPointer(unsafe.Pointer(value))
240238

241239
res, err := c.numberTextField(&v, id)
242240
if err != nil {
@@ -279,10 +277,9 @@ func (c *Context) slider(value *int, low, high, step int, opt option) (bool, err
279277
return res, nil
280278
}
281279

282-
func (c *Context) sliderF(value *float64, low, high, step float64, digits int, opt option) (bool, error) {
280+
func (c *Context) sliderF(value *float64, low, high, step float64, digits int, id controlID, opt option) (bool, error) {
283281
last := *value
284282
v := last
285-
id := c.idFromPointer(unsafe.Pointer(value))
286283

287284
res, err := c.numberTextFieldF(&v, id)
288285
if err != nil {

id.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"fmt"
88
"runtime"
99
"slices"
10-
"unsafe"
1110
)
1211

1312
// caller returns a program counter of the caller.
@@ -49,10 +48,6 @@ func (c *Context) idScopeFromGlobalString(name string, f func()) {
4948
f()
5049
}
5150

52-
func (c *Context) idFromPointer(pointer unsafe.Pointer) controlID {
53-
return controlID(fmt.Sprintf("pointer:%p", pointer))
54-
}
55-
5651
func (c *Context) idScopeToControlID() controlID {
5752
var newID controlID
5853
for _, id := range c.idStack {

textfield.go

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"os"
1010
"strconv"
1111
"unicode/utf8"
12-
"unsafe"
1312

1413
"github.com/hajimehoshi/ebiten/v2"
1514
"github.com/hajimehoshi/ebiten/v2/inpututil"
@@ -24,15 +23,16 @@ const (
2423
//
2524
// TextField returns true when this TextField is unfocused or the user pressed Enter, otherwise false.
2625
//
27-
// The identifier for a TextField is the pointer value of its buf.
28-
// TextField objects with different pointers are considered distinct.
29-
// Therefore, for example, you should not provide a pointer to a local variable;
30-
// instead, you should provide a pointer to a member variable of a struct or a pointer to a global variable.
26+
// A TextField control is uniquely determined by its call location.
27+
// Function calls made in different locations will create different controls.
28+
// If you want to generate different controls with the same function call in a loop (such as a for loop), use [IDScope].
3129
func (c *Context) TextField(buf *string) bool {
30+
pc := caller()
31+
id := c.idFromCaller(pc)
3232
var res bool
3333
c.wrapError(func() error {
3434
var err error
35-
res, err = c.textField(buf, 0)
35+
res, err = c.textField(buf, id, 0)
3636
if err != nil {
3737
return err
3838
}
@@ -119,8 +119,7 @@ func (c *Context) SetTextFieldValue(value string) {
119119
})
120120
}
121121

122-
func (c *Context) textField(buf *string, opt option) (bool, error) {
123-
id := c.idFromPointer(unsafe.Pointer(buf))
122+
func (c *Context) textField(buf *string, id controlID, opt option) (bool, error) {
124123
c.lastTextFieldID = id
125124
res, err := c.textFieldRaw(buf, id, opt)
126125
if err != nil {
@@ -135,15 +134,16 @@ func (c *Context) textField(buf *string, opt option) (bool, error) {
135134
//
136135
// NumberField returns true when the value has been changed, otherwise false.
137136
//
138-
// The identifier for a NumberField is the pointer value of its value.
139-
// NumberField objects with different pointers are considered distinct.
140-
// Therefore, for example, you should not provide a pointer to a local variable;
141-
// instead, you should provide a pointer to a member variable of a struct or a pointer to a global variable.
137+
// A NumberField control is uniquely determined by its call location.
138+
// Function calls made in different locations will create different controls.
139+
// If you want to generate different controls with the same function call in a loop (such as a for loop), use [IDScope].
142140
func (c *Context) NumberField(value *int, step int) bool {
141+
pc := caller()
142+
id := c.idFromCaller(pc)
143143
var res bool
144144
c.wrapError(func() error {
145145
var err error
146-
res, err = c.numberField(value, step, optionAlignCenter)
146+
res, err = c.numberField(value, step, id, optionAlignCenter)
147147
if err != nil {
148148
return err
149149
}
@@ -159,15 +159,16 @@ func (c *Context) NumberField(value *int, step int) bool {
159159
//
160160
// NumberFieldF returns true when the value has been changed, otherwise false.
161161
//
162-
// The identifier for a NumberFieldF is the pointer value of its value.
163-
// NumberFieldF objects with different pointers are considered distinct.
164-
// Therefore, for example, you should not provide a pointer to a local variable;
165-
// instead, you should provide a pointer to a member variable of a struct or a pointer to a global variable.
162+
// A NumberFieldF control is uniquely determined by its call location.
163+
// Function calls made in different locations will create different controls.
164+
// If you want to generate different controls with the same function call in a loop (such as a for loop), use [IDScope].
166165
func (c *Context) NumberFieldF(value *float64, step float64, digits int) bool {
166+
pc := caller()
167+
id := c.idFromCaller(pc)
167168
var res bool
168169
c.wrapError(func() error {
169170
var err error
170-
res, err = c.numberFieldF(value, step, digits, optionAlignCenter)
171+
res, err = c.numberFieldF(value, step, digits, id, optionAlignCenter)
171172
if err != nil {
172173
return err
173174
}
@@ -176,8 +177,7 @@ func (c *Context) NumberFieldF(value *float64, step float64, digits int) bool {
176177
return res
177178
}
178179

179-
func (c *Context) numberField(value *int, step int, opt option) (bool, error) {
180-
id := c.idFromPointer(unsafe.Pointer(value))
180+
func (c *Context) numberField(value *int, step int, id controlID, opt option) (bool, error) {
181181
last := *value
182182

183183
res, err := c.numberTextField(value, id)
@@ -210,8 +210,7 @@ func (c *Context) numberField(value *int, step int, opt option) (bool, error) {
210210
return res, nil
211211
}
212212

213-
func (c *Context) numberFieldF(value *float64, step float64, digits int, opt option) (bool, error) {
214-
id := c.idFromPointer(unsafe.Pointer(value))
213+
func (c *Context) numberFieldF(value *float64, step float64, digits int, id controlID, opt option) (bool, error) {
215214
last := *value
216215

217216
res, err := c.numberTextFieldF(value, id)

widget.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,16 @@ func (c *Context) Button(label string) bool {
2323
//
2424
// Slider returns true if the value of the slider has been changed, otherwise false.
2525
//
26-
// The identifier for a Slider is the pointer value of its value.
27-
// Slider objects with different pointers are considered distinct.
28-
// Therefore, for example, you should not provide a pointer to a local variable;
29-
// instead, you should provide a pointer to a member variable of a struct or a pointer to a global variable.
26+
// A Slider control is uniquely determined by its call location.
27+
// Function calls made in different locations will create different controls.
28+
// If you want to generate different controls with the same function call in a loop (such as a for loop), use [IDScope].
3029
func (c *Context) Slider(value *int, lo, hi int, step int) bool {
30+
pc := caller()
31+
id := c.idFromCaller(pc)
3132
var res bool
3233
c.wrapError(func() error {
3334
var err error
34-
res, err = c.slider(value, lo, hi, step, optionAlignCenter)
35+
res, err = c.slider(value, lo, hi, step, id, optionAlignCenter)
3536
if err != nil {
3637
return err
3738
}
@@ -47,15 +48,16 @@ func (c *Context) Slider(value *int, lo, hi int, step int) bool {
4748
//
4849
// SliderF returns true if the value of the slider has been changed, otherwise false.
4950
//
50-
// The identifier for a SliderF is the pointer value of its value.
51-
// SliderF objects with different pointers are considered distinct.
52-
// Therefore, for example, you should not provide a pointer to a local variable;
53-
// instead, you should provide a pointer to a member variable of a struct or a pointer to a global variable.
51+
// A SliderF control is uniquely determined by its call location.
52+
// Function calls made in different locations will create different controls.
53+
// If you want to generate different controls with the same function call in a loop (such as a for loop), use [IDScope].
5454
func (c *Context) SliderF(value *float64, lo, hi float64, step float64, digits int) bool {
55+
pc := caller()
56+
id := c.idFromCaller(pc)
5557
var res bool
5658
c.wrapError(func() error {
5759
var err error
58-
res, err = c.sliderF(value, lo, hi, step, digits, optionAlignCenter)
60+
res, err = c.sliderF(value, lo, hi, step, digits, id, optionAlignCenter)
5961
if err != nil {
6062
return err
6163
}

0 commit comments

Comments
 (0)