A couple of problems with this scheme:

  • Users can enter full expressions in the live mode
    • One solution is to only allow 1-operator get commands to be candidates for display
  • It doesn’t require an explicit command
  • It doesn’t allow re-assignment of any of the slots without pushing the top one off

I was thinking of something along the lines of:

  • Static areas on the empty 5-line space for about a dozen “watch” variables
  • Some sort of labels for each cell or a binary coordinate system with row and column headers.
  • A new mod: WATCH X: [post-command] that evaluates the post-command into slot X or binary coordinate X/Y.

What do you think?

3 Likes

I was considering the simplest scenarios. So my suggestion is super minimal.

Do you think the one operator/variable solution is problematic? It makes sense to me. I suppose adding GET: or WATCH: command for entering the items to watch would work as well.

As to the slots reassignment. The scrolling up I am proposing seemed like an elegant extension to what is there now. I am not dead set on this, though. It just seemed simple/minimal.

If a set 6x2 grid is set up, where user can enter/assign particular items to watch, maybe instead of special mod, user can navigate that grid using the arrow keys on the keyboard, which can move the ‘cursor’ from slot to slot in the grid and/or back to the bottom command entry line/field if they need to enter full expressions to execute.

my vote is for assignable slots, the reason being - with pushing values up as soon as you execute a new command your whole structure shifts, which would break the flow if you wanted watched variables to be in a specific order.

actually, not even assignable slots. just keep it very simple. we’re talking about just a handful of variables which would fit on one, maybe two screens. so a button or button combo to simply switch it off and on.

i assume for variables that get modified on get we simply display what their next value will be? (this will require evaluating them ahead of time)

I suppose the 6 lines can just be assignable spots. So a cursor moving up and down (could be arrow keys or something else) to place specific items to watch into those spots might be the simplest solution. I am not sure if I would need to watch more than 6 items at the same time…

Why not have, say, 3 slots, which can appear in the very top left corner, in the same row as the metro, etc indicators?

WATCH {1-3} : var

You can then see the values change from various screens.

6 lines is a bit of a waste of screen space, though. Consider that the tracker can display 4 numbers wide with a row header and graphical lines drawn between them.

A 5 x 4 grid would be possible permitting X,Y addressing of the watch slots.

I don’t like the modal shift of selecting items on the watch grid, personally. It breaks the flow.

If you keep to WATCH X Y: [sub-command], you get the benefit of being able to configure things with the init script, and eventually with F (timeline-style functions).

I think it fits the ethos of teletype better. It’s simple and consistent and fairly powerful.

Display Layout Parameters

  • Pixel grid of 128 x 64
  • Font for numbers is mono-spaced 4 x 8 including 1,1,1,0 (:arrow_up::arrow_right::arrow_down::arrow_left:) padding
  • Font grid is effectively 32 x 8
  • Bottom 2 lines and top 1 lines are occupied
  • Effective final font area: 32 x 5
  • ANY pixel graphics are possible, but keeping to the style of the existing teletype interface is cleanest IMO
  • Mimicking the row numbers and style of the tracker would be my preference
  • Right justify numbers because you can bet the implementation will. :slight_smile:

By the way, your graphic is very clean. Thank you so much for your help! I really struggle with visual design.


I think that the screen could be better used, and this would clutter a now-clean status bar. There’s a whole lot of space unused on the live mode screen.

how would WATCH work as a pre? what happens if you specify + A B - would it update whenever A or B change? what about WATCH: FLIP?

really cool idea but it’ll introduce complexity as you’d need to add a current state to any get op, and you would have to change every set op to set a dirty flag (unless there is a common place for every setter to do that).

Yes.

If we can afford a second scene_state in RAM, we could check if it changed at every command call and set the dirty bit. Or at least check the variables or some subset of the state.

Geez, this and O pose a particular challenge. I’ll think about it while I’m falling asleep tonight and see how I can tackle this. Any other modify-on-access getters I’m forgetting?

