@@ -18,73 +18,19 @@ import (
18
18
"sync/atomic"
19
19
"unsafe"
20
20
21
+ "github.com/diamondburned/gotk4/pkg/core/closure"
21
22
"github.com/diamondburned/gotk4/pkg/core/gdebug"
22
23
23
24
// Require a non-moving GC for heap pointers. Current GC is moving only by
24
25
// the stack. See https://github.com/go4org/intern.
25
26
_ "go4.org/unsafe/assume-no-moving-gc"
26
27
)
27
28
28
- const maxTypesAllowed = 2
29
-
30
- var knownTypes uint32 = 0
31
-
32
- type BoxedType [T any ] struct {
33
- ctor func (* Box ) * T
34
- id uint32
35
- }
36
-
37
- func RegisterType [T any ](ctor func (* Box ) * T ) BoxedType [T ] {
38
- t := BoxedType [T ]{
39
- ctor : ctor ,
40
- id : atomic .AddUint32 (& knownTypes , 1 ) - 1 ,
41
- }
42
- if t .id > maxTypesAllowed {
43
- panic ("BoxedType ID overflow" )
44
- }
45
- return t
46
- }
47
-
48
- func (t * BoxedType [T ]) Get (box * Box ) * T {
49
- old := atomic .LoadPointer (& box .data [t .id ])
50
- if old != nil {
51
- return (* T )(old )
52
- }
53
-
54
- if t .ctor == nil {
55
- return nil
56
- }
57
-
58
- new := t .ctor (box )
59
-
60
- if atomic .CompareAndSwapPointer (& box .data [t .id ], nil , unsafe .Pointer (new )) {
61
- return new
62
- }
63
-
64
- ptr := atomic .LoadPointer (& box .data [t .id ])
65
- if ptr != nil {
66
- return (* T )(ptr )
67
- }
68
-
69
- panic ("Load returned nil after CompareAndSwap(old = nil) failed" )
70
- }
71
-
72
- func (t * BoxedType [T ]) Set (box * Box , v * T ) {
73
- if t .ctor != nil {
74
- panic ("bug: Set not permitted if t.ctor != nil" )
75
- }
76
- atomic .StorePointer (& box .data [t .id ], unsafe .Pointer (v ))
77
- }
78
-
79
- func (t * BoxedType [T ]) Delete (box * Box ) {
80
- atomic .StorePointer (& box .data [t .id ], nil )
81
- }
82
-
83
29
// Box is an opaque type holding extra data.
84
30
type Box struct {
85
- gobject unsafe.Pointer
86
- dummy * boxDummy
87
- data [ maxTypesAllowed ]unsafe. Pointer
31
+ gobject unsafe.Pointer
32
+ closures atomic. Pointer [closure. Registry ]
33
+ dummy * boxDummy
88
34
}
89
35
90
36
type boxDummy struct {
@@ -96,6 +42,18 @@ func (b *Box) GObject() unsafe.Pointer {
96
42
return b .gobject
97
43
}
98
44
45
+ // Closures returns the closure registry for this Box.
46
+ func (b * Box ) Closures () * closure.Registry {
47
+ closures := b .closures .Load ()
48
+ if closures == nil {
49
+ closures = closure .NewRegistry ()
50
+ if ! b .closures .CompareAndSwap (nil , closures ) {
51
+ closures = b .closures .Load ()
52
+ }
53
+ }
54
+ return closures
55
+ }
56
+
99
57
// Hack to force an object on the heap.
100
58
var never bool
101
59
var sink_ interface {}
0 commit comments