VF-Linienzug: Abbruch-Wickel-Handler der 3 Modi zentralisieren
Der scharfe *error*-Abbruch-Handler (wickelt Teil-Geometrie bei ESC/(exit) zu einem VF_n-Block mit vollem Journal) stand in Modus 1/2/3 dreimal WORTGLEICH, nur der Marker-String unterschied sich. Jetzt eine gemeinsame Funktion vfl-abbruch-handler-installieren (marker), die *error* als Lambda-Liste mit eingebautem Marker-Literal setzt (list-Konstruktion, kein globaler Zwischen- zustand). Der fragile Wickel-Rumpf existiert damit nur noch EINMAL - kuenftige Fixes an einer Stelle statt drei. Die je-Modus unterschiedliche old-error-Quelle bleibt an der Aufrufstelle (M1: *error*, M2/M3: dbg-old-error via fruehem dbg-Hook) - nur der wortgleiche Handler-Rumpf wird geteilt. Alle vom Handler zur Abbruchzeit dynamisch aufgeloesten Locals (old-error/lastEnt/vfl-nummer/... /dbg-an) sind unveraendert im Modus-Frame gebunden (VERTRAG in der Funktion dokumentiert). Tests (tests/test_unit.lsp, tu-tests-vfl-abbruch): der Konstruktor erzeugt eine gueltige (lambda (msg) ...)-Struktur und baut GENAU den uebergebenen Marker als letztes Argument des vfl-modus-abbruch-sichern-Aufrufs ein (linienzug2 vs linienzug3 geprueft). 240/240 LISP-Unit-Tests gruen in BricsCAD; keine neuen Python-Failures (11 = HEAD-Baseline). Modus-1-ESC-Abbruch interaktiv bestaetigt (Teilkette bleibt als editierbarer VF_n-Block stehen). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
40d79f4993
commit
008f497b5d
+53
-55
@@ -2360,6 +2360,47 @@
|
||||
;; sich um einen frischen Bau oder einen Editier-Neuaufbau handelte (kein
|
||||
;; Sonderfall mehr noetig). Aufgerufen aus dem *error*-Handler von
|
||||
;; vf-linienzug-modus.
|
||||
;; Den scharfen Abbruch-Wickel-Handler als *error* installieren - gemeinsam
|
||||
;; fuer alle drei Linienzug-Modi (frueher 3x wortgleich ausgeschrieben, nur der
|
||||
;; Marker-String "linienzug"/"linienzug2"/"linienzug3" unterschied sich).
|
||||
;;
|
||||
;; Der Handler faengt jeden Abbruch (ESC / (exit) / Laufzeitfehler) ab, wickelt
|
||||
;; die bis dahin gebaute Teil-Geometrie per vfl-modus-abbruch-sichern zu einem
|
||||
;; VF_n-Block mit dem vollen Journal (Marker als XDATA) und stellt *error*
|
||||
;; wieder her. Details/Begruendung (dynamic scoping, *ssg-ils-dim*-Reset,
|
||||
;; ssg-end) siehe die ausfuehrlichen Kommentare an der frueheren Aufrufstelle
|
||||
;; in vf-linienzug-modus.
|
||||
;;
|
||||
;; VERTRAG (dynamic scoping): Der Aufrufer MUSS als Locals gebunden haben und
|
||||
;; VOR diesem Aufruf gesetzt haben: old-error (Ruecksprung-*error*), lastEnt,
|
||||
;; vfl-nummer, anzahl-gf, anzahl-vf, startpunkt, frame, as-seite, es-seite,
|
||||
;; dbg-an. Sie werden vom Handler-Lambda zur ABBRUCHZEIT dynamisch aufgeloest -
|
||||
;; also gegen den dann noch aktiven Modus-Frame, nicht gegen diesen Konstruktor
|
||||
;; (der ist beim Abbruch laengst zurueckgekehrt). marker wird dagegen ZUR
|
||||
;; INSTALL-ZEIT als String-Literal in den Lambda eingebacken (list-Konstruktion),
|
||||
;; damit der Handler ihn ohne globalen Zwischenzustand selbst traegt.
|
||||
(defun vfl-abbruch-handler-installieren (marker)
|
||||
;; *error* auf eine LAMBDA-LISTE setzen, in die der marker als String-Literal
|
||||
;; eingebaut ist (list-Konstruktion). AutoLISP ruft *error* als Funktion auf,
|
||||
;; egal ob (lambda ...) oder (function (lambda ...)) - die reine Lambda-Liste
|
||||
;; genuegt und vermeidet eval/function-Feinheiten. Alle uebrigen Symbole
|
||||
;; (old-error, lastEnt, ...) bleiben ungequotet-frei und werden zur Aufrufzeit
|
||||
;; dynamisch aufgeloest.
|
||||
(setq *error*
|
||||
(list 'lambda '(msg)
|
||||
'(setq *error* old-error)
|
||||
'(setq *ssg-ils-dim* nil)
|
||||
(list 'vfl-modus-abbruch-sichern 'lastEnt 'vfl-nummer 'anzahl-gf 'anzahl-vf
|
||||
'startpunkt 'frame 'as-seite 'es-seite marker)
|
||||
'(if dbg-an
|
||||
(progn
|
||||
(dbgmsg (strcat "=== ABBRUCH: " (if msg msg "(exit)") " ==="))
|
||||
(dbgreturn nil)
|
||||
(dbgclose)))
|
||||
'(if (and (boundp '*ssg-start-stack*) *ssg-start-stack*) (ssg-end))
|
||||
'(princ)))
|
||||
*error*)
|
||||
|
||||
(defun vfl-modus-abbruch-sichern (lastEnt vfl-nummer anzahl-gf anzahl-vf
|
||||
startpunkt frame as-seite es-seite marker /
|
||||
e cnt vfl-ins wickel-erg grund fwd n trunc)
|
||||
@@ -6425,32 +6466,11 @@
|
||||
(setq lastEnt (vf-lastent-ohne-attribute))
|
||||
(setq anzahl-gf 0 anzahl-vf 0 frame nil)
|
||||
(setq old-error *error*)
|
||||
;; Abbruch-Handler: zuerst *error* zuruecksetzen (kein rekursiver
|
||||
;; Wiedereintritt bei einem Fehler waehrend des Wickelns), dann wickeln.
|
||||
;; Laeuft der Aufruf innerhalb einer ssg-start-Sitzung (Editier-Pfad via
|
||||
;; c:VARIOFOERDERER_EDIT -> vfl-edit-ent), wird diese mit ssg-end sauber
|
||||
;; geschlossen (Undo-Gruppe, gesicherte Systemvariablen, *error* aus dem
|
||||
;; Sitzungs-Frame) - sonst bliebe die von ssg-start geoeffnete Undo-Gruppe
|
||||
;; offen.
|
||||
;; *ssg-ils-dim*: der Editier-/Konverter-Pfad setzt vor dem Replay einen
|
||||
;; Dimensions-Override und raeumt ihn NACH der Rueckkehr wieder ab. Bei einem
|
||||
;; Abbruch kehrt der Aufruf nie dorthin zurueck (der Handler beendet den
|
||||
;; Befehl), daher MUSS der Override hier zurueckgesetzt werden - sonst bliebe
|
||||
;; er fuer den Rest der Sitzung stehen und alle folgenden Einfuegungen liefen
|
||||
;; in der falschen Dimension.
|
||||
(setq *error*
|
||||
(function (lambda (msg)
|
||||
(setq *error* old-error)
|
||||
(setq *ssg-ils-dim* nil)
|
||||
(vfl-modus-abbruch-sichern lastEnt vfl-nummer anzahl-gf anzahl-vf
|
||||
startpunkt frame as-seite es-seite "linienzug")
|
||||
(if dbg-an
|
||||
(progn
|
||||
(dbgmsg (strcat "=== ABBRUCH: " (if msg msg "(exit)") " ==="))
|
||||
(dbgreturn nil)
|
||||
(dbgclose)))
|
||||
(if (and (boundp '*ssg-start-stack*) *ssg-start-stack*) (ssg-end))
|
||||
(princ))))
|
||||
;; Scharfen Abbruch-Wickel-Handler installieren (gemeinsam fuer alle drei
|
||||
;; Modi, siehe vfl-abbruch-handler-installieren). old-error/lastEnt/vfl-nummer/
|
||||
;; anzahl-gf/anzahl-vf/startpunkt/frame/as-seite/es-seite/dbg-an sind hier als
|
||||
;; Locals gebunden und werden vom Handler zur Abbruchzeit dynamisch gesehen.
|
||||
(vfl-abbruch-handler-installieren "linienzug")
|
||||
|
||||
(if (vfl-wizard-aktiv)
|
||||
(vl-catch-all-apply 'vflw-gruppe-punkt-hoehe-impl
|
||||
@@ -8980,19 +9000,9 @@
|
||||
;; dbg-old-error) und uebernimmt das dbgclose. *ssg-ils-dim* zuruecksetzen:
|
||||
;; Begruendung siehe gleichlautende Stelle in vf-linienzug-modus.
|
||||
(setq old-error dbg-old-error)
|
||||
(setq *error*
|
||||
(function (lambda (msg)
|
||||
(setq *error* old-error)
|
||||
(setq *ssg-ils-dim* nil)
|
||||
(vfl-modus-abbruch-sichern lastEnt vfl-nummer anzahl-gf anzahl-vf
|
||||
startpunkt frame as-seite es-seite "linienzug3")
|
||||
(if dbg-an
|
||||
(progn
|
||||
(dbgmsg (strcat "=== ABBRUCH: " (if msg msg "(exit)") " ==="))
|
||||
(dbgreturn nil)
|
||||
(dbgclose)))
|
||||
(if (and (boundp '*ssg-start-stack*) *ssg-start-stack*) (ssg-end))
|
||||
(princ))))
|
||||
;; Scharfen Abbruch-Wickel-Handler installieren (gemeinsam, siehe
|
||||
;; vfl-abbruch-handler-installieren).
|
||||
(vfl-abbruch-handler-installieren "linienzug3")
|
||||
(setq n (length segmente))
|
||||
;; erste/letzte "Linie" fuer die Trimmung bestimmen
|
||||
(setq first-line -1 last-line -1 i 0)
|
||||
@@ -9758,22 +9768,10 @@
|
||||
;; dbg-Hook selbst) und uebernehmen das dbgclose gleich mit, sonst wuerde
|
||||
;; bei einem Abbruch ab hier doppelt geschlossen.
|
||||
(setq old-error dbg-old-error)
|
||||
;; *ssg-ils-dim* hier zuruecksetzen - Begruendung siehe gleichlautende Stelle
|
||||
;; im Handler von vf-linienzug-modus (Abbruch kehrt nie zum Aufrufer zurueck,
|
||||
;; der den Override abraeumen wuerde).
|
||||
(setq *error*
|
||||
(function (lambda (msg)
|
||||
(setq *error* old-error)
|
||||
(setq *ssg-ils-dim* nil)
|
||||
(vfl-modus-abbruch-sichern lastEnt vfl-nummer anzahl-gf anzahl-vf
|
||||
startpunkt frame as-seite es-seite "linienzug2")
|
||||
(if dbg-an
|
||||
(progn
|
||||
(dbgmsg (strcat "=== ABBRUCH: " (if msg msg "(exit)") " ==="))
|
||||
(dbgreturn nil)
|
||||
(dbgclose)))
|
||||
(if (and (boundp '*ssg-start-stack*) *ssg-start-stack*) (ssg-end))
|
||||
(princ))))
|
||||
;; Scharfen Abbruch-Wickel-Handler installieren (loest den fruehen dbg-Hook ab,
|
||||
;; Ruecksprungziel bleibt dbg-old-error via old-error). Gemeinsam fuer alle
|
||||
;; Modi - siehe vfl-abbruch-handler-installieren.
|
||||
(vfl-abbruch-handler-installieren "linienzug2")
|
||||
;; erste/letzte Gerade fuer AS/ES-Trimmung bestimmen
|
||||
(setq first-line -1 last-line -1 i 0)
|
||||
(while (< i n)
|
||||
|
||||
+47
-1
@@ -905,6 +905,52 @@
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; TESTS: vf_linienzug.lsp - gemeinsamer Abbruch-Handler-Konstruktor
|
||||
;; ------------------------------------------------------------
|
||||
;; vfl-abbruch-handler-installieren baut *error* als Lambda-Liste, in die der
|
||||
;; Marker ("linienzug"/"linienzug2"/"linienzug3") als String-Literal eingebaut
|
||||
;; ist. Der wortgleiche Wickel-Handler steht damit nur noch EINMAL statt 3x.
|
||||
;; Getestet wird die KONSTRUKTION (Marker an der richtigen Stelle, Struktur
|
||||
;; aufrufbar) - NICHT ein echter Abbruch (der braeuchte Zeichnung/Geometrie).
|
||||
;; *error* wird gesichert und wiederhergestellt, damit der Testlauf unberuehrt
|
||||
;; bleibt.
|
||||
(defun tu-tests-vfl-abbruch ( / _save _h _call)
|
||||
(princ "\n[vf_linienzug/Abbruch-Handler]")
|
||||
(if (null (atoms-family 1 '("VFL-ABBRUCH-HANDLER-INSTALLIEREN")))
|
||||
(tu-record nil "vfl-abbruch/modul"
|
||||
"vf_linienzug.lsp nicht geladen (VFL-ABBRUCH-HANDLER-INSTALLIEREN fehlt)")
|
||||
(progn
|
||||
(setq _save *error*)
|
||||
(setq _h (vfl-abbruch-handler-installieren "linienzug2"))
|
||||
;; Rueckgabe = das gesetzte *error* (identisch)
|
||||
(tu-true "vfl-abbruch/setzt-error" (equal _h *error*))
|
||||
;; Struktur: (lambda (msg) ...) - erstes Element lambda, zweites (msg)
|
||||
(tu-eq "vfl-abbruch/ist-lambda" 'lambda (car _h))
|
||||
(tu-eq "vfl-abbruch/arg-msg" '(msg) (cadr _h))
|
||||
;; Der vfl-modus-abbruch-sichern-Aufruf im Rumpf traegt GENAU den
|
||||
;; uebergebenen Marker als letztes Argument (nicht einen anderen Modus).
|
||||
(setq _call (car (vl-member-if
|
||||
(function (lambda (f)
|
||||
(and (listp f) (eq (car f) 'vfl-modus-abbruch-sichern))))
|
||||
(cddr _h))))
|
||||
(tu-true "vfl-abbruch/ruft-sichern" (not (null _call)))
|
||||
(tu-eq "vfl-abbruch/marker-linienzug2" "linienzug2" (last _call))
|
||||
;; Anderer Marker -> anderes Literal an derselben Position
|
||||
(vfl-abbruch-handler-installieren "linienzug3")
|
||||
(setq _call (car (vl-member-if
|
||||
(function (lambda (f)
|
||||
(and (listp f) (eq (car f) 'vfl-modus-abbruch-sichern))))
|
||||
(cddr *error*))))
|
||||
(tu-eq "vfl-abbruch/marker-linienzug3" "linienzug3" (last _call))
|
||||
;; *error* wiederherstellen - Testlauf darf nicht mit einem Wickel-Handler
|
||||
;; ohne gebundene Modus-Locals zurueckbleiben.
|
||||
(setq *error* _save)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; BEFEHL: TEST_UNIT
|
||||
;; ------------------------------------------------------------
|
||||
@@ -927,7 +973,7 @@
|
||||
(foreach fn '("tu-tests-core" "tu-tests-lang" "tu-tests-id" "tu-tests-vfcore"
|
||||
"tu-tests-export" "tu-tests-gf" "tu-tests-omni" "tu-tests-kreisel"
|
||||
"tu-tests-sepliste" "tu-tests-json" "tu-tests-geruest"
|
||||
"tu-tests-sepscan" "tu-tests-vfl-segs")
|
||||
"tu-tests-sepscan" "tu-tests-vfl-segs" "tu-tests-vfl-abbruch")
|
||||
(tu-run-block fn))
|
||||
|
||||
(princ "\n\n----------------------------------------------------------------")
|
||||
|
||||
Reference in New Issue
Block a user