1 Like

checking just the variables should be computationally cheap, this might be the best option.

there is also DRUNK and TOSS :slight_smile:

and then you’d have difficulty with something like IN, PARAM and any remote getters…

1 Like

Even that would be a great addition.
Limited, but definitely useful.

Just some quick thoughts…

  • Having to modify your script in order to monitor a variable or debug it is problematic in a language that limits how long a line is.
  • Screen updates are expensive (in computation terms) and slow, the current architecture of the Teletype only updates the screen on demand. We might want a toggle to enable and disable the display.
  • I haven’t had time to really get my head around what’s been discussed here (sorry), but it seems like it adds a lot of extra code complexity for little benefit.

My suggestion would be to go for something much simpler.

Have a live mode toggle to display the contents of variables A, B, C, D, X, Y, Z, T on the screen in the blank area.

Layout as follows:

(icons)
A      B      C      D
1234   -1234  1234   1234
X      Y      Z      T
10     -120   23444  1234
(blank)
(previous result)
> X

I think but haven’t checked that there are enough horizontal pixels to display 4 numbers. We might want to use a custom fixed width 3x5 font for them (I can’t remember if the all the numbers are 3x5 or not).

Reasons why I think this is good:

  • Those 8 variables are the main ones we’re interested in.
  • It’s simple, just one key stroke to remember.
  • The implementation (which I can go in to detail later) is easy, and follows on from how other parts of the code work.
  • Doesn’t require modifying your scripts.
6 Likes

I like this idea for its simplicity and it looks very much how I always dreamed about it. Nice layout and clear labeling.

Also while thinking about it and going through this thread I wondered if something like programmable AUX slots could be a compromise. Something that would look like the above as a default but you could reprogram for example D with a command like WATCH DRUNK (or WATCH anything else…) to keep track over the less common variables / parameters or complex functions / counters without having to write them into another variable first.

But if this is to complicated or cpu consuming and could make tt unstable again I would be very happy with the simple version proposed by @sam try to carefully choose variables with regard to monitorizability.

I see debugging as a live activity, so it doesn’t need to follow the script. Turn them on from the command line when you need them.

Line length is already a faced limitation in the language with all mods. You can’t L 1 4 the most complex statement. You can’t IF X the most complex statement. You won’t be able to WA 1 (as an alias) the most complex statement. :man_shrugging:

Besides, it seems that the system you’re proposing is far more limited, so it’s disingenuous to point out this downside. (“Pinching is painful, let’s stab instead!”)

Re: computational cost: I wonder if the following scenelet poses any risk to stability currently:

I: M 25
M: P 0 O
* Open Tracker Screen *

Re: toggle, WATCH.SHOW 0 or something would work, and I’m not opposed to a keystroke.

Beside the interface drawing code and the operator implementation, you’re looking at a couple of memcpy() and a memcmp() bracketing run_script_with_exec_state. Then, the live screen display code checks the dirty flag, conditionally running N post-commands, where N is the number of active watches.

I disagree. I would be interested in monitoring a lot of different things. Pattern indices, queue length. I can only think of a handful that I wouldn’t want to monitor, and those are only getters because the language doesn’t differentiate between (for lack of better terms) a function and a subroutine. E.g., @STEP.

Neither does WATCH, as mentioned, if you consider debugging a live exercise.

Actually, because you would have to capture the operator DRUNK and not the result of calling DRUNK, the syntax would have to be WATCH: DRUNK to capture the operator as the post-command. You have essentially proposed a more-limited version of WATCH because all of the other slots are static.

Implementing a custom AUX slot requires 100% of the work of the system I advocated. So you’re basically getting all the code complexity for little benefit.


Compromise

  • Use the WATCH-as-mod approach, allowing great flexibility.
  • Use a toggle key / command to hide / show the display
  • By default, populate the cells with A, B, C, etc.
  • Allow users to change the post-commands in any cell by cell number.

