From 96fd272a51478eb82db71c9cc91122cffccbe173 Mon Sep 17 00:00:00 2001 From: Julian Smith Date: Sat, 24 Aug 2019 18:03:28 +0100 Subject: [PATCH] Nasal/prop_key_handler.nas: added new '#' command to listen to properties. Sets up listeners to show all changes to specified property or any of its child properties. --- Nasal/prop_key_handler.nas | 59 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/Nasal/prop_key_handler.nas b/Nasal/prop_key_handler.nas index 65866e513..8ae79267d 100644 --- a/Nasal/prop_key_handler.nas +++ b/Nasal/prop_key_handler.nas @@ -15,6 +15,7 @@ # ! -> add property to display list (reset list with /!) # : -> open property browser in this property's directory # ? -> print all properties whose path or value contains this string +# # -> add listener for property and all child properties (cancel all listeners with /#) # # # Keys: @@ -44,6 +45,8 @@ var listener = nil; var input = nil; # what the user typed (doesn't contain unconfirmed autocompleted parts) var text = nil; # what is shown in the popup var state = nil; +var listeners = []; +var listeners_children = {}; var completion = []; var completion_pos = -1; @@ -152,6 +155,62 @@ var handle_key = func(key, shift) { stop(1); return 1; + } elsif (key == `#`) { + # Add a listener. + #printf("received '#'. state.path=%s", view.str(state.path)); + if (state.path == '/') { + foreach( var l; listeners) { + removelistener(l); + } + listeners = []; + listeners_children = {}; + var text = sprintf("number of listeners=%s", size(listeners)); + print(text); + screen.log.write(text, 1, 1, 1); + } + else { + var path = state.path; + node = props.globals.getNode(path); + if (node == nil) { + var text = "cannot find node for path=" ~ path; + print(text); + screen.log.write(text, 1, 1, 1); + } + else { + var listener = func(n) { + path = n.getPath(); + value = n.getValue(); + value_prev = listeners_children[path]; + + # We store old values in listeners_children[], so + # that we avoid printing lots of diagnostics for + # writes that don't change the value. + # + # setlistener() only stores the main node's value, + # so we have to do this by hand for child nodes. + # + # [In any case, the setlistener() API isn't able to + # support both listening to child nodes and avoid + # reporting non-changing write accesses.] + # + listeners_children[path] = value; + if (value != value_prev) { + if (value == nil) value = ""; + var text = path ~ "=" ~ value; + print(text); + screen.log.write(text, 1, 1, 1); + } + } + var l = setlistener(node, listener, 0, 2); + append(listeners, l); + var text = sprintf("number of listeners=%s", size(listeners)); + print(text); + screen.log.write(text, 1, 1, 1); + } + } + stop(1); + return 1; + } elsif (key == `:` and state.node != nil and state.value == nil) { var n = state.node.getAttribute("children") ? state.node : state.parent; gui.property_browser(n);