Gweimer/utils library


#1

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


#2

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.


#3

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


#4

-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.


#5

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.

#6

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.


#7

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.


#8

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


#9

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.)


#10

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