Skip to content

Commit c9f644b

Browse files
authored
Merge pull request #8 from thomaseding/teding/feat/compression
Teding/feat/compression
2 parents b44b2c0 + 4487381 commit c9f644b

File tree

5 files changed

+142
-90
lines changed

5 files changed

+142
-90
lines changed

.lib/record-core.lua

Lines changed: 123 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -22,129 +22,148 @@ function check_api_version()
2222
end
2323
end
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()
3232
end
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
4841
end
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)
5955
end
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)
6763
end
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
113109
end
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")
117113
end
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)
121139
end
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
127146
end
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
134153
end
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
141160
end
142161

143-
function reset_snapshot(self)
144-
initialize_snapshot(self, nil)
162+
function Snapshot:reset()
163+
self:_initialize(nil)
145164
end
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()
161180
end
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
169222
end
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
179232
end
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)
187240
end

Automatic Snapshot.lua

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77

88
dofile(".lib/record-core.lua")
99

10-
local snapshot = get_snapshot()
10+
local snapshot = Snapshot.new()
1111

1212
local function take_auto_snapshot()
13-
auto_save_snapshot(snapshot)
13+
snapshot:auto_save()
1414
end
1515

1616
local function disable_auto_snapshot(dialog)
1717
snapshot.auto_snap_enabled = false
18-
if not is_snapshot_valid(snapshot) then
18+
if not snapshot:is_valid() then
1919
return
2020
end
2121

@@ -32,9 +32,9 @@ local function disable_auto_snapshot(dialog)
3232
end
3333

3434
local function enable_auto_snapshot(dialog)
35-
update_snapshot_sprite(snapshot)
35+
snapshot:update_sprite()
3636

37-
snapshot.auto_snap_enabled = is_snapshot_valid(snapshot)
37+
snapshot.auto_snap_enabled = snapshot:is_valid()
3838
if not snapshot.auto_snap_enabled then
3939
return
4040
end
@@ -60,7 +60,7 @@ if check_api_version() then
6060
local main_dialog = Dialog {
6161
title = "Record - Auto Snapshot",
6262
onclose = function()
63-
reset_snapshot(snapshot)
63+
snapshot:reset()
6464
end
6565
}
6666

@@ -89,7 +89,7 @@ if check_api_version() then
8989
id = "toggle",
9090
text = "Start",
9191
onclick = function()
92-
if is_snapshot_active(snapshot) then
92+
if snapshot:is_active() then
9393
disable_auto_snapshot(main_dialog)
9494
else
9595
enable_auto_snapshot(main_dialog)

Command Palette.lua

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,23 @@
77

88
dofile(".lib/record-core.lua")
99

10-
local snapshot = get_snapshot()
10+
local snapshot = Snapshot.new()
1111

1212
local function take_snapshot()
13-
update_snapshot_sprite(snapshot)
14-
if not is_snapshot_valid(snapshot) then
13+
snapshot:update_sprite()
14+
if not snapshot:is_valid() then
1515
return
1616
end
17-
18-
save_snapshot(snapshot)
17+
snapshot:save()
1918
end
2019

2120
local function open_time_lapse()
22-
update_snapshot_sprite(snapshot)
23-
if not is_snapshot_valid(snapshot) then
21+
snapshot:update_sprite()
22+
if not snapshot:is_valid() then
2423
return
2524
end
2625

27-
local path = get_recording_image_path_at_index(snapshot, 0)
26+
local path = snapshot:get_recording_image_path(0)
2827
if app.fs.isFile(path) then
2928
app.command.OpenFile { filename = path }
3029
else

Open Time Lapse.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ dofile(".lib/record-core.lua")
1010
if check_api_version() then
1111
local sprite = app.activeSprite
1212
if sprite and app.fs.isFile(sprite.filename) then
13-
local context = get_recording_context(sprite)
14-
local path = get_contextual_recording_image_path(context, 0)
13+
local context = RecordingContext.new(sprite)
14+
local path = context:get_recording_image_path(0)
1515
if app.fs.isFile(path) then
1616
app.command.OpenFile { filename = path }
1717
else

Take Snapshot.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ dofile(".lib/record-core.lua")
1010
if check_api_version() then
1111
local sprite = app.activeSprite
1212
if sprite and app.fs.isFile(sprite.filename) then
13-
local snapshot = get_snapshot()
14-
set_snapshot_sprite(snapshot, sprite)
15-
save_snapshot(snapshot)
13+
local snapshot = Snapshot.new()
14+
snapshot:set_sprite(sprite)
15+
snapshot:save()
1616
else
1717
return show_error(error_messages.save_required)
1818
end

0 commit comments

Comments
 (0)