Map loader optimizations (#25316)

* Cut out an unecessary locate call

* Remove an unecessary var

* Add an appropriate warning

* Move the CHECK_TICK to a more sensible place

* Change the default turf to /turf/open/space/basic

* Skip loading default turfs

* No need for CreateSpace anymore

* Improve the comment
This commit is contained in:
Cyberboss
2017-03-22 05:10:00 -04:00
committed by oranges
parent 0fdb84784a
commit 8023a02e57
19 changed files with 333 additions and 56 deletions

View File

@@ -14,6 +14,10 @@ var/global/dmm_suite/preloader/_preloader = new
// /^[\s\n]+|[\s\n]+$/
var/static/regex/trimRegex = new/regex("^\[\\s\n]+|\[\\s\n]+$", "g")
var/static/list/modelCache = list()
var/static/space_key
#ifdef TESTING
var/static/turfsSkipped
#endif
/**
* Construct the model map and control the loading process
@@ -28,7 +32,15 @@ var/global/dmm_suite/preloader/_preloader = new
/dmm_suite/load_map(dmm_file as file, x_offset as num, y_offset as num, z_offset as num, cropMap as num, measureOnly as num, no_changeturf as num)
//How I wish for RAII
Master.StartLoadingMap()
space_key = null
#ifdef TESTING
turfsSkipped = 0
#endif
. = load_map_impl(dmm_file, x_offset, y_offset, z_offset, cropMap, measureOnly, no_changeturf)
#ifdef TESTING
if(turfsSkipped)
testing("Skipped loading [turfsSkipped] default turfs")
#endif
Master.StopLoadingMap()
/dmm_suite/proc/load_map_impl(dmm_file, x_offset, y_offset, z_offset, cropMap, measureOnly, no_changeturf)
@@ -81,6 +93,8 @@ var/global/dmm_suite/preloader/_preloader = new
continue
else
world.maxz = zcrd //create a new z_level if needed
if(!no_changeturf)
WARNING("Z-level expansion occurred without no_changeturf set, this may cause problems when /turf/AfterChange is called")
bounds[MAP_MINX] = min(bounds[MAP_MINX], xcrdStart)
bounds[MAP_MINZ] = min(bounds[MAP_MINZ], zcrd)
@@ -126,11 +140,16 @@ var/global/dmm_suite/preloader/_preloader = new
if(xcrd >= 1)
var/model_key = copytext(line, tpos, tpos + key_len)
if(!grid_models[model_key])
throw EXCEPTION("Undefined model key in DMM.")
parse_grid(grid_models[model_key], xcrd, ycrd, zcrd, no_changeturf || zexpansion)
var/no_afterchange = no_changeturf || zexpansion
if(!no_afterchange || (model_key != space_key))
if(!grid_models[model_key])
throw EXCEPTION("Undefined model key in DMM.")
parse_grid(grid_models[model_key], model_key, xcrd, ycrd, zcrd, no_changeturf || zexpansion)
#ifdef TESTING
else
++turfsSkipped
#endif
CHECK_TICK
maxx = max(maxx, xcrd)
++xcrd
--ycrd
@@ -167,7 +186,7 @@ var/global/dmm_suite/preloader/_preloader = new
* 4) Instanciates the atom with its variables
*
*/
/dmm_suite/proc/parse_grid(model as text,xcrd as num,ycrd as num,zcrd as num, no_changeturf as num)
/dmm_suite/proc/parse_grid(model as text, model_key as text, xcrd as num,ycrd as num,zcrd as num, no_changeturf as num)
/*Method parse_grid()
- Accepts a text string containing a comma separated list of type paths of the
same construction as those contained in a .dmm file, and instantiates them.
@@ -228,6 +247,20 @@ var/global/dmm_suite/preloader/_preloader = new
CHECK_TICK
while(dpos != 0)
//check and see if we can just skip this turf
//So you don't have to understand this horrid statement, we can do this if
// 1. no_changeturf is set
// 2. the space_key isn't set yet
// 3. there are exactly 2 members
// 4. with no attributes
// 5. and the members are world.turf and world.area
// Basically, if we find an entry like this: "XXX" = (/turf/default, /area/default)
// We can skip calling this proc every time we see XXX
if(no_changeturf && !space_key && members.len == 2 && members_attributes.len == 2 && length(members_attributes[1]) == 0 && length(members_attributes[2]) == 0 && (world.area in members) && (world.turf in members))
space_key = model_key
return
modelCache[model] = list(members, members_attributes)
@@ -236,6 +269,7 @@ var/global/dmm_suite/preloader/_preloader = new
////////////////
//The next part of the code assumes there's ALWAYS an /area AND a /turf on a given tile
var/turf/crds = locate(xcrd,ycrd,zcrd)
//first instance the /area and remove it from the members list
index = members.len
@@ -244,7 +278,6 @@ var/global/dmm_suite/preloader/_preloader = new
_preloader.setup(members_attributes[index])//preloader for assigning set variables on atom creation
instance = locate(members[index])
var/turf/crds = locate(xcrd,ycrd,zcrd)
if(crds)
instance.contents.Add(crds)
@@ -262,26 +295,20 @@ var/global/dmm_suite/preloader/_preloader = new
//instanciate the first /turf
var/turf/T
if(members[first_turf_index] != /turf/template_noop)
T = instance_atom(members[first_turf_index],members_attributes[first_turf_index],xcrd,ycrd,zcrd,no_changeturf)
T = instance_atom(members[first_turf_index],members_attributes[first_turf_index],crds,no_changeturf)
if(T)
//if others /turf are presents, simulates the underlays piling effect
index = first_turf_index + 1
while(index <= members.len - 1) // Last item is an /area
var/underlay = T.appearance
T = instance_atom(members[index],members_attributes[index],xcrd,ycrd,zcrd,no_changeturf)//instance new turf
T = instance_atom(members[index],members_attributes[index],crds,no_changeturf)//instance new turf
T.underlays += underlay
index++
//finally instance all remainings objects/mobs
for(index in 1 to first_turf_index-1)
instance_atom(members[index],members_attributes[index],xcrd,ycrd,zcrd,no_changeturf)
//custom CHECK_TICK here because we don't want things created while we're sleeping to not initialize
if(world.tick_usage > CURRENT_TICKLIMIT)
SSatoms.map_loader_stop()
stoplag()
SSatoms.map_loader_begin()
instance_atom(members[index],members_attributes[index],crds,no_changeturf)
//Restore initialization to the previous value
SSatoms.map_loader_stop()
@@ -290,22 +317,23 @@ var/global/dmm_suite/preloader/_preloader = new
////////////////
//Instance an atom at (x,y,z) and gives it the variables in attributes
/dmm_suite/proc/instance_atom(path,list/attributes, x, y, z, no_changeturf)
var/atom/instance
/dmm_suite/proc/instance_atom(path,list/attributes, turf/crds, no_changeturf)
_preloader.setup(attributes, path)
var/turf/T = locate(x,y,z)
if(T)
if(crds)
if(!no_changeturf && ispath(path, /turf))
T.ChangeTurf(path, TRUE)
instance = T
. = crds.ChangeTurf(path, TRUE)
else
instance = new path (T)//first preloader pass
. = new path (crds)//first preloader pass
if(use_preloader && instance)//second preloader pass, for those atoms that don't ..() in New()
_preloader.load(instance)
if(use_preloader && .)//second preloader pass, for those atoms that don't ..() in New()
_preloader.load(.)
return instance
//custom CHECK_TICK here because we don't want things created while we're sleeping to not initialize
if(world.tick_usage > CURRENT_TICKLIMIT)
SSatoms.map_loader_stop()
stoplag()
SSatoms.map_loader_begin()
//text trimming (both directions) helper proc
//optionally removes quotes before and after the text (for variable name)