Co-authored-by: silicons <2003111+silicons@users.noreply.github.com>
Co-authored-by: silicons <no@you.cat>
This commit is contained in:
Cadyn
2024-03-31 04:38:23 -07:00
committed by GitHub
parent d52286da16
commit ecd8125771
39 changed files with 2275 additions and 61 deletions

View File

@@ -0,0 +1,89 @@
//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2023 Citadel Station developers. *//
/**
* An array-backed priority queue.
*
* The "front" of the queue is popped first; check comparators.dm for what this means.
*/
/datum/priority_queue
/// comparaison function
var/procpath/comparison
/// internal array
var/list/array = list()
/datum/priority_queue/New(cmp)
src.comparison = cmp
array = list()
/datum/priority_queue/proc/is_empty()
return length(array) == 0
/datum/priority_queue/proc/enqueue(entry)
array += entry
bubble_up(length(array))
/datum/priority_queue/proc/dequeue()
if(length(array) == 0)
return null
. = array[1]
array.Swap(1, length(array))
--array.len
bubble_down(1)
/datum/priority_queue/proc/peek()
return length(array)? array[1] : null
// todo: define this
/datum/priority_queue/proc/bubble_up(index)
while(index >= 2 && call(comparison)(array[index], array[index / 2]) < 0)
array.Swap(index, index / 2)
index /= 2
// todo: define this
/datum/priority_queue/proc/bubble_down(index)
var/length = length(array)
var/next = index * 2
while(next <= length)
// left always exists, right doesn't necessarily exist
if(call(comparison)(array[next], array[index]) < 0)
if(next < length && call(comparison)(array[next], array[next + 1]) > 0)
array.Swap(index, next + 1)
index = next + 1
else
array.Swap(index, next)
index = next
else if(next < length && call(comparison)(array[next + 1], array[index]) < 0)
array.Swap(index, next + 1)
index = next + 1
else
break
next = index * 2
/**
* returns copy of list of entries in no particular order
*/
/datum/priority_queue/proc/flattened()
return array.Copy()
/datum/priority_queue/proc/remove_index(index)
var/length = length(array)
if(!index || index > length)
return
if(index == length)
. = array[index]
--array.len
return
. = array[index]
array.Swap(index, length)
--array.len
bubble_down(index)
/datum/priority_queue/proc/find(entry)
return array.Find(entry)
/datum/priority_queue/proc/remove_entry(entry)
return remove_index(array.Find(entry))
/datum/priority_queue/proc/size()
return length(array)