Last active
April 23, 2026 23:11
-
-
Save magicoal-nerb/c6195f665c4d9eed21c6da0489d707d3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --!strict | |
| -- deque; could be used as an object pool | |
| -- magicoal_nerb :3 | |
| local Deque = {} | |
| export type Deque<T> = { | |
| elements: { T }, | |
| capacity: number, | |
| cursor: number, | |
| size: number, | |
| } | |
| local function wrap(a: number, b: number, c: number): number | |
| -- Assumes a is an initial position, b is an offset, | |
| -- and c as the size.. | |
| return (a + b - 1) % c + 1 | |
| end | |
| function Deque.new<T>( | |
| capacity: number, | |
| dispatch: () -> (T) | |
| ): Deque<T> | |
| local elements = {} | |
| for i = 1, capacity do | |
| elements[i] = dispatch() | |
| end | |
| return { | |
| elements = elements, | |
| capacity = #elements, | |
| size = 0, | |
| cursor = 1, | |
| } | |
| end | |
| function Deque.empty<T>(self: Deque<T>): boolean | |
| -- Returns if the current object pool is empty | |
| return self.size == 0 | |
| end | |
| function Deque.iterate<T>(self: Deque<T>, callback: (T) -> ()) | |
| -- Iterate through all of the objects | |
| -- from front to back. | |
| for i = 1, self.size do | |
| local slot = wrap(self.cursor, i - 1, self.capacity) | |
| callback(self.elements[slot]) | |
| end | |
| end | |
| function Deque.pushFront<T>(self: Deque<T>): T | |
| assert(self.size <= self.capacity, "cannot reach capacity!") | |
| -- Adds an element to the front of the array | |
| local slot = wrap(self.cursor, -1, self.capacity) | |
| self.cursor = wrap(self.cursor, -1, self.capacity) | |
| self.size += 1 | |
| return self.elements[self.cursor] | |
| end | |
| function Deque.pushBack<T>(self: Deque<T>): T | |
| assert(self.size <= self.capacity, "cannot reach capacity!") | |
| -- Adds an element to the back of the array | |
| local slot = wrap(self.cursor, self.size, self.capacity) | |
| local value = self.elements[slot] | |
| self.size += 1 | |
| return value | |
| end | |
| function Deque.front<T>(self: Deque<T>): T | |
| -- Gets the front element | |
| return self.elements[self.cursor] | |
| end | |
| function Deque.back<T>(self: Deque<T>): T | |
| -- Gets the back element | |
| return self.elements[wrap(self.cursor, self.size - 1, self.capacity)] | |
| end | |
| function Deque.popFront<T>(self: Deque<T>): T | |
| -- Removes the front element, so we advance our cursor | |
| assert(self.size >= 0, "object pool is already empty!") | |
| local value = self.elements[self.cursor] | |
| self.cursor = wrap(self.cursor, 1, self.capacity) | |
| self.size -= 1 | |
| return value | |
| end | |
| function Deque.popBack<T>(self: Deque<T>): T | |
| -- Removes the back element | |
| assert(self.size >= 0, "object pool is already empty!") | |
| local slot = wrap(self.cursor, self.size, self.capacity) | |
| self.size -= 1 | |
| return self.elements[slot] | |
| end | |
| return Deque |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment