fix: nil-guard in _invoke_context_menu + README English

- _invoke_context_menu now early-returns if locale_factory()
  returns nil mid-frame, symmetric with build_rows. Prevents the
  race where a workbench destroyed between render and right-click
  would propagate nil locale into ctx_inner and crash craft.
- README v0.2.0 sections (M.create + action-callback) translated
  from Denglisch to English for consistency with the rest of the
  file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Calic
2026-06-14 19:53:00 +02:00
parent 31e51ee8b7
commit c725ffd3bc
2 changed files with 16 additions and 16 deletions

View File

@@ -105,15 +105,15 @@ there propagate (consistent with rest of the lib stack).
### `display.create(arg, opts) -> widget_def` ### `display.create(arg, opts) -> widget_def`
Creates a crafting widget. **`arg`** ist eines von: Creates a crafting widget. **`arg`** is one of:
- **Form 1 (Bw-Compat v0.1):** bare container-entity-handle. Intern - **Form 1 (bw-compat from v0.1):** bare container-entity-handle. Wrapped
als constant locale_factory gewrappt (`function() return arg end`). internally as a constant locale_factory (`function() return arg end`).
- **Form 2 (v0.2 NEU):** `function() -> locale`wird pro Frame - **Form 2 (NEW in v0.2):** `function() -> locale`invoked per frame.
aufgerufen. Locale ist entweder ein entity-handle (Form-1 sub- Locale is either an entity-handle (Form-1 sub-semantics) or a table
semantik) oder eine Table `{sources={...}, sink=...}`. Forward- `{sources={...}, sink=...}`. Forward-compatible with dynamic
compat zu dynamischen Topologien (player-bewegt-sich → topologies (player moves → adjacent-container set changes, no widget
adjacent-Container-Set ändert sich, ohne widget-Recreate). recreate required).
**Syntax:** `display.create(arg: entity | function() -> locale, opts: table|nil) -> widget_def` **Syntax:** `display.create(arg: entity | function() -> locale, opts: table|nil) -> widget_def`
@@ -157,24 +157,23 @@ Loud-error if `arg` is `nil`.
--- ---
### Action-Callback Signatur (v0.2.0 Update) ### Action-Callback Signature (v0.2.0 Update)
Callbacks erhalten `(recipe_id, ctx_inner)` wo `ctx_inner`: Callbacks receive `(recipe_id, ctx_inner)` where `ctx_inner` is:
```lua ```lua
{ {
locale = <currently-resolved locale>, -- v0.2 NEU locale = <currently-resolved locale>, -- NEW in v0.2
container = <sink (Form-2) or handle (Form-1)>, -- bw-compat alias container = <sink (Form-2) or handle (Form-1)>, -- bw-compat alias
close_menu = function() ... end, close_menu = function() ... end,
refresh = function() ... end, refresh = function() ... end,
} }
``` ```
Modul-Aktion ruft typisch `crafting.craft(recipe_id, Module action typically calls `crafting.craft(recipe_id,
ctx_inner.locale, ctx)`. Existing v0.1 callers die ctx_inner.locale, ctx)`. Existing v0.1 callers that use
`ctx_inner.container` benutzen funktionieren weiter via Form-1 `ctx_inner.container` continue to work via the Form-1 bw-compat shim
bw-compat-shim (sink-handle wird intern als single-container (sink-handle is treated internally as a single-container).
behandelt).
--- ---

View File

@@ -296,6 +296,7 @@ end
function M._invoke_context_menu(widget, recipe_id, mx, my) function M._invoke_context_menu(widget, recipe_id, mx, my)
local locale = widget._locale_factory() local locale = widget._locale_factory()
if locale == nil then return end -- symmetric with build_rows
local sink_alias local sink_alias
if type(locale) == "table" then if type(locale) == "table" then
sink_alias = locale.sink sink_alias = locale.sink