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; }
|
|
|
|
}
|
|
|
|
|
|
|
|
public Color _active_color = Color.WHITE;
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|