44#pragma once
55
66#include < oxr_utils/oxr_session_handles.hpp>
7+ #include < schema/timestamp_generated.h>
78
89#include < XR_NVX1_tensor_data.h>
910#include < cstddef>
@@ -87,32 +88,51 @@ struct SchemaTrackerConfig
8788 * Impl(const OpenXRSessionHandles& handles, SchemaTrackerConfig config)
8889 * : m_schema_reader(handles, std::move(config)) {}
8990 *
90- * bool update(XrTime time) override {
91- * if (m_schema_reader.read_buffer(buffer_)) {
92- * auto fb = GetLocomotionCommand(buffer_.data());
91+ * bool update(XrTime) override {
92+ * m_pending.clear();
93+ * std::vector<SchemaTracker::SampleResult> raw;
94+ * m_schema_reader.read_all_samples(raw);
95+ * for (auto& s : raw) {
96+ * auto fb = flatbuffers::GetRoot<LocomotionCommand>(s.buffer.data());
9397 * if (fb) {
94- * fb->UnPackTo(&data_);
95- * return true;
98+ * LocomotionCommandT parsed;
99+ * fb->UnPackTo(&parsed);
100+ * m_pending.push_back({std::move(parsed), s.timestamp});
96101 * }
97102 * }
98- * return false;
103+ * if (!m_pending.empty()) data_ = m_pending.back().data;
104+ * return true;
99105 * }
100106 *
101107 * DeviceDataTimestamp serialize(flatbuffers::FlatBufferBuilder& builder, size_t) const override {
102- * auto data_offset = LocomotionCommand::Pack(builder, &data_);
108+ * auto offset = LocomotionCommand::Pack(builder, &data_);
109+ * auto& ts = m_pending.empty() ? DeviceDataTimestamp{} : m_pending.back().timestamp;
103110 * LocomotionCommandRecordBuilder rb(builder);
104- * rb.add_data(data_offset );
105- * rb.add_timestamp(&m_last_timestamp );
111+ * rb.add_data(offset );
112+ * rb.add_timestamp(&ts );
106113 * builder.Finish(rb.Finish());
107- * return m_last_timestamp;
114+ * return ts;
115+ * }
116+ *
117+ * void serialize_all(size_t, const RecordCallback& cb) const override {
118+ * for (const auto& r : m_pending) {
119+ * flatbuffers::FlatBufferBuilder b(256);
120+ * auto offset = LocomotionCommand::Pack(b, &r.data);
121+ * LocomotionCommandRecordBuilder rb(b);
122+ * rb.add_data(offset);
123+ * rb.add_timestamp(&r.timestamp);
124+ * b.Finish(rb.Finish());
125+ * cb(r.timestamp, b.GetBufferPointer(), b.GetSize());
126+ * }
108127 * }
109128 *
110129 * const LocomotionCommandT& get_data() const { return data_; }
111130 *
112131 * private:
132+ * struct Pending { LocomotionCommandT data; DeviceDataTimestamp timestamp; };
113133 * SchemaTracker m_schema_reader;
114- * std::vector<uint8_t> buffer_;
115134 * LocomotionCommandT data_;
135+ * std::vector<Pending> m_pending;
116136 * };
117137 * };
118138 * @endcode
@@ -145,16 +165,26 @@ class SchemaTracker
145165 */
146166 static std::vector<std::string> get_required_extensions ();
147167
168+ // ! A single tensor sample with its data buffer and real timestamps.
169+ struct SampleResult
170+ {
171+ std::vector<uint8_t > buffer;
172+ DeviceDataTimestamp timestamp;
173+ };
174+
148175 /* !
149- * @brief Read the next available raw sample buffer .
176+ * @brief Read ALL pending samples from the tensor collection .
150177 *
151- * This method polls for tensor list updates, discovers the target collection
152- * if not already connected, and retrieves the next available sample.
178+ * Drains every available sample since the last read, appending each to the
179+ * output vector with real timestamps from XrTensorSampleMetadataNV:
180+ * - sample_time_device_clock = rawDeviceTimestamp
181+ * - sample_time_common_clock = timestamp (OpenXR time domain)
182+ * - available_time_common_clock = arrivalTimestamp
153183 *
154- * @param buffer Output vector that will be resized and filled with sample data .
155- * @return true if data was read, false if no new data available .
184+ * @param samples Output vector; new samples are appended (not cleared) .
185+ * @return Number of samples read in this call .
156186 */
157- bool read_buffer (std::vector<uint8_t >& buffer );
187+ size_t read_all_samples (std::vector<SampleResult >& samples );
158188
159189 /* !
160190 * @brief Access the configuration.
@@ -164,9 +194,10 @@ class SchemaTracker
164194private:
165195 void initialize_tensor_data_functions ();
166196 void create_tensor_list ();
197+ bool ensure_collection ();
167198 void poll_for_updates ();
168199 std::optional<uint32_t > find_target_collection ();
169- bool read_next_sample (std::vector< uint8_t >& buffer );
200+ bool read_next_sample (SampleResult& out );
170201
171202 OpenXRSessionHandles m_handles;
172203 SchemaTrackerConfig m_config;
0 commit comments