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)
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 nazarijtipusak080/accumulate-and-read-character-string 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)]);
}
}
}