mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-12 08:27:13 +01:00
List stuff (#2932)
changes: Converted some list procs to macros (why the fuck was islist() a proc?!) Removed some old sorting procs and replaced their few remaining calls with sortTim() calls.
This commit is contained in:
@@ -8,3 +8,9 @@
|
||||
#define LAZYCLEARLIST(L) if(L) L.Cut()
|
||||
|
||||
#define LAZYPICK(L,DEFAULT) (LAZYLEN(L) ? pick(L) : DEFAULT)
|
||||
|
||||
// Shims for some list procs in lists.dm.
|
||||
#define islist(L) istype(L,/list)
|
||||
#define isemptylist(L) (!LAZYLEN(L))
|
||||
#define safepick(L) LAZYPICK(L,null)
|
||||
#define listgetindex(L,I) LAZYACCESS(L,I)
|
||||
|
||||
@@ -37,33 +37,6 @@
|
||||
temp_list[O] = text2num(temp_list[O])
|
||||
return temp_list
|
||||
|
||||
//Returns list element or null. Should prevent "index out of bounds" error.
|
||||
proc/listgetindex(var/list/list,index)
|
||||
if(istype(list) && list.len)
|
||||
if(isnum(index))
|
||||
if(InRange(index,1,list.len))
|
||||
return list[index]
|
||||
else if(index in list)
|
||||
return list[index]
|
||||
return
|
||||
|
||||
proc/islist(list/list)
|
||||
if(istype(list))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//Return either pick(list) or null if list is not of type /list or is empty
|
||||
proc/safepick(list/list)
|
||||
if(!islist(list) || !list.len)
|
||||
return
|
||||
return pick(list)
|
||||
|
||||
//Checks if the list is empty
|
||||
proc/isemptylist(list/list)
|
||||
if(!list.len)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//Checks for specific types in a list
|
||||
/proc/is_type_in_list(var/atom/A, var/list/L)
|
||||
for(var/type in L)
|
||||
@@ -104,11 +77,6 @@ proc/isemptylist(list/list)
|
||||
instances++
|
||||
return instances
|
||||
|
||||
//Empties the list by .Cut(). Setting lenght = 0 has been confirmed to leak references.
|
||||
proc/clearlist(var/list/L)
|
||||
if(islist(L))
|
||||
L.Cut()
|
||||
|
||||
//Removes any null entries from the list
|
||||
//Returns TRUE if the list had nulls, FALSE otherwise
|
||||
/proc/listclearnulls(list/L)
|
||||
@@ -339,218 +307,6 @@ proc/clearlist(var/list/L)
|
||||
i++
|
||||
return i
|
||||
|
||||
//Don't use this on lists larger than half a dozen or so
|
||||
/proc/insertion_sort_numeric_list_ascending(var/list/L)
|
||||
//world.log << "ascending len input: [L.len]"
|
||||
var/list/out = list(pop(L))
|
||||
for(var/entry in L)
|
||||
if(isnum(entry))
|
||||
var/success = 0
|
||||
for(var/i=1, i<=out.len, i++)
|
||||
if(entry <= out[i])
|
||||
success = 1
|
||||
out.Insert(i, entry)
|
||||
break
|
||||
if(!success)
|
||||
out.Add(entry)
|
||||
|
||||
//world.log << " output: [out.len]"
|
||||
return out
|
||||
|
||||
/proc/insertion_sort_numeric_list_descending(var/list/L)
|
||||
//world.log << "descending len input: [L.len]"
|
||||
var/list/out = insertion_sort_numeric_list_ascending(L)
|
||||
//world.log << " output: [out.len]"
|
||||
return reverselist(out)
|
||||
|
||||
/proc/dd_sortedObjectList(var/list/L, var/cache=list())
|
||||
if(L.len < 2)
|
||||
return L
|
||||
var/middle = L.len / 2 + 1 // Copy is first,second-1
|
||||
return dd_mergeObjectList(dd_sortedObjectList(L.Copy(0,middle), cache), dd_sortedObjectList(L.Copy(middle), cache), cache) //second parameter null = to end of list
|
||||
|
||||
/proc/dd_mergeObjectList(var/list/L, var/list/R, var/list/cache)
|
||||
var/Li=1
|
||||
var/Ri=1
|
||||
var/list/result = new()
|
||||
while(Li <= L.len && Ri <= R.len)
|
||||
var/LLi = L[Li]
|
||||
var/RRi = R[Ri]
|
||||
var/LLiV = cache[LLi]
|
||||
var/RRiV = cache[RRi]
|
||||
if(!LLiV)
|
||||
LLiV = LLi:dd_SortValue()
|
||||
cache[LLi] = LLiV
|
||||
if(!RRiV)
|
||||
RRiV = RRi:dd_SortValue()
|
||||
cache[RRi] = RRiV
|
||||
if(LLiV < RRiV)
|
||||
result += L[Li++]
|
||||
else
|
||||
result += R[Ri++]
|
||||
|
||||
if(Li <= L.len)
|
||||
return (result + L.Copy(Li, 0))
|
||||
return (result + R.Copy(Ri, 0))
|
||||
|
||||
// Insert an object into a sorted list, preserving sortedness
|
||||
/proc/dd_insertObjectList(var/list/L, var/O)
|
||||
var/min = 1
|
||||
var/max = L.len
|
||||
var/Oval = O:dd_SortValue()
|
||||
|
||||
while(1)
|
||||
var/mid = min+round((max-min)/2)
|
||||
|
||||
if(mid == max)
|
||||
L.Insert(mid, O)
|
||||
return
|
||||
|
||||
var/Lmid = L[mid]
|
||||
var/midval = Lmid:dd_SortValue()
|
||||
if(Oval == midval)
|
||||
L.Insert(mid, O)
|
||||
return
|
||||
else if(Oval < midval)
|
||||
max = mid
|
||||
else
|
||||
min = mid+1
|
||||
|
||||
/*
|
||||
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_old(name)]"
|
||||
|
||||
/obj/machinery/camera/dd_SortValue()
|
||||
return "[c_tag]"
|
||||
|
||||
/datum/alarm/dd_SortValue()
|
||||
return "[sanitize_old(last_name)]"
|
||||
|
||||
/proc/subtypesof(prototype)
|
||||
return (typesof(prototype) - prototype)
|
||||
|
||||
|
||||
@@ -427,7 +427,7 @@
|
||||
if(!P.owner || P.toff || P.hidden) continue
|
||||
sendPDAs += P
|
||||
if(PDAs && PDAs.len > 0)
|
||||
customrecepient = input(usr, "Select a PDA from the list.") as null|anything in sortAtom(sendPDAs)
|
||||
customrecepient = input(usr, "Select a PDA from the list.") as null|anything in sendPDAs
|
||||
else
|
||||
customrecepient = null
|
||||
|
||||
|
||||
@@ -47,9 +47,6 @@ var/datum/admin_secrets/admin_secrets = new()
|
||||
var/permissions = R_ADMIN
|
||||
var/warn_before_use = 0
|
||||
|
||||
/datum/admin_secret_item/dd_SortValue()
|
||||
return "[name]"
|
||||
|
||||
/datum/admin_secret_item/proc/name()
|
||||
return name
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
// /obj/machinery/message_server/proc/send_pda_message(var/recipient = "",var/sender = "",var/message = "")
|
||||
var/obj/item/device/pda/P
|
||||
var/list/viables = list()
|
||||
for(var/obj/item/device/pda/check_pda in sortAtom(PDAs))
|
||||
for(var/obj/item/device/pda/check_pda in PDAs)
|
||||
if (!check_pda.owner||check_pda.toff||check_pda == src||check_pda.hidden)
|
||||
continue
|
||||
viables.Add(check_pda)
|
||||
@@ -59,7 +59,7 @@
|
||||
message = pick("Luxury watches for Blowout sale prices!",\
|
||||
"Watches, Jewelry & Accessories, Bags & Wallets !",\
|
||||
"Deposit 100$ and get 300$ totally free!",\
|
||||
" 100K NT.|WOWGOLD õnly $89 <HOT>",\
|
||||
" 100K NT.|WOWGOLD õnly $89 <HOT>",\
|
||||
"We have been filed with a complaint from one of your customers in respect of their business relations with you.",\
|
||||
"We kindly ask you to open the COMPLAINT REPORT (attached) to reply on this complaint..")
|
||||
if(4)
|
||||
|
||||
@@ -189,7 +189,7 @@
|
||||
src.ears = headset_to_add
|
||||
usr << "You fit the headset onto [src]."
|
||||
|
||||
clearlist(available_channels)
|
||||
LAZYCLEARLIST(available_channels)
|
||||
for(var/ch in headset_to_add.channels)
|
||||
switch(ch)
|
||||
if("Engineering")
|
||||
@@ -293,7 +293,7 @@
|
||||
speak.Remove(pick(speak))
|
||||
|
||||
speak.Add(pick(speech_buffer))
|
||||
clearlist(speech_buffer)
|
||||
LAZYCLEARLIST(speech_buffer)
|
||||
|
||||
|
||||
//-----SLEEPING
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
player_laws = new()
|
||||
|
||||
init_subtypes(/datum/ai_laws, admin_laws)
|
||||
admin_laws = dd_sortedObjectList(admin_laws)
|
||||
sortTim(admin_laws, /proc/cmp_name_asc)
|
||||
|
||||
for(var/datum/ai_laws/laws in admin_laws)
|
||||
if(laws.selectable)
|
||||
|
||||
Reference in New Issue
Block a user