Files
Bubberstation/code/datums/components/egg_layer.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

91 lines
3.2 KiB
Plaintext

/**
* # egg layer component!
*
* Component that manages how many eggs to lay, what can be fed to the mob to make them lay more, and what is actually laid.
* Since the only real interaction with the component is an attackby, the nice part is that we're able to make this an atom level proc.
* egg_layer will loudly fail if you do not provide it the arguments, as to encourage explicicy(?)
*/
/datum/component/egg_layer
/// item laid by the mob
var/egg_type
/// items that can be fed to the mob to make it lay more eggs
var/list/food_types
/// messages sent when fed
var/list/feed_messages
/// messages sent when laying an egg
var/list/lay_messages
/// how many eggs left to lay
var/eggs_left
/// how many eggs to lay given from food
var/eggs_added_from_eating
/// how many eggs can be stored
var/max_eggs_held
/// callback to a proc that allows the parent to modify their new eggs
var/datum/callback/egg_laid_callback
/datum/component/egg_layer/Initialize(egg_type, food_types, feed_messages, lay_messages, eggs_left, eggs_added_from_eating, max_eggs_held, egg_laid_callback)
if(!isatom(parent)) //yes, you could make a tameable toolbox.
return COMPONENT_INCOMPATIBLE
src.egg_type = egg_type
src.food_types = food_types
src.feed_messages = feed_messages
src.lay_messages = lay_messages
src.eggs_left = eggs_left
src.eggs_added_from_eating = eggs_added_from_eating
src.max_eggs_held = max_eggs_held
src.egg_laid_callback = egg_laid_callback
START_PROCESSING(SSobj, src)
/datum/component/egg_layer/RegisterWithParent()
. = ..()
RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, PROC_REF(feed_food))
/datum/component/egg_layer/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, COMSIG_ATOM_ATTACKBY)
/datum/component/egg_layer/Destroy(force)
. = ..()
STOP_PROCESSING(SSobj, src)
egg_laid_callback = null
/datum/component/egg_layer/proc/feed_food(datum/source, obj/item/food, mob/living/attacker, params)
SIGNAL_HANDLER
var/atom/at_least_atom = parent
if(!is_type_in_list(food, food_types))
return
if(isliving(at_least_atom))
var/mob/living/potentially_dead_horse = at_least_atom
if(potentially_dead_horse.stat == DEAD)
to_chat(attacker, span_warning("[parent] is dead!"))
return COMPONENT_CANCEL_ATTACK_CHAIN
if(eggs_left > max_eggs_held)
to_chat(attacker, span_warning("[parent] doesn't seem hungry!"))
return COMPONENT_CANCEL_ATTACK_CHAIN
attacker.visible_message(span_notice("[attacker] hand-feeds [food] to [parent]."), span_notice("You hand-feed [food] to [parent]."))
at_least_atom.visible_message(pick(feed_messages))
qdel(food)
eggs_left += min(eggs_left + eggs_added_from_eating, max_eggs_held)
return COMPONENT_CANCEL_ATTACK_CHAIN
/datum/component/egg_layer/process(seconds_per_tick = SSOBJ_DT)
var/atom/at_least_atom = parent
if(isliving(at_least_atom))
var/mob/living/potentially_dead_horse = at_least_atom
if(potentially_dead_horse.stat != CONSCIOUS)
return
if(!eggs_left || !SPT_PROB(1.5, seconds_per_tick))
return
at_least_atom.visible_message(span_alertalien("[at_least_atom] [pick(lay_messages)]"))
eggs_left--
var/obj/item/egg = new egg_type(get_turf(at_least_atom))
egg.pixel_x = rand(-6, 6)
egg.pixel_y = rand(-6, 6)
egg_laid_callback?.Invoke(egg)