I'm writing a simple command line tool to send data by UDP once per second forever, to test some software on another machine. Not actually forever, of course, but until ^C or I hit 'Q'. I want to tap keys to make other things happen, like change the data or rate of sending.

Not sure of the best way to do this. Thought I'd try a thread whose job is just to loop, calling readln() or getch() or something similar, and setting a global variables according to what key was tapped. The loop in the main thread can then break, or do some other action, according to the value of that variable.

Code I have written is below, stripped to just the stuff relevant to key watching. It doesn't work. When it runs, it prints "Repetitive work" over and over, but never see anything appear in "cmd [ ]". When I tap 'A' I expect to see "cmd [A]" and a line of several 'A'. This does not happen. But the writeln in cmdwatcher() does show whatever I typed just fine.

How to fix this, or redesign the whole thing to work?

Note that I'm coming from science and fine art. My know-how in computer science is uneven, and I probably have gaps in my knowledge about threads.


import std.stdio;
import core.stdc.stdio; // for getchar(). There's nothing similar in D std libs?
import std.concurrency;
import core.thread; // just for sleep()

bool running=true;
char command = '?';

void cmdwatcher()
{
    writeln("Key Watcher");
    while (running)  {
        char c = cast(char)getchar();
        if (c>=' ')  {
            command = c;
            writefln("     key %c  %04X", c, c);
        }
    }
}

void main()
{
    writeln("Start main");
    spawn(&cmdwatcher);

    while (running) {
        writeln("Repetitive work");
        Thread.sleep( dur!("msecs")( 900 ) );

char cmd = command; // local copy can't change during rest of this loop
        command = ' ';
        writefln("cmd [%c]  running %d", cmd, running);

        switch (cmd)
        {
            case 'A':
                    writeln("A A A A A");
                    break;

            case 'Q':
                    writeln("Quitting");
                    running=false;
                    break;
            default:
                break;
        }
    }
}





Reply via email to