MCPcopy Create free account
hub / github.com/PlotJuggler/PlotJuggler / resolveInputField

Method resolveInputField

pj_runtime/src/DataProcessorService.cpp:321–386  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

319}
320
321std::optional<DataProcessorService::ResolvedInput> DataProcessorService::resolveInputField(
322 const std::string& name) const {
323 // Exact whole-topic name → the topic's first leaf column.
324 if (const auto topic = resolveInputTopic(name)) {
325 return ResolvedInput{topic->first, topic->second, 0};
326 }
327 // Otherwise treat the name as "<topic>/<field-path>": find the LONGEST live topic
328 // whose name prefixes `name` (topic names can themselves contain '/'), then map the
329 // trailing field path to its flattened-leaf column index.
330 const TopicStorage* best_storage = nullptr;
331 TopicId best_tid = 0;
332 DatasetId best_ds = 0;
333 std::string best_field;
334 std::size_t best_topic_len = 0;
335 for (const DatasetId ds : engine_.listDatasets()) {
336 for (const TopicId tid : engine_.listTopics(ds)) {
337 const TopicStorage* storage = engine_.getTopicStorage(tid);
338 if (storage == nullptr) {
339 continue;
340 }
341 const std::string& tn = storage->descriptor().name;
342 if (name.size() > tn.size() + 1 && name.compare(0, tn.size(), tn) == 0 && name[tn.size()] == '/' &&
343 tn.size() > best_topic_len) {
344 best_topic_len = tn.size();
345 best_storage = storage;
346 best_tid = tid;
347 best_ds = ds;
348 best_field = name.substr(tn.size() + 1);
349 }
350 }
351 }
352 if (best_storage == nullptr) {
353 return std::nullopt;
354 }
355 // Map the field path to its leaf column index. The dropped/display name separates
356 // nested fields with '/', but both the type tree (flattenFieldPaths) and the stored
357 // column descriptors use '.'-separated paths (e.g. "orientation.w"); normalize the
358 // queried field to '.' before matching so a nested input resolves, not just a flat
359 // one. The returned index is the engine's leaf-column order — exactly what
360 // add_mimo_transform reads per input.
361 std::string field_dotted = best_field;
362 std::replace(field_dotted.begin(), field_dotted.end(), '/', '.');
363 const auto matches = [&](const std::string& path) { return path == best_field || path == field_dotted; };
364
365 // Schema-bearing topics (e.g. ROS/CDR): resolve through the TypeRegistry tree.
366 const PJ::SchemaId schema_id = best_storage->descriptor().schema_id;
367 if (schema_id != 0) {
368 if (const PJ::TypeTreeNode* root = engine_.typeRegistry().lookup(schema_id)) {
369 const std::vector<std::string> paths = PJ::flattenFieldPaths(*root);
370 for (std::size_t i = 0; i < paths.size(); ++i) {
371 if (matches(paths[i])) {
372 return ResolvedInput{best_tid, best_ds, i};
373 }
374 }
375 }
376 }
377 // Schema-less topics (schema_id == 0, e.g. JSON scalar-only ingest): the leaf names
378 // live in the stored column descriptors, whose order is the engine column index.

Callers

nothing calls this directly

Calls 9

getTopicStorageMethod · 0.80
descriptorMethod · 0.80
compareMethod · 0.80
listDatasetsMethod · 0.45
listTopicsMethod · 0.45
sizeMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
lookupMethod · 0.45

Tested by

no test coverage detected