1
0
mirror of https://github.com/fumiama/go-onebot-agent.git synced 2026-06-05 02:00:23 +08:00
Files
go-onebot-agent/ctx.go
2025-09-21 00:37:19 +08:00

73 lines
1.6 KiB
Go

package goba
import (
"reflect"
"sync"
"github.com/pkg/errors"
zero "github.com/wdvxdr1123/ZeroBot"
)
var (
ErrInvalidFirstContextType = errors.New("invalid first context type")
)
var (
eventType = reflect.TypeOf(Event{})
// requestType = reflect.TypeOf(zero.APIRequest{})
)
type generalctx struct {
mu sync.Mutex
ctx []events
}
func addctx[T Event | zero.APIRequest](
ctx *generalctx, v *T, ctxcap, evcap int,
) {
ctx.mu.Lock()
defer ctx.mu.Unlock()
typ := reflect.TypeOf(v).Elem()
if len(ctx.ctx) == 0 {
// must triggered by event
if !typ.AssignableTo(eventType) {
panic(errors.Wrap(ErrInvalidFirstContextType, typ.String()))
}
// ctxcap & evcap must > 0, no need to check
evs := make(events, 1, evcap)
evs[0] = v
ctx.ctx = make([]events, 1, ctxcap)
ctx.ctx[0] = evs
return
}
// Get the last events slice
lastEvents := &ctx.ctx[len(ctx.ctx)-1]
// Check if the type matches the first element of the last events
firstElemType := reflect.TypeOf((*lastEvents)[0]).Elem()
if typ.AssignableTo(firstElemType) {
// Same type, add to the last events
if len(*lastEvents) >= evcap {
// Shift elements forward by 1 (discard first element)
copy((*lastEvents)[:], (*lastEvents)[1:])
(*lastEvents)[len(*lastEvents)-1] = any(v)
} else {
*lastEvents = append(*lastEvents, any(v))
}
return
}
// Different type or empty last events, create new events slice
if len(ctx.ctx) >= ctxcap {
// Shift elements forward by 2 (user-assistant pair)
copy(ctx.ctx[:], ctx.ctx[2:])
ctx.ctx = ctx.ctx[:len(ctx.ctx)-2]
}
evs := make(events, 1, evcap)
evs[0] = v
ctx.ctx = append(ctx.ctx, evs)
}