[LIB-9] Replace engine sending commands via transmitter
authorgotty <gotty@hedgecode.org>
Fri, 7 Dec 2018 22:50:54 +0000 (01:50 +0300)
committergotty <gotty@hedgecode.org>
Fri, 7 Dec 2018 22:50:54 +0000 (01:50 +0300)
src/main/java/org/hedgecode/chess/hedgefish/HedgefishEngineRunner.java
src/main/java/org/hedgecode/chess/hedgefish/HedgefishTransmitter.java
src/main/java/org/hedgecode/chess/uci/CommandEnvironment.java
src/main/java/org/hedgecode/chess/uci/ConsoleAcceptor.java
src/main/java/org/hedgecode/chess/uci/ConsoleAcceptorRunner.java
src/main/java/org/hedgecode/chess/uci/ExternalEngine.java
src/main/java/org/hedgecode/chess/uci/ExternalEngineRunner.java
src/main/java/org/hedgecode/chess/uci/ExternalEngineTransmitter.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/uci/Receiver.java [deleted file]
src/main/java/org/hedgecode/chess/uci/Transmitter.java

index 0eaedc6..a47b3a5 100644 (file)
@@ -54,8 +54,8 @@ public final class HedgefishEngineRunner implements EngineRunner {
         Thread engineThread = new Thread(
                 new Runnable() {
                     public void run() {
+                        Transmitter<HedgefishCommand> engineTransmitter = engine.transmitter();
                         try {
-                            Transmitter<HedgefishCommand> engineTransmitter = engine.transmitter();
                             while (engineTransmitter.isActive()) {
                                 if (engineTransmitter.hasCommand()) {
                                     HedgefishCommand command = engineTransmitter.transmitCommand();
@@ -72,6 +72,7 @@ public final class HedgefishEngineRunner implements EngineRunner {
                                     CommandDirection.FROM_ENGINE,
                                     null
                             );
+                            engineTransmitter.close();
                             isRunning = false;
                         }
                     }
index a945b02..9bda062 100644 (file)
@@ -62,4 +62,9 @@ public class HedgefishTransmitter implements Transmitter<HedgefishCommand> {
         isActive = false;
     }
 
+    @Override
+    public void close() {
+        queue.clear();
+    }
+
 }
index 348a902..1cc5d5f 100644 (file)
@@ -28,7 +28,6 @@ public final class CommandEnvironment {
 
     private static final String ENGINE_BIN_DIR = Paths.get("bin").toAbsolutePath().toString();
 
-
     public static void main(String... args) throws Exception {
 
         EngineRunner engineRunner = new ExternalEngineRunner(
@@ -38,14 +37,11 @@ public final class CommandEnvironment {
 
         AcceptorRunner acceptorRunner = new ConsoleAcceptorRunner(); // new AcceptorStubRunner();
         Acceptor acceptor = acceptorRunner.init();
-        //AcceptorStub acceptor = new AcceptorStub();
 
         CommandExecutor commandExecutor = SyncCommandExecutor.Factory.create(engine, acceptor);
 
-        //acceptor.init(commandExecutor);
         engineRunner.run(commandExecutor);
         acceptorRunner.run(commandExecutor);
-        //acceptor.start();
     }
 
 }
index 028cdaf..f9da8e9 100644 (file)
@@ -32,12 +32,12 @@ import org.hedgecode.chess.uci.command.OptionType;
  */
 public class ConsoleAcceptor implements Acceptor {
 
-    private class ConsoleReceiver implements Receiver<String> {
+    private class ConsoleTransmitter implements Transmitter<String> {
 
         private Scanner scanner;
         private boolean isActive;
 
-        ConsoleReceiver(InputStream input) {
+        ConsoleTransmitter(InputStream input) {
             scanner = new Scanner(input);
             isActive = true;
         }
@@ -53,11 +53,16 @@ public class ConsoleAcceptor implements Acceptor {
         }
 
         @Override
-        public String receiveCommand() {
+        public String transmitCommand() {
             return scanner.nextLine();
         }
 
         @Override
+        public void addCommand(String command) {
+            // not supported for console acceptor
+        }
+
+        @Override
         public void stop() {
             isActive = false;
         }
@@ -68,16 +73,16 @@ public class ConsoleAcceptor implements Acceptor {
         }
     }
 
-    private ConsoleReceiver receiver;
+    private ConsoleTransmitter transmitter;
     private PrintWriter writer;
 
     ConsoleAcceptor(InputStream input, OutputStream output) {
-        receiver = new ConsoleReceiver(input);
+        transmitter = new ConsoleTransmitter(input);
         writer = new PrintWriter(output, true);
     }
 
-    public Receiver<String> receiver() {
-        return receiver;
+    public Transmitter<String> transmitter() {
+        return transmitter;
     }
 
     @Override
@@ -165,7 +170,7 @@ public class ConsoleAcceptor implements Acceptor {
 
     @Override
     public void terminate(String params) {
-        receiver.stop();
+        transmitter.stop();
     }
 
     private void console(String name, String params) {
index d699eed..e5a448f 100644 (file)
@@ -61,11 +61,11 @@ public class ConsoleAcceptorRunner implements AcceptorRunner {
         Thread engineThread = new Thread(
                 new Runnable() {
                     public void run() {
-                        Receiver<String> acceptorReceiver = acceptor.receiver();
+                        Transmitter<String> acceptorTransmitter = acceptor.transmitter();
                         try {
-                            while (acceptorReceiver.isActive()) {
-                                if (acceptorReceiver.hasCommand()) {
-                                    String command = acceptorReceiver.receiveCommand();
+                            while (acceptorTransmitter.isActive()) {
+                                if (acceptorTransmitter.hasCommand()) {
+                                    String command = acceptorTransmitter.transmitCommand();
                                     if (command.isEmpty()) continue;
                                     CommandParams commandParams = new CommandParams(command);
                                     commandExecutor.exec(
@@ -74,11 +74,11 @@ public class ConsoleAcceptorRunner implements AcceptorRunner {
                                             commandParams.getParams()
                                     );
                                     if (UCIConstants.QUIT.equals(commandParams.getName()))
-                                        acceptorReceiver.stop();
+                                        acceptorTransmitter.stop();
                                 }
                             }
                         } finally {
-                            acceptorReceiver.close();
+                            acceptorTransmitter.close();
                             isRunning = false;
                         }
                     }
index 7b09fb5..fe4a8c9 100644 (file)
@@ -16,8 +16,9 @@
 
 package org.hedgecode.chess.uci;
 
-import java.io.BufferedWriter;
-import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
 
 /**
  * External UCI Engine.
@@ -27,21 +28,21 @@ import java.io.IOException;
 public class ExternalEngine implements Engine {
 
     private static final String COMMAND_FORMAT = "%s %s";
-    private static final String CRLF = System.getProperty("line.separator");
 
-    private BufferedWriter engineWriter;
+    private Transmitter<String> transmitter;
+    private PrintWriter engineWriter;
 
-    ExternalEngine(BufferedWriter writer) {
-        engineWriter = writer;
+    ExternalEngine(InputStream input, OutputStream output) {
+        transmitter = new ExternalEngineTransmitter(input);
+        engineWriter = new PrintWriter(output, true);
+    }
+
+    public Transmitter<String> transmitter() {
+        return transmitter;
     }
 
     private void write(String command) {
-        try {
-            engineWriter.write(command);
-            engineWriter.write(CRLF);
-            engineWriter.flush();
-        } catch (IOException ignored) {
-        }
+        engineWriter.println(command);
     }
 
     private String format(String name, String params) {
index fd81352..cb84f03 100644 (file)
 
 package org.hedgecode.chess.uci;
 
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
 import java.util.List;
-import java.util.Scanner;
 
 import org.hedgecode.chess.uci.annotation.CommandDirection;
 import org.hedgecode.chess.uci.command.CommandParams;
@@ -39,8 +32,7 @@ public final class ExternalEngineRunner implements EngineRunner {
     private Process process;
     private ProcessBuilder processBuilder;
 
-    private BufferedReader reader;
-    private BufferedWriter writer;
+    private ExternalEngine engine;
 
     private boolean isInit = false;
 
@@ -62,21 +54,14 @@ public final class ExternalEngineRunner implements EngineRunner {
         } catch (IOException e) {
             throw new EngineException("uci.engine.external.start", e.getLocalizedMessage());
         }
-        reader = new BufferedReader(
-                new InputStreamReader(
-                        process.getInputStream()
-                )
-        );
-        writer = new BufferedWriter(
-                new OutputStreamWriter(
-                        process.getOutputStream()
-                )
+
+        engine = new ExternalEngine(
+                process.getInputStream(),
+                process.getOutputStream()
         );
         isInit = true;
 
-        return new ExternalEngine(
-                writer
-        );
+        return engine;
     }
 
     @Override
@@ -87,10 +72,10 @@ public final class ExternalEngineRunner implements EngineRunner {
         Thread engineThread = new Thread(
                 new Runnable() {
                     public void run() {
+                        Transmitter<String> engineTransmitter = engine.transmitter();
                         try {
-                            Scanner scanner = new Scanner(reader);
-                            while (scanner.hasNextLine()) {
-                                String command = scanner.nextLine();
+                            while (engineTransmitter.hasCommand()) {
+                                String command = engineTransmitter.transmitCommand();
                                 if (command.isEmpty()) continue;
                                 CommandParams commandParams = new CommandParams(command);
                                 commandExecutor.exec(
@@ -100,16 +85,15 @@ public final class ExternalEngineRunner implements EngineRunner {
                                 );
                             }
                         } finally {
-                            try {
-                                writer.close();
-                                reader.close();
-                            } catch (IOException ignored) {
-                            }
                             commandExecutor.exec(
                                     UCIConstants.TERMINATE,
                                     CommandDirection.FROM_ENGINE,
                                     null
                             );
+                            engineTransmitter.stop();
+                            engineTransmitter.close();
+                            if (process.isAlive()) process.destroy();
+                            isInit = false;
                         }
                     }
                 }
@@ -117,58 +101,4 @@ public final class ExternalEngineRunner implements EngineRunner {
         engineThread.start();
     }
 
-    public void run() throws IOException, InterruptedException {
-        //Map<String, String> environment = processBuilder.environment();
-        Process process = processBuilder.start();
-        InputStream is = process.getInputStream();
-        BufferedReader br = new BufferedReader(new InputStreamReader(is));
-        OutputStream os = process.getOutputStream();
-        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
-
-        Thread engineThread = new Thread(
-                new Runnable() {
-                    public void run() {
-                        Scanner scanner = new Scanner(br); //
-                        while (scanner.hasNextLine()) {
-                            System.out.println(scanner.nextLine());
-                        }
-/*
-                        String line;
-                        try {
-                            while ((line = br.readLine()) != null) {
-                                System.out.println(line);
-                                bw.write("isready");
-                            }
-                        } catch (IOException e) {
-                            e.printStackTrace();
-                        }
-*/
-                        System.out.println("Engine terminated.");
-                    }
-                }
-        );
-        engineThread.start();
-
-        bw.write("uci\n");
-        bw.flush();
-        bw.write("isready\n");
-        bw.flush();
-        bw.write("quit\n");
-        bw.flush();
-
-        //process.waitFor();
-
-    }
-
-
-    public static void main(String... args) throws Exception {
-/*
-        String[] strings = " uci     test one more test".trim().split("\\s+", 2);
-        for (String string : strings)
-            System.out.println(string);
-*/
-
-        new ExternalEngineRunner("stockfish.exe").run();
-    }
-
 }
diff --git a/src/main/java/org/hedgecode/chess/uci/ExternalEngineTransmitter.java b/src/main/java/org/hedgecode/chess/uci/ExternalEngineTransmitter.java
new file mode 100644 (file)
index 0000000..3a20bb1
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * 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.InputStream;
+import java.util.Scanner;
+
+/**
+ *
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class ExternalEngineTransmitter implements Transmitter<String> {
+
+    private Scanner scanner;
+    private boolean isActive;
+
+    ExternalEngineTransmitter(InputStream input) {
+        scanner = new Scanner(input);
+        isActive = true;
+    }
+
+    @Override
+    public boolean isActive() {
+        return isActive;
+    }
+
+    @Override
+    public boolean hasCommand() {
+        return isActive && scanner.hasNextLine();
+    }
+
+    @Override
+    public String transmitCommand() {
+        return scanner.nextLine();
+    }
+
+    @Override
+    public void addCommand(String command) {
+        // not supported for external engine
+    }
+
+    @Override
+    public void stop() {
+        isActive = false;
+    }
+
+    @Override
+    public void close() {
+        scanner.close();
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/uci/Receiver.java b/src/main/java/org/hedgecode/chess/uci/Receiver.java
deleted file mode 100644 (file)
index e135642..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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;
-
-/**
- *
- *
- * @author Dmitry Samoshin aka gotty
- */
-public interface Receiver<T> {
-
-    boolean isActive();
-
-    boolean hasCommand();
-
-    T receiveCommand();
-
-    void stop();
-
-    void close();
-
-}