@@ -22,129 +22,148 @@ function check_api_version()
2222 end
2323end
2424
25- function show_error (errorMsg )
25+ function show_error (error_msg )
2626 local error_dialog = Dialog (" Error" )
2727 error_dialog
28- :label { text = errorMsg }
28+ :label { text = error_msg }
2929 :newrow ()
3030 :button { text = " Close" , onclick = function () error_dialog :close () end }
3131 error_dialog :show ()
3232end
3333
34- -- Core functions
35- local function initialize_snapshot (self , sprite )
36- self .auto_snap_enabled = false
37- self .auto_snap_delay = 1
38- self .auto_snap_increment = 0
39- self .context = nil
40-
41- -- Instance of Aseprite Sprite object
42- -- https://github.com/aseprite/api/blob/master/api/sprite.md#sprite
43- self .sprite = nil
44- if sprite then
45- self .sprite = sprite
46- self .context = get_recording_context (sprite )
34+ local function get_active_frame_number ()
35+ local frame = app .activeFrame
36+ if frame == nil then
37+ return 1
38+ else
39+ return frame
4740 end
4841end
4942
50- local function get_snapshot_recording_index (self )
51- local path = self .context .index_file
43+ RecordingContext = {}
44+
45+ function RecordingContext :get_recording_index ()
46+ local path = self .index_file
5247 if not app .fs .isFile (path ) then
5348 return 0
5449 end
5550 local file = io.open (path , " r" )
51+ assert (file )
5652 local contents = file :read ()
5753 io.close (file )
5854 return tonumber (contents )
5955end
6056
61- local function increment_snapshot_recording_index (self )
62- local index = get_snapshot_recording_index (self ) + 1
63- local path = self .context .index_file
57+ function RecordingContext :set_recording_index (index )
58+ local path = self .index_file
6459 local file = io.open (path , " w" )
60+ assert (file )
6561 file :write (" " .. index )
6662 io.close (file )
6763end
6864
69- local function get_active_frame_number ()
70- local frame = app .activeFrame
71- if frame == nil then
72- return 1
73- else
74- return frame
75- end
76- end
77-
78- function get_recording_context (sprite )
65+ function RecordingContext .new (sprite )
7966 local self = {}
67+ setmetatable (self , { __index = RecordingContext })
8068 self .sprite_file_name = app .fs .fileTitle (sprite .filename )
8169 self .sprite_file_path = app .fs .filePath (sprite .filename )
70+ self :_init_directory ()
71+ self .index_file = app .fs .joinPath (self .record_directory_path , " _index.txt" )
72+ self :_promote_v2_to_v3 ()
73+ return self
74+ end
8275
83- -- 2.x Target Directory Backwards Compatibility
84- self .record_directory_name_legacy = self .sprite_file_name .. " _record"
85- local is_legacy_recording = false
86- if app .fs .isDirectory (app .fs .joinPath (self .sprite_file_path , self .record_directory_name_legacy )) then
87- is_legacy_recording = true
88- self .record_directory_name = self .record_directory_name_legacy
76+ function RecordingContext :_init_directory ()
77+ local dir_name_legacy = self .sprite_file_name .. " _record"
78+ local dir_path_legacy = app .fs .joinPath (self .sprite_file_path , dir_name_legacy )
79+ if app .fs .isDirectory (dir_path_legacy ) then
80+ -- For 2.x Target Directory Backwards Compatibility
81+ self ._is_legacy_recording = true
82+ self .record_directory_name = dir_name_legacy
8983 else
84+ self ._is_legacy_recording = false
9085 self .record_directory_name = self .sprite_file_name .. " __record"
9186 end
9287
9388 self .record_directory_path = app .fs .joinPath (self .sprite_file_path , self .record_directory_name )
94- self . index_file = app . fs . joinPath ( self . record_directory_path , " _index.txt " )
89+ end
9590
91+ function RecordingContext :_promote_v2_to_v3 ()
92+ if not self ._is_legacy_recording then
93+ return -- Is not v2.x
94+ end
95+ if app .fs .isFile (self .index_file ) then
96+ return -- Is v2.x, but already has promoted structure
97+ end
9698 -- 2.x Add Missing Index File for Forward Compatibility
97- if is_legacy_recording and not app .fs .isFile (self .index_file ) then
98- local is_index_set = false
99- local current_index = 0
100- while not is_index_set do
101- if not app .fs .isFile (get_contextual_recording_image_path (self , current_index )) then
102- is_index_set = true
103- local file = io.open (self .index_file , " w" )
104- file :write (" " .. current_index )
105- io.close (file )
106- else
107- current_index = current_index + 1
108- end
99+ local is_index_set = false
100+ local current_index = 0
101+ while not is_index_set do
102+ if not app .fs .isFile (self :get_recording_image_path (current_index )) then
103+ is_index_set = true
104+ self .context :set_recording_index (current_index )
105+ else
106+ current_index = current_index + 1
109107 end
110108 end
111-
112- return self
113109end
114110
115- function get_contextual_recording_image_path ( self , index )
111+ function RecordingContext : get_recording_image_path ( index )
116112 return app .fs .joinPath (self .record_directory_path , self .sprite_file_name .. " _" .. index .. " .png" )
117113end
118114
119- function get_recording_image_path_at_index (self , index )
120- return get_contextual_recording_image_path (self .context , index )
115+ Snapshot = {}
116+
117+ function Snapshot :_initialize (sprite )
118+ self .auto_snap_enabled = false
119+ self .auto_snap_delay = 1
120+ self .auto_snap_increment = 0
121+ self .context = nil
122+
123+ -- Instance of Aseprite Sprite object
124+ -- https://github.com/aseprite/api/blob/master/api/sprite.md#sprite
125+ self .sprite = nil
126+ if sprite then
127+ self .sprite = sprite
128+ self .context = RecordingContext .new (sprite )
129+ end
130+ end
131+
132+ function Snapshot :_increment_recording_index ()
133+ local index = self .context :get_recording_index (self ) + 1
134+ self .context :set_recording_index (index )
135+ end
136+
137+ function Snapshot :get_recording_image_path (index )
138+ return self .context :get_recording_image_path (index )
121139end
122140
123- function get_snapshot ()
141+ function Snapshot . new ()
124142 local self = {}
125- initialize_snapshot (self , nil )
143+ setmetatable (self , { __index = Snapshot })
144+ self :_initialize (nil )
126145 return self
127146end
128147
129- function is_snapshot_active ( self )
130- if not is_snapshot_valid ( self ) then
148+ function Snapshot : is_active ( )
149+ if not self : is_valid ( ) then
131150 return false
132151 end
133152 return self .auto_snap_enabled
134153end
135154
136- function is_snapshot_valid ( self )
155+ function Snapshot : is_valid ( )
137156 if self .sprite then
138157 return true
139158 end
140159 return false
141160end
142161
143- function reset_snapshot ( self )
144- initialize_snapshot ( self , nil )
162+ function Snapshot : reset ( )
163+ self : _initialize ( nil )
145164end
146165
147- function auto_save_snapshot ( self )
166+ function Snapshot : auto_save ( )
148167 if not self .auto_snap_enabled then
149168 return
150169 end
@@ -157,31 +176,65 @@ function auto_save_snapshot(self)
157176 return
158177 end
159178 self .auto_snap_increment = 0
160- save_snapshot ( self )
179+ self : save ( )
161180end
162181
163- function save_snapshot (self )
164- local path = get_recording_image_path_at_index (self , get_snapshot_recording_index (self ))
182+ function Snapshot :_get_current_image ()
165183 local image = Image (self .sprite )
166184 image :drawSprite (self .sprite , get_active_frame_number ())
185+ return image
186+ end
187+
188+ function Snapshot :_get_saved_image_content (index )
189+ if index < 0 then
190+ return nil
191+ end
192+ local path = self :get_recording_image_path (index )
193+ if not app .fs .isFile (path ) then
194+ return nil
195+ end
196+ local file = io.open (path , " rb" )
197+ assert (file )
198+ local content = file :read (" a" )
199+ io.close (file )
200+ return content
201+ end
202+
203+ function Snapshot :save ()
204+ local image = self :_get_current_image ()
205+ local index = self .context :get_recording_index ()
206+ local path = self :get_recording_image_path (index )
167207 image :saveAs (path )
168- increment_snapshot_recording_index (self )
208+
209+ local image_changed = true
210+ local prev_content = self :_get_saved_image_content (index - 1 )
211+ if prev_content ~= nil then
212+ local curr_content = self :_get_saved_image_content (index )
213+ assert (curr_content ~= nil )
214+ if prev_content == curr_content then
215+ image_changed = false
216+ end
217+ end
218+
219+ if image_changed then
220+ self :_increment_recording_index ()
221+ end
169222end
170223
171- function set_snapshot_sprite ( self , sprite )
224+ function Snapshot : set_sprite ( sprite )
172225 if not app .fs .isFile (sprite .filename ) then
173226 return show_error (error_messages .save_required )
174227 end
175228
176229 if (not self .sprite or self .sprite ~= sprite ) then
177- initialize_snapshot ( self , sprite )
230+ self : _initialize ( sprite )
178231 end
179232end
180233
181- function update_snapshot_sprite ( self )
234+ function Snapshot : update_sprite ( )
182235 local sprite = app .activeSprite
183236 if not sprite then
184237 return show_error (error_messages .no_active_sprite )
185238 end
186- set_snapshot_sprite ( self , sprite )
239+ self : set_sprite ( sprite )
187240end
0 commit comments