gnome-chess/src/chess-clock.vala

154 lines
3.5 KiB
Vala
Raw Normal View History

2011-01-06 22:10:29 +00:00
public class ChessClock : Object
{
2011-01-07 04:20:27 +00:00
private uint _white_duration;
public uint white_duration
{
get { return _white_duration; }
}
private uint _black_duration;
public uint black_duration
{
get { return _black_duration; }
}
private uint _white_used;
public uint white_used
{
get
{
if (active_color == Color.WHITE)
return _white_used + (uint) (timer.elapsed () * 1000);
else
return _white_used;
}
}
public uint white_used_in_seconds
{
get { return (white_used + 500) / 1000; }
}
private uint _black_used;
public uint black_used
{
get
{
if (active_color == Color.WHITE)
return _black_used;
else
return _black_used + (uint) (timer.elapsed () * 1000);
}
}
public uint black_used_in_seconds
{
get { return (black_used + 500) / 1000; }
}
private Color _active_color = Color.WHITE;
2011-01-07 04:20:27 +00:00
public Color active_color
{
get { return _active_color; }
set
{
if (value == active_color)
return;
stop ();
_active_color = value;
start ();
}
}
2011-01-06 22:10:29 +00:00
private Timer timer;
2011-01-07 04:20:27 +00:00
private uint expire_timeout = 0;
private uint tick_timeout = 0;
2011-01-06 22:10:29 +00:00
public signal void tick ();
public signal void expired ();
public ChessClock (uint white_duration, uint black_duration, uint white_used = 0, uint black_used = 0)
{
2011-01-07 04:20:27 +00:00
_white_duration = white_duration * 1000;
_black_duration = black_duration * 1000;
_white_used = white_used;
_black_used = black_used;
2011-01-06 22:10:29 +00:00
timer = new Timer ();
}
2011-01-07 04:20:27 +00:00
private bool is_started
{
get { return expire_timeout != 0; }
}
2011-01-06 22:10:29 +00:00
public void start ()
{
2011-01-07 04:20:27 +00:00
if (is_started)
2011-01-06 22:10:29 +00:00
return;
2011-01-07 04:20:27 +00:00
/* Start stopwatch */
timer.start ();
/* Notify when this timer has expired */
2011-01-06 22:10:29 +00:00
if (active_color == Color.WHITE)
2011-01-07 04:20:27 +00:00
expire_timeout = Timeout.add (white_duration - _white_used, timer_expired_cb);
2011-01-06 22:10:29 +00:00
else
2011-01-07 04:20:27 +00:00
expire_timeout = Timeout.add (black_duration - _black_used, timer_expired_cb);
2011-01-06 22:10:29 +00:00
2011-01-07 04:20:27 +00:00
/* Wake up each second */
tick_cb ();
2011-01-06 22:10:29 +00:00
}
private bool timer_expired_cb ()
{
2011-01-07 04:20:27 +00:00
stop ();
2011-01-06 22:10:29 +00:00
expired ();
return false;
}
2011-01-07 04:20:27 +00:00
private bool tick_cb ()
2011-01-06 22:10:29 +00:00
{
2011-01-07 04:20:27 +00:00
if (tick_timeout != 0)
tick ();
2011-01-06 22:10:29 +00:00
2011-01-07 04:20:27 +00:00
uint elapsed = (uint) (timer.elapsed () * 1000);
uint used;
2011-01-06 22:10:29 +00:00
if (active_color == Color.WHITE)
2011-01-07 04:20:27 +00:00
used = _white_used + elapsed;
2011-01-06 22:10:29 +00:00
else
2011-01-07 04:20:27 +00:00
used = _black_used + elapsed;
var next_tick_time = ((used / 1000) + 1) * 1000;
tick_timeout = Timeout.add (next_tick_time - used, tick_cb);
return false;
2011-01-06 22:10:29 +00:00
}
2011-01-07 04:20:27 +00:00
public void stop ()
2011-01-06 22:10:29 +00:00
{
2011-01-07 04:20:27 +00:00
if (!is_started)
2011-01-06 22:10:29 +00:00
return;
2011-01-07 04:20:27 +00:00
timer.stop ();
Source.remove (expire_timeout);
expire_timeout = 0;
Source.remove (tick_timeout);
tick_timeout = 0;
var elapsed = (uint) (timer.elapsed () * 1000);
if (active_color == Color.WHITE)
{
_white_used += elapsed;
if (_white_used > white_duration)
_white_used = white_duration;
}
else
{
_black_used += elapsed;
if (_black_used > black_duration)
_black_used = black_duration;
}
timer.reset ();
2011-01-06 22:10:29 +00:00
}
}