feat(uci): add adapter seam and convert globals to struct types#118
Draft
CorentinGS wants to merge 1 commit into
Draft
feat(uci): add adapter seam and convert globals to struct types#118CorentinGS wants to merge 1 commit into
CorentinGS wants to merge 1 commit into
Conversation
d76a3b1 to
fdd76b9
Compare
167f09a to
13ec153
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces an Adapter seam for UCI I/O and refactors the command layer from global variables/functions into struct-based command types, enabling easier testing (including a new fake adapter) and decoupling the engine from subprocess specifics.
Changes:
- Added an
Adapterinterface with aSubprocessAdapterimplementation and aFakeAdapterfor tests. - Refactored
Engineto communicate via an injected adapter (NewWithAdapter) instead of directly owning pipes/process. - Redefined
Cmdto useIsDone/Handle/LockRequiredand converted previously-global commands into struct types.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| uci/fake.go | Adds FakeAdapter to return canned responses keyed by command verb. |
| uci/engine.go | Refactors Engine to use an injected Adapter; adds NewWithAdapter; updates command execution flow. |
| uci/engine_test.go | Updates tests to use the new struct command types (CmdUCI{} etc.). |
| uci/cmd.go | Redesigns the Cmd interface and rewrites built-in commands as struct types with adapter-driven response handling. |
| uci/adapter.go | Introduces Adapter and SubprocessAdapter encapsulating subprocess + scan/write exchange. |
| uci/adapter_test.go | Adds unit tests around FakeAdapter + adapter-driven command handling. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+100
to
102
| func (CmdEval) IsDone(line string) bool { | ||
| return strings.HasPrefix(line, "Final evaluation") | ||
| } |
| } | ||
| func (CmdSetOption) IsDone(_ string) bool { return true } | ||
|
|
||
| func (CmdSetOption) LockRequired() bool { return false } |
|
|
||
| func (CmdQuit) IsDone(_ string) bool { return true } | ||
|
|
||
| func (CmdQuit) LockRequired() bool { return false } |
Comment on lines
102
to
105
| func (e *Engine) Close() error { | ||
| if err := e.Run(CmdQuit); err != nil { | ||
| return err | ||
| } | ||
| if err := e.in.Close(); err != nil { | ||
| return err | ||
| } | ||
| if err := e.out.Close(); err != nil { | ||
| return err | ||
| } | ||
| return e.cmd.Process.Kill() | ||
| _ = e.Run(CmdQuit{}) | ||
| return e.adapter.Close() | ||
| } |
| } | ||
| } | ||
|
|
||
| func Test_FakeAdapter_FireAndForgetPathrough(t *testing.T) { |
fdd76b9 to
60f222b
Compare
13ec153 to
93c8d1f
Compare
93c8d1f to
222d597
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR refactors the
ucipackage around an adapter seam so engine communication is no longer hard-wired directly intoEngine.The main goals are:
Engine.Run(...)as the main execution entry point while routing commands through anAdapterNew API
New adapter interface:
New subprocess adapter:
New engine constructor for tests/custom transports:
New fake adapter for tests:
Example:
Command API Changes
Cmdnow describes both command completion and response handling:Commands are now concrete struct types instead of package-level command values:
Existing struct commands remain struct values:
Breaking Changes
This is a source-level breaking change for callers using the
ucipackage.Callers must update global command usage from value references to struct construction:
Custom command implementations must update from:
to:
Other compatibility notes:
Engine.New(path, opts...)still exists and still launches a subprocess engine.Engine.Run(...)still accepts commands and executes them in order.Engine.Close()now delegates shutdown to the adapter after sendingCmdQuit{}.Engine.Getpid()was removed fromEngine; subprocess process IDs are now exposed onSubprocessAdapter.Pid().CmdStop,CmdPonderHit,CmdQuit, andCmdSetOptionare modeled as commands that do not require the engine mutex.Implementation Notes
Enginenow stores anAdapterinstead of rawexec.Cmd, stdin pipe, and stdout pipe fields.New(path, opts...)creates aSubprocessAdapterinternally, then delegates toNewWithAdapter(...).SubprocessAdapter.Exchange(...)writes the command string and reads response lines untilcmd.IsDone(line)returns true.ProcessResponsemethods intoHandle(lines, e)implementations.FakeAdapterreturns deterministic command responses for tests without requiring Stockfish or another UCI binary.Tests
Added adapter-focused tests covering:
CmdUCIID and option parsing throughFakeAdapterCmdGobest move and search info parsingCmdEvalparsingCmdIsReadyucinewgame,stop, andponderhitUpdated existing UCI engine tests to construct command struct values, for example
uci.CmdUCI{}instead ofuci.CmdUCI.