Skip to content

Commit

Permalink
Document embed and fix form reference
Browse files Browse the repository at this point in the history
  • Loading branch information
luk3yx committed Jul 31, 2024
1 parent 0b25461 commit cf0fd10
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 14 deletions.
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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>
30 changes: 16 additions & 14 deletions embed.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit cf0fd10

Please sign in to comment.