From 154a282a0d899613ec821780bb40847a2d401219 Mon Sep 17 00:00:00 2001 From: Markolie Date: Tue, 28 Jul 2015 19:54:17 +0200 Subject: [PATCH] NanoUI caching for cameras/crew manifest --- code/game/machinery/camera/camera.dm | 17 ++++++++ code/game/machinery/computer/camera.dm | 39 ++++++++----------- code/game/objects/effects/datacore-effect.dm | 6 ++- code/game/objects/items/devices/PDA/PDA.dm | 5 ++- .../living/silicon/pai/software_modules.dm | 2 +- code/modules/nano/JSON Writer.dm | 28 +++++++------ code/modules/nano/_JSON.dm | 20 ++++------ code/modules/nano/nanoui.dm | 19 +-------- 8 files changed, 64 insertions(+), 72 deletions(-) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 0c16939a97f..289a67ca432 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -37,6 +37,8 @@ assembly.anchored = 1 assembly.update_icon() + invalidateCameraCache() + /* // Use this to look for cameras that have the same c_tag. for(var/obj/machinery/camera/C in cameranet.cameras) var/list/tempnetwork = C.network&src.network @@ -50,6 +52,7 @@ deactivate() /obj/machinery/camera/Destroy() + invalidateCameraCache() deactivate(null, 0) //kick anyone viewing out if(assembly) qdel(assembly) @@ -66,6 +69,7 @@ /obj/machinery/camera/emp_act(severity) if(!isEmpProof()) if(prob(100/severity)) + invalidateCameraCache() icon_state = "[initial(icon_state)]emp" var/list/previous_network = network network = list() @@ -85,6 +89,7 @@ if(can_use()) cameranet.addCamera(src) emped = 0 //Resets the consecutive EMP count + invalidateCameraCache() for(var/mob/O in mob_list) if (O.client && O.client.eye == src) O.unset_machine() @@ -114,6 +119,7 @@ user.electrocute_act(10, src) /obj/machinery/camera/attackby(W as obj, mob/living/user as mob, params) + invalidateCameraCache() var/msg = "You attach [W] into the assembly inner circuits." var/msg2 = "The camera already has that upgrade!" @@ -221,6 +227,7 @@ /obj/machinery/camera/proc/deactivate(user as mob, var/choice = 1) if(choice==1) + invalidateCameraCache() status = !( src.status ) if (!(src.status)) if(user) @@ -331,3 +338,13 @@ return 1 busy = 0 return 0 + +/obj/machinery/camera/proc/nano_structure() + var/cam[0] + cam["name"] = sanitize(c_tag) + cam["deact"] = !can_use() + cam["camera"] = "\ref[src]" + cam["x"] = x + cam["y"] = y + cam["z"] = z + return cam \ No newline at end of file diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index bf616e8a859..7aec194ddac 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -1,8 +1,8 @@ -var/camera_cache_id = 1 +/var/camera_cache_id = 1 /proc/invalidateCameraCache() camera_cache_id = (++camera_cache_id % 999999) - + /obj/machinery/computer/security name = "Camera Monitor" desc = "Used to access the various cameras networks on the station." @@ -79,32 +79,21 @@ var/camera_cache_id = 1 var/data[0] - data["current"] = null - var/list/L = list() - for (var/obj/machinery/camera/C in cameranet.cameras) - if(can_access_camera(C)) - L.Add(C) + if(camera_cache_id != cache_id) + cache_id = camera_cache_id + cameranet.process_sort() - cameranet.process_sort() + var/cameras[0] + for(var/obj/machinery/camera/C in cameranet.cameras) + if(!can_access_camera(C)) + continue - var/cameras[0] - for(var/obj/machinery/camera/C in L) - var/cam[0] - cam["name"] = C.c_tag - cam["deact"] = !C.can_use() - cam["camera"] = "\ref[C]" - cam["x"] = C.x - cam["y"] = C.y - cam["z"] = C.z + var/cam = C.nano_structure() + cameras[++cameras.len] = cam - cameras[++cameras.len] = cam - - if(C == current) - data["current"] = cam - - data["cameras"] = cameras + camera_cache=list2json(cameras) tempnets.Cut() if(emagged) @@ -124,6 +113,10 @@ var/camera_cache_id = 1 break if(tempnets.len) data["networks"] = tempnets + + if(current) + data["current"] = current.nano_structure() + data["cameras"] = list("__json_cache" = camera_cache) ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) diff --git a/code/game/objects/effects/datacore-effect.dm b/code/game/objects/effects/datacore-effect.dm index ac2ec220987..cd3dd60011f 100644 --- a/code/game/objects/effects/datacore-effect.dm +++ b/code/game/objects/effects/datacore-effect.dm @@ -132,10 +132,11 @@ using /obj/effect/datacore/proc/manifest_inject( ), or manifest_insert( ) */ var/global/list/PDA_Manifest = list() +var/global/ManifestJSON /obj/effect/datacore/proc/get_manifest_json() if(PDA_Manifest.len) - return PDA_Manifest + return var/heads[0] var/sec[0] var/eng[0] @@ -206,5 +207,6 @@ var/global/list/PDA_Manifest = list() "bot" = bot,\ "misc" = misc\ ) - return PDA_Manifest + ManifestJSON = list2json(PDA_Manifest) + return diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index ac5afb75b07..f7af05b808d 100755 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -467,7 +467,7 @@ var/global/list/obj/item/device/pda/PDAs = list() data["convo_job"] = sanitize(c["job"]) break if(mode==41) - data["manifest"] = data_core.get_manifest_json() + data_core.get_manifest_json() if(mode==3) @@ -499,12 +499,15 @@ var/global/list/obj/item/device/pda/PDAs = list() data["aircontents"] = list("reading" = 0) + data["manifest"] = list("__json_cache" = ManifestJSON) + // update the ui if it exists, returns null if no ui is passed/found ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) // the ui does not exist, so we'll create a new() one // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm ui = new(user, src, ui_key, "pda.tmpl", title, 630, 600) + // when the ui is first opened this is the data it will use ui.set_initial_data(data) // open the new ui window diff --git a/code/modules/mob/living/silicon/pai/software_modules.dm b/code/modules/mob/living/silicon/pai/software_modules.dm index 877c6002dc6..14a3733154d 100644 --- a/code/modules/mob/living/silicon/pai/software_modules.dm +++ b/code/modules/mob/living/silicon/pai/software_modules.dm @@ -123,7 +123,7 @@ on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) var/data[0] - data["manifest"] = data_core.get_manifest_json() + data["manifest"] = list("__json_cache" = ManifestJSON) ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) if(!ui) diff --git a/code/modules/nano/JSON Writer.dm b/code/modules/nano/JSON Writer.dm index f4c74d35ebb..2b70239e7e6 100644 --- a/code/modules/nano/JSON Writer.dm +++ b/code/modules/nano/JSON Writer.dm @@ -1,7 +1,13 @@ json_writer + var + use_cache = 0 + proc WriteObject(list/L, cached_data = null) + if(use_cache && L["__json_cache"]) + return L["__json_cache"] + . = "{" var/i = 1 for(var/k in L) @@ -9,13 +15,11 @@ json_writer . += {"\"[k]\":[write(val)]"} if(i++ < L.len) . += "," - if(cached_data) - . = copytext(., 1, lentext(.)) + ",\"cached\":[cached_data]}" - .+= "}" + . += "}" write(val) if(isnum(val)) - return num2text(val, 100) + return num2text(val) else if(isnull(val)) return "null" else if(istype(val, /list)) @@ -35,27 +39,21 @@ json_writer . += "]" write_string(txt) - var/static/list/json_escape = list("\\", "\"", "'", "\n") + var/static/list/json_escape = list("\\" = "\\\\", "\"" = "\\\"", "\n" = "\\n") for(var/targ in json_escape) var/start = 1 while(start <= lentext(txt)) var/i = findtext(txt, targ, start) if(!i) break - if(targ == "\n") - txt = copytext(txt, 1, i) + "\\n" + copytext(txt, i+2) - start = i + 1 // 1 character added - if(targ == "'") - txt = copytext(txt, 1, i) + "`" + copytext(txt, i+1) // apostrophies fuck shit up... - start = i + 1 // 1 character added - else - txt = copytext(txt, 1, i) + "\\" + copytext(txt, i) - start = i + 2 // 2 characters added + var/lrep = length(json_escape[targ]) + txt = copytext(txt, 1, i) + json_escape[targ] + copytext(txt, i + length(targ)) + start = i + lrep return {""[txt]""} is_associative(list/L) for(var/key in L) // if the key is a list that means it's actually an array of lists (stupid Byond...) - if(!isnum(key) && !istype(key, /list)) + if(!isnum(key) && !isnull(L[key]) && !istype(key, /list)) return TRUE diff --git a/code/modules/nano/_JSON.dm b/code/modules/nano/_JSON.dm index 554b21dafa3..95791899817 100644 --- a/code/modules/nano/_JSON.dm +++ b/code/modules/nano/_JSON.dm @@ -5,19 +5,13 @@ n_Json v11.3.21 proc json2list(json) var/static/json_reader/_jsonr = new() - // N3X: Array support. - if(dd_hasprefix(json,"\[")) - return _jsonr.ReadArray(_jsonr.ScanJson(json)) - else - return _jsonr.ReadObject(_jsonr.ScanJson(json)) + return _jsonr.ReadObject(_jsonr.ScanJson(json)) - list2json(list/L, var/cached_data = null) + list2json(list/L) var/static/json_writer/_jsonw = new() - // Detect if it's just a list of things, or an associative list - // (Used to just assume associative, which broke things.) - if(_jsonw.is_associative(L)) - return _jsonw.WriteObject(L, cached_data) - else - return _jsonw.write_array(L) - + return _jsonw.write(L) + list2json_usecache(list/L) + var/static/json_writer/_jsonw = new() + _jsonw.use_cache = 1 + return _jsonw.write(L) diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index ad797db7d74..592644ba17b 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -57,8 +57,6 @@ nanoui is used to open and update nano browser uis var/list/datum/nanoui/children = list() var/datum/topic_state/custom_state = null - var/cached_data = null - /** * Create a new nanoui instance. * @@ -350,7 +348,7 @@ nanoui is used to open and update nano browser uis template_data_json = list2json(templates) var/list/send_data = get_send_data(initial_data) - var/initial_data_json = list2json(send_data, cached_data) + var/initial_data_json = replacetext(list2json_usecache(send_data), "'", "'") var/url_parameters_json = list2json(list("src" = "\ref[src]")) @@ -432,19 +430,6 @@ nanoui is used to open and update nano browser uis winset(user, window_id, "on-close=\"nanoclose [params]\"") -/** - * Appends already processed json txt to the list2json proc when setting initial-data and data pushes - * Used for data that is fucking huge like manifests and camera lists that doesn't change often. - * And we only want to process them when they change. - * Fuck javascript - * - * @return nothing - */ -/datum/nanoui/proc/load_cached_data(var/data) - cached_data = data - return - - /** * Push data to an already open UI window * @@ -458,7 +443,7 @@ nanoui is used to open and update nano browser uis var/list/send_data = get_send_data(data) //user << list2json(data) // used for debugging - user << output(list2params(list(list2json(send_data,cached_data))),"[window_id].browser:receiveUpdateData") + user << output(list2params(list(list2json_usecache(send_data))),"[window_id].browser:receiveUpdateData") /** * This Topic() proc is called whenever a user clicks on a link within a Nano UI