OSDN Git Service

fix play leaf
[pettanr/pettanr.git] / lib / peta / leaf.rb
1 module Peta
2   class Leaf < Content
3     self.abstract_class = true
4     
5     # Dynamic ClassMethods
6     
7     def self.load_manifest
8       super
9       return nil if self._skip_load?
10       # Class Methods
11       pm = Manifest.manifest.models[self.my_peta.parent_model_name].classify
12       define_singleton_method("parent_model") do 
13         pm
14       end
15       pfk = self.my_peta.parent_model_name + '_id'
16       define_singleton_method("binder_key") do 
17         pfk
18       end
19       # Instance Methods
20     end
21     
22     def self.element?
23       true
24     end
25     
26     def self.root_model
27       self.parent_model
28     end
29     
30     def root
31       self.__send__ self.class.root_model.item_name
32     end
33     
34     def own? operators
35       self.root.own? operators
36     end
37     
38     # super return if my item
39     def visible? operators
40       return false if super == false
41       self.root.visible? operators
42     end
43     
44     def self.play_list_where cid
45       ['scroll_panels.scroll_id = ?', cid]
46     end
47     
48     def self.play_list_order
49       'story_sheets.t'
50     end
51     
52     def self.play_list scroll, author, offset = 0, limit = ScrollPanel.default_panel_size
53       ScrollPanel.where(self.play_list_where(scroll.id)).includes(ScrollPanel.list_opt).order('scroll_panels.t').offset(offset).limit(limit)
54     end
55     
56     def self.play_sheet_where sid
57       ['story_sheets.story_id = ?', sid]
58     end
59     
60     def self.play_sheet story, operators, page = 1
61       ss = StorySheet.where(self.play_sheet_where(story.id)).includes(StorySheet.list_opt).order('story_sheets.t').offset(page -1).limit(1).first
62       if ss 
63         if ss.sheet
64           Sheet.show(ss.sheet.id, operators)
65         else
66           nil
67         end
68       else
69         nil
70       end
71     end
72     
73     def self.play_paginate story, page
74       Kaminari.paginate_array(Array.new(StorySheet.where(self.play_sheet_where(story.id)).includes(StorySheet.list_opt).count, nil)).page(page).per(1)
75     end
76     
77     def self.new_t binder_id
78       r = self.max_t(binder_id)
79       r.blank? ? 0 : r.to_i + 1
80     end
81     
82     def self.max_t binder_id
83       self.maximum(:t, :conditions => [self.binder_key + ' = ?', binder_id])
84     end
85     
86     def self.find_t binder_id, t
87       self.find(:first, :conditions => [self.binder_key + ' = ? and t = ?', binder_id, t])
88     end
89     
90     def self.collect_t binder_id
91       r = self.find(:all, :conditions => [self.binder_key + ' = ?', binder_id], :order => 't')
92       r.map {|sp| sp.t}
93     end
94     
95     def self.top_sheet story, author
96       StorySheet.play_list(story, author).first
97     end
98     
99     def self.serial? ary
100       i = 0
101       ary.compact.sort.each do |t|
102         break false unless t == i
103         i += 1
104       end
105       ary.compact.size == i
106     end
107     
108     def self.validate_t binder_id
109       self.serial?(self.collect_t(binder_id))
110     end
111     
112     def binder_key
113       self.class.binder_key
114     end
115     
116     def binder_id
117       self.attributes[self.binder_key]
118     end
119     
120     def insert_shift
121       self.class.update_all('t = t + 1', 
122         [self.binder_key + ' = ? and t >= ?', self.binder_id, self.t]
123       )
124     end
125     
126     def lesser_shift old_t
127       self.t = 0 if self.t < 0
128       self.class.update_all('t = t + 1', 
129         [self.binder_key + ' = ? and (t >= ? and t < ?)', self.binder_id, self.t, old_t]
130       )
131     end
132     
133     def higher_shift old_t
134       nf = self.class.find_t(self.binder_id, self.t)
135       max_t = self.class.max_t(self.binder_id).to_i
136       self.t = max_t if self.t > max_t
137       self.class.update_all('t = t - 1', 
138         [self.binder_key + ' = ? and (t > ? and t <= ?)', self.binder_id, old_t, self.t]
139       )
140     end
141     
142     def update_shift old_t
143       if self.t > old_t
144         higher_shift old_t
145       else
146         lesser_shift old_t
147       end
148     end
149     
150     def rotate old_t = nil
151       if self.new_record?
152         if self.t.blank?
153           self.t = self.class.new_t self.binder_id
154         else
155           self.insert_shift
156         end
157       else
158         if self.t.blank?
159         else
160           self.update_shift old_t
161         end
162       end
163     end
164     
165     def destroy_and_shorten
166       res = false
167       self.class.transaction do
168         self.class.update_all('t = t - 1', 
169           [self.binder_key + ' = ? and (t > ?)', self.binder_id, self.t]
170         )
171         raise ActiveRecord::Rollback unless self.destroy
172         res = true
173       end
174       res
175     end
176     
177   end
178 end
179