A lot of perf micro-optimisations (#20188)

* Refactors Investigate Log

* Speedup character loading

* Optimise SSinstancing

* Removes both path images

* Optimises SSdebugview

* CRLF --> LF

* Update config/example/config.toml
This commit is contained in:
AffectedArc07
2023-01-14 20:01:16 +00:00
committed by GitHub
parent bf61975b2a
commit 0db3259f47
25 changed files with 79 additions and 145 deletions
+1 -1
View File
@@ -26,7 +26,7 @@
#define PLANT_WEED_HUD "21"// Weed level
#define DIAG_TRACK_HUD "22"// Mech tracking beacon
#define DIAG_AIRLOCK_HUD "23" // Airlock shock overlay
#define DIAG_PATH_HUD "24"//Bot path indicators
//#define DIAG_PATH_HUD "24"//Bot path indicators
#define GLAND_HUD "25"//Gland indicators for abductors
//by default everything in the hud_list of an atom is an image
-1
View File
@@ -49,4 +49,3 @@ GLOBAL_PROTECT(OOClog)
GLOBAL_DATUM_INIT(logging, /datum/logging, new /datum/logging())
GLOBAL_LIST_INIT(investigate_log_subjects, list("notes", "watchlist", "hrefs"))
@@ -22,6 +22,8 @@
var/list/topic_ip_ratelimit_bypass = list()
/// Server instance ID
var/instance_id = "paradise_main"
/// Do we want to enable instancing stuff at all?
var/enable_multi_instance_support = FALSE
/// Server internal IP
var/internal_ip = "127.0.0.1"
/// Are we using an external handler for TOS
@@ -36,6 +38,7 @@
CONFIG_LOAD_BOOL(shutdown_on_reboot, data["shutdown_on_reboot"])
CONFIG_LOAD_BOOL(is_production, data["is_production"])
CONFIG_LOAD_BOOL(external_tos_handler, data["external_tos_handler"])
CONFIG_LOAD_BOOL(enable_multi_instance_support, data["enable_multi_instance_support"])
CONFIG_LOAD_STR(topic_key, data["communications_password"])
CONFIG_LOAD_STR(medal_hub_address, data["medal_hub_address"])
+4
View File
@@ -7,6 +7,10 @@ SUBSYSTEM_DEF(debugview)
var/list/client/processing = list()
/datum/controller/subsystem/debugview/fire(resumed)
// Dont generate text if no one is there to look at it
if(!length(processing))
return
// Generate debug text
var/list/entries = list()
entries += "CPU: [round(world.cpu, 1)] | MCPU: [round(world.map_cpu, 1)] | FPS/TPS: [world.fps] | Clients: [length(GLOB.clients)] | BYOND: [world.byond_version].[world.byond_build]"
+17 -1
View File
@@ -14,7 +14,7 @@ SUBSYSTEM_DEF(instancing)
CRASH("SSinstancing was set to init before SSredis. Who broke it?")
// Dont even bother if we arent connected to redis or the DB
if(!SSdbcore.IsConnected() || !SSredis.connected)
if(!SSdbcore.IsConnected() || !SSredis.connected || !GLOB.configuration.system.enable_multi_instance_support)
flags |= SS_NO_FIRE
return ..()
@@ -43,6 +43,10 @@ SUBSYSTEM_DEF(instancing)
update_playercache()
/datum/controller/subsystem/instancing/proc/execute_command(source, command, list/arguments)
// We aint enabled. Dont bother.
if(!GLOB.configuration.system.enable_multi_instance_support)
return
var/datum/server_command/SC = registered_commands[command]
if(!SC)
CRASH("Attempted to execute command with ID '[command]' from [source], but that command didnt exist!")
@@ -58,6 +62,10 @@ SUBSYSTEM_DEF(instancing)
* Updates the player cache in the DB. Different from heartbeat so we can force invoke it on player operations
*/
/datum/controller/subsystem/instancing/proc/update_playercache(optional_ckey)
// We aint enabled. Dont bother.
if(!GLOB.configuration.system.enable_multi_instance_support)
return
// You may be wondering, why the fuck is an "optional ckey" variable here
// Well, this is invoked in client/New(), and needs to read from GLOB.clients
// However, this proc sleeps, and if you sleep during client/New() once the client is in GLOB.clients, stuff breaks bad
@@ -111,6 +119,10 @@ SUBSYSTEM_DEF(instancing)
* This is called during world/New() instead of on initialize so it can be done *instantly*
*/
/datum/controller/subsystem/instancing/proc/seed_data()
// We aint enabled. Dont bother.
if(!GLOB.configuration.system.enable_multi_instance_support)
return
// We need to seed a lot of keys, so lets just use a key-value-pair-map to do this easily
var/list/kvp_map = list()
kvp_map["server_name"] = GLOB.configuration.general.server_name // Name of the server
@@ -145,6 +157,10 @@ SUBSYSTEM_DEF(instancing)
* ckey - The ckey to check if they are logged into another server
*/
/datum/controller/subsystem/instancing/proc/check_player(ckey)
// We aint enabled. Dont bother.
if(!GLOB.configuration.system.enable_multi_instance_support)
return
// Please see above rant on L127
var/datum/db_query/dbq1 = SSdbcore.NewQuery({"
SELECT server_id, key_value FROM instance_data_cache WHERE server_id IN
+1 -4
View File
@@ -49,10 +49,7 @@
hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD)
/datum/atom_hud/data/diagnostic/advanced
hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_PATH_HUD)
/datum/atom_hud/data/bot_path
hud_icons = list(DIAG_PATH_HUD)
hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD)
/datum/atom_hud/abductor
hud_icons = list(GLAND_HUD)
+1 -1
View File
@@ -149,7 +149,7 @@ GLOBAL_LIST_EMPTY(tcomms_machines)
*/
/obj/machinery/tcomms/proc/log_action(user, msg, adminmsg = FALSE)
log_game("NTTC: [key_name(user)] [msg]")
log_investigate("[key_name(user)] [msg]", "nttc")
investigate_log("[key_name(user)] [msg]", "nttc")
if(adminmsg)
message_admins("[key_name_admin(user)] [msg]")
/**
-2
View File
@@ -58,8 +58,6 @@ GLOBAL_DATUM(test_runner, /datum/test_runner)
GLOB.timezoneOffset = text2num(time2text(0, "hh")) * 36000
investigate_reset()
update_status()
GLOB.space_manager.initialize() //Before the MC starts up
+20 -50
View File
@@ -1,61 +1,31 @@
//By Carnwennan
//This system was made as an alternative to all the in-game lists and variables used to log stuff in-game.
//lists and variables are great. However, they have several major flaws:
//Firstly, they use memory. TGstation has one of the highest memory usage of all the ss13 branches.
//Secondly, they are usually stored in an object. This means that they aren't centralised. It also means that
//the data is lost when the object is deleted! This is especially annoying for things like the singulo engine!
#define INVESTIGATE_DIR "data/investigate/"
//SYSTEM
/proc/investigate_subject2file(subject)
return wrap_file("[INVESTIGATE_DIR][subject].html")
/proc/investigate_reset()
if(fdel(INVESTIGATE_DIR)) return 1
return 0
// Atom investigate stuff
// All of this is stored in a global list because its faster than file IO and we arent ram constrained like TG -aa07
GLOBAL_LIST_EMPTY(investigate_log_wrapper)
GLOBAL_PROTECT(investigate_log_wrapper)
/atom/proc/investigate_log(message, subject)
if(!message) return
var/F = investigate_subject2file(subject)
if(!F) return
GLOB.investigate_log_subjects |= subject
F << "<small>[time_stamp()] \ref[src] [ADMIN_COORDJMP(src)] </small> || [src] [message]<br>"
if(!message || !subject)
return
/proc/log_investigate(message, subject)
if(!message) return
var/F = investigate_subject2file(subject)
if(!F) return
GLOB.investigate_log_subjects |= subject
F << "<small>[time_stamp()] || [message]<br>"
if(!(subject in GLOB.investigate_log_wrapper))
GLOB.investigate_log_wrapper[subject] = list()
GLOB.investigate_log_wrapper[subject] += "<small>[time_stamp()] [UID()] [ADMIN_COORDJMP(src)] </small> || [src] [message]"
//ADMINVERBS
/client/proc/investigate_show( subject in GLOB.investigate_log_subjects )
set name = "Investigate"
/client/proc/investigate_show(subject in GLOB.investigate_log_wrapper)
set name = "Investigate Round Objects"
set category = "Admin"
if(!check_rights(R_ADMIN))
return
switch(subject)
if("notes")
show_note()
if("watchlist")
watchlist_show()
// Should never happen
if(!(subject in GLOB.investigate_log_wrapper))
return
if("hrefs") //persistant logs and stuff
if(GLOB.configuration.logging.href_logging)
if(GLOB.world_href_log)
src << browse(file(GLOB.world_href_log), "window=investigate[subject];size=800x300")
else
to_chat(src, "<font color='red'>Error: admin_investigate: No href logfile found.</font>")
return
else
to_chat(src, "<font color='red'>Error: admin_investigate: Href Logging is not on.</font>")
return
var/list/entries = GLOB.investigate_log_wrapper[subject]
else //general one-round-only stuff
var/F = investigate_subject2file(subject)
if(!F)
to_chat(src, "<font color='red'>Error: admin_investigate: [INVESTIGATE_DIR][subject] is an invalid path or cannot be accessed.</font>")
return
src << browse(F,"window=investigate[subject];size=800x300")
var/datum/browser/B = new(usr, "investigatelog", "Investigate ([subject])", 800, 400)
B.set_content(entries.Join("<br>"))
B.open()
+11 -1
View File
@@ -69,7 +69,8 @@ GLOBAL_LIST_INIT(admin_verbs_admin, list(
/client/proc/ccbdb_lookup_ckey,
/client/proc/view_instances,
/client/proc/start_vote,
/client/proc/ping_all_admins
/client/proc/ping_all_admins,
/client/proc/show_watchlist
))
GLOBAL_LIST_INIT(admin_verbs_ban, list(
/client/proc/ban_panel,
@@ -996,3 +997,12 @@ GLOBAL_LIST_INIT(admin_verbs_maintainer, list(
log_admin("[key_name(usr)] has [advanced_admin_interaction ? "activated" : "deactivated"] their advanced admin interaction.")
message_admins("[key_name_admin(usr)] has [advanced_admin_interaction ? "activated" : "deactivated"] their advanced admin interaction.")
/client/proc/show_watchlist()
set name = "Show Watchlist"
set category = "Admin"
if(!check_rights(R_ADMIN))
return
watchlist_show()
@@ -35,17 +35,21 @@ Thus, the two variables affect pump operation are set in New():
/obj/machinery/atmospherics/binary/pump/CtrlClick(mob/living/user)
if(can_use_shortcut(user))
toggle(user)
investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", "atmos")
return ..()
/obj/machinery/atmospherics/binary/pump/AICtrlClick(mob/living/silicon/user)
toggle(user)
investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", "atmos")
/obj/machinery/atmospherics/binary/pump/AltClick(mob/living/user)
if(can_use_shortcut(user))
set_max(user)
investigate_log("was set to [target_pressure] kPa by [key_name(user)]", "atmos")
/obj/machinery/atmospherics/binary/pump/AIAltClick(mob/living/silicon/user)
set_max(user)
investigate_log("was set to [target_pressure] kPa by [key_name(user)]", "atmos")
/obj/machinery/atmospherics/binary/pump/on
icon_state = "map_on"
@@ -32,17 +32,21 @@ Thus, the two variables affect pump operation are set in New():
/obj/machinery/atmospherics/binary/volume_pump/CtrlClick(mob/living/user)
if(can_use_shortcut(user))
toggle(user)
investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", "atmos")
return ..()
/obj/machinery/atmospherics/binary/volume_pump/AICtrlClick(mob/living/silicon/user)
toggle(user)
investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", "atmos")
/obj/machinery/atmospherics/binary/volume_pump/AltClick(mob/living/user)
if(can_use_shortcut(user))
set_max(user)
investigate_log("was set to [target_pressure] kPa by [key_name(user)]", "atmos")
/obj/machinery/atmospherics/binary/volume_pump/AIAltClick(mob/living/silicon/user)
set_max(user)
investigate_log("was set to [target_pressure] kPa by [key_name(user)]", "atmos")
/obj/machinery/atmospherics/binary/volume_pump/on
on = TRUE
@@ -38,17 +38,21 @@
/obj/machinery/atmospherics/trinary/filter/CtrlClick(mob/living/user)
if(can_use_shortcut(user))
toggle(user)
investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", "atmos")
return ..()
/obj/machinery/atmospherics/trinary/filter/AICtrlClick(mob/living/silicon/user)
toggle(user)
investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", "atmos")
/obj/machinery/atmospherics/trinary/filter/AltClick(mob/living/user)
if(can_use_shortcut(user))
set_max(user)
investigate_log("was set to [target_pressure] kPa by [key_name(user)]", "atmos")
/obj/machinery/atmospherics/trinary/filter/AIAltClick(mob/living/silicon/user)
set_max(user)
investigate_log("was set to [target_pressure] kPa by [key_name(user)]", "atmos")
/obj/machinery/atmospherics/trinary/filter/flipped
icon_state = "mmap"
@@ -19,17 +19,21 @@
/obj/machinery/atmospherics/trinary/mixer/CtrlClick(mob/living/user)
if(can_use_shortcut(user))
toggle(user)
investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", "atmos")
return ..()
/obj/machinery/atmospherics/trinary/mixer/AICtrlClick(mob/living/silicon/user)
toggle(user)
investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", "atmos")
/obj/machinery/atmospherics/trinary/mixer/AltClick(mob/living/user)
if(can_use_shortcut(user))
set_max(user)
investigate_log("was set to [target_pressure] kPa by [key_name(user)]", "atmos")
/obj/machinery/atmospherics/trinary/mixer/AIAltClick(mob/living/silicon/user)
set_max(user)
investigate_log("was set to [target_pressure] kPa by [key_name(user)]", "atmos")
/obj/machinery/atmospherics/trinary/mixer/flipped
icon_state = "mmap"
@@ -103,7 +103,6 @@
// Fuckery to prevent null characters
/datum/character_save/New()
randomise()
real_name = random_name(gender, species)
/datum/character_save/proc/save(client/C)
@@ -47,7 +47,7 @@
var/frustration = 0 //Used by some bots for tracking failures to reach their target.
var/base_speed = 2 //The speed at which the bot moves, or the number of times it moves per process() tick.
var/turf/ai_waypoint //The end point of a bot's path, or the target location.
var/list/path = list() //List of turfs through which a bot 'steps' to reach the waypoint, associated with the path image, if there is one.
var/list/path = list() //List of turfs through which a bot 'steps' to reach the waypoint
var/pathset = FALSE
var/list/ignore_list = list() //List of unreachable targets for an ignore-list enabled bot to ignore.
var/mode = BOT_IDLE //Standardizes the vars that indicate the bot is busy with its function.
@@ -86,16 +86,12 @@
"Responding", "Navigating to Delivery Location", "Navigating to Home", \
"Waiting for clear path", "Calculating navigation path", "Pinging beacon network", "Unable to reach destination")
var/datum/atom_hud/data/bot_path/path_hud = new /datum/atom_hud/data/bot_path()
var/path_image_icon = 'icons/obj/aibots.dmi'
var/path_image_icon_state = "path_indicator"
var/path_image_color = "#FFFFFF"
var/reset_access_timer_id
/// List of access values you can have to access the bot. Consider this as req_one_access
var/list/req_access = list()
hud_possible = list(DIAG_STAT_HUD, DIAG_BOT_HUD, DIAG_HUD, DIAG_PATH_HUD = HUD_LIST_LIST)//Diagnostic HUD views
hud_possible = list(DIAG_STAT_HUD, DIAG_BOT_HUD, DIAG_HUD)//Diagnostic HUD views
/obj/item/radio/headset/bot
requires_tcomms = FALSE
@@ -170,9 +166,6 @@
diag_hud_set_botstat()
diag_hud_set_botmode()
if(path_hud)
path_hud.add_to_hud(src)
/mob/living/simple_animal/bot/med_hud_set_health()
return //we use a different hud
@@ -185,9 +178,6 @@
if(paicard)
ejectpai()
set_path(null)
if(path_hud)
QDEL_NULL(path_hud)
path_hud = null
var/datum/atom_hud/data_hud = GLOB.huds[data_hud_type]
if(data_hud)
@@ -1028,75 +1018,11 @@ Pass a positive integer as an argument to override a bot's default speed.
/mob/living/simple_animal/bot/proc/set_path(list/newpath)
path = newpath ? newpath : list()
if(!path_hud)
return
var/list/path_huds_watching_me = list(GLOB.huds[DATA_HUD_DIAGNOSTIC_ADVANCED])
if(path_hud)
path_huds_watching_me += path_hud
for(var/V in path_huds_watching_me)
var/datum/atom_hud/H = V
H.remove_from_hud(src)
clear_path_image()
var/list/path_images = hud_list[DIAG_PATH_HUD]
QDEL_LIST_CONTENTS(path_images)
if(newpath)
for(var/i in 1 to newpath.len)
var/turf/T = newpath[i]
if(T == loc) //don't bother putting an image if it's where we already exist.
continue
var/direction = NORTH
if(i > 1)
var/turf/prevT = path[i - 1]
var/image/prevI = path[prevT]
direction = get_dir(prevT, T)
if(i > 2)
var/turf/prevprevT = path[i - 2]
var/prevDir = get_dir(prevprevT, prevT)
var/mixDir = direction|prevDir
if(mixDir in GLOB.diagonals)
prevI.dir = mixDir
if(prevDir & (NORTH|SOUTH))
var/matrix/ntransform = matrix()
ntransform.Turn(90)
if((mixDir == NORTHWEST) || (mixDir == SOUTHEAST))
ntransform.Scale(-1, 1)
else
ntransform.Scale(1, -1)
prevI.transform = ntransform
var/mutable_appearance/MA = new /mutable_appearance()
MA.icon = path_image_icon
MA.icon_state = path_image_icon_state
MA.layer = ABOVE_OPEN_TURF_LAYER
MA.plane = FLOOR_PLANE
MA.appearance_flags = RESET_COLOR|RESET_TRANSFORM
MA.color = path_image_color
MA.dir = direction
var/image/I = image(loc = T)
I.appearance = MA
path[T] = I
path_images += I
for(var/V in path_huds_watching_me)
var/datum/atom_hud/H = V
H.add_to_hud(src)
/mob/living/simple_animal/bot/proc/increment_path()
if(!path || !length(path))
return
var/image/I = path[path[1]]
if(I)
I.icon_state = null
path.Cut(1, 2)
/mob/living/simple_animal/bot/proc/clear_path_image()
if(!path || !length(path))
return
for(var/P in path)
var/image/I = path[P]
if(I?.icon_state)
I.icon_state = null
/mob/living/simple_animal/bot/proc/drop_part(obj/item/drop_item, dropzone)
new drop_item(dropzone)
@@ -17,7 +17,6 @@
window_id = "autoclean"
window_name = "Automatic Station Cleaner v1.1"
pass_flags = PASSMOB
path_image_color = "#993299"
var/blood = TRUE
@@ -22,7 +22,6 @@
req_access = list(ACCESS_SECURITY)
window_id = "autoed209"
window_name = "Automatic Security Unit v2.6"
path_image_color = "#FF0000"
data_hud_type = DATA_HUD_SECURITY_ADVANCED
allow_pai = FALSE
@@ -17,7 +17,6 @@
req_access = list(ACCESS_CONSTRUCTION, ACCESS_ROBOTICS)
window_id = "autofloor"
window_name = "Automatic Station Floor Repairer v1.1"
path_image_color = "#FFA500"
var/process_type //Determines what to do when process_scan() recieves a target. See process_scan() for details.
var/targetdirection
@@ -17,7 +17,6 @@
window_id = "autohonk"
window_name = "Honkomatic Bike Horn Unit v1.0.7"
data_hud_type = DATA_HUD_SECURITY_BASIC // show jobs
path_image_color = "#FF69B4"
var/honksound = 'sound/items/bikehorn.ogg' //customizable sound
var/spam_flag = FALSE
@@ -19,7 +19,6 @@
req_access = list(ACCESS_MEDICAL, ACCESS_ROBOTICS)
window_id = "automed"
window_name = "Automatic Medical Unit v1.1"
path_image_color = "#DDDDFF"
data_hud_type = DATA_HUD_MEDICAL_ADVANCED
var/obj/item/reagent_containers/glass/reagent_glass = null //Can be set to draw from this for reagents.
@@ -26,7 +26,6 @@
model = "MULE"
bot_purpose = "deliver crates and other packages between departments, as requested"
req_access = list(ACCESS_CARGO)
path_image_color = "#7F5200"
suffix = ""
@@ -20,7 +20,6 @@
req_access = list(ACCESS_SECURITY)
window_id = "autosec"
window_name = "Automatic Security Unit v1.6"
path_image_color = "#FF0000"
data_hud_type = DATA_HUD_SECURITY_ADVANCED
var/base_icon = "secbot"
+3
View File
@@ -737,6 +737,9 @@ is_production = false
# Server instance ID. This is used for tagging the server in the database
# You do NOT want to change this once you are running in production
instance_id = "paradise_main"
# Enable the below setting if you plan to run multiple instances of the server
# Enabling this if you dont run multiple instances wont cause problems, but will add a **TINY** amount more lag at times
enable_multi_instance_support = false
# Server internal IP. Used if you are splitting instances over multiple internal IPs.
# In most cases this is just 127.0.0.1
internal_ip = "127.0.0.1"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 79 KiB