Repository navigation
[Plugins] Any way to store objects in the plugin state, i.e. for OOP? #4465
Describe the questionI've read the Sendables section of the plugin docs. I'm making a plugin that would benefit from OOP. I'm tracking when files are deleted, renamed, or moved, and allowing those operations to be undone. It would be great to store an object with a So far it seems like storing any object that has functions (other than Thanks! Checklist
|
Replies: 1 comment 1 reply
|
Functions can't go into the state from your async code. Everything you pass into or return from a You can still have -- Behavior lives at module level and never crosses threads.
local Op = {}
Op.__index = Op
local undo_by_kind = {
rename = function(op) --[[ move op.to back to op.from ]] end,
move = function(op) --[[ move op.to back to op.from ]] end,
delete = function(op) --[[ restore op.path from the trash ]] end,
}
function Op:undo() return undo_by_kind[self.kind](self) end
local function as_op(record) return record and setmetatable(record, Op) end
-- State only holds plain, sendable records (store paths as strings).
local push = ya.sync(function(state, record)
state.history = state.history or {}
table.insert(state.history, record)
end)
local pop = ya.sync(function(state)
return state.history and table.remove(state.history)
end)
return {
entry = function()
-- recording: push { kind = "rename", from = "/a/old.txt", to = "/a/new.txt" }
local op = as_op(pop())
if op then
op:undo()
end
end,
}The If you'd rather have one class per kind, map the kind to the class instead: |
Functions can't go into the state from your async code. Everything you pass into or return from a
ya.sync()block crosses threads, and only sendable values can make that trip: nil, booleans, numbers, strings,Url, and tables of those. A method is a function, so it gets rejected, and a metatable isn't carried across either.You can still have
op:undo(), though. Keep the data sendable and the behavior in your plugin. Store a plain record with akind, then attach the methods with a metatable after you read it back: