Atmospherics computer now displays a sorted list of air alarms

This commit is contained in:
PsiOmega
2014-08-23 11:45:25 +02:00
parent 7db352fcc6
commit e21da52af9
2 changed files with 130 additions and 2 deletions

View File

@@ -35,7 +35,7 @@
if(current)
dat += specific()
else
for(var/obj/machinery/alarm/alarm in machines)
for(var/obj/machinery/alarm/alarm in dd_sortedObjectList(machines))
dat += "<a href='?src=\ref[src]&alarm=\ref[alarm]'>"
switch(max(alarm.danger_level, alarm.alarm_area.atmosalm))
if (0)
@@ -44,7 +44,7 @@
dat += "<font color=blue>"
if (2)
dat += "<font color=red>"
dat += "[alarm]</font></a><br/>"
dat += "[sanitize(alarm.name)]</font></a><br/>"
user << browse(dat, "window=atmoscontrol")
/obj/machinery/computer/atmoscontrol/attackby(var/obj/item/I as obj, var/mob/user as mob)

View File

@@ -399,3 +399,131 @@ proc/listclearnulls(list/list)
var/list/out = insertion_sort_numeric_list_ascending(L)
//world.log << " output: [out.len]"
return reverselist(out)
proc/dd_sortedObjectList(list/incoming)
/*
Use binary search to order by dd_SortValue().
This works by going to the half-point of the list, seeing if the node in
question is higher or lower cost, then going halfway up or down the list
and checking again. This is a very fast way to sort an item into a list.
*/
var/list/sorted_list = new()
var/low_index
var/high_index
var/insert_index
var/midway_calc
var/current_index
var/current_item
var/current_item_value
var/current_sort_object_value
var/list/list_bottom
var/current_sort_object
for (current_sort_object in incoming)
low_index = 1
high_index = sorted_list.len
while (low_index <= high_index)
// Figure out the midpoint, rounding up for fractions. (BYOND rounds down, so add 1 if necessary.)
midway_calc = (low_index + high_index) / 2
current_index = round(midway_calc)
if (midway_calc > current_index)
current_index++
current_item = sorted_list[current_index]
current_item_value = current_item:dd_SortValue()
current_sort_object_value = current_sort_object:dd_SortValue()
if (current_sort_object_value < current_item_value)
high_index = current_index - 1
else if (current_sort_object_value > current_item_value)
low_index = current_index + 1
else
// current_sort_object == current_item
low_index = current_index
break
// Insert before low_index.
insert_index = low_index
// Special case adding to end of list.
if (insert_index > sorted_list.len)
sorted_list += current_sort_object
continue
// Because BYOND lists don't support insert, have to do it by:
// 1) taking out bottom of list, 2) adding item, 3) putting back bottom of list.
list_bottom = sorted_list.Copy(insert_index)
sorted_list.Cut(insert_index)
sorted_list += current_sort_object
sorted_list += list_bottom
return sorted_list
proc/dd_sortedtextlist(list/incoming, case_sensitive = 0)
// Returns a new list with the text values sorted.
// Use binary search to order by sortValue.
// This works by going to the half-point of the list, seeing if the node in question is higher or lower cost,
// then going halfway up or down the list and checking again.
// This is a very fast way to sort an item into a list.
var/list/sorted_text = new()
var/low_index
var/high_index
var/insert_index
var/midway_calc
var/current_index
var/current_item
var/list/list_bottom
var/sort_result
var/current_sort_text
for (current_sort_text in incoming)
low_index = 1
high_index = sorted_text.len
while (low_index <= high_index)
// Figure out the midpoint, rounding up for fractions. (BYOND rounds down, so add 1 if necessary.)
midway_calc = (low_index + high_index) / 2
current_index = round(midway_calc)
if (midway_calc > current_index)
current_index++
current_item = sorted_text[current_index]
if (case_sensitive)
sort_result = sorttextEx(current_sort_text, current_item)
else
sort_result = sorttext(current_sort_text, current_item)
switch(sort_result)
if (1)
high_index = current_index - 1 // current_sort_text < current_item
if (-1)
low_index = current_index + 1 // current_sort_text > current_item
if (0)
low_index = current_index // current_sort_text == current_item
break
// Insert before low_index.
insert_index = low_index
// Special case adding to end of list.
if (insert_index > sorted_text.len)
sorted_text += current_sort_text
continue
// Because BYOND lists don't support insert, have to do it by:
// 1) taking out bottom of list, 2) adding item, 3) putting back bottom of list.
list_bottom = sorted_text.Copy(insert_index)
sorted_text.Cut(insert_index)
sorted_text += current_sort_text
sorted_text += list_bottom
return sorted_text
proc/dd_sortedTextList(list/incoming)
var/case_sensitive = 1
return dd_sortedtextlist(incoming, case_sensitive)
datum/proc/dd_SortValue()
return "[src]"
/obj/machinery/dd_SortValue()
return "[sanitize(name)]"