videochess bot behaves correctly if chess engine (stockfish) can't be found

cleanup up how bo GUI features are requested/discarded
This commit is contained in:
JetSetIlly 2021-12-10 12:10:32 +00:00
parent 8dca33d2ec
commit fe2bd37451
8 changed files with 42 additions and 28 deletions

View file

@ -56,5 +56,5 @@ type Feedback struct {
type Bot interface {
BotID() string
Quit()
Feedback() Feedback
Feedback() *Feedback
}

View file

@ -24,6 +24,7 @@ import (
"time"
"github.com/jetsetilly/gopher2600/bots"
"github.com/jetsetilly/gopher2600/curated"
"github.com/jetsetilly/gopher2600/logger"
)
@ -71,28 +72,35 @@ func NewUCI(pathToEngine string, diagnostic chan bots.Diagnostic) (*UCI, error)
uci.stdin, err = cmd.StdinPipe()
if err != nil {
return nil, err
return nil, curated.Errorf("uci: %s", err.Error())
}
uci.stdout, err = cmd.StdoutPipe()
if err != nil {
return nil, err
return nil, curated.Errorf("uci: %s", err.Error())
}
end := make(chan error)
done := make(chan error)
go func() {
err := cmd.Run()
err := cmd.Start()
if err != nil {
end <- err
done <- err
return
}
done <- nil
err = cmd.Wait()
if err != nil {
end <- err
logger.Logf("uci", err.Error())
return
}
}()
err = <-done
if err != nil {
return nil, curated.Errorf("uci: %s", err.Error())
}
return uci, nil
}

View file

@ -509,7 +509,7 @@ func NewVideoChess(vcs bots.VCS, tv bots.TV) (bots.Bot, error) {
uci, err := uci.NewUCI("/usr/local/bin/stockfish", bot.feedback.Diagnostic)
if err != nil {
return nil, curated.Errorf("bot: %v", err)
return nil, curated.Errorf("videochess: %v", err)
}
uci.Start()
@ -687,6 +687,6 @@ func (bot *videoChessBot) Quit() {
}
// Feedback implements the bots.Bot interface.
func (bot *videoChessBot) Feedback() bots.Feedback {
return bot.feedback
func (bot *videoChessBot) Feedback() *bots.Feedback {
return &bot.feedback
}

View file

@ -41,7 +41,7 @@ func NewBots(vcs bots.VCS, tv bots.TV) *Bots {
}
// ActivateBot uses the cartridge hash value to and loads any available bot.
func (b *Bots) ActivateBot(cartHash string) (bots.Feedback, error) {
func (b *Bots) ActivateBot(cartHash string) (*bots.Feedback, error) {
b.Quit()
var err error
@ -50,12 +50,12 @@ func (b *Bots) ActivateBot(cartHash string) (bots.Feedback, error) {
case "043ef523e4fcb9fc2fc2fda21f15671bf8620fc3":
b.running, err = chess.NewVideoChess(b.vcs, b.tv)
if err != nil {
return bots.Feedback{}, curated.Errorf("bots: %v", err)
return nil, curated.Errorf("bots: %v", err)
}
logger.Logf("bots", "%s start", b.running.BotID())
default:
return bots.Feedback{}, nil
return nil, nil
}
return b.running.Feedback(), nil

View file

@ -565,6 +565,7 @@ func (dbg *Debugger) setMode(mode emulation.Mode) error {
// End cleans up any resources that may be dangling.
func (dbg *Debugger) end() {
dbg.removeComparisonEmulation()
dbg.bots.Quit()
dbg.vcs.End()
@ -757,6 +758,9 @@ func (dbg *Debugger) reset(newCartridge bool) error {
// this is the glue that hold the cartridge and disassembly packages together.
// especially important is the repointing of the symbols table in the instance of dbgmem.
func (dbg *Debugger) attachCartridge(cartload cartridgeloader.Loader) (e error) {
// stop any existing bots
dbg.bots.Quit()
dbg.setState(emulation.Initialising)
// set state after initialisation according to the emulation mode
@ -896,8 +900,10 @@ func (dbg *Debugger) attachCartridge(cartload cartridgeloader.Loader) (e error)
// activate bot if possible
feedback, err := dbg.bots.ActivateBot(dbg.vcs.Mem.Cart.Hash)
if err != nil {
return curated.Errorf("debugger: %v", err)
logger.Logf("debugger", err.Error())
}
// always ReqBotFeedback. if feedback is nil then the bot features will be disbaled
err = dbg.gui.SetFeature(gui.ReqBotFeedback, feedback)
if err != nil {
return curated.Errorf("debugger: %v", err)

View file

@ -72,8 +72,9 @@ const (
// request for a comparison window to be opened
ReqComparison FeatureReq = "ReqComparison" // chan *image.RGBA, chan *image.RGBA
// request for a bot window to be opened
ReqBotFeedback FeatureReq = "ReqBotFeedback" // bots.Feedback
// request for bot features to be enabled. a nil argument will cause the
// bot features to be removed
ReqBotFeedback FeatureReq = "ReqBotFeedback" // *bots.Feedback
)
// Sentinal error returned if GUI does no support requested feature.

View file

@ -144,10 +144,8 @@ func (img *SdlImgui) serviceSetFeature(request featureRequest) {
case gui.ReqBotFeedback:
err = argLen(request.args, 1)
if err == nil {
if request.args[0] != nil {
f := request.args[0].(bots.Feedback)
img.wm.windows[winBotID].(*winBot).startBotSession(f)
}
f := request.args[0].(*bots.Feedback)
img.wm.windows[winBotID].(*winBot).startBotSession(f)
}
default:

View file

@ -35,7 +35,7 @@ type winBot struct {
dirty bool
// render channels are given to use by the main emulation through a GUI request
feedback bots.Feedback
feedback *bots.Feedback
}
func newWinBot(img *SdlImgui) (window, error) {
@ -64,7 +64,7 @@ func (win *winBot) isOpen() bool {
}
// start bot session will effectively end a bot session if feedback channels are nil
func (win *winBot) startBotSession(feedback bots.Feedback) {
func (win *winBot) startBotSession(feedback *bots.Feedback) {
win.feedback = feedback
gl.BindTexture(gl.TEXTURE_2D, win.obsTexture)
@ -78,18 +78,19 @@ func (win *winBot) startBotSession(feedback bots.Feedback) {
// do not open if no bot is defined
func (win *winBot) setOpen(open bool) {
if win.feedback.Diagnostic == nil || win.feedback.Images == nil {
if win.feedback == nil {
win.open = false
return
}
win.open = open
if win.open {
// clear texture
}
}
func (win *winBot) draw() {
// no bot feedback instance
if win.feedback == nil {
return
}
// receive new thumbnail data and copy to texture
select {
case img := <-win.feedback.Images: