Files

70 lines
2.3 KiB
Plaintext

//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2024 Citadel Station Developers *//
/**
* Arbitrary holder for string-sequence combos.
*
* * Precomputes variables used in checking.
* * Owns the /datum/combo's in it; other things should never edit or delete them unless changing the entire combo set.
*
* ## Hey! Listen!
*
* * A design flaw in how /datum/combo_tracker works means that combo sets and their internal combos **will** be hard referenced
* and there's currently no way to inform holders to clear ref when we're being deleted. For now.
* A component signal system will be added later. For now, until we need to start deleting these / runtime-generating,
* please store combo sets in global variables.
*/
/datum/combo_set
/// expected combo type
var/expected_combo_type = /datum/combo
/// combos;
/// * set to typepaths or anonymous types to init on New()
var/list/datum/combo/combos = list()
/// cached: max sequence length of any combo's keys
var/tmp/computed_max_sequence_length = 0
/datum/combo_set/New(list/datum/combo/combos = src.combos)
src.combos = combos
hydrate()
reload()
/datum/combo_set/Destroy()
QDEL_NULL(combos)
return ..()
/datum/combo_set/proc/hydrate()
for(var/i in 1 to length(combos))
var/datum/combo/maybe_combo = combos[i]
if(ispath(maybe_combo))
maybe_combo = new maybe_combo
else if(IS_ANONYMOUS_TYPEPATH(maybe_combo))
maybe_combo = new maybe_combo
combos[i] = maybe_combo
/datum/combo_set/proc/reload()
computed_max_sequence_length = 0
for(var/datum/combo/combo as anything in combos)
computed_max_sequence_length = max(computed_max_sequence_length, combo.get_length())
/**
* check tail match, where 1 to n is first to last of current combo;
* returns the first combo resolved from the current stored set
*
* @return /datum/combo instance or null
*/
/datum/combo_set/proc/simple_tail_match(list/keys_so_far)
var/stored_length = length(keys_so_far)
var/offset = min(0, stored_length - computed_max_sequence_length)
for(var/datum/combo/combo as anything in combos)
if(length(combo.keys) > stored_length)
continue
var/adjusted_offset = offset + (computed_max_sequence_length - length(combo.keys))
for(var/i in 1 to length(combo.keys))
if(combo.keys[i] != keys_so_far[adjusted_offset + i])
continue
. = combo
break
if(.)
break