com.xrlab.labframe_brainbit 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -60,8 +60,15 @@ public class BrainBitConfig
60
60
  /// </summary>
61
61
  public bool EmotionsMentalEstimation = false;
62
62
 
63
- /// <summary>
64
- /// 情緒分析優先腦側:NONE / LEFT / RIGHT,預設 NONE(雙側平均)。
65
- /// </summary>
66
- public SideType EmotionsPrioritySide = SideType.NONE;
67
- }
63
+ /// <summary>
64
+ /// 情緒分析優先腦側:NONE / LEFT / RIGHT,預設 NONE(雙側平均)。
65
+ /// </summary>
66
+ public SideType EmotionsPrioritySide = SideType.NONE;
67
+
68
+ /// <summary>
69
+ /// 指定要連線的 BrainBit 裝置 MAC(例如 "E0:39:7A:68:75:58")。
70
+ /// 留空 = 維持原行為(依掃描結果與 AutoSelectBestSignal 選擇)。
71
+ /// 多台同時在場時設定此值,可避免連錯台。
72
+ /// </summary>
73
+ public string TargetDeviceAddress = "";
74
+ }
@@ -124,13 +124,21 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
124
124
  private bool _autoWriteEEGData = false;
125
125
  private bool _autoWriteImpedanceData = false;
126
126
 
127
- private Coroutine _connectionMonitorCoroutine;
128
- private Coroutine _scanTimeoutCoroutine;
129
-
130
- private int _reconnectAttempts = 0;
131
-
132
- // 用於記錄目前 EEG 寫入資料的標籤 (對應不同的儲存檔案)
133
- private string _currentEEGTag = "eeg";
127
+ private Coroutine _connectionMonitorCoroutine;
128
+ private Coroutine _scanTimeoutCoroutine;
129
+
130
+ private int _reconnectAttempts = 0;
131
+ private bool _isInitialized = false;
132
+ private bool _autoConnectScheduled = false;
133
+ private const int TargetDeviceFallbackAttempts = 3;
134
+ private const double TargetDeviceAttemptIntervalSeconds = 2.0;
135
+ private int _targetDeviceMissAttempts = 0;
136
+ private DateTime _nextTargetDeviceAttemptUtc = DateTime.MinValue;
137
+ private bool _connectionSelectionQueued = false;
138
+ private readonly object _sensorSelectionLock = new object();
139
+
140
+ // 用於記錄目前 EEG 寫入資料的標籤 (對應不同的儲存檔案)
141
+ private string _currentEEGTag = "eeg";
134
142
  // 用於記錄目前阻抗寫入資料的標籤
135
143
  private string _currentImpedanceTag = "impedance";
136
144
 
@@ -139,10 +147,10 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
139
147
 
140
148
  // === Emotions ===
141
149
  private EmotionsController _emotionsController;
142
- private bool _autoWriteEmotionData = false;
143
- private string _currentMindTag = "mind";
144
- private string _currentSpectralTag = "spectral";
145
- private BrainBit_MindData _lastMindData;
150
+ private bool _autoWriteEmotionData = false;
151
+ private string _currentMindTag = "mind";
152
+ private string _currentSpectralTag = "spectral";
153
+ private BrainBit_MindData _lastMindData;
146
154
  private BrainBit_SpectralData _lastSpectralData;
147
155
  // 若為 true,代表 EEG 串流是被情緒處理自動啟動的 — StopEmotionsProcessing 時要一起停
148
156
  private bool _emotionsStartedEEG = false;
@@ -154,20 +162,21 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
154
162
  LabTools.Log("[BrainBit] Initializing BrainBit Manager...");
155
163
 
156
164
  // 載入配置
157
- _config = LabTools.GetConfig<BrainBitConfig>(true);
165
+ if (!EnsureInitialized(nameof(ManagerInit)))
166
+ {
167
+ return;
168
+ }
158
169
 
159
170
  // 初始化數據對象
