openlang

Should a rejected tile move the palette forward?

Creating a coroutine in Lua runs nothing yet. The host calls coroutine.resume, and only then does the generator run, up to the point where it explicitly yields a proposal. One tile at a time.

A red tile is already accepted. The generator yields a blue square for the neighbouring position. That yield is where control changes hands. The user rejects it and asks for amber. The host resumes the suspended coroutine with that decision, and the generator reads it from the values its coroutine.yield call returns. Then it prepares another proposal.

What does the rejection change? The palette position could advance, stay put, or roll back to the state from before the proposal. Each gives the artist a different way of revising. Keeping the rejected proposal and the decision visible would explain why the next tile looks different.

If the user stops, the host just stops resuming. The coroutine is left suspended, not finished, so the application needs a policy for the state and resources it still holds.

I lean toward leaving the position where it was, so a rejection costs nothing. Has anyone tried the other two with people actually drawing?

后续讨论 6

顺着彼此的依据读下去
  1. 固定链接

    The rejected blue square is half the record. Keep only the final pattern and a replay can't tell why that tile ended up amber.

    If the Clojure host keeps the accepted pattern in one Ref and the revision number in another, a dosync keeps the two in step. Send the preview to an agent with send from inside that transaction. Clojure holds agent sends made in a transaction until it commits and drops them if the body is retried, so a conflict can't put out a second preview.

    That leaves one gap. The state can commit and the preview never arrive, and the Refs have nothing to say about delivery.

  2. 固定链接

    Fun wrinkle. Two resumes can both pass reject and still not be the same step, because the generator moved its palette position in between. One decision, two starting points. Before I'd call a revision repeatable I want the starting palette, the generator's state and the whole sequence of decisions on record. Then flip one decision in the middle and see whether everything after it changes the way you'd expect.

  3. 固定链接

    Does that record live in the session? If it does, it goes away with the session, and a replay after the user stops has nothing to read. In Swift I'd keep the palette and the decisions in a plain struct that the session appends to and hands out by copy. Then the history doesn't care how long the session object lives.

  4. 固定链接

    The user stops. The session goes away. A pending preview promise fulfills a moment later. Follow that fulfillment, because nothing about it should turn a stopped session back into a displayed revision. The application decides that, not the promise.

    That gives three statuses. Stopped, preview skipped, preview available. And please don't call the last one resolved. A promise resolved to another pending promise can still be pending.

  5. 固定链接

    On the coroutine left suspended after the user stops. If the host's reference is the only thing keeping it alive, dropping that reference lets the collector take it without running the rest of the body. Any <close> variable inside it then never gets closed, and the Lua manual says as much about a coroutine that yields and is never resumed. So the stop path should call coroutine.close on it, which closes those pending variables and leaves the coroutine dead. After that, stopped means the generator has let go of what it held, not only that nobody is resuming it anymore.

  6. 固定链接

    I'd put the revision inside the status itself. Something like { kind: 'previewAvailable', revision: 4 }, with the stopped state carrying the last revision it accepted. When a preview fulfills late, the reducer compares its revision with the current state before anything is shown, and stopped plus any preview stays stopped.

    "Preview skipped" is the one I'm less sure about. Skipped because the user stopped, or because a newer revision replaced it before it arrived? On screen those look identical. For a replay they're different facts, and at this stage I'd rather have two variants than find out later which one a log line meant.

同一个问题的其他角度

  1. Who owns a Vulkan buffer after submission?

    A C++ RAII wrapper around a Vulkan buffer records work that uses the buffer, submits it, and goes out of scope. Its destructo…

    回复 7最近活动 cppc
  2. A status region that reads Saved twice

    The screen reader said "Saved" twice after one save. The state behind it has a single transition into saved, and the reducer…

    回复 3最近活动 typescriptjavascript
  3. One health bar went red and took the rest with it

    Got bitten by shared resources in Godot UI this time. Every unit in my little prototype has a health bar scene, a ProgressBar…

    回复 10最近活动 gdscript