aboutsummaryrefslogtreecommitdiffstats
path: root/src/queue.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/queue.js')
-rw-r--r--src/queue.js81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/queue.js b/src/queue.js
new file mode 100644
index 0000000..abcfb84
--- /dev/null
+++ b/src/queue.js
@@ -0,0 +1,81 @@
+SVG.Queue = SVG.invent({
+ create: function () {
+ this._first = null
+ this._last = null
+ this.length = 0
+ this.id = 0
+ },
+
+ extend: {
+ push: function (value) {
+
+ // An item stores an id and the provided value
+ var item = { id: this.id++, value: value }
+
+ // Deal with the queue being empty or populated
+ if (this._last) {
+ this._last = this._last.next = item
+ } else {
+ this._last = this._first = item
+ }
+
+ this.length++
+ },
+
+ shift: function () {
+ if (this.length == 0) {
+ return
+ }
+
+ var remove = this._first
+ this._first = remove.next
+ this._last = --this.length ? this._last : null
+ return remove.value
+ },
+
+ // Shows us the first item in the list
+ first: function () {
+ return this._first && this._first.value
+ },
+
+ // Shows us the last item in the list
+ last: function () {
+ return this._last && this._last.value
+ },
+
+ // Removes the first item from the front where matcher returns true
+ remove: function (matcher) {
+ // Find the first match
+ var previous = null
+ var current = this._first
+ while (current) {
+
+ // If we have a match, we are done
+ if (matcher(current)) break
+
+ // Otherwise, advance both of the pointers
+ previous = current
+ current = current.next
+ }
+
+ // If we got the first item, adjust the first pointer
+ if (current && current === this._first)
+ this._first = this._first.next
+
+ // If we got the last item, adjust the last pointer
+ if (current && current === this._last)
+ this._last = previous
+
+ // If we got an item, fix the list and return the item
+ if (current) {
+ --this.length
+
+ if (previous) {
+ previous.next = current.next
+ }
+
+ return current.item
+ }
+ }
+ }
+})