Simple linear move list.
[kaya.git] / lib / history.rb
blobe28a9a845e43af261f04cc945b6de5b0c72affb6
1 require 'observer_utils.rb'
3 class History < Qt::AbstractListModel
4   include Enumerable
5   include Observer
6   include ModelUtils
7   
8   attr_reader :current
9   
10   Item = Struct.new(:state, :move, :text)
11   OutOfBound = Class.new(Exception)
13   def initialize(state)
14     super(nil)
15     @history = [Item.new(state.dup, nil, "Mainline")]
16     @current = 0
17   end
18   
19   def each
20     @history.each {|item| yield item.state, item.move }
21   end
22   
23   def add_move(state, move)
24     item = Item.new(state.dup, move, nil)
25     
26     removing_rows(nil, @current + 1, @history.size - 1) do
27       @history = @history[0..@current]
28     end
30     inserting_rows(nil, @current + 1, @current + 1) do
31       @history << item
32       @current = @history.size - 1
33     end
34   end
35   
36   def forward
37     raise OutOfBound if @current >= @history.size - 1
38     @current += 1
39     item = @history[@current]
40     [item.state, item.move]
41   end
42   
43   def back
44     raise OutOfBound if @current <= 0
45     move = @history[@current].move
46     @current -= 1
47     [@history[@current].state, move]
48   end
49   
50   def state
51     @history[current].state
52   end
53   
54   def move
55     @history[current].move
56   end
57   
58   def size
59     @history.size
60   end
61   
62   def [](index)
63     @history[index]
64   end
65   
66   # model interface
67   
68   # set a serializer for this model
69   # if no serializer has been set, it will
70   # be impossible to use it with a view
71   def serializer=(ser)
72     @serializer = ser
73   end
74   
75   def data(index, role)
76     if @serializer and role == Qt::DisplayRole
77       unless @history[index.row].text
78         state = @history[index.row - 1].state
79         move = @history[index.row].move
80         san = @serializer.serialize(move, state)
81         
82         count = index.row / 2 + 1
83         dots = if index.row % 2 == 0
84           '.'
85         else
86           '...'
87         end
88         
89         @history[index.row].text = "#{count}#{dots} #{san}"
90       end
91       @history[index.row].text
92     end
93   end
94   
95   def rowCount(parent)
96     size
97   end
98   
99 end