Document embed and fix form reference

This commit is contained in:
luk3yx 2024-07-31 15:50:33 +12:00
parent 0b25461948
commit cf0fd10708
2 changed files with 43 additions and 14 deletions

View File

@ -566,4 +566,31 @@ call `form:render_to_formspec_string(player, ctx, standalone)`.
> [!CAUTION]
> Do not use this API with node meta formspecs, it can and will break!
</details><details>
<summary><b>Embedding a form into another form</b></summary>
You can embed form objects inside others like this:
```lua
local parent_form = flow.make_gui(function(player, ctx)
return gui.VBox{
gui.Label{label = "Hello world"},
other_form:embed{
-- Passing in the player is required for now. You must use the same
-- player object that you get sent by flow to avoid breakages in
-- the future if this becomes optional.
player = player,
-- A name for the embed. If this is specified, the embedded form
-- will get its own context (accessible at ctx.my_embed_name) and
-- field names will be rewritten to avoid conflicts with the
-- parent form. If name is not specified, the embedded form will
-- share ctx and ctx.form with the parent, and will not have field
-- names rewritten.
name = "my_embed_name",
},
}
end)
```
</details>

View File

@ -2,30 +2,32 @@ local embed_create_ctx_mt = {}
function embed_create_ctx_mt:__index(key)
-- rawget ensures we don't do recursion
local form = rawget(self, "_flow_embed_parent_form")
local ctx = rawget(self, "_flow_embed_parent_ctx")
local prefix = rawget(self, "_flow_embed_prefix")
return form[prefix .. key]
return ctx.form[prefix .. key]
end
function embed_create_ctx_mt:__newindex(key, value)
local form = rawget(self, "_flow_embed_parent_form")
local ctx = rawget(self, "_flow_embed_parent_ctx")
local prefix = rawget(self, "_flow_embed_prefix")
form[prefix .. key] = value
ctx.form[prefix .. key] = value
end
local function embed_create_ctx(ctx, name, prefix)
if not ctx[name] then
ctx[name] = {}
local function embed_create_ctx(parent_ctx, name, prefix)
if not parent_ctx[name] then
parent_ctx[name] = {}
end
if not ctx[name].form then
ctx[name].form = {}
local new_ctx = parent_ctx[name]
if not new_ctx.form then
new_ctx.form = {}
end
if getmetatable(ctx[name].form) ~= embed_create_ctx_mt then
ctx[name].form._flow_embed_prefix = prefix
ctx[name].form._flow_embed_parent_form = ctx.form
ctx[name].form = setmetatable(ctx[name].form, embed_create_ctx_mt)
if getmetatable(new_ctx.form) ~= embed_create_ctx_mt then
new_ctx.form._flow_embed_prefix = prefix
new_ctx.form._flow_embed_parent_ctx = parent_ctx
setmetatable(new_ctx.form, embed_create_ctx_mt)
end
return ctx[name]
return new_ctx
end
local function embed_wrap_callback_func(func, name, prefix)