refactor(rt/c++): introduce Context ctx abstraction layer

Change standard signature of native nodes from

void evaluate(NodeId nid)

to

void evaluate(Context ctx)

Currently, this is a pure fiction. But it would allow to introduce
required abstraction layer for lists lifting in which case
Context ≠ NodeId.
This commit is contained in:
Victor Nakoryakov
2017-07-27 17:19:19 +03:00
parent 6d20c35beb
commit 43cfffc919
52 changed files with 260 additions and 252 deletions

View File

@@ -40,6 +40,8 @@ namespace _program {
// and uint32_t if there are more than 65535
typedef uint16_t NodeId;
typedef NodeId Context;
/*
* PinKey is an address value used to find inputs or outputs data within
* nodes Storage.

View File

@@ -3,6 +3,6 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
void evaluate(Context ctx) {
/* Native implementation goes here */
}

View File

@@ -32,7 +32,7 @@ using input_IN2 = InputDescriptor<Number, offsetof(Storage, input_IN2)>;
using output_OUT = OutputDescriptor<Number, offsetof(Storage, output_OUT), 0>;
void evaluate(NodeId nid) {
void evaluate(Context ctx) {
/* Native implementation goes here */
}

View File

@@ -679,6 +679,8 @@ namespace _program {
// and uint32_t if there are more than 65535
typedef uint16_t NodeId;
typedef NodeId Context;
/*
* PinKey is an address value used to find inputs or outputs data within
* nodes Storage.
@@ -937,25 +939,25 @@ using input_RST = InputDescriptor<Logic, offsetof(Storage, input_RST)>;
using output_TICK = OutputDescriptor<Logic, offsetof(Storage, output_TICK), 0>;
void evaluate(NodeId nid) {
State* state = getState(nid);
void evaluate(Context ctx) {
State* state = getState(ctx);
TimeMs tNow = transactionTime();
TimeMs dt = getValue<input_IVAL>(nid) * 1000;
TimeMs dt = getValue<input_IVAL>(ctx) * 1000;
TimeMs tNext = tNow + dt;
if (isInputDirty<input_RST>(nid)) {
if (isInputDirty<input_RST>(ctx)) {
if (dt == 0) {
state->nextTrig = 0;
clearTimeout(nid);
clearTimeout(ctx);
} else if (state->nextTrig < tNow || state->nextTrig > tNext) {
state->nextTrig = tNext;
setTimeout(nid, dt);
setTimeout(ctx, dt);
}
} else {
// It was a scheduled tick
emitValue<output_TICK>(nid, 1);
emitValue<output_TICK>(ctx, 1);
state->nextTrig = tNext;
setTimeout(nid, dt);
setTimeout(ctx, dt);
}
}
@@ -983,9 +985,9 @@ State* getState(NodeId nid) {
using input_PORT = InputDescriptor<Number, offsetof(Storage, input_PORT)>;
using input_SIG = InputDescriptor<Logic, offsetof(Storage, input_SIG)>;
void evaluate(NodeId nid) {
State* state = getState(nid);
const int port = (int)getValue<input_PORT>(nid);
void evaluate(Context ctx) {
State* state = getState(ctx);
const int port = (int)getValue<input_PORT>(ctx);
if (port != state->configuredPort) {
::pinMode(port, OUTPUT);
// Store configured port so to avoid repeating `pinMode` call if just
@@ -993,7 +995,7 @@ void evaluate(NodeId nid) {
state->configuredPort = port;
}
const bool val = getValue<input_SIG>(nid);
const bool val = getValue<input_SIG>(ctx);
::digitalWrite(port, val);
}
@@ -1026,12 +1028,12 @@ using input_RST = InputDescriptor<Logic, offsetof(Storage, input_RST)>;
using output_MEM = OutputDescriptor<Logic, offsetof(Storage, output_MEM), 0>;
void evaluate(NodeId nid) {
State* state = getState(nid);
void evaluate(Context ctx) {
State* state = getState(ctx);
bool newState = state->state;
if (isInputDirty<input_TGL>(nid)) {
if (isInputDirty<input_TGL>(ctx)) {
newState = !state->state;
} else if (isInputDirty<input_SET>(nid)) {
} else if (isInputDirty<input_SET>(ctx)) {
newState = true;
} else {
newState = false;
@@ -1041,7 +1043,7 @@ void evaluate(NodeId nid) {
return;
state->state = newState;
emitValue<output_MEM>(nid, newState);
emitValue<output_MEM>(ctx, newState);
}
} // namespace xod__core__flip_flop
@@ -1064,8 +1066,8 @@ State* getState(NodeId nid) {
using output_VAL = OutputDescriptor<Number, offsetof(Storage, output_VAL), 0>;
void evaluate(NodeId nid) {
reemitValue<output_VAL>(nid);
void evaluate(Context ctx) {
reemitValue<output_VAL>(ctx);
}
} // namespace xod__core__constant_number

View File

@@ -679,6 +679,8 @@ namespace _program {
// and uint32_t if there are more than 65535
typedef uint16_t NodeId;
typedef NodeId Context;
/*
* PinKey is an address value used to find inputs or outputs data within
* nodes Storage.
@@ -934,8 +936,8 @@ using input_UPD = InputDescriptor<Logic, offsetof(Storage, input_UPD)>;
using output_TIME = OutputDescriptor<Number, offsetof(Storage, output_TIME), 0>;
void evaluate(NodeId nid) {
emitValue<output_TIME>(nid, millis() / 1000.f);
void evaluate(Context ctx) {
emitValue<output_TIME>(ctx, millis() / 1000.f);
}
} // namespace xod__core__system_time
@@ -990,23 +992,23 @@ void printLine(LiquidCrystal* lcd, uint8_t lineIndex, XString str) {
lcd->write(*it);
}
void evaluate(NodeId nid) {
State* state = getState(nid);
void evaluate(Context ctx) {
State* state = getState(ctx);
auto lcd = state->lcd;
if (!state->lcd) {
state->lcd = lcd = new LiquidCrystal(
(int)getValue<input_RS>(nid),
(int)getValue<input_EN>(nid),
(int)getValue<input_D4>(nid),
(int)getValue<input_D5>(nid),
(int)getValue<input_D6>(nid),
(int)getValue<input_D7>(nid));
(int)getValue<input_RS>(ctx),
(int)getValue<input_EN>(ctx),
(int)getValue<input_D4>(ctx),
(int)getValue<input_D5>(ctx),
(int)getValue<input_D6>(ctx),
(int)getValue<input_D7>(ctx));
lcd->begin(16, 2);
}
printLine(lcd, 0, getValue<input_L1>(nid));
printLine(lcd, 1, getValue<input_L2>(nid));
printLine(lcd, 0, getValue<input_L1>(ctx));
printLine(lcd, 1, getValue<input_L2>(ctx));
}
} // namespace xod__common_hardware__text_lcd_16x2
@@ -1033,12 +1035,12 @@ using input_IN = InputDescriptor<Number, offsetof(Storage, input_IN)>;
using output_OUT = OutputDescriptor<XString, offsetof(Storage, output_OUT), 0>;
void evaluate(NodeId nid) {
void evaluate(Context ctx) {
char str[16];
auto num = getValue<input_IN>(nid);
auto num = getValue<input_IN>(ctx);
dtostrf(num, 0, 2, str);
auto xstr = ::xod::List<char>::fromPlainArray(str, strlen(str));
emitValue<output_OUT>(nid, xstr);
emitValue<output_OUT>(ctx, xstr);
}
} // namespace xod__core__cast_number_to_string
@@ -1062,9 +1064,9 @@ State* getState(NodeId nid) {
using output_TICK = OutputDescriptor<Logic, offsetof(Storage, output_TICK), 0>;
void evaluate(NodeId nid) {
emitValue<output_TICK>(nid, 1);
setTimeout(nid, 0);
void evaluate(Context ctx) {
emitValue<output_TICK>(ctx, 1);
setTimeout(ctx, 0);
}
} // namespace xod__core__continuously
@@ -1087,8 +1089,8 @@ State* getState(NodeId nid) {
using output_VAL = OutputDescriptor<Number, offsetof(Storage, output_VAL), 0>;
void evaluate(NodeId nid) {
reemitValue<output_VAL>(nid);
void evaluate(Context ctx) {
reemitValue<output_VAL>(ctx);
}
} // namespace xod__core__constant_number
@@ -1111,8 +1113,8 @@ State* getState(NodeId nid) {
using output_VAL = OutputDescriptor<XString, offsetof(Storage, output_VAL), 0>;
void evaluate(NodeId nid) {
reemitValue<output_VAL>(nid);
void evaluate(Context ctx) {
reemitValue<output_VAL>(ctx);
}
} // namespace xod__core__constant_string

View File

@@ -10,13 +10,13 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
State* state = getState(nid);
auto port = (int)getValue<input_PORT>(nid);
void evaluate(Context ctx) {
State* state = getState(ctx);
auto port = (int)getValue<input_PORT>(ctx);
if (port != state->configuredPort) {
state->servo.attach(port);
state->configuredPort = port;
}
state->servo.write(getValue<input_VAL>(nid) * 180);
state->servo.write(getValue<input_VAL>(ctx) * 180);
}

View File

@@ -18,21 +18,21 @@ void printLine(LiquidCrystal* lcd, uint8_t lineIndex, XString str) {
lcd->write(*it);
}
void evaluate(NodeId nid) {
State* state = getState(nid);
void evaluate(Context ctx) {
State* state = getState(ctx);
auto lcd = state->lcd;
if (!state->lcd) {
state->lcd = lcd = new LiquidCrystal(
(int)getValue<input_RS>(nid),
(int)getValue<input_EN>(nid),
(int)getValue<input_D4>(nid),
(int)getValue<input_D5>(nid),
(int)getValue<input_D6>(nid),
(int)getValue<input_D7>(nid));
(int)getValue<input_RS>(ctx),
(int)getValue<input_EN>(ctx),
(int)getValue<input_D4>(ctx),
(int)getValue<input_D5>(ctx),
(int)getValue<input_D6>(ctx),
(int)getValue<input_D7>(ctx));
lcd->begin(16, 2);
}
printLine(lcd, 0, getValue<input_L1>(nid));
printLine(lcd, 1, getValue<input_L2>(nid));
printLine(lcd, 0, getValue<input_L1>(ctx));
printLine(lcd, 1, getValue<input_L2>(ctx));
}

View File

@@ -3,7 +3,7 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto x = getValue<input_X>(nid);
emitValue<output_ABSX>(nid, abs(x));
void evaluate(Context ctx) {
auto x = getValue<input_X>(ctx);
emitValue<output_ABSX>(ctx, abs(x));
}

View File

@@ -3,8 +3,8 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto x = getValue<input_X>(nid);
auto y = getValue<input_Y>(nid);
emitValue<output_SUM>(nid, x + y);
void evaluate(Context ctx) {
auto x = getValue<input_X>(ctx);
auto y = getValue<input_Y>(ctx);
emitValue<output_SUM>(ctx, x + y);
}

View File

@@ -4,12 +4,12 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
if (!isInputDirty<input_UPD>(nid))
void evaluate(Context ctx) {
if (!isInputDirty<input_UPD>(ctx))
return;
State* state = getState(nid);
const int port = (int)getValue<input_PORT>(nid);
State* state = getState(ctx);
const int port = (int)getValue<input_PORT>(ctx);
if (port != state->configuredPort) {
::pinMode(port, INPUT);
// Store configured port so to avoid repeating `pinMode` on
@@ -17,5 +17,5 @@ void evaluate(NodeId nid) {
state->configuredPort = port;
}
emitValue<output_VAL>(nid, ::analogRead(port) / 1023.);
emitValue<output_VAL>(ctx, ::analogRead(port) / 1023.);
}

View File

@@ -3,8 +3,8 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto a = getValue<input_A>(nid);
auto b = getValue<input_B>(nid);
emitValue<output_AND>(nid, a && b);
void evaluate(Context ctx) {
auto a = getValue<input_A>(ctx);
auto b = getValue<input_B>(ctx);
emitValue<output_AND>(ctx, a && b);
}

View File

@@ -3,9 +3,9 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
bool p1 = isInputDirty<input_P1>(nid);
bool p2 = isInputDirty<input_P2>(nid);
void evaluate(Context ctx) {
bool p1 = isInputDirty<input_P1>(ctx);
bool p2 = isInputDirty<input_P2>(ctx);
if (p1 || p2)
emitValue<output_ANY>(nid, true);
emitValue<output_ANY>(ctx, true);
}

View File

@@ -3,6 +3,6 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
emitValue<output_BOOT>(nid, 1);
void evaluate(Context ctx) {
emitValue<output_BOOT>(ctx, 1);
}

View File

@@ -4,15 +4,15 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
if (!isInputDirty<input_UPD>(nid))
void evaluate(Context ctx) {
if (!isInputDirty<input_UPD>(ctx))
return;
State* state = getState(nid);
auto newValue = getValue<input_NEW>(nid);
State* state = getState(ctx);
auto newValue = getValue<input_NEW>(ctx);
if (newValue == state->value)
return;
state->value = newValue;
emitValue<output_MEM>(nid, newValue);
emitValue<output_MEM>(ctx, newValue);
}

View File

@@ -3,6 +3,6 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
emitValue<output_OUT>(nid, getValue<Inputs::IN>(nid) ? 1.0 : 0.0);
void evaluate(Context ctx) {
emitValue<output_OUT>(ctx, getValue<Inputs::IN>(nid) ? 1.0 : 0.0);
}

View File

@@ -4,12 +4,12 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
State* state = getState(nid);
auto newValue = getValue<input_IN>(nid);
void evaluate(Context ctx) {
State* state = getState(ctx);
auto newValue = getValue<input_IN>(ctx);
if (newValue == true && state->state == false)
emitValue<output_OUT>(nid, 1);
emitValue<output_OUT>(ctx, 1);
state->state = newValue;
}

View File

@@ -3,10 +3,10 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto x = getValue<input_IN>(nid);
void evaluate(Context ctx) {
auto x = getValue<input_IN>(ctx);
auto xstr = x
? ::xod::List<char>::fromPlainArray("true", 4)
: ::xod::List<char>::fromPlainArray("false", 5);
emitValue<output_OUT>(nid, xstr);
emitValue<output_OUT>(ctx, xstr);
}

View File

@@ -3,6 +3,6 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
emitValue<output_OUT>(nid, getValue<Inputs::IN>(nid) != 0.0);
void evaluate(Context ctx) {
emitValue<output_OUT>(ctx, getValue<Inputs::IN>(nid) != 0.0);
}

View File

@@ -3,10 +3,10 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
void evaluate(Context ctx) {
char str[16];
auto num = getValue<input_IN>(nid);
auto num = getValue<input_IN>(ctx);
dtostrf(num, 0, 2, str);
auto xstr = ::xod::List<char>::fromPlainArray(str, strlen(str));
emitValue<output_OUT>(nid, xstr);
emitValue<output_OUT>(ctx, xstr);
}

View File

@@ -3,7 +3,7 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto x = getValue<input_X>(nid);
emitValue<output_CEIL>(nid, ceil(x));
void evaluate(Context ctx) {
auto x = getValue<input_X>(ctx);
emitValue<output_CEIL>(ctx, ceil(x));
}

View File

@@ -4,24 +4,24 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
State* state = getState(nid);
void evaluate(Context ctx) {
State* state = getState(ctx);
TimeMs tNow = transactionTime();
TimeMs dt = getValue<input_IVAL>(nid) * 1000;
TimeMs dt = getValue<input_IVAL>(ctx) * 1000;
TimeMs tNext = tNow + dt;
if (isInputDirty<input_RST>(nid)) {
if (isInputDirty<input_RST>(ctx)) {
if (dt == 0) {
state->nextTrig = 0;
clearTimeout(nid);
clearTimeout(ctx);
} else if (state->nextTrig < tNow || state->nextTrig > tNext) {
state->nextTrig = tNext;
setTimeout(nid, dt);
setTimeout(ctx, dt);
}
} else {
// It was a scheduled tick
emitValue<output_TICK>(nid, 1);
emitValue<output_TICK>(ctx, 1);
state->nextTrig = tNext;
setTimeout(nid, dt);
setTimeout(ctx, dt);
}
}

View File

@@ -3,8 +3,8 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto head = getValue<input_HEAD>(nid);
auto tail = getValue<input_TAIL>(nid);
emitValue<output_STR>(nid, head->concat(tail));
void evaluate(Context ctx) {
auto head = getValue<input_HEAD>(ctx);
auto tail = getValue<input_TAIL>(ctx);
emitValue<output_STR>(ctx, head->concat(tail));
}

View File

@@ -4,16 +4,16 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
if (!isInputDirty<input_DUMP>(nid))
void evaluate(Context ctx) {
if (!isInputDirty<input_DUMP>(ctx))
return;
State* state = getState(nid);
State* state = getState(ctx);
if (!state->begun) {
Serial.begin(9600);
}
auto line = getValue<input_LINE>(nid);
auto line = getValue<input_LINE>(ctx);
if (line) {
for (auto it = line->iterate(); it; ++it)
Serial.write((char)*it);

View File

@@ -3,6 +3,6 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
reemitValue<output_VAL>(nid);
void evaluate(Context ctx) {
reemitValue<output_VAL>(ctx);
}

View File

@@ -2,6 +2,6 @@ struct State {};
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
reemitValue<output_VAL>(nid);
void evaluate(Context ctx) {
reemitValue<output_VAL>(ctx);
}

View File

@@ -2,6 +2,6 @@ struct State {};
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
reemitValue<output_VAL>(nid);
void evaluate(Context ctx) {
reemitValue<output_VAL>(ctx);
}

View File

@@ -3,9 +3,9 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto x = getValue<input_X>(nid);
auto minX = getValue<input_MIN>(nid);
auto maxX = getValue<input_MAX>(nid);
emitValue<output_XC>(nid, x < minX ? minX : (x > maxX ? maxX : x));
void evaluate(Context ctx) {
auto x = getValue<input_X>(ctx);
auto minX = getValue<input_MIN>(ctx);
auto maxX = getValue<input_MAX>(ctx);
emitValue<output_XC>(ctx, x < minX ? minX : (x > maxX ? maxX : x));
}

View File

@@ -3,7 +3,7 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
emitValue<output_TICK>(nid, 1);
setTimeout(nid, 0);
void evaluate(Context ctx) {
emitValue<output_TICK>(ctx, 1);
setTimeout(ctx, 0);
}

View File

@@ -3,15 +3,15 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
TimeMs dt = getValue<input_T>(nid) * 1000;
void evaluate(Context ctx) {
TimeMs dt = getValue<input_T>(ctx) * 1000;
if (isInputDirty<input_RST>(nid)) {
clearTimeout(nid);
} else if (isInputDirty<input_SET>(nid)) {
setTimeout(nid, dt);
if (isInputDirty<input_RST>(ctx)) {
clearTimeout(ctx);
} else if (isInputDirty<input_SET>(ctx)) {
setTimeout(ctx, dt);
} else {
// It was a scheduled evaluation
emitValue<output_DONE>(nid, true);
emitValue<output_DONE>(ctx, true);
}
}

View File

@@ -4,12 +4,12 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
if (!isInputDirty<input_UPD>(nid))
void evaluate(Context ctx) {
if (!isInputDirty<input_UPD>(ctx))
return;
State* state = getState(nid);
const int port = (int)getValue<input_PORT>(nid);
State* state = getState(ctx);
const int port = (int)getValue<input_PORT>(ctx);
if (port != state->configuredPort) {
::pinMode(port, INPUT);
// Store configured port so to avoid repeating `pinMode` on
@@ -17,5 +17,5 @@ void evaluate(NodeId nid) {
state->configuredPort = port;
}
emitValue<output_SIG>(nid, ::digitalRead(port));
emitValue<output_SIG>(ctx, ::digitalRead(port));
}

View File

@@ -4,9 +4,9 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
State* state = getState(nid);
const int port = (int)getValue<input_PORT>(nid);
void evaluate(Context ctx) {
State* state = getState(ctx);
const int port = (int)getValue<input_PORT>(ctx);
if (port != state->configuredPort) {
::pinMode(port, OUTPUT);
// Store configured port so to avoid repeating `pinMode` call if just
@@ -14,6 +14,6 @@ void evaluate(NodeId nid) {
state->configuredPort = port;
}
const bool val = getValue<input_SIG>(nid);
const bool val = getValue<input_SIG>(ctx);
::digitalWrite(port, val);
}

View File

@@ -3,8 +3,8 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto x = getValue<input_X>(nid);
auto y = getValue<input_Y>(nid);
emitValue<output_FRAC>(nid, x / y);
void evaluate(Context ctx) {
auto x = getValue<input_X>(ctx);
auto y = getValue<input_Y>(ctx);
emitValue<output_FRAC>(ctx, x / y);
}

View File

@@ -3,8 +3,8 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto lhs = getValue<input_LHS>(nid);
auto rhs = getValue<input_RHS>(nid);
emitValue<output_EQ>(nid, lhs == rhs);
void evaluate(Context ctx) {
auto lhs = getValue<input_LHS>(ctx);
auto rhs = getValue<input_RHS>(ctx);
emitValue<output_EQ>(ctx, lhs == rhs);
}

View File

@@ -4,12 +4,12 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
State* state = getState(nid);
void evaluate(Context ctx) {
State* state = getState(ctx);
bool newState = state->state;
if (isInputDirty<input_TGL>(nid)) {
if (isInputDirty<input_TGL>(ctx)) {
newState = !state->state;
} else if (isInputDirty<input_SET>(nid)) {
} else if (isInputDirty<input_SET>(ctx)) {
newState = true;
} else {
newState = false;
@@ -19,5 +19,5 @@ void evaluate(NodeId nid) {
return;
state->state = newState;
emitValue<output_MEM>(nid, newState);
emitValue<output_MEM>(ctx, newState);
}

View File

@@ -3,7 +3,7 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto x = getValue<input_X>(nid);
emitValue<output_FLR>(nid, floor(x));
void evaluate(Context ctx) {
auto x = getValue<input_X>(ctx);
emitValue<output_FLR>(ctx, floor(x));
}

View File

@@ -3,11 +3,11 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
void evaluate(Context ctx) {
char str[16];
auto num = getValue<input_NUM>(nid);
auto dig = getValue<input_DIG>(nid);
auto num = getValue<input_NUM>(ctx);
auto dig = getValue<input_DIG>(ctx);
dtostrf(num, 0, dig, str);
auto xstr = ::xod::List<char>::fromPlainArray(str, strlen(str));
emitValue<output_STR>(nid, xstr);
emitValue<output_STR>(ctx, xstr);
}

View File

@@ -3,13 +3,13 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
if (!isInputDirty<input_TRIG>(nid))
void evaluate(Context ctx) {
if (!isInputDirty<input_TRIG>(ctx))
return;
if (getValue<input_GATE>(nid)) {
emitValue<output_T>(nid, 1);
if (getValue<input_GATE>(ctx)) {
emitValue<output_T>(ctx, 1);
} else {
emitValue<output_F>(nid, 1);
emitValue<output_F>(ctx, 1);
}
}

View File

@@ -3,8 +3,8 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto lhs = getValue<input_LHS>(nid);
auto rhs = getValue<input_RHS>(nid);
emitValue<output_GT>(nid, lhs > rhs);
void evaluate(Context ctx) {
auto lhs = getValue<input_LHS>(ctx);
auto rhs = getValue<input_RHS>(ctx);
emitValue<output_GT>(ctx, lhs > rhs);
}

View File

@@ -3,9 +3,9 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto cond = getValue<input_COND>(nid);
auto trueVal = getValue<input_T>(nid);
auto falseVal = getValue<input_F>(nid);
emitValue<output_R>(nid, cond ? trueVal : falseVal);
void evaluate(Context ctx) {
auto cond = getValue<input_COND>(ctx);
auto trueVal = getValue<input_T>(ctx);
auto falseVal = getValue<input_F>(ctx);
emitValue<output_R>(ctx, cond ? trueVal : falseVal);
}

View File

@@ -2,8 +2,8 @@ struct State {};
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto lhs = getValue<input_LHS>(nid);
auto rhs = getValue<input_RHS>(nid);
emitValue<output_LT>(nid, lhs < rhs);
void evaluate(Context ctx) {
auto lhs = getValue<input_LHS>(ctx);
auto rhs = getValue<input_RHS>(ctx);
emitValue<output_LT>(ctx, lhs < rhs);
}

View File

@@ -3,13 +3,13 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto x = getValue<input_X>(nid);
auto sMin = getValue<input_Smin>(nid);
auto sMax = getValue<input_Smax>(nid);
auto tMin = getValue<input_Tmin>(nid);
auto tMax = getValue<input_Tmax>(nid);
void evaluate(Context ctx) {
auto x = getValue<input_X>(ctx);
auto sMin = getValue<input_Smin>(ctx);
auto sMax = getValue<input_Smax>(ctx);
auto tMin = getValue<input_Tmin>(ctx);
auto tMax = getValue<input_Tmax>(ctx);
auto k = (x - sMin) / (sMax - sMin);
auto xm = tMin + k * (tMax - tMin);
emitValue<output_Xm>(nid, xm);
emitValue<output_Xm>(ctx, xm);
}

View File

@@ -3,8 +3,8 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto x = getValue<input_X>(nid);
auto y = getValue<input_Y>(nid);
emitValue<output_PROD>(nid, x * y);
void evaluate(Context ctx) {
auto x = getValue<input_X>(ctx);
auto y = getValue<input_Y>(ctx);
emitValue<output_PROD>(ctx, x * y);
}

View File

@@ -3,8 +3,8 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto a = getValue<input_A>(nid);
auto b = getValue<input_B>(nid);
emitValue<output_NAND>(nid, !(a && b));
void evaluate(Context ctx) {
auto a = getValue<input_A>(ctx);
auto b = getValue<input_B>(ctx);
emitValue<output_NAND>(ctx, !(a && b));
}

View File

@@ -3,8 +3,8 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto a = getValue<input_A>(nid);
auto b = getValue<input_B>(nid);
emitValue<output_NOR>(nid, !(a || b));
void evaluate(Context ctx) {
auto a = getValue<input_A>(ctx);
auto b = getValue<input_B>(ctx);
emitValue<output_NOR>(ctx, !(a || b));
}

View File

@@ -3,7 +3,7 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto x = getValue<input_X>(nid);
emitValue<output_NOTX>(nid, !x);
void evaluate(Context ctx) {
auto x = getValue<input_X>(ctx);
emitValue<output_NOTX>(ctx, !x);
}

View File

@@ -3,8 +3,8 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto a = getValue<input_A>(nid);
auto b = getValue<input_B>(nid);
emitValue<output_OR>(nid, a || b);
void evaluate(Context ctx) {
auto a = getValue<input_A>(ctx);
auto b = getValue<input_B>(ctx);
emitValue<output_OR>(ctx, a || b);
}

View File

@@ -4,9 +4,9 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
State* state = getState(nid);
const int port = (int)getValue<input_PORT>(nid);
void evaluate(Context ctx) {
State* state = getState(ctx);
const int port = (int)getValue<input_PORT>(ctx);
if (port != state->configuredPort) {
::pinMode(port, OUTPUT);
// Store configured port so to avoid repeating `pinMode` call if just
@@ -14,7 +14,7 @@ void evaluate(NodeId nid) {
state->configuredPort = port;
}
auto duty = getValue<input_DUTY>(nid);
auto duty = getValue<input_DUTY>(ctx);
duty = duty > 1 ? 1 : (duty < 0 ? 0 : duty);
uint8_t val = (uint8_t)(duty * 255.0);

View File

@@ -3,7 +3,7 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto x = getValue<input_X>(nid);
emitValue<output_RND>(nid, round(x));
void evaluate(Context ctx) {
auto x = getValue<input_X>(ctx);
emitValue<output_RND>(ctx, round(x));
}

View File

@@ -3,8 +3,8 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto x = getValue<input_X>(nid);
auto y = getValue<input_Y>(nid);
emitValue<output_DIFF>(nid, x - y);
void evaluate(Context ctx) {
auto x = getValue<input_X>(ctx);
auto y = getValue<input_Y>(ctx);
emitValue<output_DIFF>(ctx, x - y);
}

View File

@@ -3,6 +3,6 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
emitValue<output_TIME>(nid, millis() / 1000.f);
void evaluate(Context ctx) {
emitValue<output_TIME>(ctx, millis() / 1000.f);
}

View File

@@ -3,8 +3,8 @@ struct State {
{{ GENERATED_CODE }}
void evaluate(NodeId nid) {
auto a = getValue<input_A>(nid);
auto b = getValue<input_B>(nid);
emitValue<output_XOR>(nid, a != b);
void evaluate(Context ctx) {
auto a = getValue<input_A>(ctx);
auto b = getValue<input_B>(ctx);
emitValue<output_XOR>(ctx, a != b);
}

View File

@@ -679,6 +679,8 @@ namespace _program {
// and uint32_t if there are more than 65535
typedef uint16_t NodeId;
typedef NodeId Context;
/*
* PinKey is an address value used to find inputs or outputs data within
* nodes Storage.
@@ -938,14 +940,14 @@ using input_TRIG = InputDescriptor<Logic, offsetof(Storage, input_TRIG)>;
using output_T = OutputDescriptor<Logic, offsetof(Storage, output_T), 0>;
using output_F = OutputDescriptor<Logic, offsetof(Storage, output_F), 1>;
void evaluate(NodeId nid) {
if (!isInputDirty<input_TRIG>(nid))
void evaluate(Context ctx) {
if (!isInputDirty<input_TRIG>(ctx))
return;
if (getValue<input_GATE>(nid)) {
emitValue<output_T>(nid, 1);
if (getValue<input_GATE>(ctx)) {
emitValue<output_T>(ctx, 1);
} else {
emitValue<output_F>(nid, 1);
emitValue<output_F>(ctx, 1);
}
}
@@ -976,12 +978,12 @@ using input_UPD = InputDescriptor<Logic, offsetof(Storage, input_UPD)>;
using output_SIG = OutputDescriptor<Logic, offsetof(Storage, output_SIG), 0>;
void evaluate(NodeId nid) {
if (!isInputDirty<input_UPD>(nid))
void evaluate(Context ctx) {
if (!isInputDirty<input_UPD>(ctx))
return;
State* state = getState(nid);
const int port = (int)getValue<input_PORT>(nid);
State* state = getState(ctx);
const int port = (int)getValue<input_PORT>(ctx);
if (port != state->configuredPort) {
::pinMode(port, INPUT);
// Store configured port so to avoid repeating `pinMode` on
@@ -989,7 +991,7 @@ void evaluate(NodeId nid) {
state->configuredPort = port;
}
emitValue<output_SIG>(nid, ::digitalRead(port));
emitValue<output_SIG>(ctx, ::digitalRead(port));
}
} // namespace xod__core__digital_input
@@ -1021,12 +1023,12 @@ using input_RST = InputDescriptor<Logic, offsetof(Storage, input_RST)>;
using output_MEM = OutputDescriptor<Logic, offsetof(Storage, output_MEM), 0>;
void evaluate(NodeId nid) {
State* state = getState(nid);
void evaluate(Context ctx) {
State* state = getState(ctx);
bool newState = state->state;
if (isInputDirty<input_TGL>(nid)) {
if (isInputDirty<input_TGL>(ctx)) {
newState = !state->state;
} else if (isInputDirty<input_SET>(nid)) {
} else if (isInputDirty<input_SET>(ctx)) {
newState = true;
} else {
newState = false;
@@ -1036,7 +1038,7 @@ void evaluate(NodeId nid) {
return;
state->state = newState;
emitValue<output_MEM>(nid, newState);
emitValue<output_MEM>(ctx, newState);
}
} // namespace xod__core__flip_flop
@@ -1063,9 +1065,9 @@ State* getState(NodeId nid) {
using input_PORT = InputDescriptor<Number, offsetof(Storage, input_PORT)>;
using input_SIG = InputDescriptor<Logic, offsetof(Storage, input_SIG)>;
void evaluate(NodeId nid) {
State* state = getState(nid);
const int port = (int)getValue<input_PORT>(nid);
void evaluate(Context ctx) {
State* state = getState(ctx);
const int port = (int)getValue<input_PORT>(ctx);
if (port != state->configuredPort) {
::pinMode(port, OUTPUT);
// Store configured port so to avoid repeating `pinMode` call if just
@@ -1073,7 +1075,7 @@ void evaluate(NodeId nid) {
state->configuredPort = port;
}
const bool val = getValue<input_SIG>(nid);
const bool val = getValue<input_SIG>(ctx);
::digitalWrite(port, val);
}
@@ -1098,9 +1100,9 @@ State* getState(NodeId nid) {
using output_TICK = OutputDescriptor<Logic, offsetof(Storage, output_TICK), 0>;
void evaluate(NodeId nid) {
emitValue<output_TICK>(nid, 1);
setTimeout(nid, 0);
void evaluate(Context ctx) {
emitValue<output_TICK>(ctx, 1);
setTimeout(ctx, 0);
}
} // namespace xod__core__continuously
@@ -1123,8 +1125,8 @@ State* getState(NodeId nid) {
using output_VAL = OutputDescriptor<Number, offsetof(Storage, output_VAL), 0>;
void evaluate(NodeId nid) {
reemitValue<output_VAL>(nid);
void evaluate(Context ctx) {
reemitValue<output_VAL>(ctx);
}
} // namespace xod__core__constant_number