code wiki / (root) / nx_editstack_lib.nx

nx_editstack_lib.nx

buildroot/runtime/nx_editstack_lib.nx

15701 B316 linesdepth 2pulls 2 transitivereach 13 importersview sourcekind library
docsdependenciesstructsconstsfunctions

about

nx_editstack_lib.nx -- THE NON-DESTRUCTIVE OPERATION STACK: record, undo, redo, replay, re-evaluate. This is the spine every content-creation tool is built on (Blender's modifier stack, ZBrush's layers, Houdini's graph) and the one thing this estate has never had. /compare/dcc DC1 and DC2. CHECK-BEFORE-BUILD, and the incumbent was READ, not guessed. nx_spendgate named nx_editor_canvas.nx as the nearest candidate and it is NOT this: it is a 2D page-layout canvas ([kind,x,y,w,h] elements -- heading, text, button, image) whose undo is ec_save/ec_undo, a ONE-DEEP FULL-ARRAY SNAPSHOT copied in and out. That cannot redo, cannot replay, cannot re-evaluate a parameter at depth, and costs O(state) per step. nx_siteedit_history.nx is file REVISION history, a different layer again. So the estate's only existing undo is one-deep and snapshot-shaped; this is the log-shaped primitive underneath, and nx_editor_canvas is a candidate consumer of it rather than a rival to it. WHY UNDO IS REPLAY-FROM-BASE AND NOT AN INVERSE OP. Applying an inverse operation is how a float editor loses precision: scale by 3/7 then by 7/3 does not return you to where you started, so undo DRIFTS and the drift is invisible because nobody digests the state. Replaying the log from the base cannot drift, by construction, and it is what makes the bit-exact claim on the /compare/dcc board checkable rather than asserted. The cost is O(cells x ops) per undo, paid deliberately and named here so the next reader does not mistake it for an oversight. THE STATE IS AN i64 CELL VECTOR ON PURPOSE. A consumer maps its own data onto cells (a mesh maps vertex components, the canvas above would map [kind,x,y,w,h]), so there is ONE stack in the estate rather than one per subject. All integer: no float enters, which is why replay is bit-exact. 100% sovereign. No hardware writes (Rule 26). license_tier: ORIGINAL

dependencies 1 imports · 6 importers

nx_syscalls.nx nx_editstack_lib.nx nx_editor_canvas.nx nx_editor_canvas_gate.nx nx_editstack_gate.nx nx_texpaint_gate.nx nx_texpaint_lib.nx nx_vpick_lib.nx

imports: nx_syscalls.nx

imported by: nx_editor_canvas.nxnx_editor_canvas_gate.nxnx_editstack_gate.nxnx_texpaint_gate.nxnx_texpaint_lib.nxnx_vpick_lib.nx

structs

none

consts

31const ES_H_CAP: i64 = 0
32const ES_H_NCELL: i64 = 1
33const ES_H_COUNT: i64 = 2
34const ES_H_HEAD: i64 = 3
35const ES_H_ERR: i64 = 4
36const ES_HDR: i64 = 5
37const ES_REC: i64 = 5 // [kind, a0, a1, a2, a3] -- one word per field, each named below
38const ES_I64_BYTES: i64 = 8
46const ES_F_KIND: i64 = 0
47const ES_F_A0: i64 = 1
48const ES_F_A1: i64 = 2
49const ES_F_A2: i64 = 3
50const ES_F_A3: i64 = 4
54const ES_OK: i64 = 0
55const ES_E_CELL: i64 = 0 - 1
56const ES_E_FULL: i64 = 0 - 2
57const ES_E_ATBASE: i64 = 0 - 3
58const ES_E_ATHEAD: i64 = 0 - 4
59const ES_E_DIV: i64 = 0 - 5
60const ES_E_KIND: i64 = 0 - 6
61const ES_E_IDX: i64 = 0 - 7
62const ES_E_RANGE: i64 = 0 - 8
63const ES_E_ARGS: i64 = 0 - 9
64const ES_E_RESERVED: i64 = 0 - 10
66const ES_OP_SET: i64 = 1
67const ES_OP_ADD: i64 = 2
68const ES_OP_SCALE: i64 = 3 // rational scale: cell = cell * a1 / a2, integer, a2 == 0 REFUSES
69const ES_OP_RADD: i64 = 4 // range add over [a0, a1)
77const ES_OP_CONSUMER_BASE: i64 = 1024
83const ES_HASH_MUL: i64 = 1099511628211

functions

85func es_live_off(st: *i64) -> i64 { return ES_HDR + st[ES_H_NCELL] }
86func es_ops_off(st: *i64) -> i64 { return ES_HDR + st[ES_H_NCELL] + st[ES_H_NCELL] }
88func es_ncells(st: *i64) -> i64 { return st[ES_H_NCELL] }
called by 2: ecs_nelemecs_seed
89func es_cap(st: *i64) -> i64 { return st[ES_H_CAP] }
called by 2: ecs_pushtp_record
90func es_count(st: *i64) -> i64 { return st[ES_H_COUNT] }
91func es_head(st: *i64) -> i64 { return st[ES_H_HEAD] }
92func es_err(st: *i64) -> i64 { return st[ES_H_ERR] }
94func es_err_name(e: i64) -> *u8
called by 2: ecs_code_namemain
109func es_words_for(cap_ops: i64, ncells: i64) -> i64
called by 1: es_new
114func es_new(cap_ops: i64, ncells: i64) -> *i64
127func es_base_set(st: *i64, i: i64, v: i64) -> i64
called by 2: ecs_seedeg_seed calls 1: es_live_off
137func es_cell(st: *i64, i: i64) -> i64
called by 1: main calls 1: es_live_off
143func es_op_field(st: *i64, idx: i64, f: i64) -> i64
154func es_apply(st: *i64, kind: i64, a0: i64, a1: i64, a2: i64, a3: i64) -> i64
called by 2: es_replayes_push calls 1: es_live_off
191func es_restore_base(st: *i64) -> i64
called by 2: ecs_replayes_replay calls 1: es_live_off
203func es_live_ptr(st: *i64) -> *i64
208func es_replay(st: *i64) -> i64
230func es_record(st: *i64, kind: i64, a0: i64, a1: i64, a2: i64, a3: i64) -> i64
called by 2: es_pushes_push_raw calls 1: es_ops_off
244func es_push(st: *i64, kind: i64, a0: i64, a1: i64, a2: i64, a3: i64) -> i64
259func es_push_raw(st: *i64, kind: i64, a0: i64, a1: i64, a2: i64, a3: i64) -> i64
called by 2: ecs_pushmain calls 1: es_record
267func es_head_set(st: *i64, h: i64) -> i64
called by 2: ecs_undoecs_redo
274func es_undo(st: *i64) -> i64
called by 2: mainmain calls 1: es_replay
280func es_redo(st: *i64) -> i64
called by 2: mainmain calls 1: es_replay
292func es_op_args_set(st: *i64, idx: i64, a0: i64, a1: i64, a2: i64, a3: i64) -> i64
called by 2: ecs_reevales_reeval calls 1: es_ops_off
303func es_reeval(st: *i64, idx: i64, a0: i64, a1: i64, a2: i64, a3: i64) -> i64
309func es_digest(st: *i64) -> i64
called by 2: ecs_digestmain calls 1: es_live_off