public StreamEngineTracker(StreamEngineTracker_Description description) { _streamEngineInteropWrapper = new StreamEngineInteropWrapper(); _customLog = new tobii_custom_log_t { log_func = LogCallback }; if (description == null) { description = new StreamEngineTracker_Description(); } // Connect StreamEngineContext context; if (ConnectionHelper.TryConnect(_streamEngineInteropWrapper, description, out context, _customLog) == false) { throw new Exception("Failed to connect to tracker"); } Context = context; // Subscribe to requested streams tobii_error_t result; if (description.WearableDataCallback != null) { _wearableDataCallbackPointer = GCHandle.Alloc(description.WearableDataCallback); result = Interop.tobii_wearable_consumer_data_subscribe(context.Device, WearableDataCallback, GCHandle.ToIntPtr(_wearableDataCallbackPointer)); if (result != tobii_error_t.TOBII_ERROR_NO_ERROR) { throw new Exception("Failed to subscribe to eye tracking data: " + result); } } if (description.WearableAdvancedDataCallback != null) { _wearableAdvancedDataCallbackPointer = GCHandle.Alloc(description.WearableAdvancedDataCallback); result = Interop.tobii_wearable_advanced_data_subscribe(context.Device, AdvancedWearableDataCallback, GCHandle.ToIntPtr(_wearableAdvancedDataCallbackPointer)); if (result != tobii_error_t.TOBII_ERROR_NO_ERROR) { throw new Exception("Failed to subscribe to eye tracking data: " + result); } } if (description.WearableFoveatedDataCallback != null) { _wearableFoveatedDataCallbackPointer = GCHandle.Alloc(description.WearableFoveatedDataCallback); result = Interop.tobii_wearable_foveated_gaze_subscribe(context.Device, WearableFoveatedGazeCallback, GCHandle.ToIntPtr(_wearableFoveatedDataCallbackPointer)); if (result != tobii_error_t.TOBII_ERROR_NO_ERROR) { throw new Exception("Failed to subscribe to eye tracking data: " + result); } } // Get connection metadata CheckForCapabilities(Context.Device); tobii_feature_group_t licenseLevel; Interop.tobii_get_feature_group(Context.Device, out licenseLevel); LicenseLevel = licenseLevel; }