package buffer import ( "fmt" "reflect" "zworld/engine/renderapi/device" "zworld/engine/util" ) // Strongly typed array buffer type Array[K any] interface { T // Set the value of element i and flushes the buffer. Set(index int, data K) // Sets a range of elements, starting at i and flushes the buffer. SetRange(index int, data []K) // Count returns the number of items in the array Count() int // Element returns the aligned byte size of a single element Element() int } type array[K any] struct { T element int count int } // NewArray creates a new typed array buffer. // When allocating arrays, the Size argument is the number of elements func NewArray[K any](device device.T, args Args) Array[K] { align, maxSize := GetBufferLimits(device, args.Usage) var empty K kind := reflect.TypeOf(empty) element := util.Align(int(kind.Size()), align) count := args.Size size := count * element if size > maxSize { panic(fmt.Sprintf("buffer is too large for the specified usage. size: %d, max: %d", size, maxSize)) } args.Size = size buffer := New(device, args) return &array[K]{ T: buffer, element: element, count: count, } } func (a *array[K]) Set(index int, data K) { a.Write(index*a.element, &data) a.Flush() } func (a *array[K]) SetRange(offset int, data []K) { for i, el := range data { a.Write((i+offset)*a.element, &el) } a.Flush() } func (a *array[K]) Count() int { return a.count } func (a *array[K]) Element() int { return a.element }