Skip to content

Commit 2083b26

Browse files
committed
update Cargo.lock for 1.4.1
1 parent ded037a commit 2083b26

6 files changed

Lines changed: 49 additions & 16 deletions

File tree

lib/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "aseprite-dmi"
3-
version = "1.4.0"
3+
version = "1.4.1"
44
edition = "2021"
55
repository = "https://github.com/spacestation13/aseprite-dmi"
66

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "asprite-dmi",
33
"displayName": "DMI Editor",
44
"description": "DMI Editor Extension for Aseprite",
5-
"version": "1.4.0",
5+
"version": "1.4.1",
66
"contributors": [
77
{
88
"name": "Seefaaa",

scripts/classes/editor/_editor.lua

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
--- @field widgets (AnyWidget)[] A table containing all state widgets.
1717
--- @field selected_states State[] Selected icon widgets to possibly combine.
1818
--- @field context_widget ContextWidget|nil The state that is currently being right clicked
19-
--- @field beforecommand number The event object for the "beforecommand" event.
20-
--- @field aftercommand number The event object for the "aftercommand" event.
2119
--- @field dialog Dialog The dialog object.
2220
--- @field save_path string|nil The path of the file to be saved.
2321
--- @field open_path string|nil The path of the file to be opened.
@@ -68,10 +66,6 @@ function Editor.new(title, dmi)
6866

6967
self.image_cache = ImageCache.new()
7068

71-
self.beforecommand = app.events:on("beforecommand", function(ev) self:onbeforecommand(ev) end)
72-
73-
self.aftercommand = app.events:on("aftercommand", function(ev) self:onaftercommand(ev) end)
74-
7569
self:new_dialog(title)
7670
self:show()
7771

@@ -215,24 +209,22 @@ function Editor:close(event, force)
215209
libdmi.remove_dir(self.dmi.temp, false)
216210
end
217211

212+
-- Close sprites first to release file locks, then remove temp directory
218213
self:gc_open_sprites()
219214
for _, state_sprite in ipairs(self.open_sprites) do
220215
if state_sprite.sprite and Editor.is_sprite_open(state_sprite.sprite) then
221216
state_sprite.sprite:close()
222217
end
223218
end
224219

225-
app.events:off(self.beforecommand)
226-
app.events:off(self.aftercommand)
227-
228220
self.mouse = nil
229221
self.focused_widget = nil
230222
self.dialog = nil
231223
self.widgets = nil
232224
self.dmi = nil
233225
self.open_sprites = nil
234-
self.beforecommand = nil
235-
self.aftercommand = nil
226+
self.animation_timer = nil
227+
self.animation_running = false
236228

237229
return true
238230
end

scripts/classes/preferences.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ function Preferences.show(plugin)
5151
selected = Preferences.plugin.preferences.auto_flatten,
5252
}
5353

54+
5455
dialog:button {
5556
text = "&OK",
5657
focus = true,

scripts/main.lua

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,60 @@ function init(plugin)
3939
if ev.name == "OpenFile" then
4040
local opening_raw = RawDmi.opening
4141
RawDmi.after_open(app.sprite)
42-
42+
-- Collect all .dmi placeholder sprites first, then close them, then create editors.
43+
-- Calling Editor.new() -> app.events:on() inside an event callback can reallocate
44+
-- Aseprite's internal callback vector while Events::call is iterating it (use-after-free).
45+
local filenames = {}
4346
if app.sprite and app.sprite.filename:ends_with(".dmi") and not opening_raw then
4447
local filename = app.sprite.filename
4548
app.command.CloseFile { ui = false }
4649

50+
-- Prevent duplicate editor instances for the same file
51+
local normalized = string.lower(filename)
52+
local found = false
53+
for _, editor in ipairs(open_editors) do
54+
if not editor.closed and string.lower(editor:path()) == normalized then
55+
editor:repaint()
56+
found = true
57+
break
58+
end
59+
end
60+
61+
if not found then
62+
table.insert(filenames, filename)
63+
end
64+
end
65+
66+
-- Now create editors outside the event callback
67+
if #filenames > 0 then
4768
loadlib(plugin.path)
48-
Editor.new(DIALOG_NAME, filename)
69+
for _, filename in ipairs(filenames) do
70+
Editor.new(DIALOG_NAME, filename)
71+
end
4972
end
5073
elseif ev.name == "Exit" then
5174
exiting = true
5275
end
76+
77+
-- Dispatch to open editors. We do NOT register per-editor
78+
-- listeners because calling app.events:on() from inside an
79+
-- event callback can reallocate Aseprite's internal callback
80+
-- vector while Events::call is iterating it (use-after-free).
81+
for _, editor in ipairs(open_editors) do
82+
if not editor.closed then
83+
editor:onaftercommand(ev)
84+
end
85+
end
5386
end)
5487

5588
before_listener = app.events:on("beforecommand", function(ev)
89+
-- Dispatch to open editors first (same reason as aftercommand above).
90+
for _, editor in ipairs(open_editors) do
91+
if not editor.closed then
92+
editor:onbeforecommand(ev)
93+
end
94+
end
95+
5696
if RawDmi.beforecommand(ev) then
5797
return
5898
elseif ev.name == "Exit" then

0 commit comments

Comments
 (0)