Witam. Szybko i zwięźle, oto kod:
#include <iostream>
#include <string>
#include <sstream>
#include <sys/types.h>
#include <sys/time.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
using namespace std;
#define WHITESPACE " \t\n\r"
template<typename type>
inline string ToString (type p_thing)
{
stringstream result;
result << p_thing;
return result.str();
}
void TrimWhitespace (string& p_string)
{
int wsf;
int wsb;
wsf = p_string.find_first_not_of(WHITESPACE);
wsb = p_string.find_last_not_of(WHITESPACE);
if (wsf == (signed int)string::npos)
{
wsf = 0;
wsb = -1;
}
p_string = p_string.substr(wsf, wsb - wsf + 1);
}
int main (int argc, char **argv)
{
char buffer[2048];
string in_buffer;
string out_buffer;
int pulse = 1;
int select_result;
int read_result;
fd_set inputs;
fd_set testfds;
struct timeval timeout;
struct timeval last_sleep;
struct timeval sleep_time;
struct timeval now_time;
int secs;
int usecs;
const int pps = 5;
FD_ZERO(&inputs);
FD_SET(0,&inputs);
gettimeofday(&last_sleep, NULL);
while (true)
{
testfds = inputs;
// 1 sec = 1 000 000 usec
timeout.tv_sec = 1;
timeout.tv_usec = 0;
select_result = select(FD_SETSIZE, &testfds, (fd_set*)0, (fd_set*)0, &timeout);
// Jeżeli nic nie dostaliśmy...
if (select_result == 0)
{
}
// Jeżeli stracono połączenie...
else if (select_result == -1)
{
// select error
return 1;
}
// Jeżeli coś dostaliśmy...
else if (FD_ISSET(0,&testfds))
{
ioctl(0, FIONREAD, &read_result);
// Jeżeli... CO?
if (read_result == 0)
{
// keyboard done
return 0;
}
read_result = read(0, buffer, read_result);
buffer[read_result] = 0;
in_buffer = buffer;
TrimWhitespace(in_buffer);
pulse++;
}
// Jeżeli niczego nie dostaliśmy...
if (in_buffer.empty())
{
out_buffer += "\nŚwiat się kręci... To już ";
out_buffer += ToString(pulse);
out_buffer += ". sekunda!";
out_buffer += "\n\n<prompt> ";
pulse++;
}
// ...w przeciwnym wypadku...
else
{
out_buffer += "Dostałem " + in_buffer + "!";
out_buffer += "\n\n<prompt> ";
in_buffer.erase();
}
// Jeżeli jest coś do wysłania...
if (!out_buffer.empty())
{
write(0, out_buffer.c_str(), out_buffer.size());
out_buffer.erase();
}
// Obsługa drzemania
if (pps > 0)
{
gettimeofday(&now_time, NULL);
// Policz ile czasu trzeba się zdrzemnąć
usecs = (int) (last_sleep.tv_usec - now_time.tv_usec) + 1000000 / pps;
secs = (int) (last_sleep.tv_sec - now_time.tv_sec);
while (usecs < 0)
{
usecs += 1000000;
secs -= 1;
}
while (usecs >= 1000000)
{
usecs -= 1000000;
secs += 1;
}
// Zdrzemnij się, jeśli to konieczne
if (secs > 0 || (secs == 0 && usecs > 0))
{
sleep_time.tv_usec = usecs;
sleep_time.tv_sec = secs;
select(0, NULL, NULL, NULL, &sleep_time);
}
// Zapamiętaj czas ostatniej drzemki
gettimeofday(&last_sleep, NULL);
}
}
return 0;
}
Co zrobić, żeby "świat" nie "przyspieszał" kiedy użytkownik np. przytrzyma Enter? Prosiłbym o konkretne rozwiązania, zamiast lakonicznych "man select"... ;-) Z góry dzięki,