refactor(qconnect): extract QconnectServiceState to service.rs
The final extraction of Alcance A. Move the public service facade (QconnectServiceState struct + impl + Default impl, plus the spawned event-loop task, the renderer/queue snapshot queries, the controller- handoff helpers, send_command/send_renderer_report, the deferred renderer-join plumbing, and the bootstrap_remote_presence pending- action machinery) from mod.rs into a dedicated service submodule. Items moved: - struct QconnectRuntime, QconnectServiceInner - pub struct QconnectServiceState (re-exported via `pub use`) - impl QconnectServiceState (~50 methods) and impl Default - bootstrap_remote_presence, deferred_renderer_join, clear_pending_if_matches - queue_payload_track_preview, update_lifecycle_state_if_running, emit_qconnect_diagnostic (private helpers used only by the service) - Constants: JOIN_SESSION_REASON_CONTROLLER_REQUEST, QCONNECT_PLAY_TRACK_HANDOFF_WAIT_MS, QCONNECT_PLAY_TRACK_HANDOFF_POLL_MS All methods on QconnectServiceState are pub(super) so the commands submodule (which was already extracted) can dispatch through them. The Default impl uses plain `fn default()` (visibility qualifiers are not permitted in trait impls). mod.rs now contains only the cross-submodule glue (~140 lines): shared constants (PLAYING_STATE_*, AUDIO_QUALITY_*, BUFFER_STATE_OK, DEFAULT_QCONNECT_CHANNEL_COUNT, QCONNECT_REMOTE_QUEUE_SOURCE), the QconnectRemoteSyncState accumulator, qconnect_now_ms, qconnect_repeat_mode_from_loop_mode, normalize_volume_to_fraction, model_track_to_core_queue_track, and the module declarations. session.rs and commands.rs imports re-pathed to point at submodules directly (super::transport::*, super::queue_resolution::*, super::session::*, super::service::*) instead of going through re-exports in mod.rs. mod.rs: 1820 → 142 lines (-92%). service.rs: 1689 lines. Final layout: src-tauri/src/qconnect/ ├── mod.rs ( 142) module glue ├── types.rs ( 273) wire types, payloads ├── session.rs ( 374) topology, renderer snapshots ├── queue_resolution.rs ( 481) cursors, shuffle order ├── corebridge.rs ( 566) apply_renderer_command, materialize ├── track_loading.rs ( 337) streaming, FLAC probe, dedup ├── event_sink.rs ( 461) QconnectEventSink + dispatch ├── transport.rs ( 386) credentials, device identity ├── service.rs (1689) QconnectServiceState facade ├── commands.rs ( 849) Tauri invoke handlers └── tests.rs (1044) 37 unit tests From 6371 lines in 1 monolith → 6602 lines across 11 focused files, each with a single clear responsibility. mod.rs went 6371 → 142 lines (-98%). All 37 tests pass. Alcance A complete; the codebase is ready for unified-binary Phase 0 to resume. cc
This commit is contained in:
5 files changed
+1730
-1720
No files matched your search
@@ -15,21 +15,22 @@ use crate::core_bridge::CoreBridgeState;
|
|||||||
use crate::runtime::{CommandRequirement, RuntimeError, RuntimeManagerState};
|
use crate::runtime::{CommandRequirement, RuntimeError, RuntimeManagerState};
|
||||||
use crate::AppState;
|
use crate::AppState;
|
||||||
|
|
||||||
use super::session::QconnectFileAudioQualitySnapshot;
|
use super::service::QconnectServiceState;
|
||||||
|
use super::session::{QconnectFileAudioQualitySnapshot, QconnectRendererReportDebugEvent};
|
||||||
use super::transport::{
|
use super::transport::{
|
||||||
persist_device_name, resolve_default_qconnect_device_name, resolve_system_hostname,
|
persist_device_name, resolve_default_qconnect_device_name, resolve_system_hostname,
|
||||||
resolve_transport_config,
|
resolve_transport_config,
|
||||||
};
|
};
|
||||||
use super::{
|
use super::{
|
||||||
QconnectAdmissionBlockedEvent, QconnectAdmissionResult, QconnectAskForRendererStateRequest,
|
QconnectAdmissionBlockedEvent, QconnectAdmissionResult, QconnectAskForRendererStateRequest,
|
||||||
QconnectConnectOptions, QconnectConnectionStatus, QconnectJoinSessionRequest,
|
QconnectConnectOptions, QconnectConnectionStatus, QconnectHandoffIntent,
|
||||||
QconnectMuteVolumeRequest, QconnectQueueVersionPayload, QconnectRendererReportDebugEvent,
|
QconnectJoinSessionRequest, QconnectMuteVolumeRequest, QconnectQueueVersionPayload,
|
||||||
QconnectHandoffIntent, QconnectSendCommandRequest, QconnectSendCommandWithAdmissionRequest,
|
QconnectSendCommandRequest, QconnectSendCommandWithAdmissionRequest, QconnectSessionState,
|
||||||
QconnectServiceState, QconnectSessionState, QconnectSetActiveRendererRequest,
|
QconnectSetActiveRendererRequest, QconnectSetLoopModeRequest,
|
||||||
QconnectSetLoopModeRequest, QconnectSetMaxAudioQualityRequest, QconnectSetPlayerStateRequest,
|
QconnectSetMaxAudioQualityRequest, QconnectSetPlayerStateRequest, QconnectSetVolumeRequest,
|
||||||
QconnectSetVolumeRequest, QconnectTrackOrigin, AUDIO_QUALITY_CD, AUDIO_QUALITY_HIRES_LEVEL1,
|
QconnectTrackOrigin, AUDIO_QUALITY_CD, AUDIO_QUALITY_HIRES_LEVEL1, AUDIO_QUALITY_HIRES_LEVEL2,
|
||||||
AUDIO_QUALITY_HIRES_LEVEL2, AUDIO_QUALITY_HIRES_LEVEL3, AUDIO_QUALITY_MP3,
|
AUDIO_QUALITY_HIRES_LEVEL3, AUDIO_QUALITY_MP3, AUDIO_QUALITY_UNKNOWN, BUFFER_STATE_OK,
|
||||||
AUDIO_QUALITY_UNKNOWN, BUFFER_STATE_OK, DEFAULT_QCONNECT_CHANNEL_COUNT,
|
DEFAULT_QCONNECT_CHANNEL_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(super) fn classify_qconnect_audio_quality(sample_rate: u32, bit_depth: u32) -> i32 {
|
pub(super) fn classify_qconnect_audio_quality(sample_rate: u32, bit_depth: u32) -> i32 {
|
||||||
|
|||||||
+28
-1703
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -13,9 +13,9 @@ use super::queue_resolution::{
|
|||||||
find_cursor_index_by_queue_item_id, normalize_current_queue_item_id_from_queue_state,
|
find_cursor_index_by_queue_item_id, normalize_current_queue_item_id_from_queue_state,
|
||||||
ordered_queue_cursors, QconnectOrderedQueueCursor,
|
ordered_queue_cursors, QconnectOrderedQueueCursor,
|
||||||
};
|
};
|
||||||
|
use super::transport::{default_qconnect_device_info, resolve_qconnect_device_uuid};
|
||||||
use super::{
|
use super::{
|
||||||
default_qconnect_device_info, resolve_qconnect_device_uuid, QconnectQueueVersionPayload,
|
QconnectQueueVersionPayload, QconnectRemoteSyncState, QconnectVisibleQueueProjection,
|
||||||
QconnectRemoteSyncState, QconnectVisibleQueueProjection,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(super) fn queue_item_snapshot_for_cursor(
|
pub(super) fn queue_item_snapshot_for_cursor(
|
||||||
@@ -290,7 +290,7 @@ pub(super) fn build_visible_queue_projection(
|
|||||||
queue: &QConnectQueueState,
|
queue: &QConnectQueueState,
|
||||||
renderer: &QConnectRendererState,
|
renderer: &QConnectRendererState,
|
||||||
) -> QconnectVisibleQueueProjection {
|
) -> QconnectVisibleQueueProjection {
|
||||||
use super::find_cursor_index_by_track_id;
|
use super::queue_resolution::find_cursor_index_by_track_id;
|
||||||
|
|
||||||
let cursors = ordered_queue_cursors(queue);
|
let cursors = ordered_queue_cursors(queue);
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ fn maps_qconnect_track_origin_to_core_origin_and_handoff() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn refreshes_local_renderer_id_from_exact_device_uuid_match() {
|
fn refreshes_local_renderer_id_from_exact_device_uuid_match() {
|
||||||
let local_device_uuid = super::resolve_qconnect_device_uuid();
|
let local_device_uuid = super::transport::resolve_qconnect_device_uuid();
|
||||||
let mut session = QconnectSessionState {
|
let mut session = QconnectSessionState {
|
||||||
renderers: vec![
|
renderers: vec![
|
||||||
QconnectRendererInfo {
|
QconnectRendererInfo {
|
||||||
@@ -476,7 +476,7 @@ fn effective_renderer_snapshot_prefers_session_cursor_over_stale_app_snapshot()
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let snapshot = super::build_effective_renderer_snapshot(
|
let snapshot = super::session::build_effective_renderer_snapshot(
|
||||||
&queue,
|
&queue,
|
||||||
&base_renderer,
|
&base_renderer,
|
||||||
Some(&renderer_state),
|
Some(&renderer_state),
|
||||||
@@ -542,7 +542,7 @@ fn effective_renderer_snapshot_preserves_authoritative_renderer_next_track() {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let snapshot = super::build_effective_renderer_snapshot(&queue, &base_renderer, None, None);
|
let snapshot = super::session::build_effective_renderer_snapshot(&queue, &base_renderer, None, None);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
snapshot
|
snapshot
|
||||||
@@ -593,7 +593,7 @@ fn visible_queue_projection_respects_remote_shuffle_order() {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let projection = super::build_visible_queue_projection(&queue, &renderer);
|
let projection = super::session::build_visible_queue_projection(&queue, &renderer);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
projection
|
projection
|
||||||
@@ -640,7 +640,7 @@ fn visible_queue_projection_can_infer_current_from_next_anchor() {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let projection = super::build_visible_queue_projection(&queue, &renderer);
|
let projection = super::session::build_visible_queue_projection(&queue, &renderer);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
projection
|
projection
|
||||||
|
|||||||
Reference in new issue
Block a user