nodejs read keyboard buffer issue

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
maksimKorzh
Posts: 771
Joined: Sat Sep 08, 2018 5:37 pm
Location: Ukraine
Full name: Maksim Korzh

nodejs read keyboard buffer issue

Post by maksimKorzh »

Hi guys

Today I've finally managed to connect my javascript chess engine running in nodejs via UCI to arena GUI.
The problem is I can't figure out how properly to read keyboard buffer to be able to stop engine from searching on demand ('quit' or 'stop')
I know I can use child process and interact via messages but this assumes that engine would be in separate file from the uci loop one
and I don't want that, so I'm trying to implement good all schema when every 2047 nodes communicate() fires and within that function
we read keyboard input.

Here's code in C that works for me:

Code: Select all

int input_waiting()
{
    #ifndef WIN32
        fd_set readfds;
        struct timeval tv;
        FD_ZERO (&readfds);
        FD_SET (fileno(stdin), &readfds);
        tv.tv_sec=0; tv.tv_usec=0;
        select(16, &readfds, 0, 0, &tv);

        return (FD_ISSET(fileno(stdin), &readfds));
    #else
        static int init = 0, pipe;
        static HANDLE inh;
        DWORD dw;

        if (!init)
        {
            init = 1;
            inh = GetStdHandle(STD_INPUT_HANDLE);
            pipe = !GetConsoleMode(inh, &dw);
            if (!pipe)
            {
                SetConsoleMode(inh, dw & ~(ENABLE_MOUSE_INPUT|ENABLE_WINDOW_INPUT));
                FlushConsoleInputBuffer(inh);
            }
        }
        
        if (pipe)
        {
           if (!PeekNamedPipe(inh, NULL, 0, NULL, &dw, NULL)) return 1;
           return dw;
        }
        
        else
        {
           GetNumberOfConsoleInputEvents(inh, &dw);
           return dw <= 1 ? 0 : dw;
        }

    #endif
}
So I've started looking for nodejs equivalent, but process.stdin.on('keypress') seems to be deprecated in latest nodejs versions so I found
"keypress" module that restores old nodejs binding and I can actually listen on keypresses assuming that console is set to the raw mode.

Now my issue is that I can't "listen" on keypress when my communicate() fires - all the keypresses are getting handled but only after search
(in my case I'm testing it with perft, but that doesn't matter) is finished. So here's the code:

Code: Select all

  function communicate() {
    //console.log('communicate');
    readKeyboard();
  }

  function readKeyboard() {
    
    console.log('read keyboard')
    
    // listen for the "keypress" event
    process.stdin.on('keypress', function (ch, key) {
      console.log('got "keypress"', key);
      if (key && key.ctrl && key.name == 'c') {
        process.exit();
      }
    });

    process.stdin.setRawMode(true);
    process.stdin.resume();
  }
in the above code, say I'm running perft, every 2047 communicate() fires, then readKeyboard() fires and then I see message: "read keyboard" BUT
process.stdin.on('keypress',...) gets handled only after perft is finished.

So my question is: how can I read single key presses during communicate() ?
User avatar
maksimKorzh
Posts: 771
Joined: Sat Sep 08, 2018 5:37 pm
Location: Ukraine
Full name: Maksim Korzh

Re: nodejs read keyboard buffer issue

Post by maksimKorzh »

Ok... I didn't do much still - I only managed to kill the child process in node js on GUI's "quit" or "stop" command, but no way to
interrupt search function to return bestmove on demand. If anyone is aware how that can be done in nodejs please kindly let me know.
jwilson82
Posts: 9
Joined: Tue Oct 06, 2015 5:00 pm

Re: nodejs read keyboard buffer issue

Post by jwilson82 »

https://nodejs.org/api/worker_threads.html

Seems like this would let you do what you want. Parse the input in a worker thread and set a stop variable when the promise resolves?
User avatar
maksimKorzh
Posts: 771
Joined: Sat Sep 08, 2018 5:37 pm
Location: Ukraine
Full name: Maksim Korzh

Re: nodejs read keyboard buffer issue

Post by maksimKorzh »

jwilson82 wrote: Sat Dec 19, 2020 6:56 pm https://nodejs.org/api/worker_threads.html

Seems like this would let you do what you want. Parse the input in a worker thread and set a stop variable when the promise resolves?
I've researched other JS engines - none of them seems to be implementing this feature.
This worker thread is interesting, thanks for sharing)
Btw, you can have a look at more less completed initial release:
https://github.com/maksimKorzh/wukongJS