cchat-gtk/internal/ui/rich/async.go

47 lines
1.0 KiB
Go

package rich
import (
"context"
"log"
"github.com/diamondburned/cchat-gtk/internal/gts"
)
// Reuser is an interface for structs that inherit Reusable.
type Reuser interface {
Context() context.Context
Acquire() int64
Validate(int64) bool
SwapResource(v interface{}, cancel func())
}
type AsyncUser = func(context.Context) (interface{}, func(), error)
// AsyncUse is a handler for structs that implement the Reuser primitive. The
// passed in function will be called asynchronously, but swap will be called in
// the Gtk main thread.
func AsyncUse(r Reuser, fn AsyncUser) {
// Acquire an ID.
id := r.Acquire()
ctx := r.Context()
gts.Async(func() (func(), error) {
// Run the callback asynchronously.
v, cancel, err := fn(ctx)
if err != nil {
return nil, err
}
return func() {
// Validate the ID. Cancel if it's invalid.
if !r.Validate(id) {
log.Println("Async function value dropped for reusable primitive.")
return
}
// Update the resource.
r.SwapResource(v, cancel)
}, nil
})
}