Technical Solution to O, FLIP, IN, etc.

Shadow these variables in the scene state. Update the low-level getters to optionally draw from the shadowed value when the shadow flag is set, i.e.: when the screen draw routine is calling process_command().

Remote Getters (i2c, etc.)

WATCH: could easily just drop post-commands with any obviously problematic operators, which would be especially easy if we maintained an order of the operator table with all i2c ops at the end.

edit: actually, with a little bit of RAM, all last-known-ii-requests could be cached and shadowed with only changes to tele_ii_rx() and tele_ii_tx()! If you haven’t used it, why are you watching it?

(note that I understand the concern for computational overhead and could design this to be lightweight in that regard)

1 Like

So that statement wasn’t aimed directly at your solution. More at those suggesting we insert “print” style statements into commands that add to a log.

Stability no (not any more). But I strongly suspect it messes with CV timing.

As I understand it, WATCH would allow you to specific a custom command that’s output is displayed in a cell on the live screen? Right? (Please excuse me if I’ve got this completely wrong, not enough time…)

How does a WATCH'd command know that it needs to run to update it’s value on the live screen. Display updates are demand based, it’s not continuously updated.

Also as you mention there are several OPs that modify state… what to do about them in a systematic manor? (e.g. P.RM, P.POP, S.ALL, etc, etc) Some that are slow (IN, PARAM, anything i2c). How will that interact with SCRIPT and sub commands?

that’s exactly what i was suggesting…

having WATCH as a pre would add a burden on both the system and adding new ops. this functionality is already doable by setting a pattern value and watching that instead with the benefit that the script itself decides when is a good time to update the watched value.

1 Like

So this is on my radar. A scheduler redesign will be required to ensure that there is any predictability in CV behaviour given the breadth and scope of what a user script can do.

CV slew resolution is my biggest qualm with teletype, and I am highly motivated to solve it while permitting maximum CPU load for user purposes via scripts and improving the timing of critical functions.

I think those are excellent candidates for ineligibility for use with WATCH and should generate a syntax error if attempted. They are “subroutines” as opposed to “getter functions” and should be excluded.

Easy to shadow, as mentioned.

WATCH N: SCRIPT M should also be a syntax error. Sub-commands are fine but probably nonsensical. Only one of them can leave a “return” value on the stack.

  1. Adding core variable ops, yes. (None on my radar except CHAOS, I don’t think)
  2. Adding any i2c ops, no. Every single i2c response/request can be cached from a single place with a one-time change.

Concerns about system performance (CPU consumption)

I am concerned about the overhead of this feature (and any feature), but I feel that it’s necessary to quantify those concerns as opposed to raising potentialities as a specter.

Of course, to do this requires profiling of teletype. I’ll concede that until I am comfortable profiling and load-testing the CPU, that such a complex feature should not be added to a release branch.

Therefore: WATCH as advanced in my posts will not see release until profiling, a prerequisite to the scheduler change, which is a prerequisite to the R (Repeat) feature, a 3.0 target feature.


Simpler Live Display Option

I am willing to do the A B C D X Y Z T display for the next release, on the condition that we leave the functionality open to transforming into WATCH in the future.

1 Like

it wouldn’t be just i2c ops. there are other ops that change some state without scripts being involved. having to maintain a list of things that are supported by WATCH is error prone.

also i think having a pre op that changes the meaning of the sub command is something we should avoid.

2 Likes

Please do!
Any live monitoring will be helpful.
And thank you again for taking this on.

1 Like

Just quoting this back at you…

Also, updating the validation code to disallow illegal OPs in WATCH, adding caching to i2c, updating other OPs to add shadowing. Shirley this is getting complex?

This would mean that any newcomers wanting to add an OP would need to consider the watch system when adding it.

3 Likes

i really can’t emphasize strong enough that having a pre that changes the meaning of the sub command just raises a huge red flag for me.

2 Likes