mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-21 15:42:35 +00:00
Port of tgstation/tgstation#26975. Changes the lighting engine to apply lighting changes in one step using stored lum value differences instead of two steps (remove_lum, add_lum). Seems to show a speedup in lighting updates as well as a reduction in server memory usage due to aggressive freeing of unneeded lists. Lighting overlays also default to fullbright instead of fulldark so movable area transitions look less strange.
150 lines
4.0 KiB
Plaintext
150 lines
4.0 KiB
Plaintext
var/datum/controller/subsystem/lighting/SSlighting
|
|
|
|
/var/lighting_profiling = FALSE
|
|
|
|
/datum/controller/subsystem/lighting
|
|
name = "Lighting"
|
|
wait = LIGHTING_INTERVAL
|
|
|
|
priority = SS_PRIORITY_LIGHTING
|
|
init_order = SS_INIT_LIGHTING
|
|
|
|
var/list/lighting_overlays // List of all lighting overlays in the world.
|
|
var/list/lighting_corners // List of all lighting corners in the world.
|
|
|
|
var/list/light_queue = list() // lighting sources queued for update.
|
|
var/list/corner_queue = list() // lighting corners queued for update.
|
|
var/list/overlay_queue = list() // lighting overlays queued for update.
|
|
|
|
var/tmp/processed_lights = 0
|
|
var/tmp/processed_corners = 0
|
|
var/tmp/processed_overlays = 0
|
|
|
|
var/force_queued = TRUE
|
|
var/force_override = FALSE // For admins.
|
|
|
|
var/instant_tick_limit = 80 // Tick limit used by instant lighting updates. If world.tick_usage is higher than this when a light updates, it will be updated via. SSlighting.
|
|
|
|
/datum/controller/subsystem/lighting/New()
|
|
NEW_SS_GLOBAL(SSlighting)
|
|
LAZYINITLIST(lighting_corners)
|
|
LAZYINITLIST(lighting_overlays)
|
|
|
|
/datum/controller/subsystem/lighting/stat_entry()
|
|
..("O:[lighting_overlays.len] C:[lighting_corners.len] ITL:[round(instant_tick_limit, 0.1)]%\n\tP:{L:[light_queue.len]|C:[corner_queue.len]|O:[overlay_queue.len]}\n\tL:{L:[processed_lights]|C:[processed_corners]|O:[processed_overlays]}")
|
|
|
|
/datum/controller/subsystem/lighting/ExplosionStart()
|
|
force_queued = TRUE
|
|
|
|
/datum/controller/subsystem/lighting/ExplosionEnd()
|
|
if (!force_override)
|
|
force_queued = FALSE
|
|
|
|
/datum/controller/subsystem/lighting/proc/handle_roundstart()
|
|
force_queued = FALSE
|
|
|
|
/datum/controller/subsystem/lighting/Initialize(timeofday)
|
|
var/overlaycount = 0
|
|
// Generate overlays.
|
|
for (var/zlevel = 1 to world.maxz)
|
|
for (var/turf/T in block(locate(1, 1, zlevel), locate(world.maxx, world.maxy, zlevel)))
|
|
if (!T.dynamic_lighting)
|
|
continue
|
|
|
|
var/area/A = T.loc
|
|
if (!A.dynamic_lighting)
|
|
continue
|
|
|
|
new /atom/movable/lighting_overlay(T)
|
|
overlaycount++
|
|
|
|
CHECK_TICK
|
|
|
|
admin_notice(span("danger", "Created [overlaycount] lighting overlays."), R_DEBUG)
|
|
|
|
// Tick once to clear most lights.
|
|
fire(FALSE, TRUE)
|
|
|
|
admin_notice(span("danger", "Processed [processed_lights] light sources."), R_DEBUG)
|
|
admin_notice(span("danger", "Processed [processed_corners] light corners."), R_DEBUG)
|
|
admin_notice(span("danger", "Processed [processed_overlays] light overlays."), R_DEBUG)
|
|
|
|
log_ss("lighting", "NOv:[overlaycount] L:[processed_lights] C:[processed_corners] O:[processed_overlays]")
|
|
|
|
SSticker.OnRoundstart(CALLBACK(src, .proc/handle_roundstart))
|
|
|
|
..()
|
|
|
|
/datum/controller/subsystem/lighting/fire(resumed = FALSE, no_mc_tick = FALSE)
|
|
if (!resumed)
|
|
processed_lights = 0
|
|
processed_corners = 0
|
|
processed_overlays = 0
|
|
|
|
instant_tick_limit = CURRENT_TICKLIMIT * 0.8
|
|
|
|
MC_SPLIT_TICK_INIT(3)
|
|
if (!no_mc_tick)
|
|
MC_SPLIT_TICK
|
|
|
|
var/list/curr_lights = light_queue
|
|
var/list/curr_corners = corner_queue
|
|
var/list/curr_overlays = overlay_queue
|
|
|
|
while (curr_lights.len)
|
|
var/datum/light_source/L = curr_lights[curr_lights.len]
|
|
curr_lights.len--
|
|
|
|
L.update_corners()
|
|
|
|
L.needs_update = LIGHTING_NO_UPDATE
|
|
|
|
processed_lights++
|
|
|
|
if (no_mc_tick)
|
|
CHECK_TICK
|
|
else if (MC_TICK_CHECK)
|
|
break
|
|
|
|
if (!no_mc_tick)
|
|
MC_SPLIT_TICK
|
|
|
|
while (curr_corners.len)
|
|
var/datum/lighting_corner/C = curr_corners[curr_corners.len]
|
|
curr_corners.len--
|
|
|
|
C.update_overlays()
|
|
|
|
C.needs_update = FALSE
|
|
|
|
processed_corners++
|
|
|
|
if (no_mc_tick)
|
|
CHECK_TICK
|
|
else if (MC_TICK_CHECK)
|
|
break
|
|
|
|
if (!no_mc_tick)
|
|
MC_SPLIT_TICK
|
|
|
|
while (curr_overlays.len)
|
|
var/atom/movable/lighting_overlay/O = curr_overlays[curr_overlays.len]
|
|
curr_overlays.len--
|
|
|
|
O.update_overlay()
|
|
O.needs_update = FALSE
|
|
|
|
processed_overlays++
|
|
|
|
if (no_mc_tick)
|
|
CHECK_TICK
|
|
else if (MC_TICK_CHECK)
|
|
break
|
|
|
|
/datum/controller/subsystem/lighting/Recover()
|
|
src.light_queue = SSlighting.light_queue
|
|
src.corner_queue = SSlighting.corner_queue
|
|
src.overlay_queue = SSlighting.overlay_queue
|
|
lighting_corners = SSlighting.lighting_corners
|
|
lighting_overlays = SSlighting.lighting_overlays
|