mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-25 14:08:31 +01:00
Builds logic that manages turfs contained inside an area (#70966)
## About The Pull Request Area contents isn't a real list, instead it involves filtering everything in world This is slow, and something we should have better support for. So instead, lets manage a list of turfs inside our area. This is simple, since we already move turfs by area contents anyway This should speed up the uses I've found, and opens us up to using this pattern more often, which should make dev work easier. By nature this is a tad fragile, so I've added a unit test to double check my work Rather then instantly removing turfs from the contained_turfs list, we enter them into a list of turfs to pull out, later. Then we just use a getter for contained_turfs rather then a var read This means we don't need to generate a lot of usage off removing turf by turf from space, and can instead do it only when we need to I've added a subsystem to manage this process as well, to ensure we don't get any out of memory errors. It goes entry by entry, ensuring we get no overtime. This allows me to keep things like space clean, while keeping high amounts of usage on a sepearate subsystem when convienient As a part of this goal of keeping space's churn as low as possible, I've setup code to ensure we do not add turfs to areas during a z level increment adjacent mapload. this saves a LOT of time, but is a tad messy I've expanded where we use contained_turfs, including into some cases that filter for objects in areas. need to see if this is sane or not. Builds sortedAreas on demand, caching until we mark the cache as violated It's faster, and it also has the same behavior I'm not posting speed changes cause frankly they're gonna be a bit scattered and I'm scared to. @Mothblocks if you'd like I can look into it. I think it'll pay for itself just off `reg_in_areas_in_z` (I looked into it. it's really hard to tell, sometimes it's a bit slower (0.7), sometimes it's 2 seconds (0.5 if you use the old master figure) faster. life is pain.) ## Why It's Good For The Game Less stupid, more flexible, more speed Co-authored-by: san7890 <the@san7890.com>
This commit is contained in:
co-authored by
san7890
parent
1ed6876e37
commit
5b4ba051a0
@@ -50,10 +50,10 @@
|
||||
/// - `no_changeturf`: When true, [/turf/proc/AfterChange] won't be called on loaded turfs
|
||||
/// - `x_lower`, `x_upper`, `y_lower`, `y_upper`: Coordinates (relative to the map) to crop to (Optional).
|
||||
/// - `placeOnTop`: Whether to use [/turf/proc/PlaceOnTop] rather than [/turf/proc/ChangeTurf] (Optional).
|
||||
/proc/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, x_lower = -INFINITY as num, x_upper = INFINITY as num, y_lower = -INFINITY as num, y_upper = INFINITY as num, placeOnTop = FALSE as num)
|
||||
/proc/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, x_lower = -INFINITY as num, x_upper = INFINITY as num, y_lower = -INFINITY as num, y_upper = INFINITY as num, placeOnTop = FALSE as num, new_z)
|
||||
var/datum/parsed_map/parsed = new(dmm_file, x_lower, x_upper, y_lower, y_upper, measureOnly)
|
||||
if(parsed.bounds && !measureOnly)
|
||||
parsed.load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop)
|
||||
parsed.load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, new_z = new_z)
|
||||
return parsed
|
||||
|
||||
/// Parse a map, possibly cropping it.
|
||||
@@ -157,10 +157,10 @@
|
||||
src.key_len = key_len
|
||||
|
||||
/// Load the parsed map into the world. See [/proc/load_map] for arguments.
|
||||
/datum/parsed_map/proc/load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, whitelist = FALSE)
|
||||
/datum/parsed_map/proc/load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, whitelist = FALSE, new_z)
|
||||
//How I wish for RAII
|
||||
Master.StartLoadingMap()
|
||||
. = _load_impl(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop)
|
||||
. = _load_impl(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, new_z)
|
||||
Master.StopLoadingMap()
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@
|
||||
SSatoms.map_loader_begin(); \
|
||||
}
|
||||
// Do not call except via load() above.
|
||||
/datum/parsed_map/proc/_load_impl(x_offset = 1, y_offset = 1, z_offset = world.maxz + 1, cropMap = FALSE, no_changeturf = FALSE, x_lower = -INFINITY, x_upper = INFINITY, y_lower = -INFINITY, y_upper = INFINITY, placeOnTop = FALSE)
|
||||
/datum/parsed_map/proc/_load_impl(x_offset = 1, y_offset = 1, z_offset = world.maxz + 1, cropMap = FALSE, no_changeturf = FALSE, x_lower = -INFINITY, x_upper = INFINITY, y_lower = -INFINITY, y_upper = INFINITY, placeOnTop = FALSE, new_z = FALSE)
|
||||
PRIVATE_PROC(TRUE)
|
||||
var/list/modelCache = build_cache(no_changeturf)
|
||||
var/space_key = modelCache[SPACE_KEY]
|
||||
@@ -288,7 +288,7 @@
|
||||
if(!cache)
|
||||
SSatoms.map_loader_stop()
|
||||
CRASH("Undefined model key in DMM: [line]")
|
||||
build_coordinate(cache, locate(true_xcrd, ycrd, zcrd), no_afterchange, placeOnTop)
|
||||
build_coordinate(cache, locate(true_xcrd, ycrd, zcrd), no_afterchange, placeOnTop, new_z)
|
||||
|
||||
// only bother with bounds that actually exist
|
||||
if(!first_found)
|
||||
@@ -320,7 +320,7 @@
|
||||
if(!cache)
|
||||
SSatoms.map_loader_stop()
|
||||
CRASH("Undefined model key in DMM: [model_key]")
|
||||
build_coordinate(cache, locate(xcrd, ycrd, zcrd), no_afterchange, placeOnTop)
|
||||
build_coordinate(cache, locate(xcrd, ycrd, zcrd), no_afterchange, placeOnTop, new_z)
|
||||
|
||||
// only bother with bounds that actually exist
|
||||
if(!first_found)
|
||||
@@ -347,6 +347,10 @@
|
||||
//we do this after we load everything in. if we don't; we'll have weird atmos bugs regarding atmos adjacent turfs
|
||||
T.AfterChange(CHANGETURF_IGNORE_AIR)
|
||||
|
||||
if(new_z)
|
||||
for(var/z_index in bounds[MAP_MINZ] to bounds[MAP_MAXZ])
|
||||
SSmapping.build_area_turfs(z_index)
|
||||
|
||||
if(has_expanded_world_maxx || has_expanded_world_maxy)
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_EXPANDED_WORLD_BOUNDS, has_expanded_world_maxx, has_expanded_world_maxy)
|
||||
|
||||
@@ -437,7 +441,7 @@ GLOBAL_LIST_EMPTY(map_model_default)
|
||||
|
||||
.[model_key] = list(members, members_attributes)
|
||||
|
||||
/datum/parsed_map/proc/build_coordinate(list/model, turf/crds, no_changeturf as num, placeOnTop as num)
|
||||
/datum/parsed_map/proc/build_coordinate(list/model, turf/crds, no_changeturf as num, placeOnTop as num, new_z)
|
||||
// If we don't have a turf, nothing we will do next will actually acomplish anything, so just go back
|
||||
// Note, this would actually drop area vvs in the tile, but like, why tho
|
||||
if(!crds)
|
||||
@@ -458,29 +462,34 @@ GLOBAL_LIST_EMPTY(map_model_default)
|
||||
//The next part of the code assumes there's ALWAYS an /area AND a /turf on a given tile
|
||||
//first instance the /area and remove it from the members list
|
||||
index = members.len
|
||||
var/atom/instance
|
||||
if(members[index] != /area/template_noop)
|
||||
var/area/area_instance
|
||||
if(members_attributes[index] != default_list)
|
||||
world.preloader_setup(members_attributes[index], members[index])//preloader for assigning set variables on atom creation
|
||||
instance = loaded_areas[members[index]]
|
||||
if(!instance)
|
||||
area_instance = loaded_areas[members[index]]
|
||||
if(!area_instance)
|
||||
var/area_type = members[index]
|
||||
// If this parsed map doesn't have that area already, we check the global cache
|
||||
instance = GLOB.areas_by_type[area_type]
|
||||
area_instance = GLOB.areas_by_type[area_type]
|
||||
// If the global list DOESN'T have this area it's either not a unique area, or it just hasn't been created yet
|
||||
if (!instance)
|
||||
instance = new area_type(null)
|
||||
if(!instance)
|
||||
if (!area_instance)
|
||||
area_instance = new area_type(null)
|
||||
if(!area_instance)
|
||||
CRASH("[area_type] failed to be new'd, what'd you do?")
|
||||
loaded_areas[area_type] = instance
|
||||
loaded_areas[area_type] = area_instance
|
||||
|
||||
instance.contents.Add(crds)
|
||||
if(!new_z)
|
||||
var/area/old_area = crds.loc
|
||||
old_area.turfs_to_uncontain += crds
|
||||
area_instance.contained_turfs.Add(crds)
|
||||
area_instance.contents.Add(crds)
|
||||
|
||||
if(GLOB.use_preloader)
|
||||
world.preloader_load(instance)
|
||||
world.preloader_load(area_instance)
|
||||
|
||||
// Index right before /area is /turf
|
||||
index--
|
||||
var/atom/instance
|
||||
//then instance the /turf
|
||||
//NOTE: this used to place any turfs before the last "underneath" it using .appearance and underlays
|
||||
//We don't actually use this, and all it did was cost cpu, so we don't do this anymore
|
||||
|
||||
Reference in New Issue
Block a user