92 lines
1.9 KiB
TypeScript
92 lines
1.9 KiB
TypeScript
import { int32, int64, PackedVector2Array, Vector2 } from 'godot'
|
|
|
|
export class InputBufferError extends Error {
|
|
constructor(message: string) {
|
|
super(`InputBufferError: ${message}`)
|
|
}
|
|
|
|
static empty() {
|
|
return new InputBufferError('cannot perform operation, buffer is empty')
|
|
}
|
|
|
|
static outOfBounds(index: int64) {
|
|
return new InputBufferError(`cannot access ${index}: index out of bounds`)
|
|
}
|
|
}
|
|
|
|
export default class InputBuffer {
|
|
readonly capacity: int32
|
|
private _buffer: PackedVector2Array
|
|
private _head: int32 = 0
|
|
private _tail: int32 = 0
|
|
private _size: int32 = 0
|
|
|
|
constructor(capacity: int32) {
|
|
this.capacity = capacity
|
|
this._buffer = new PackedVector2Array()
|
|
this._buffer.resize(capacity)
|
|
this._buffer.fill(Vector2.ZERO)
|
|
}
|
|
|
|
is_empty() {
|
|
return this._size === 0
|
|
}
|
|
|
|
is_full() {
|
|
return this._size === this.capacity
|
|
}
|
|
|
|
push(value: Vector2) {
|
|
this._buffer.set_indexed(this._head, value)
|
|
this._head = (this._head + 1) % this.capacity
|
|
|
|
if (this.is_full()) {
|
|
this._tail = this._head
|
|
} else {
|
|
this._size += 1
|
|
}
|
|
}
|
|
|
|
pop(): Vector2 {
|
|
if (this.is_empty()) {
|
|
throw InputBufferError.empty()
|
|
}
|
|
|
|
const value = this.tail()
|
|
this._tail = (this._tail + 1) % this.capacity
|
|
this._size += 1
|
|
return value
|
|
}
|
|
|
|
at(index: int64) {
|
|
if (index >= this._size) {
|
|
throw InputBufferError.outOfBounds(index)
|
|
}
|
|
|
|
const n = index < 0 ? this._head - index : this._tail + index
|
|
const idx = n % this.capacity
|
|
return this._buffer.get_indexed(idx)
|
|
}
|
|
|
|
size() {
|
|
return this._size
|
|
}
|
|
|
|
head() {
|
|
return this._buffer.get_indexed(this._head)
|
|
}
|
|
|
|
tail() {
|
|
return this._buffer.get_indexed(this._tail)
|
|
}
|
|
|
|
slice(begin: int64, end?: int64) {
|
|
return this._buffer.slice(begin, end)
|
|
}
|
|
|
|
clear() {
|
|
this._size = 0
|
|
this._head = 0
|
|
this._tail = 0
|
|
}
|
|
}
|