160
- _lastEEGData = new BrainBit_EEGData();
161
- _lastImpedanceData = new BrainBit_ImpedanceData();
162
171
 
163
172
  // 開始連接監控
164
- _connectionMonitorCoroutine = StartCoroutine(MonitorConnection());
165
173
 
166
174
  // 自動連接
167
- if (_config.AutoConnectOnInit)
168
- {
169
- StartCoroutine(DelayedAutoConnect());
170
- }
175
+ if (_config.AutoConnectOnInit && !_autoConnectScheduled && !IsConnected && !IsScanning)
176
+ {
177
+ _autoConnectScheduled = true;
178
+ StartCoroutine(DelayedAutoConnect());
179
+ }
171
180
 
172
181
  LabTools.Log("[BrainBit] Manager initialized successfully");
173
182
  LabTools.Log($"[BrainBit] Config - AutoConnect: {_config.AutoConnectOnInit}, ScanTimeout: {_config.ScanTimeoutSeconds}s");
@@ -232,21 +241,70 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
232
241
  }
233
242
  #endregion
234
243
 
235
- #region Public Methods
236
- /// <summary>
244
+ #region Public Methods
245
+ private bool EnsureInitialized(string callerName)
246
+ {
247
+ if (_isInitialized && _config != null)
248
+ {
249
+ return true;
250
+ }
251
+
252
+ try
253
+ {
254
+ _config ??= LabTools.GetConfig<BrainBitConfig>(false);
255
+ if (_config == null)
256
+ {
257
+ LabTools.LogError($"[BrainBit] {callerName} failed - BrainBitConfig is missing");
258
+ OnError?.Invoke("BrainBit config is missing");
259
+ return false;
260
+ }
261
+
262
+ _lastEEGData ??= new BrainBit_EEGData();
263
+ _lastImpedanceData ??= new BrainBit_ImpedanceData();
264
+
265
+ if (_connectionMonitorCoroutine == null)
266
+ {
267
+ _connectionMonitorCoroutine = StartCoroutine(MonitorConnection());
268
+ }
269
+
270
+ _isInitialized = true;
271
+ LabTools.Log($"[BrainBit] Initialization ready for {callerName}");
272
+ return true;
273
+ }
274
+ catch (Exception e)
275
+ {
276
+ LabTools.LogError($"[BrainBit] {callerName} failed during initialization: {e.Message}");
277
+ OnError?.Invoke($"Initialization failed: {e.Message}");
278
+ return false;
279
+ }
280
+ }
281
+
282
+ /// <summary>
237
283
  /// 開始掃描 BrainBit 設備
238
284
  /// </summary>
