string-queue

gweimer/utils/string-queue

No description
string-queue
@/string-queue
CAPnumber
The capacity of the string buffer. Defines the maximum length. Must be a constant value. Any changes during program execution will be ignored.
CHARbyte
A new character to be pushed to the end of the string
PUSHpulse
Push new character
RSTpulse
Empty the accumulated string and start over
IDXbyte
Display IDX character of string. This is 0-based, so range is 0 - (CAP-1)
string-queue
CAP
CHAR
PUSH
RST
IDX
STR
UPD
FULL
OUT
POP
POPbyte
Last character popped of front of string to make room for next CHAR
OUTbyte
IDX character in string (0 if IDX is larger than current size of string)
FULLboolean
True once string is at capacity
UPDpulse
Pulses when resulting string is updated
STRstring
String that is accumulated so far
To use the node in your project you should have the gweimer/utils library installed. Use the “File → Add Library” menu item in XOD IDE if you don’t have it yet. See Using libraries for more info.

C++ implementation

node {
    char* buff;
    char* cursor;
    size_t cap;
    CStringView view;

    void evaluate(Context ctx) {
        if (isSettingUp()) {
            // save initial cap to ignore possiple input changes during program execution
            cap = getValue<input_CAP>(ctx);
            buff = new char[cap + 1]; // +1 to make room for terminal '\0'
            view = CStringView(buff);
        }

        if (isSettingUp() || isInputDirty<input_RST>(ctx)) {
            memset(buff, '\0', cap + 1);
            cursor = buff;
            emitValue<output_FULL>(ctx, 0);
            emitValue<output_OUT>(ctx, 0);
            emitValue<output_POP>(ctx, 0);
            emitValue<output_STR>(ctx, XString(&view));
            emitValue<output_UPD>(ctx, 1);
        }

        if (isInputDirty<input_PUSH>(ctx)) {
            if (cursor >= &buff[cap]) {
                emitValue<output_FULL>(ctx, 1);
                emitValue<output_POP>(ctx, buff[0]);
                for (auto i=0; i < cap; i++) {
                    buff[i] = buff[i+1];
                }
                cursor = &buff[cap-1];
            }

            *cursor = getValue<input_CHAR>(ctx);
            if (cursor < &buff[cap]) {
                cursor++;
            }
            emitValue<output_STR>(ctx, XString(&view));
            emitValue<output_UPD>(ctx, 1);
        }

        if (isInputDirty<input_IDX>(ctx) || isInputDirty<input_PUSH>(ctx)) {
            emitValue<output_OUT>(ctx, buff[getValue<input_IDX>(ctx)]);
        }
    }
}