-
-
Notifications
You must be signed in to change notification settings - Fork 135
/
StatefulReflectiveBoundTexture.go
180 lines (154 loc) · 5.13 KB
/
StatefulReflectiveBoundTexture.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
package giu
import (
"errors"
"fmt"
)
// ErrNeedReset is an error indicating that the surface cannot be loaded without a reset.
// The method (*StatefulReflectiveBoundTexture).ResetState() should be called.
var ErrNeedReset = errors.New("cannot load surface without a reset. Should call (*StatefulReflectiveBoundTexture).ResetState()")
// ErrIsLoading is an error indicating that the surface state cannot be reset while loading.
var ErrIsLoading = errors.New("cannot reset surface state while loading")
// SurfaceState represents the state of the surface.
type SurfaceState int
//go:generate stringer -type=SurfaceState
const (
// SurfaceStateNone indicates that the surface state is none.
SurfaceStateNone SurfaceState = iota
// SurfaceStateLoading indicates that the surface is currently loading.
SurfaceStateLoading
// SurfaceStateFailure indicates that the surface loading has failed.
SurfaceStateFailure
// SurfaceStateSuccess indicates that the surface loading was successful.
SurfaceStateSuccess
)
// StatefulReflectiveBoundTexture is a ReflectiveBoundTexture with added async, states, and event callbacks.
type StatefulReflectiveBoundTexture struct {
ReflectiveBoundTexture
state SurfaceState
lastError error
onReset func()
onLoading func()
onSuccess func()
onFailure func(error)
}
// GetState returns the current state of the surface.
//
// Returns:
// - SurfaceState: The current state of the surface.
func (s *StatefulReflectiveBoundTexture) GetState() SurfaceState {
return s.state
}
// GetLastError returns the last error that occurred during surface loading.
//
// Returns:
// - error: The last error that occurred, or nil if no error occurred.
func (s *StatefulReflectiveBoundTexture) GetLastError() error {
return s.lastError
}
// OnReset sets the callback function to be called when the surface state is reset.
//
// Parameters:
// - fn: The callback function to be called on reset.
//
// Returns:
// - *StatefulReflectiveBoundTexture: The current instance of StatefulReflectiveBoundTexture.
func (s *StatefulReflectiveBoundTexture) OnReset(fn func()) *StatefulReflectiveBoundTexture {
s.onReset = fn
return s
}
// OnLoading sets the callback function to be called when the surface is loading.
//
// Parameters:
// - fn: The callback function to be called on loading.
//
// Returns:
// - *StatefulReflectiveBoundTexture: The current instance of StatefulReflectiveBoundTexture.
func (s *StatefulReflectiveBoundTexture) OnLoading(fn func()) *StatefulReflectiveBoundTexture {
s.onLoading = fn
return s
}
// OnSuccess sets the callback function to be called when the surface loading is successful.
//
// Parameters:
// - fn: The callback function to be called on success.
//
// Returns:
// - *StatefulReflectiveBoundTexture: The current instance of StatefulReflectiveBoundTexture.
func (s *StatefulReflectiveBoundTexture) OnSuccess(fn func()) *StatefulReflectiveBoundTexture {
s.onSuccess = fn
return s
}
// OnFailure sets the callback function to be called when the surface loading fails.
//
// Parameters:
// - fn: The callback function to be called on failure, with the error as a parameter.
//
// Returns:
// - *StatefulReflectiveBoundTexture: The current instance of StatefulReflectiveBoundTexture.
func (s *StatefulReflectiveBoundTexture) OnFailure(fn func(error)) *StatefulReflectiveBoundTexture {
s.onFailure = fn
return s
}
// ResetState resets the state of the StatefulReflectiveBoundTexture.
//
// Returns:
// - error: An error if the state is currently loading, otherwise nil.
func (s *StatefulReflectiveBoundTexture) ResetState() error {
switch s.state {
case SurfaceStateNone:
return nil
case SurfaceStateLoading:
return ErrIsLoading
default:
s.state = SurfaceStateNone
s.lastError = nil
if s.onReset != nil {
go s.onReset()
}
}
return nil
}
// LoadSurfaceAsync loads the surface asynchronously using the provided SurfaceLoader.
// It sets the state to loading, and upon completion, updates the state to success or failure
// based on the result. It also triggers the appropriate callback functions.
//
// Parameters:
// - loader: The SurfaceLoader to use for loading the surface.
// - commit: A boolean flag indicating whether to commit the changes.
//
// Returns:
// - error: An error if the state is not SsNone, otherwise nil.
func (s *StatefulReflectiveBoundTexture) LoadSurfaceAsync(loader SurfaceLoader, commit bool) error {
if s.state != SurfaceStateNone {
return ErrNeedReset
}
s.state = SurfaceStateLoading
if s.onLoading != nil {
go s.onLoading()
}
go func() {
img, err := loader.ServeRGBA()
if err != nil {
s.state = SurfaceStateFailure
s.lastError = fmt.Errorf("in ReflectiveBoundTexture LoadSurface after loader.ServeRGBA: %w", err)
if s.onFailure != nil {
go s.onFailure(s.lastError)
}
return
}
e := s.SetSurfaceFromRGBA(img, commit)
if e != nil {
s.state = SurfaceStateFailure
s.lastError = fmt.Errorf("in ReflectiveBoundTexture LoadSurface after SetSurfaceFromRGBA: %w", err)
if s.onFailure != nil {
go s.onFailure(s.lastError)
}
return
}
s.state = SurfaceStateSuccess
if s.onSuccess != nil {
go s.onSuccess()
}
}()
return nil
}