239
- public void StartScan()
240
- {
241
- if (IsScanning)
242
- {
243
- LabTools.LogError("[BrainBit] Already scanning for devices");
244
- return;
245
- }
246
-
247
- try
248
- {
249
- LabTools.Log("[BrainBit] Starting device scan...");
285
+ public void StartScan()
286
+ {
287
+ if (!EnsureInitialized(nameof(StartScan)))
288
+ {
289
+ return;
290
+ }
291
+
292
+ if (IsScanning)
293
+ {
294
+ LabTools.LogError("[BrainBit] Already scanning for devices");
295
+ return;
296
+ }
297
+
298
+ lock (_sensorSelectionLock)
299
+ {
300
+ _targetDeviceMissAttempts = 0;
301
+ _nextTargetDeviceAttemptUtc = DateTime.MinValue;
302
+ _connectionSelectionQueued = false;
303
+ }
304
+
305
+ try
306
+ {
307
+ LabTools.Log("[BrainBit] Starting device scan...");
250
308
 
251
309
  // 重用 Scanner,避免重複建立造成 native 資源洩漏
252
310
  if (_scanner == null)
@@ -281,10 +339,10 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
281
339
  private IEnumerator DebugScanStatus()
282
340
  {
283
341
  int attempts = 0;
284
- while (IsScanning && attempts < 10)
285
- {
286
- yield return new WaitForSeconds(1f);
287
- attempts++;
342
+ while (IsScanning && attempts < 10)
343
+ {
344
+ yield return new WaitForSeconds((float)TargetDeviceAttemptIntervalSeconds);
345
+ attempts++;
288
346
 
289
347
  try
290
348
  {
@@ -295,12 +353,18 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
295
353
  if (foundDevices != null && foundDevices.Count > 0)
296
354
  {
297
355
  foreach (var device in foundDevices)
298
- {
299
- LabTools.Log($"[BrainBit] Found device: {device.Name} ({device.Address}) RSSI: {device.RSSI}");
300
- }
301
- }
302
- }
303
- catch (Exception e)
356
+ {
357
+ LabTools.Log($"[BrainBit] Found device: {device.Name} ({device.Address}) RSSI: {device.RSSI}");
358
+ }
359
+
360
+ TrySelectAndQueueDevice(foundDevices);
361
+ if (_connectionSelectionQueued)
362
+ {
363
+ yield break;
364
+ }
365
+ }
366
+ }
367
+ catch (Exception e)
304
368
  {
305
369
  LabTools.LogError($"[BrainBit] Error during scan debug: {e.Message}");
306
370
  }
@@ -577,10 +641,18 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
577
641
  }
578
642
  }
579
643
 
580
- private IEnumerator ScanTimeout()
581
- {
582
- LabTools.Log($"[BrainBit] Scan timeout set for {_config.ScanTimeoutSeconds} seconds");
583
- yield return new WaitForSeconds(_config.ScanTimeoutSeconds);
644
+ private IEnumerator ScanTimeout()
645
+ {
646
+ if (!EnsureInitialized(nameof(ScanTimeout)))
647
+ {
648
+ IsScanning = false;
649
+ _scanTimeoutCoroutine = null;
650
+ yield break;
651
+ }
652
+
653
+ float timeoutSeconds = _config.ScanTimeoutSeconds;
654
+ LabTools.Log($"[BrainBit] Scan timeout set for {timeoutSeconds} seconds");
655
+ yield return new WaitForSeconds(timeoutSeconds);
584
656
 
585
657
  if (_scanTimeoutCoroutine != null && _currentSensor == null)
586
658
  {
@@ -595,54 +667,126 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
595
667
  _scanTimeoutCoroutine = null;
596
668
  }
597
669
 
598
- private void OnSensorsFound(IScanner scanner, IReadOnlyList<SensorInfo> sensors)
599
- {
600
- // 此回呼由 NeuroSDK 在背景執行緒觸發!
601
- // 必須將所有 Unity API 呼叫(StartCoroutine、StopCoroutine 等)派發到主執行緒
670
+ private void OnSensorsFound(IScanner scanner, IReadOnlyList<SensorInfo> sensors)
671
+ {
672
+ // 此回呼由 NeuroSDK 在背景執行緒觸發!
673
+ // 必須將所有 Unity API 呼叫(StartCoroutine、StopCoroutine 等)派發到主執行緒
602
674
  try
603
675
  {
604
676
  LabTools.Log($"[BrainBit] Found {sensors.Count} device(s) (background thread)");
605
-
606
- if (sensors.Count > 0)
607
- {
608
- // 選擇要連接的設備(純邏輯,不涉及 Unity API,可以在背景執行緒執行)
609
- SensorInfo targetSensor = SelectBestDevice(sensors);
610
- LabTools.Log($"[BrainBit] Selected device: {targetSensor.Name} (RSSI: {targetSensor.RSSI})");
611
-
612
- // 先在背景緒停止 Scanner(SDK 層級,非 Unity API)
613
- _scanner?.Stop();
614
- _scanner.EventSensorsChanged -= OnSensorsFound;
615
-
616
- // 將剩下的操作排入主執行緒執行
617
- _mainThreadActions.Enqueue(() =>
618
- {
619
- IsScanning = false;
620
-
621
- // 觸發設備發現事件
622
- OnDeviceFound?.Invoke(new List<SensorInfo>(sensors));
623
-
624
- if (_scanTimeoutCoroutine != null)
625
- {
626
- StopCoroutine(_scanTimeoutCoroutine);
627
- _scanTimeoutCoroutine = null;
628
- LabTools.Log("[BrainBit] Scan timeout coroutine stopped");
629
- }
630
-
631
- // 等待一段時間後建立連接(確保掃描完全停止)
632
- StartCoroutine(DelayedConnect(targetSensor));
633
- });
634
- }
635
- }
636
- catch (Exception e)
637
- {
638
- LabTools.LogError($"[BrainBit] Error in OnSensorsFound: {e.Message}");
639
- _mainThreadActions.Enqueue(() => OnError?.Invoke($"Device discovery error: {e.Message}"));
640
- }
641
- }
642
-
643
- /// <summary>
644
- /// 選擇最佳設備
645
- /// </summary>
677
+
678
+ if (sensors.Count > 0)
679
+ {
680
+ TrySelectAndQueueDevice(sensors);
681
+ }
682
+ }
683
+ catch (Exception e)
684
+ {
685
+ LabTools.LogError($"[BrainBit] Error in OnSensorsFound: {e.Message}");
686
+ _mainThreadActions.Enqueue(() => OnError?.Invoke($"Device discovery error: {e.Message}"));
687
+ }
688
+ }
689
+
690
+ private void TrySelectAndQueueDevice(IReadOnlyList<SensorInfo> sensors)
691
+ {
692
+ if (sensors == null || sensors.Count == 0)
693
+ {
694
+ return;
695
+ }
696
+
697
+ SensorInfo targetSensor;
698
+ lock (_sensorSelectionLock)
699
+ {
700
+ if (_connectionSelectionQueued)
701
+ {
702
+ return;
703
+ }
704
+
705
+ if (!TryChooseDevice(sensors, out targetSensor))
706
+ {
707
+ return;
708
+ }
709
+
710
+ _connectionSelectionQueued = true;
711
+ }
712
+
713
+ LabTools.Log($"[BrainBit] Selected device: {targetSensor.Name} (RSSI: {targetSensor.RSSI})");
714
+
715
+ // 先停止 Scanner(SDK 層級,非 Unity API)
716
+ if (_scanner != null)
717
+ {
718
+ _scanner.Stop();
719
+ _scanner.EventSensorsChanged -= OnSensorsFound;
720
+ }
721
+
722
+ var foundSensors = new List<SensorInfo>(sensors);
723
+
724
+ // 將剩下的操作排入主執行緒執行
725
+ _mainThreadActions.Enqueue(() =>
726
+ {
727
+ IsScanning = false;
728
+
729
+ // 觸發設備發現事件
730
+ OnDeviceFound?.Invoke(foundSensors);
731
+
732
+ if (_scanTimeoutCoroutine != null)
733
+ {
734
+ StopCoroutine(_scanTimeoutCoroutine);
735
+ _scanTimeoutCoroutine = null;
736
+ LabTools.Log("[BrainBit] Scan timeout coroutine stopped");
737
+ }
738
+
739
+ // 等待一段時間後建立連接(確保掃描完全停止)
740
+ StartCoroutine(DelayedConnect(targetSensor));
741
+ });
742
+ }
743
+
744
+ private bool TryChooseDevice(IReadOnlyList<SensorInfo> sensors, out SensorInfo targetSensor)
745
+ {
746
+ string targetAddress = _config.TargetDeviceAddress?.Trim();
747
+ if (string.IsNullOrEmpty(targetAddress))
748
+ {
749
+ targetSensor = SelectBestDevice(sensors);
750
+ return true;
751
+ }
752
+
753
+ foreach (var sensor in sensors)
754
+ {
755
+ if (string.Equals(sensor.Address, targetAddress, StringComparison.OrdinalIgnoreCase))
756
+ {
757
+ _targetDeviceMissAttempts = 0;
758
+ _nextTargetDeviceAttemptUtc = DateTime.MinValue;
759
+ targetSensor = sensor;
760
+ return true;
761
+ }
762
+ }
763
+
764
+ DateTime nowUtc = DateTime.UtcNow;
765
+ if (nowUtc < _nextTargetDeviceAttemptUtc)
766
+ {
767
+ targetSensor = default;
768
+ return false;
769
+ }
770
+
771
+ _targetDeviceMissAttempts++;
772
+ _nextTargetDeviceAttemptUtc = nowUtc.AddSeconds(TargetDeviceAttemptIntervalSeconds);
773
+ if (_targetDeviceMissAttempts < TargetDeviceFallbackAttempts)
774
+ {
775
+ LabTools.Log($"[BrainBit] Target {targetAddress} not found among {sensors.Count} device(s); attempt {_targetDeviceMissAttempts}/{TargetDeviceFallbackAttempts}, retry in {TargetDeviceAttemptIntervalSeconds:0.#}s.");
776
+ targetSensor = default;
777
+ return false;
778
+ }
779
+
780
+ LabTools.Log($"[BrainBit] Target {targetAddress} not found after {TargetDeviceFallbackAttempts} attempts; selecting another device.");
781
+ _targetDeviceMissAttempts = 0;
782
+ _nextTargetDeviceAttemptUtc = DateTime.MinValue;
783
+ targetSensor = SelectBestDevice(sensors);
784
+ return true;
785
+ }
786
+
787
+ /// <summary>
788
+ /// 選擇最佳設備
789
+ /// </summary>
646
790
  /// <param name="sensors">發現的設備列表</param>
647
791
  /// <returns>選中的設備</returns>
648
792
  private SensorInfo SelectBestDevice(IReadOnlyList<SensorInfo> sensors)
@@ -681,12 +825,18 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
681
825
  /// 延遲連接設備
682
826
  /// </summary>
683
827
  /// <param name="sensorInfo">設備信息</param>
684
- private IEnumerator DelayedConnect(SensorInfo sensorInfo)
685
- {
686
- LabTools.Log($"[BrainBit] Waiting {_config.ConnectDelaySeconds}s before connecting...");
828
+ private IEnumerator DelayedConnect(SensorInfo sensorInfo)
829
+ {
830
+ if (!EnsureInitialized(nameof(DelayedConnect)))
831
+ {
832
+ yield break;
833
+ }
834
+
835
+ float connectDelaySeconds = _config.ConnectDelaySeconds;
836
+ LabTools.Log($"[BrainBit] Waiting {connectDelaySeconds}s before connecting...");
687
837
 
688
838
  // 等待指定時間,確保掃描完全停止
689
- yield return new WaitForSeconds(_config.ConnectDelaySeconds);
839
+ yield return new WaitForSeconds(connectDelaySeconds);
690
840
 
691
841
  // 建立連接
692
842
  ConnectToDevice(sensorInfo);
@@ -777,12 +927,18 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
777
927
  }
778
928
  }
779
929
 
780
- private void HandleDisconnection()
781
- {
782
- LabTools.LogError($"[BrainBit] Device disconnected: {ConnectedDeviceName}");
783
-
784
- if (_config.DisconnectNotification)
785
- {
930
+ private void HandleDisconnection()
931
+ {
932
+ LabTools.LogError($"[BrainBit] Device disconnected: {ConnectedDeviceName}");
933
+
934
+ if (!EnsureInitialized(nameof(HandleDisconnection)))
935
+ {
936
+ Disconnect();
937
+ return;
938
+ }
939
+
940
+ if (_config.DisconnectNotification)
941
+ {
786
942
  LabPromptBox.Show($"BrainBit 設備已斷線!\nDevice {ConnectedDeviceName} disconnected!");
787
943
  }
788
944
 
@@ -795,12 +951,18 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
795
951
  Disconnect();
796
952
  }
797
953
 
798
- private IEnumerator AttemptReconnect()
799
- {
800
- _reconnectAttempts++;
801
- LabTools.Log($"[BrainBit] Attempting reconnection ({_reconnectAttempts}/{_config.AutoReconnectAttempts})...");
802
-
803
- yield return new WaitForSeconds(_config.ReconnectIntervalSeconds);
954
+ private IEnumerator AttemptReconnect()
955
+ {
956
+ if (!EnsureInitialized(nameof(AttemptReconnect)))
957
+ {
958
+ yield break;
959
+ }
960
+
961
+ _reconnectAttempts++;
962
+ LabTools.Log($"[BrainBit] Attempting reconnection ({_reconnectAttempts}/{_config.AutoReconnectAttempts})...");
963
+
964
+ float reconnectIntervalSeconds = _config.ReconnectIntervalSeconds;
965
+ yield return new WaitForSeconds(reconnectIntervalSeconds);
804
966
 
805
967
  if (!IsConnected)
806
968
  {
@@ -908,13 +1070,18 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
908
1070
  IsEmotionsCalibrated = false;
909
1071
 
910
1072
  // 重置狀態
911
- IsConnected = false;
912
- IsStreamingEEG = false;
913
- IsStreamingImpedance = false;
914
- IsScanning = false;
915
-
916
- LabTools.Log("[BrainBit] Resources cleaned up");
917
- }
1073
+ IsConnected = false;
1074
+ IsStreamingEEG = false;
1075
+ IsStreamingImpedance = false;
1076
+ IsScanning = false;
1077
+ _isInitialized = false;
1078
+ _autoConnectScheduled = false;
1079
+ _targetDeviceMissAttempts = 0;
1080
+ _nextTargetDeviceAttemptUtc = DateTime.MinValue;
1081
+ _connectionSelectionQueued = false;
1082
+
1083
+ LabTools.Log("[BrainBit] Resources cleaned up");
1084
+ }
918
1085
  catch (Exception e)
919
1086
  {
920
1087
  LabTools.LogError($"[BrainBit] Error during cleanup: {e.Message}");
@@ -928,15 +1095,20 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
928
1095
  /// 啟動情緒處理(MindData / SpectralData / 校正進度)。
929
1096
  /// 若 EEG 串流未啟動,會自動啟動;呼叫 StopEmotionsProcessing 時會同步停止該 EEG 串流。
930
1097
  /// </summary>
931
- public void StartEmotionsProcessing(bool autoWriteToLabData = true,
932
- string mindTag = "mind",
933
- string spectralTag = "spectral")
934
- {
935
- if (!IsConnected)
936
- {
937
- LabTools.LogError("[BrainBit] Device not connected");
938
- OnError?.Invoke("Device not connected");
939
- return;
1098
+ public void StartEmotionsProcessing(bool autoWriteToLabData = true,
1099
+ string mindTag = "mind",
1100
+ string spectralTag = "spectral")
1101
+ {
1102
+ if (!EnsureInitialized(nameof(StartEmotionsProcessing)))
1103
+ {
1104
+ return;
1105
+ }
1106
+
1107
+ if (!IsConnected)
1108
+ {
1109
+ LabTools.LogError("[BrainBit] Device not connected");
1110
+ OnError?.Invoke("Device not connected");
1111
+ return;
940
1112
  }
941
1113
 
942
1114
  if (IsProcessingEmotions)
@@ -948,8 +1120,8 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
948
1120
  try
949
1121
  {
950
1122
  _autoWriteEmotionData = autoWriteToLabData;
951
- _currentMindTag = string.IsNullOrEmpty(mindTag) ? "mind" : mindTag;
952
- _currentSpectralTag = string.IsNullOrEmpty(spectralTag) ? "spectral" : spectralTag;
1123
+ _currentMindTag = string.IsNullOrEmpty(mindTag) ? "mind" : mindTag;
1124
+ _currentSpectralTag = string.IsNullOrEmpty(spectralTag) ? "spectral" : spectralTag;
953
1125
 
954
1126
  // 若 EEG 未啟動,自動啟動並記錄
955
1127
  if (!IsStreamingEEG)
@@ -969,9 +1141,9 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
969
1141
 
970
1142
  // 校正狀態重置
971
1143
  IsEmotionsCalibrated = false;
972
- CalibrationProgress = 0;
973
- _lastMindData = null;
974
- _lastSpectralData = null;
1144
+ CalibrationProgress = 0;
1145
+ _lastMindData = null;
1146
+ _lastSpectralData = null;
975
1147
 
976
1148
  _emotionsController.StartCalibration();
977
1149
  IsProcessingEmotions = true;
@@ -1010,8 +1182,8 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
1010
1182
  }
1011
1183
 
1012
1184
  _autoWriteEmotionData = false;
1013
- IsEmotionsCalibrated = false;
1014
- CalibrationProgress = 0;
1185
+ IsEmotionsCalibrated = false;
1186
+ CalibrationProgress = 0;
1015
1187
 
1016
1188
  if (_emotionsStartedEEG && IsStreamingEEG)
1017
1189
  {
@@ -1039,7 +1211,7 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
1039
1211
  }
1040
1212
 
1041
1213
  IsEmotionsCalibrated = false;
1042
- CalibrationProgress = 0;
1214
+ CalibrationProgress = 0;
1043
1215
  _emotionsController.StartCalibration();
1044
1216
 
1045
1217
  LabTools.Log("[BrainBit] Emotion calibration restarted");
@@ -1077,22 +1249,22 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
1077
1249
  {
1078
1250
  if (_emotionsController == null) return;
1079
1251
 
1080
- _emotionsController.progressCalibrationCallback = OnEmotionsCalibrationProgress;
1081
- _emotionsController.lastMindDataCallback = OnRawMindDataReceived;
1082
- _emotionsController.lastSpectralDataCallback = OnRawSpectralDataReceived;
1083
- _emotionsController.isArtefactedSequenceCallback = OnEmotionsArtifactDetected;
1084
- _emotionsController.isBothSidesArtifactedCallback = OnEmotionsArtifactDetected;
1252
+ _emotionsController.progressCalibrationCallback = OnEmotionsCalibrationProgress;
1253
+ _emotionsController.lastMindDataCallback = OnRawMindDataReceived;
1254
+ _emotionsController.lastSpectralDataCallback = OnRawSpectralDataReceived;
1255
+ _emotionsController.isArtefactedSequenceCallback = OnEmotionsArtifactDetected;
1256
+ _emotionsController.isBothSidesArtifactedCallback = OnEmotionsArtifactDetected;
1085
1257
  }
1086
1258
 
1087
1259
  private void UnwireEmotionsCallbacks()
1088
1260
  {
1089
1261
  if (_emotionsController == null) return;
1090
1262
 
1091
- _emotionsController.progressCalibrationCallback = null;
1092
- _emotionsController.lastMindDataCallback = null;
1093
- _emotionsController.lastSpectralDataCallback = null;
1094
- _emotionsController.isArtefactedSequenceCallback = null;
1095
- _emotionsController.isBothSidesArtifactedCallback = null;
1263
+ _emotionsController.progressCalibrationCallback = null;
1264
+ _emotionsController.lastMindDataCallback = null;
1265
+ _emotionsController.lastSpectralDataCallback = null;
1266
+ _emotionsController.isArtefactedSequenceCallback = null;
1267
+ _emotionsController.isBothSidesArtifactedCallback = null;
1096
1268
  }
1097
1269
 
1098
1270
  private void OnEmotionsCalibrationProgress(int progress)
@@ -1150,4 +1322,4 @@ public class BrainBitManager : LabSingleton<BrainBitManager>, IManager
1150
1322
  }
1151
1323
 
1152
1324
  #endregion
1153
- }
1325
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.xrlab.labframe_brainbit",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "displayName": "Lab Frame 2023 - BrainBit Plugin",
5
5
  "description": "BrainBit Support for LabFrame2023.\nNote: Currently only supports BrainBit in lab!!",
6
6
  "unity": "2022.3",