From 04479dc06adde6663cae6f91946e271f3545a3fa Mon Sep 17 00:00:00 2001 From: MrPerson Date: Sat, 20 Jun 2015 21:36:18 -0700 Subject: [PATCH] Allow any datum to be pooled, including images Tested on a non-ss13 project and works so it should work here. Renamed the file from atom_pool to pool I'll try to recap any other changes here: Changed pick_n_take to pop when grabbing stuff out of the pool. Contents is excluded from vars set to initial (would runtime with images), but it gets reset manually by atom/movable. --- code/game/pooling/atom_pool.dm | 111 ------------------------------- code/game/pooling/pool.dm | 115 +++++++++++++++++++++++++++++++++ tgstation.dme | 2 +- 3 files changed, 116 insertions(+), 112 deletions(-) delete mode 100644 code/game/pooling/atom_pool.dm create mode 100644 code/game/pooling/pool.dm diff --git a/code/game/pooling/atom_pool.dm b/code/game/pooling/atom_pool.dm deleted file mode 100644 index 19bdbdf22b6..00000000000 --- a/code/game/pooling/atom_pool.dm +++ /dev/null @@ -1,111 +0,0 @@ - -/* -/tg/station13 /atom/movable Pool: ---------------------------------- -By RemieRichards - -Creation/Deletion is laggy, so let's reduce reuse and recycle! - -Locked to /atom/movable and it's subtypes due to Loc being a const var on /atom -but being read&write on /movable due to how they... move. - -Usage: - -To get a object, just called PoolOrNew(type, list of args to pass to New) - -To put a object back in the pool, call place in pool. -This will call destroy on the object, set its loc to null, -and reset all of its vars to their default - -You can override your object's destroy to return QDEL_HINT_PLACEINPOOL -to ensure its always placed in this pool (this will only be acted on if qdel calls destroy, and destroy will not get called twice) - -*/ - -var/global/list/GlobalPool = list() - -//You'll be using this proc 90% of the time. -//It grabs a type from the pool if it can -//And if it can't, it creates one -//The pool is flexible and will expand to fit -//The new created atom when it eventually -//Goes into the pool - -//Second argument can be a new location -//Or a list of arguments -//Either way it gets passed to new - -/proc/PoolOrNew(var/get_type,var/second_arg) - if(!get_type) - return - - var/atom/movable/AM - AM = GetFromPool(get_type,second_arg) - - if(!AM) - if(ispath(get_type)) - if(islist(second_arg)) - AM = new get_type (arglist(second_arg)) - else - AM = new get_type (second_arg) - - if(AM) - return AM - - - -/proc/GetFromPool(var/get_type,var/second_arg) - if(!get_type) - return 0 - - if(isnull(GlobalPool[get_type])) - return 0 - - if(length(GlobalPool[get_type]) == 0) - return 0 - - var/atom/movable/AM = pick_n_take(GlobalPool[get_type]) - if(AM) - AM.ResetVars() - if(islist(second_arg)) - AM.loc = second_arg[1] - AM.New(arglist(second_arg)) - else - AM.loc = second_arg - AM.New(second_arg) - return AM - return 0 - - - -/proc/PlaceInPool(var/atom/movable/AM, destroy = 1) - if(!istype(AM)) - return - - if(AM in GlobalPool[AM.type]) - return - - if(!GlobalPool[AM.type]) - GlobalPool[AM.type] = list() - - GlobalPool[AM.type] |= AM - - if (destroy) - AM.Destroy() - - AM.ResetVars() - - - -/atom/movable/proc/ResetVars() - var/list/excluded = list("animate_movement", "loc", "locs", "parent_type", "vars", "verbs", "type") - - for(var/V in vars) - if(V in excluded) - continue - - vars[V] = initial(vars[V]) - - vars["loc"] = null - - diff --git a/code/game/pooling/pool.dm b/code/game/pooling/pool.dm new file mode 100644 index 00000000000..df250d767b6 --- /dev/null +++ b/code/game/pooling/pool.dm @@ -0,0 +1,115 @@ + +/* +/tg/station13 /datum Pool: +--------------------------------- +By RemieRichards + +Creation/Deletion is laggy, so let's reduce reuse and recycle! + +Usage: + +To get a object, just call + - PoolOrNew(type, arg) if you only want to pass one argument to New(), usually loc + - PoolOrNew(type, list) if you want to pass multiple arguments to New() + +To put a object back in the pool, call PlaceInPool(object) +This will call destroy on the object, set its loc to null, +and reset all of its vars to their default + +You can override your object's destroy to return QDEL_HINT_PLACEINPOOL +to ensure its always placed in this pool (this will only be acted on if qdel calls destroy, and destroy will not get called twice) + +*/ + +var/global/list/GlobalPool = list() + +//You'll be using this proc 90% of the time. +//It grabs a type from the pool if it can +//And if it can't, it creates one +//The pool is flexible and will expand to fit +//The new created atom when it eventually +//Goes into the pool + +//Second argument can be a single arg +//Or a list of arguments +//Either way it gets passed to new + +/proc/PoolOrNew(var/get_type,var/second_arg) + if(!get_type) + return + + . = GetFromPool(get_type,second_arg) + + if(!.) + if(ispath(get_type)) + if(islist(second_arg)) + . = new get_type (arglist(second_arg)) + else + . = new get_type (second_arg) + + +/proc/GetFromPool(var/get_type,var/second_arg) + if(!get_type) + return + + if(isnull(GlobalPool[get_type])) + return + + if(length(GlobalPool[get_type]) == 0) + return + + var/datum/pooled = pop(GlobalPool[get_type]) + if(pooled) + pooled.ResetVars() + var/atom/movable/AM + if(istype(pooled, /atom/movable)) + AM = pooled + + if(islist(second_arg)) + if(AM) + AM.loc = second_arg[1] //we need to do loc setting explicetly before even calling New() to replicate new()'s behavior + pooled.New(arglist(second_arg)) + + else + if(AM) + AM.loc = second_arg + pooled.New(second_arg) + + return pooled + + +/proc/PlaceInPool(var/datum/diver, destroy = 1) + if(!istype(diver)) + return + + if(diver in GlobalPool[diver.type]) + return + + if(!GlobalPool[diver.type]) + GlobalPool[diver.type] = list() + + GlobalPool[diver.type] |= diver + + if (destroy) + diver.Destroy() + + diver.ResetVars() + + +/datum/proc/ResetVars() + var/list/excluded = list("animate_movement", "contents", "loc", "locs", "parent_type", "vars", "verbs", "type") + + for(var/V in vars) + if(V in excluded) + continue + + vars[V] = initial(vars[V]) + +/atom/movable/ResetVars() + ..() + loc = null + contents = initial(contents) //something is really wrong if this object still has stuff in it by this point + +/image/ResetVars() + ..() + loc = null \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index 6f47e668fda..1b9844a4973 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -757,7 +757,7 @@ #include "code\game\objects\structures\transit_tubes\transit_tube.dm" #include "code\game\objects\structures\transit_tubes\transit_tube_construction.dm" #include "code\game\objects\structures\transit_tubes\transit_tube_pod.dm" -#include "code\game\pooling\atom_pool.dm" +#include "code\game\pooling\pool.dm" #include "code\game\turfs\simulated.dm" #include "code\game\turfs\turf.dm" #include "code\game\turfs\unsimulated.dm"