Files
Bubberstation/code/datums/components/evolutionary_leap.dm
SkyratBot 067188d366 [MIRROR] Micro-optimize qdel by only permitting one parameter [MDB IGNORE] (#25889)
* Micro-optimize qdel by only permitting one parameter (#80628)

Productionizes #80615.

The core optimization is this:

```patch
-	var/hint = to_delete.Destroy(arglist(args.Copy(2))) // Let our friend know they're about to get fucked up.
+	var/hint = to_delete.Destroy(force) // Let our friend know they're about to get fucked up.
```

We avoid a heap allocation in the form of copying the args over to a new
list. A/B testing shows this results in 33% better overtime, and in a
real round shaving off a full second of self time and 0.4 seconds of
overtime--both of these would be doubled in the event this is merged as
the new proc was only being run 50% of the time.

* Micro-optimize qdel by only permitting one parameter

---------

Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
2023-12-29 14:41:12 +00:00

61 lines
2.0 KiB
Plaintext

/**
* ### Evolutionary Leap Component; set a time in the round for a mob to evolve into a more dangerous form!
*
* Used for bileworms, to turn into vileworms!
*/
/datum/component/evolutionary_leap
/// how much time until the parent makes an evolutionary leap
var/evolve_mark
/// id for leap timer
var/timer_id
/// what this mob turns into
var/evolve_path
/datum/component/evolutionary_leap/Initialize(evolve_mark, evolve_path)
if(!isliving(parent))
return COMPONENT_INCOMPATIBLE
src.evolve_mark = evolve_mark
src.evolve_path = evolve_path
//don't setup timer yet, timer calc requires the round to have started
if(!SSticker.HasRoundStarted())
RegisterSignal(SSticker, COMSIG_TICKER_ROUND_STARTING, PROC_REF(comp_on_round_start))
return
//if the round has already taken long enough, just leap right away.
if((world.time - SSticker.round_start_time) > evolve_mark)
leap(silent = TRUE)
return
setup_timer()
/datum/component/evolutionary_leap/Destroy(force)
. = ..()
deltimer(timer_id)
/datum/component/evolutionary_leap/UnregisterFromParent()
UnregisterSignal(SSticker, COMSIG_TICKER_ROUND_STARTING)
/// Proc ran when round starts.
/datum/component/evolutionary_leap/proc/comp_on_round_start()
SIGNAL_HANDLER
UnregisterSignal(SSticker, COMSIG_TICKER_ROUND_STARTING)
setup_timer()
/datum/component/evolutionary_leap/proc/setup_timer()
//in cases where this is calculating roundstart, world.time - SSticker.round_start_time should equal 0
var/sum = (world.time - SSticker.round_start_time)
var/mark = evolve_mark - sum
timer_id = addtimer(CALLBACK(src, PROC_REF(leap), FALSE), mark, TIMER_STOPPABLE)
/datum/component/evolutionary_leap/proc/leap(silent)
var/mob/living/old_mob = parent
if (old_mob.stat == DEAD)
return
var/mob/living/new_mob = evolve_path
var/new_mob_name = initial(new_mob.name)
if(!silent)
old_mob.visible_message(span_warning("[old_mob] evolves into \a [new_mob_name]!"))
old_mob.change_mob_type(evolve_path, old_mob.loc, new_name = new_mob_name, delete_old_mob = TRUE)