Event-based system to run code when an input widget is changed

Sometimes a piece of code only needs to run when a parameter is changed. Currently in NetLogo, this requires either (1) running the code every time through the go loop even when it isn’t needed or (2) keeping track of the previous value, comparing it to the current value, and then, if there was a change, running the code.

It would be great if input widgets could have a “run-on-change” field which could be given some code to run whenever the widget is changed.

By “input widgets”, do you mean specifically the string/number/color input widget, or any widget that has a user-specified value?

Good clarification. I meant anything with a user-specified value.

Hi Jacob,

I implemented a draft solution of this feature for the slider widget, which I can demo at the next devel meeting if I’m able to attend. It can run any number of commands in the observer context, and it will run those commands when the slider is modified in the GUI or when it is set programmatically. It seems to work well in my opinion, but there may be some specific things you intended for the feature that I haven’t yet implemented.

Isaac B.

P.S: There aren’t infinite recursion checks at the moment, I’ll worry about that later.

1 Like

This would be a useful feature. I think we should prioritize work that is necessary for us to be able to work on the documentation and ABM book updates.

Interestingly, I have implemented an interface event system in Turtle Universe through an extension. Maybe we can find someone to migrate it to NLW first.

I think this is a great idea but I feel like adding code to widgets may cause issues in debugging in the future because people may not realize that some code in a particular widget is messing with the model’s outcome (if there’s no syntax error).

I remember this was a major problem when Flash & Actionscript 2 ruled the web back in the day (darn, I’m old!). People would add code snippets into sprites and keyframes. When the animation or app project gets somewhat large, it would become a major hassle to debug it. NetLogo models in the library do not have too many input widgets for this to be a problem but I see models in the wild with tens of sliders and switches all the time.

An alternative solution would be a reactive programming approach. It can be a core feature or an extension that provides a means to specify specific variables that trigger a procedure on change. For example, I use the Dash library in Python, and it has an @callback decorator that does exactly this. Another alternative would be to define a new procedure type such as to-react, which only runs when a global variable changes.

Even an easier implementation would be a reporter like widget-changed? or has-new-value? which would still require running in a loop but abstract out the keeping track part that we do manually, so it would save users time, code, and most importantly, risk of implementing a hidden bug.

I second the to-react idea, that sounds really smart. We should discuss this in a future devel meeting.

Here is what I did in Turtle Universe:

The grammar isn’t the best I would expect, but it is flexible:

Or, with anonymous procedure:

The idea here is similar to HTML/Javascript, but maybe we can make it simpler:

I would be strongly in favor of any grammar-level design that makes event-driven development easier. It can benefit the core functionalities of ABM as well!