// Example 03 — Multi-Output (Fan-Out) // // A single "parse" node reads "KEY=VALUE" strings and fans out to two // independent downstream sinks — one for keys, one for values. // // +--> [print_key] // [generate] --string--> [parse] // +--> [print_value] // // The parser returns std::tuple. // Network::connect() routes each element of the tuple to a different node. #include #include #include #include #include #include // ── Node functions ──────────────────────────────────────────────────────────── static int gen_index = 0; static std::string generate() { static const char* pairs[] = { "host=localhost", "port=8080", "timeout=30s", "retries=3", "protocol=http2", }; std::this_thread::sleep_for(std::chrono::milliseconds(60)); return pairs[gen_index++ % 5]; } // Multi-output: returns (key, value) as a tuple — KPN++ routes each element // to its own output port automatically. static std::tuple parse(std::string kv) { auto sep = kv.find('='); if (sep == std::string::npos) return {kv, ""}; return {kv.substr(0, sep), kv.substr(sep + 1)}; } static void print_key(std::string key) { std::cout << "KEY → " << key << '\n'; } static void print_value(std::string value) { std::cout << "VALUE → " << value << '\n'; } // ── main ────────────────────────────────────────────────────────────────────── int main() { using namespace kpn; auto gen = make_node(out<"kv">{}, 4); auto par = make_node (in<"kv">{}, out<"key", "value">{}, 4); auto keys = make_node (in<"key">{}, 4); auto vals = make_node(in<"value">{}, 4); Network net; net.add("gen", gen) .add("par", par) .add("keys", keys) .add("vals", vals) .connect("gen", gen.template output<"kv">(), "par", par.template input<"kv">()) .connect("par", par.template output<"key">(), "keys", keys.template input<"key">()) .connect("par", par.template output<"value">(), "vals", vals.template input<"value">()) .build(); net.start(); std::this_thread::sleep_for(std::chrono::milliseconds(600)); net.stop(); }