Tiles are now (mostly) pooled objects (#19112)

* Tiles are now (mostly) pooled objects

Floors no longer have a builtin_tile, but instead use PoolOrNew().

Also added a do-nothing SSpool so you can inspect the global pool.

* Entries for time keeping

* MORE STATISTICS

* Stat tracking, auto filling

* Code review I

* Code review II

* Code review III
This commit is contained in:
coiax
2016-07-08 13:32:40 -04:00
committed by Joan Lung
parent 7572717ff4
commit afb7ebd790
14 changed files with 97 additions and 34 deletions
+1
View File
@@ -474,3 +474,4 @@ var/global/list/ghost_others_options = list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define debug_world_log(msg) if (Debug2) world.log << "DEBUG: [msg]"
#define COORD(A) "([A.x],[A.y],[A.z])"
#define INCREMENT_TALLY(L, stat) if(L[stat]){L[stat]++}else{L[stat] = 1}
+48
View File
@@ -0,0 +1,48 @@
var/datum/subsystem/pool/SSpool
/datum/subsystem/pool
name = "Pool"
init_order = 20
flags = SS_BACKGROUND | SS_FIRE_IN_LOBBY
var/list/global_pool
var/list/pool_levels = list()
var/sum = 0
var/list/maintained_types = list(
/obj/item/stack/tile/plasteel = 100
)
var/list/stats_placed_in_pool = list()
var/list/stats_pooled_or_newed = list()
var/list/stats_reused = list()
var/list/stats_created_new = list()
/datum/subsystem/pool/New()
NEW_SS_GLOBAL(SSpool)
/datum/subsystem/pool/Initialize(timeofday)
global_pool = GlobalPool
/datum/subsystem/pool/stat_entry(msg)
if(global_pool)
msg += "Types: [global_pool.len]|Total Pooled Objects: [sum]"
else
msg += "NULL POOL"
..(msg)
/datum/subsystem/pool/fire()
sum = 0
for(var/type in global_pool + maintained_types)
var/list/L = global_pool[type]
var/required_number = maintained_types[type] || 0
// Update pool levels and tracker
var/amount = 0
if(L)
amount = L.len
sum += amount
// why yes, just inflate the pool at one item per tick
if(amount < required_number)
var/diver = new type
qdel(diver)
@@ -250,8 +250,8 @@
PoolOrNew(/obj/effect/overlay/temp/revenant, T)
if(!istype(T, /turf/open/floor/plating) && !istype(T, /turf/open/floor/engine/cult) && istype(T, /turf/open/floor) && prob(15))
var/turf/open/floor/floor = T
if(floor.intact)
floor.builtin_tile.loc = floor
if(floor.intact && floor.floor_tile)
PoolOrNew(floor.floor_tile, floor)
floor.broken = 0
floor.burnt = 0
floor.make_plating(1)
@@ -29,7 +29,7 @@
var/obj/item/stack/sheet/metal/M = O
if (M.use(1))
use(1)
var/obj/item/stack/tile/light/L = new (user.loc)
var/obj/item/L = PoolOrNew(/obj/item/stack/tile/light, user.loc)
user << "<span class='notice'>You make a light tile.</span>"
L.add_fingerprint(user)
else
@@ -18,6 +18,10 @@
pixel_x = rand(-3, 3)
pixel_y = rand(-3, 3) //randomize a little
/obj/item/stack/tile/Destroy()
..()
return QDEL_HINT_PUTINPOOL
/obj/item/stack/tile/attackby(obj/item/W, mob/user, params)
if (istype(W, /obj/item/weapon/weldingtool))
@@ -285,7 +285,7 @@
/obj/item/weapon/storage/backpack/satchel_flat/New()
..()
new /obj/item/stack/tile/plasteel(src)
PoolOrNew(/obj/item/stack/tile/plasteel, src)
new /obj/item/weapon/crowbar(src)
/obj/item/weapon/storage/backpack/dufflebag
+11
View File
@@ -40,14 +40,22 @@ var/global/list/GlobalPool = list()
if(!get_type)
return
if(SSpool)
INCREMENT_TALLY(SSpool.stats_pooled_or_newed, get_type)
. = GetFromPool(get_type,second_arg)
if(!.)
if(SSpool)
INCREMENT_TALLY(SSpool.stats_created_new, get_type)
if(ispath(get_type))
if(islist(second_arg))
. = new get_type (arglist(second_arg))
else
. = new get_type (second_arg)
else
if(SSpool)
INCREMENT_TALLY(SSpool.stats_reused, get_type)
/proc/GetFromPool(get_type,second_arg)
@@ -88,6 +96,9 @@ var/global/list/GlobalPool = list()
if(diver in GlobalPool[diver.type])
return
if(SSpool)
INCREMENT_TALLY(SSpool.stats_placed_in_pool, diver.type)
if(!GlobalPool[diver.type])
GlobalPool[diver.type] = list()
+8 -17
View File
@@ -19,7 +19,6 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
//NOTE: Floor code has been refactored, many procs were removed and refactored
//- you should use istype() if you want to find out whether a floor has a certain type
//- floor_tile is now a path, and not a tile obj
//- builtin_tile should be dropped if needed for performance reasons (eg singularity_act())
name = "floor"
icon = 'icons/turf/floors.dmi'
@@ -31,7 +30,6 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
var/broken = 0
var/burnt = 0
var/floor_tile = null //tile that this floor drops
var/obj/item/stack/tile/builtin_tile = null //needed for performance reasons when the singularity rips off floor tiles
var/list/broken_states = list("damaged1", "damaged2", "damaged3", "damaged4", "damaged5")
var/list/burnt_states = list()
@@ -41,14 +39,6 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
icon_regular_floor = "floor"
else
icon_regular_floor = icon_state
if(floor_tile)
builtin_tile = new floor_tile
/turf/open/floor/Destroy()
if(builtin_tile)
qdel(builtin_tile)
builtin_tile = null
. = ..()
/turf/open/floor/ex_act(severity, target)
var/shielded = is_shielded()
@@ -150,7 +140,8 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
user << "<span class='danger'>You forcefully pry off the planks, destroying them in the process.</span>"
else
user << "<span class='danger'>You remove the floor tile.</span>"
builtin_tile.loc = src
if(floor_tile)
PoolOrNew(floor_tile, src)
make_plating()
playsound(src, 'sound/items/Crowbar.ogg', 80, 1)
return 1
@@ -159,18 +150,18 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
/turf/open/floor/singularity_pull(S, current_size)
if(current_size == STAGE_THREE)
if(prob(30))
if(builtin_tile)
builtin_tile.loc = src
if(floor_tile)
PoolOrNew(floor_tile, src)
make_plating()
else if(current_size == STAGE_FOUR)
if(prob(50))
if(builtin_tile)
builtin_tile.loc = src
if(floor_tile)
PoolOrNew(floor_tile, src)
make_plating()
else if(current_size >= STAGE_FIVE)
if(builtin_tile)
if(floor_tile)
if(prob(70))
builtin_tile.loc = src
PoolOrNew(floor_tile, src)
make_plating()
else if(prob(50))
ReplaceWithLattice()
@@ -12,10 +12,6 @@
/turf/open/floor/light/New()
..()
spawn(5) //needed because when placing a light floor tile it will take a short while before setting state
if(istype(builtin_tile, /obj/item/stack/tile/light))
var/obj/item/stack/tile/light/L = builtin_tile
L.state = state
update_icon()
/turf/open/floor/light/update_icon()
+2 -2
View File
@@ -168,9 +168,9 @@
/turf/open/floor/engine/singularity_pull(S, current_size)
if(current_size >= STAGE_FIVE)
if(builtin_tile)
if(floor_tile)
if(prob(30))
builtin_tile.loc = src
PoolOrNew(floor_tile, src)
make_plating()
else if(prob(30))
ReplaceWithLattice()
@@ -258,9 +258,8 @@
if(istype(T, /turf/open/floor)) //intact floor, pop the tile
var/turf/open/floor/myturf = T
if(myturf.builtin_tile)
myturf.builtin_tile.loc = T
myturf.builtin_tile = null
if(myturf.floor_tile)
PoolOrNew(myturf.floor_tile, T)
myturf.make_plating()
if(direction) // direction is specified
+1
View File
@@ -11,6 +11,7 @@ var/global/list/map_transition_config = MAP_TRANSITION_CONFIG
/world/New()
check_for_cleanbot_bug()
map_ready = 1
world.log << "Map is ready."
#if (PRELOAD_RSC == 0)
external_rsc_urls = file2list("config/external_rsc_urls.txt","\n")
+1
View File
@@ -148,6 +148,7 @@
#include "code\controllers\subsystem\npcpool.dm"
#include "code\controllers\subsystem\objects.dm"
#include "code\controllers\subsystem\pai.dm"
#include "code\controllers\subsystem\pool.dm"
#include "code\controllers\subsystem\radio.dm"
#include "code\controllers\subsystem\server_maintenance.dm"
#include "code\controllers\subsystem\shuttles.dm"
+15 -4
View File
@@ -4,6 +4,7 @@ import subprocess
import os
import sys
import argparse
import time
from subprocess import PIPE, STDOUT
null = open("/dev/null", "wb")
@@ -36,7 +37,8 @@ def stage2(map):
p = subprocess.Popen(args, shell=True)
wait(p)
def stage3():
def stage3(profile_mode=False):
start_time = time.time()
play("sound/misc/compiler-stage2.ogg")
logfile = open('server.log~','w')
p = subprocess.Popen(
@@ -45,9 +47,15 @@ def stage3():
try:
while p.returncode is None:
stdout = p.stdout.readline()
t = "Initializations complete."
if t in stdout:
if "Initializations complete." in stdout:
play("sound/misc/server-ready.ogg")
time_taken = time.time() - start_time
print("{} seconds taken to fully start".format(time_taken))
if "Map is ready." in stdout:
time_taken = time.time() - start_time
print("{} seconds for initial map loading".format(time_taken))
if profile_mode:
return time_taken
sys.stdout.write(stdout)
sys.stdout.flush()
logfile.write(stdout)
@@ -63,6 +71,7 @@ def main():
parser.add_argument('-s','---stage',default=1,type=int)
parser.add_argument('--only',action='store_true')
parser.add_argument('-m','--map',type=str)
parser.add_argument('--profile-mode',action='store_true')
args = parser.parse_args()
stage = args.stage
assert stage in (1,2,3)
@@ -75,7 +84,9 @@ def main():
if not args.only:
stage = 3
if stage == 3:
stage3()
value = stage3(profile_mode=args.profile_mode)
with open('profile~', 'a') as f:
f.write("{}\n".format(value))
if __name__=='__main__':
try: