feat(app): wire the hints adapter
- commit
- 2a96044cc93aa6bd36cffdffec4750d2bce7a8d4
- author
- brice · · 2026-10-19 10:37 UTC
- parent
- 4b455b2
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +20 -8
M internal/app/session.go +7 -0
| @@ -14,6 +14,7 @@ import ( | |||
| 14 | 14 | "github.com/bnema/neferwl/internal/adapters/config" | |
| 15 | 15 | "github.com/bnema/neferwl/internal/adapters/drm" | |
| 16 | 16 | "github.com/bnema/neferwl/internal/adapters/headlessinput" | |
| 17 | + | "github.com/bnema/neferwl/internal/adapters/hints" | |
| 17 | 18 | "github.com/bnema/neferwl/internal/adapters/launcher" | |
| 18 | 19 | "github.com/bnema/neferwl/internal/adapters/libinput" | |
| 19 | 20 | "github.com/bnema/neferwl/internal/adapters/logging" | |
| @@ -342,6 +343,12 @@ func (s *session) run(ctx context.Context, inject func(chan<- ports.InputEvent)) | |||
| 342 | 343 | }() | |
| 343 | 344 | workers.Add(1) | |
| 344 | 345 | go func() { defer workers.Done(); routeCaptured(ctx, p.capturedAll, p.captured, p.internalCaptured()) }() | |
| 346 | + | workers.Add(1) | |
| 347 | + | go func() { | |
| 348 | + | defer workers.Done() | |
| 349 | + | // Run only returns when ctx is done: nothing to report. | |
| 350 | + | _ = hints.Run(ctx, p.hintScans, p.captures, p.hintCaptured, p.hintResults) | |
| 351 | + | }() | |
| 345 | 352 | go func() { defer workers.Done(); done <- child.Run(ctx, p.spawn) }() | |
| 346 | 353 | go func() { defer workers.Done(); done <- c.Run(ctx) }() | |
| 347 | 354 | workers.Add(1) | |
| @@ -14,6 +14,7 @@ import ( | |||||
| 14 | "github.com/bnema/neferwl/internal/adapters/config" | 14 | "github.com/bnema/neferwl/internal/adapters/config" | ||
| 15 | "github.com/bnema/neferwl/internal/adapters/drm" | 15 | "github.com/bnema/neferwl/internal/adapters/drm" | ||
| 16 | "github.com/bnema/neferwl/internal/adapters/headlessinput" | 16 | "github.com/bnema/neferwl/internal/adapters/headlessinput" | ||
| 17 | + | "github.com/bnema/neferwl/internal/adapters/hints" | |||
| 17 | "github.com/bnema/neferwl/internal/adapters/launcher" | 18 | "github.com/bnema/neferwl/internal/adapters/launcher" | ||
| 18 | "github.com/bnema/neferwl/internal/adapters/libinput" | 19 | "github.com/bnema/neferwl/internal/adapters/libinput" | ||
| 19 | "github.com/bnema/neferwl/internal/adapters/logging" | 20 | "github.com/bnema/neferwl/internal/adapters/logging" | ||
| @@ -342,6 +343,12 @@ func (s *session) run(ctx context.Context, inject func(chan<- ports.InputEvent)) | |||||
| 342 | }() | 343 | }() | ||
| 343 | workers.Add(1) | 344 | workers.Add(1) | ||
| 344 | go func() { defer workers.Done(); routeCaptured(ctx, p.capturedAll, p.captured, p.internalCaptured()) }() | 345 | go func() { defer workers.Done(); routeCaptured(ctx, p.capturedAll, p.captured, p.internalCaptured()) }() | ||
| 346 | + | workers.Add(1) | |||
| 347 | + | go func() { | |||
| 348 | + | defer workers.Done() | |||
| 349 | + | // Run only returns when ctx is done: nothing to report. | |||
| 350 | + | _ = hints.Run(ctx, p.hintScans, p.captures, p.hintCaptured, p.hintResults) | |||
| 351 | + | }() | |||
| 345 | go func() { defer workers.Done(); done <- child.Run(ctx, p.spawn) }() | 352 | go func() { defer workers.Done(); done <- child.Run(ctx, p.spawn) }() | ||
| 346 | go func() { defer workers.Done(); done <- c.Run(ctx) }() | 353 | go func() { defer workers.Done(); done <- c.Run(ctx) }() | ||
| 347 | workers.Add(1) | 354 | workers.Add(1) | ||
M internal/app/wiring.go +13 -8
| @@ -46,6 +46,10 @@ type pipes struct { | |||
| 46 | 46 | // move running slides. | |
| 47 | 47 | frames chan ports.OutputFrame | |
| 48 | 48 | ||
| 49 | + | // Hint mode: core asks the hints adapter for a scan and gets the result. | |
| 50 | + | hintScans chan ports.HintScanRequest | |
| 51 | + | hintResults chan ports.HintScanResult | |
| 52 | + | ||
| 49 | 53 | captures chan ports.CaptureRequest | |
| 50 | 54 | // Every admitted capture owns one reply slot until routeCaptured takes | |
| 51 | 55 | // it. Keep this capacity tied to admission so output routing never waits. | |
| @@ -54,9 +58,7 @@ type pipes struct { | |||
| 54 | 58 | // hintCaptured (internal consumers). | |
| 55 | 59 | capturedAll chan ports.CaptureDone | |
| 56 | 60 | captured chan ports.CaptureDone | |
| 57 | - | // hintCaptured carries internal capture replies. Until an internal | |
| 58 | - | // consumer (the hints adapter) is wired, nothing reads it: see | |
| 59 | - | // internalCaptured. | |
| 61 | + | // hintCaptured carries internal capture replies to the hints adapter. | |
| 60 | 62 | hintCaptured chan ports.CaptureDone | |
| 61 | 63 | ||
| 62 | 64 | outputFormats chan ports.OutputFormats | |
| @@ -105,6 +107,9 @@ func newPipes(realSession bool) *pipes { | |||
| 105 | 107 | ||
| 106 | 108 | frames: make(chan ports.OutputFrame, 8), | |
| 107 | 109 | ||
| 110 | + | hintScans: make(chan ports.HintScanRequest, 1), | |
| 111 | + | hintResults: make(chan ports.HintScanResult, 1), | |
| 112 | + | ||
| 108 | 113 | captures: make(chan ports.CaptureRequest, ports.MaxCaptureInflight), | |
| 109 | 114 | capturedAll: make(chan ports.CaptureDone, ports.MaxCaptureInflight), | |
| 110 | 115 | captured: make(chan ports.CaptureDone, ports.MaxCaptureInflight), | |
| @@ -146,14 +151,14 @@ func (p *pipes) core() core.Channels { | |||
| 146 | 151 | ConfigErrors: p.configErrors, | |
| 147 | 152 | Scales: p.scales, | |
| 148 | 153 | Frames: p.frames, | |
| 154 | + | HintScans: p.hintScans, | |
| 155 | + | Hints: p.hintResults, | |
| 149 | 156 | } | |
| 150 | 157 | } | |
| 151 | 158 | ||
| 152 | - | // internalCaptured is the channel internal capture replies are routed to, nil | |
| 153 | - | // while no internal consumer is wired: routeCaptured then drops them (debug | |
| 154 | - | // log) rather than blocking on a channel nobody reads. The hints adapter | |
| 155 | - | // makes it p.hintCaptured. | |
| 156 | - | func (p *pipes) internalCaptured() chan<- ports.CaptureDone { return nil } | |
| 159 | + | // internalCaptured is the channel internal capture replies are routed to: the | |
| 160 | + | // hints adapter reads it. | |
| 161 | + | func (p *pipes) internalCaptured() chan<- ports.CaptureDone { return p.hintCaptured } | |
| 157 | 162 | ||
| 158 | 163 | // wayland is the wayland server's side. | |
| 159 | 164 | func (p *pipes) wayland() wayland.Channels { | |
| @@ -46,6 +46,10 @@ type pipes struct { | |||||
| 46 | // move running slides. | 46 | // move running slides. | ||
| 47 | frames chan ports.OutputFrame | 47 | frames chan ports.OutputFrame | ||
| 48 | 48 | ||||
| 49 | + | // Hint mode: core asks the hints adapter for a scan and gets the result. | |||
| 50 | + | hintScans chan ports.HintScanRequest | |||
| 51 | + | hintResults chan ports.HintScanResult | |||
| 52 | + | ||||
| 49 | captures chan ports.CaptureRequest | 53 | captures chan ports.CaptureRequest | ||
| 50 | // Every admitted capture owns one reply slot until routeCaptured takes | 54 | // Every admitted capture owns one reply slot until routeCaptured takes | ||
| 51 | // it. Keep this capacity tied to admission so output routing never waits. | 55 | // it. Keep this capacity tied to admission so output routing never waits. | ||
| @@ -54,9 +58,7 @@ type pipes struct { | |||||
| 54 | // hintCaptured (internal consumers). | 58 | // hintCaptured (internal consumers). | ||
| 55 | capturedAll chan ports.CaptureDone | 59 | capturedAll chan ports.CaptureDone | ||
| 56 | captured chan ports.CaptureDone | 60 | captured chan ports.CaptureDone | ||
| 57 | - | // hintCaptured carries internal capture replies. Until an internal | 61 | + | // hintCaptured carries internal capture replies to the hints adapter. |
| 58 | - | // consumer (the hints adapter) is wired, nothing reads it: see | |||
| 59 | - | // internalCaptured. | |||
| 60 | hintCaptured chan ports.CaptureDone | 62 | hintCaptured chan ports.CaptureDone | ||
| 61 | 63 | ||||
| 62 | outputFormats chan ports.OutputFormats | 64 | outputFormats chan ports.OutputFormats | ||
| @@ -105,6 +107,9 @@ func newPipes(realSession bool) *pipes { | |||||
| 105 | 107 | ||||
| 106 | frames: make(chan ports.OutputFrame, 8), | 108 | frames: make(chan ports.OutputFrame, 8), | ||
| 107 | 109 | ||||
| 110 | + | hintScans: make(chan ports.HintScanRequest, 1), | |||
| 111 | + | hintResults: make(chan ports.HintScanResult, 1), | |||
| 112 | + | ||||
| 108 | captures: make(chan ports.CaptureRequest, ports.MaxCaptureInflight), | 113 | captures: make(chan ports.CaptureRequest, ports.MaxCaptureInflight), | ||
| 109 | capturedAll: make(chan ports.CaptureDone, ports.MaxCaptureInflight), | 114 | capturedAll: make(chan ports.CaptureDone, ports.MaxCaptureInflight), | ||
| 110 | captured: make(chan ports.CaptureDone, ports.MaxCaptureInflight), | 115 | captured: make(chan ports.CaptureDone, ports.MaxCaptureInflight), | ||
| @@ -146,14 +151,14 @@ func (p *pipes) core() core.Channels { | |||||
| 146 | ConfigErrors: p.configErrors, | 151 | ConfigErrors: p.configErrors, | ||
| 147 | Scales: p.scales, | 152 | Scales: p.scales, | ||
| 148 | Frames: p.frames, | 153 | Frames: p.frames, | ||
| 154 | + | HintScans: p.hintScans, | |||
| 155 | + | Hints: p.hintResults, | |||
| 149 | } | 156 | } | ||
| 150 | } | 157 | } | ||
| 151 | 158 | ||||
| 152 | - | // internalCaptured is the channel internal capture replies are routed to, nil | 159 | + | // internalCaptured is the channel internal capture replies are routed to: the |
| 153 | - | // while no internal consumer is wired: routeCaptured then drops them (debug | 160 | + | // hints adapter reads it. |
| 154 | - | // log) rather than blocking on a channel nobody reads. The hints adapter | 161 | + | func (p *pipes) internalCaptured() chan<- ports.CaptureDone { return p.hintCaptured } |
| 155 | - | // makes it p.hintCaptured. | |||
| 156 | - | func (p *pipes) internalCaptured() chan<- ports.CaptureDone { return nil } | |||
| 157 | 162 | ||||
| 158 | // wayland is the wayland server's side. | 163 | // wayland is the wayland server's side. | ||
| 159 | func (p *pipes) wayland() wayland.Channels { | 164 | func (p *pipes) wayland() wayland.Channels { | ||