/* * Copyright (c) 2018. Developed by Hedgecode. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.hedgecode.chess.uci; import java.io.IOException; import java.util.List; import org.hedgecode.chess.uci.annotation.CommandDirection; import org.hedgecode.chess.uci.command.CommandParams; /** * External UCI Engine Runner. * * @author Dmitry Samoshin aka gotty */ public final class ExternalEngineRunner implements EngineRunner { private Process process; private ProcessBuilder processBuilder; private ExternalEngine engine; private boolean isInit = false; ExternalEngineRunner(String extEngineCommand) { processBuilder = new ProcessBuilder(extEngineCommand); } ExternalEngineRunner(List extEngineCommands) { processBuilder = new ProcessBuilder(extEngineCommands); } @Override public Engine init() throws EngineException { if (isInit) throw new EngineException("uci.engine.already.init"); try { process = processBuilder.start(); } catch (IOException e) { throw new EngineException("uci.engine.external.start", e.getLocalizedMessage()); } engine = new ExternalEngine( process.getInputStream(), process.getOutputStream() ); isInit = true; return engine; } @Override public void run(final CommandExecutor commandExecutor) throws EngineException { if (!isInit) throw new EngineException("uci.engine.not.init"); Thread engineThread = new Thread( new Runnable() { public void run() { Transmitter engineTransmitter = engine.transmitter(); try { while (engineTransmitter.hasCommand()) { String command = engineTransmitter.transmitCommand(); if (command.isEmpty()) continue; CommandParams commandParams = new CommandParams(command); commandExecutor.exec( commandParams.getName(), CommandDirection.FROM_ENGINE, commandParams.getParams() ); } } finally { commandExecutor.exec( UCIConstants.TERMINATE, CommandDirection.FROM_ENGINE, null ); engineTransmitter.stop(); engineTransmitter.close(); if (process.isAlive()) process.destroy(); isInit = false; } } } ); engineThread.start(); } }