|
AutoCAD... AutoLISP... VisualLISP... |
|
[15] Zmienne systemowe |
|
» Zmienne systemowe AutoCAD przechowuje nastawy (lub wartości) swojego środowiska operacyjnego i niektórych swoich poleceń w zmiennych systemowych. Każda zmienna systemowa ma przypisany typ: calkowity (integer), rzeczywisty (real), punkt (list) albo lańcuch tekstowy (string). Zmienne mogą być zapisywane w rysunku, w rejestrze Windows, lub niektóre w ogóle nie są zapamietywane. Jezeli zmienna systemowa nie jest zmienną tylko do odczytu (read only), to można sprawdzić i zmienić jej wartość bezpośrednio w linii poleceń, wykorzystując polecenieZMSYS (_SETVAR) lub funkcje AutoLISP-u getvar (odczyt) i setvar (zapis), lub przez zmiany opcji niektórych poleceń i okien dialogowych.Wywolanie funkcji getvar wygląda następująco:(getvar [VAR (String)]) np.(getvar "OSMODE") może zwrócić 183lub (getvar "LASTPOINT") zwraca (0.0 0.0 0.0)Warto zauważyć że jeżeli zmienna nie wystepuje funkcja zwraca NIL:(getvar "ABC") zwraca: NilDo zmiany wartości zmiennych (którym można ją zmienić) sluży funkcja setvar która wymaga dwóch argumentów:
Funkcja zwraca zmienioną wartość: (setvar "OSMODE" 0) zwraca: 0.
Podanie niepoprawnych wartości argumentów (np. nazwy nieistniejącej zmiennej, złej wartości zmiennej itp.) powoduje błąd AutoLISP-a.» "Hurtowa" zmiana wielu zmiennych Niestety używanie funkcjigetvar jest nieco uciążliwe ponieważ dla każdej zmiany trzeba ją ponownie wywoływać. W razie potrzeby jednorazowej zmiany wielu zmiennych (zobacz: pułapki command), warto wykorzystać funkcję przedstawioną poniżej. Wymaga ona jednego argumentu w postaci listy na której umieszczone są naprzemiennie nazwy zmiennych i ich nowe wartości. Funkcja gdy nie wystąpił żaden błąd zwraca NIL. Dodatkowo wykorzystując nowe mozliwości Visual LISP-a, skonstruowałem funkcję tak aby była maksymalnie odporna na możliwe błędy (funkcja nic nie robi lub wykonuje tylko możliwe do zrealizowania działania):
W przypadku gdy wystąpi jakikolwiek błąd funkcja zwraca T. Przykłady: (jk:SYS_SetVars '("CMDECHO" 0))
i zmienia wartość zmiennej CMDECHO na 1(jk:SYS_SetVars '("CMDECHO" 1 "OSMODE" "ABC"))
- zwraca: T i zmienia tylko wartość dla CMDECHO (OSMODE musi być INTeger)(jk:SYS_SetVars '("CMDECHO" 1 "OSMODE" 183 "WRITESTAT" 2)) - zmienia CMDECHO i OSMODE (zmienna WRITESTAT jest read-only), zwraca T. Funkcja wygląda tak:
|
;;; ;;; Zmienia wartości zmiennych z listy podanej jako argument [l] ;;; (defun jk:SYS_SetVars (l / e) (if (listp l) (while l (if (setq e (vl-catch-all-error-p (vl-catch-all-apply 'setvar (list (car l)(cadr l)) ) ) ) Nil (setvar (car l)(cadr l)) ) (setq l (cddr l)) ) (setq e T) ) e ) |
|
» Zapamiętywanie wartości zmiennych systemowych O ile funkcjajk:SYS_SetVars może mieć wpływ na bardziej wydajną zmianę wielu zmiennych, do całości obrazu zarządzania zmiennymi systemowymi brakuje rozwiązania problemu przywracania poprzednich wartości zmiennych, które uległy zmianie. Najbardziej prostą i niewymagającą żadnych nakładow pracy (oprócz pisania kodu) jest stosowanie sekwencji:1). (setq old (getvar "VAR")) ; <- zapamietanie starej wartości
2). (setvar "VAR" new) ; <- zmiana wartości
3). ; *** - kod programu - ***4). (setvar "var" old) ; <- przywrócenie wartości zmiennej
W przypadku zmiany wartości dla niewielu zmiennych, stosowanie takiej sekwencji jest proste i nie sprawia żadnego problemu, jednak wraz ze wzrostem ilości zmiennych do zmiany, łatwo zauważymy pewne niedogodności. Są to: Wykorzystując cechy LISP-a najlepiej stosowac wszystko to co LISP robi najlepiej czyli operacje na listach. Od razu nasuwa sie proste rozwiązanie: przechowywać nazwy zmiennych i ich wartości na jednej liście (jako jeden symbol - zmienna globalna), i na podstawie tej listy przywracać te wartości z powrotem. Skojarzenie nazwy zmiennej systemowej i jej wartości, naturalnie narzuca konstrukcję tej listy - najlepszym rozwiązaniem wydaje sie byc lista par kropkowych, podobnie jak ma to miejsce przy listach DXF danych obiektow. Sposób ten jest powszechnie stosowany (wystarczy przejrzec standardowe pliki lsp AutoCAD-a i ExpressTools - funkcje modes i moder). Funkcja modes zapisuje liste z danymi zmiennych - a moder na podstawie tej listy przywraca te wartości.Na swoje potrzeby, napisalem podobnie działające dwie funkcje - ktore są bardziej elastyczne, posiadają ponadto dodatkowe cechy:
|
;;; ;;; Funkcja zapamietująca wartości zmiennych ;;; (defun jk:SYS_ModeS (l) (if (listp l) (if (setq l (vl-remove-if-not 'getvar l)) (if (not *jk-Var) (setq *jk-Var (mapcar '(lambda (%)(cons % (getvar %))) l)) (foreach % (mapcar '(lambda (%)(cons % (getvar %))) l) (if (not (car (assoc (car %) *jk-var))) (setq *jk-Var (append *jk-Var (list %))) Nil ) ) ) ) ) *jk-Var ) |
Argumentem funkcji jest lista, i jeśli znajdują sie na niej nazwy nieistniejących zmiennych systemowych zostają one odrzucone. Pozostałe elementy (poprawne nazwy zmiennych systemowych) łączone są w pary kropkowe (typu (nazwa_zmiennej . jej_wartość)) i zapisywane jako jedna lista. Lista jest zapisywana jako zmienna globalna *jk-Var (gdy nie istnieje), w przeciwnym wypadku do istniejącej listy dodawane są tylko nowe pary kropkowe. Pozwala to na wielokrotne wywołanie funkcji i aktualizowanie zmiennej *jk-Var. Funkcja zwraca utworzoną listę.Przykładowo: (jk:SYS_ModeS '("OSMODE" "BLIPMODE" "CMDECHO"))zwraca: (("OSMODE" . 183) ("BLIPMODE" . 0) ("CMDECHO" . 1))Następnie: (jk:SYS_ModeS '("CMDECHO" "ABC" "LASTPOINT"))zwraca: (("OSMODE" . 183)("BLIPMODE" . 0)("CMDECHO" . 1)("LASTPOINT" 0.0 0.0 0.0))LASTPOINT została dodana do listy, natomiast, nie zostały dodane: CMDECHO (bo już jest) i ABC bo nie jest zmienną systemową.
» Przywracanie wartości zmiennych systemowych Drugą funkcją zarządzająca zmiennymi systemowymi jest funkcja przywracająca wartości zmiennych na podstawie listy bedącą wartością zmiennej*jk-Var. Funkcja nie posiada zadnych argumentow, zawsze zwraca Nil, a wygląda tak: |
;;; ;;; Funkcja przywracająca wartości zmiennych ;;; (defun jk:SYS_ModeR () (if *jk-Var (jk:SYS_SetVars (apply 'append (mapcar '(lambda (%)(list (car %)(cdr %))) *jk-var ) ) ) Nil ) (setq *jk-var nil) ) |
Funkcja przekazuje funkcji jk:SYS_SetVars jako argument połączone w jedną listę pary kropkowe zmiennej *jk-var, której na koniec przypisuje wartość Nil.Teraz (uzbrojeni w takie narzędzia) zapewnienie prawidłowego, szybkiego i prostego sposobu zapisu, zmiany i przywracania zmiennych systemowych może wyglądać tak: 1) (jk:SYS_ModeS '("OSMODE" "BLIPMODE" "CMDECHO"))2) (jk:SYS_SetVars '("OSMODE" 0 "BLIPMODE" 0 "CMDECHO" 0))3) *** kod programu ***4) (jk:SYS_ModeR)Warto pamietać że wywołanie (jk:SYS_ModeR) może występować w funkcjach obsługi błedów, jako wygodny sposob przywracania środowiska.
Zobacz także: Wczytywanie zmiennych systemowych |
|
|
|
|
|