Gweimer/utils library

Currently includes nodes to cast number to a HEX string, convert byte to bits, and convert bits to byte.

2 Likes

I had added if-else nodes using variadic pins, but accidentally used xod_bkp node in example instead of actual xod node; that has been fixed now.

Fixed bug in bit/byte nodes and made pin order more intuitive (which probably breaks it for anyone using the old version :frowning: ).

Replaced LCD code in examples with watch nodes; watch nodes weren’t working for me earlier, but they do now & are more universally available to all users.

1 Like

Hey man I wanna ask if you are able to upload new libraries?

-Is there something wrong with the current ones?- I assume this is in reference to another thread where you are not able to publish. I followed up there.

Updated gweimer/utils for XOD v0.20.x. Replaced old defer nodes with new generic. Made if-else-v (variadic) generic. Added missing node descriptions.

Any chance xod/core/if-else will be made a variadic? Down-sides I can think of: 1) F as 1st pin is less intuitive, but needed to allow cond/true grouping for variadic pins; 2) Returns value for last True instead of the 1st True, which is not very intuitive for experienced programmers.

Any reason why xod/core/buffer isn’t a generic? Seems buffering strings might be useful and there is no reason to prevent buffering of true/false, etc. I was going to make queue-buffer generic, but it depends on buffer, so it doesn’t make sense at this point…

gweimer/utils now has:

  • bits-to-byte
  • byte-to-bits
  • cast-number-to-hex-string
  • hex-to-number (hex -> decimal conversion)
  • if-else-v (variadic if-else)
  • queue-buffer (building block for fixed-length queue)
  • running-avg (Avg for last number of values; built on queue-buffer)
  • utils-example-* showing examples (and providing tests) for each of the above nodes.
1 Like

Cool! Thank you for sharing!

It is somewhat counter-intuitive, let’s leave it as is. However, your version is useful. Maybe the conflict could be solved just by choosing a better metaphor/name for the node?

No real reason. Going to make it generic eventually for plain types. PR’s are welcome :wink:

Strings, however, is a more complicated story. The maximal size of an upstream string is unknown at compile time (yet), so buffer(string) will not be able to preallocate a static buffer to store snapshots. Only dynamic allocation is possible currently, which is a bad practice on microcontrollers since it could lead to serious heap memory fragmentation, and consequently to stack-heap collision, and MCU hang (in the best case). I’d like to stay away from buffering strings for now.

Thought of that, but not coming up with any good ideas. “Case” isn’t really a good match either. “Select” is close, but pulse/cond pins would conflict with no clear resolution. Maybe “case” is the best option with DFLT pin and COND/VAL variadics, but it will still return last match, not 1st… I can’t think of a way to fix that without extra pins for internal-use-only to pass status info down the cascade.

Maybe something like override / chain / squash? I am thinking of it as of process which takes an initial value (SEED or INIT) and then applies a series of overrides for the accumulated value from left to right

Of those, I like override best. Chain is pretty vague and squash implies making something smaller… DFLT and (COND/VAL) would still make sense for override.

“Return DFLT if all COND are false, else override DFLT with VAL associated with right-most COND that is true. A variadic version of if-else with quirky side-affects.”

Hmm…I just realized: if you use F (T/COND), you end up with variadic if-else with all the pins in reverse order… If you read pins from right-to-left, you return T value for 1st True COND, else default to F. Still not “intuitively obvious” since it is reversed, but at least easier to explain… You could keep static if-else and call this if-nested (or if-variadic, or…)

If there were a way to reverse the display order of pins, we would have an easy fix…(but it would put variadic pins 1st).

Another idea that might help is to have a way to process variadic pins in reverse order. If we tried to implement a case node, we would want KEY specified 1st, then return 1st match for any variadic (Match/VAL) pair; default processing order would return last match instead of 1st match (same issue we have with variadic if-else).

Both these “reversing” ideas are just cosmetic to be able to make nodes more intuitive. If we could make reverse-processing of variadic pins conditional at run-time, it might provide a way to implement push/pop stack in a variadic node, but that would not be just a cosmetic change (and might not be practical anyway; how would you deal with wires/pins for both directions? My brain is refusing to work on that now…implementing the grouping of queue-buffers in gweimer/utils/utils-example-queue as a variadic node would be a good test. gweimer/utils/running-avg gives an example that works when only push is needed.)

if-else-v now works with generic data types, but requires at least XOD v0.20.3

1 Like

Back when data type “Byte” was added, gweimer/utils/byte-to-bits was broken. I finally got around to fixing it by forcing type conversions. Thanks to ceasars for reminding me & even suggesting the solution.

1 Like

Updated for XOD 0.28.0. queue-buffer now uses generic pins for data (but there is an issue resolving pin types if you try to implement a list that supports both push & pop–see utils-example-queue for work-around)

2 Likes