@@ -1,3 +1,80 @@
|
||||
// Example 02 — Named Ports
|
||||
//
|
||||
// A three-stage text pipeline where port names carry semantic meaning:
|
||||
//
|
||||
// [tokenise] --"words"--> [count_words] --"count"--> [report]
|
||||
// --"words"--> [report]
|
||||
//
|
||||
// Named ports let the connect() call read like documentation:
|
||||
// connect("tok", tok.output<"words">(), "cnt", cnt.input<"words">())
|
||||
// A typo in the name is a compile-time error, not a runtime surprise.
|
||||
|
||||
#include <kpn/kpn.hpp>
|
||||
// TODO: implement example
|
||||
int main() { return 0; }
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
// ── Node functions ────────────────────────────────────────────────────────────
|
||||
|
||||
static int sentence_index = 0;
|
||||
|
||||
static std::vector<std::string> tokenise() {
|
||||
static const char* sentences[] = {
|
||||
"the quick brown fox jumps over the lazy dog",
|
||||
"kahn process networks are a model of concurrent computation",
|
||||
"each node runs in its own thread communicating via channels",
|
||||
"named ports catch wiring mistakes at compile time",
|
||||
};
|
||||
std::istringstream ss(sentences[sentence_index++ % 4]);
|
||||
std::vector<std::string> words;
|
||||
std::string w;
|
||||
while (ss >> w) words.push_back(w);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
return words;
|
||||
}
|
||||
|
||||
// Returns (word_count, original_words) — two outputs via tuple
|
||||
static std::tuple<int, std::vector<std::string>>
|
||||
count_words(std::vector<std::string> words) {
|
||||
return {static_cast<int>(words.size()), std::move(words)};
|
||||
}
|
||||
|
||||
static void report(int count, std::vector<std::string> words) {
|
||||
std::cout << "[" << count << " words] ";
|
||||
for (auto& w : words) std::cout << w << ' ';
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
// ── main ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
int main() {
|
||||
using namespace kpn;
|
||||
|
||||
// tokenise: no inputs, one named output "words"
|
||||
auto tok = make_node<tokenise>(out<"words">{}, 4);
|
||||
|
||||
// count_words: named input "words", named outputs "count" and "words"
|
||||
auto cnt = make_node<count_words>(in<"words">{}, out<"count", "words">{}, 4);
|
||||
|
||||
// report: two named inputs — note the function takes (int, vector<string>)
|
||||
// so we need two separate input ports wired independently
|
||||
// For a two-input sink we wire each output of cnt to a different input of report
|
||||
auto snk = make_node<report>(in<"count", "words">{}, 4);
|
||||
|
||||
Network net;
|
||||
net.add("tok", tok)
|
||||
.add("cnt", cnt)
|
||||
.add("snk", snk)
|
||||
.connect("tok", tok.template output<"words">(), "cnt", cnt.template input<"words">())
|
||||
.connect("cnt", cnt.template output<"count">(), "snk", snk.template input<"count">())
|
||||
.connect("cnt", cnt.template output<"words">(), "snk", snk.template input<"words">())
|
||||
.build();
|
||||
|
||||
net.start();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
net.stop();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user