Author Topic: Keep objects (discussion)  (Read 8894 times)

0 Members and 1 Guest are viewing this topic.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Keep objects (discussion)
« on: August 25, 2005, 01:12:43 AM »
This discussion was spawned from this post.

==============================================

That's a great example that's useful and yet concise; excellent post Luis.

When I wish to understand a code snip I reformat it in an "expanded vertical" style, as (to me) it makes it easy to disect the logic and see the parentage of the various statements. I find I don't need comments when code is formatted in said format. As I did it with the code you supplied I thought I'd share it with others that might find the compressed format challenging to read as my old eyes do.

Also, I modded the c:Keep function so it will prompt for multiple entities.

I hope you don't mind these intrusions into your thread or these modifications.

Code: [Select]
(defun ObjectErased ( reactor params )
    (if (wcmatch (car params) "ERASE,EXPLODE")
        (foreach handle
            (vl-remove-if-not
                (function
                    (lambda (i)
                        (not (entget (handent i)))
                    )
                )
                kept_list
            )
            (entdel (handent handle))
        )
    )
)

(defun C:Keep  ( / ss obj i )
    (cond
        (   (setq ss (ssget))
            (repeat (setq i (sslength ss))
                (if
                    (not
                        (vl-position
                            (vla-get-handle
                                (setq obj
                                    (vlax-ename->vla-object
                                        (ssname ss
                                            (setq i (1- i))
                                        )
                                    )
                                )
                            )
                            kept_list
                        )
                    )
                    (setq kept_list
                        (cons
                            (vla-get-handle obj)
                            kept_list
                        )
                    )
                )
            )
            (if (not reactor)
                (setq reactor
                    (vlr-editor-reactor
                        "keep reactor"
                       '((:vlr-commandended . ObjectErased))
                    )
                )
            )
        )
    )    
    (princ)
)

Again, my compliments on a concise yet very useful (and fun) coding example.

Cheers,

Michael.

:)
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Keep objects (discussion)
« Reply #1 on: August 25, 2005, 08:09:17 AM »
While this may be better served in a separate thread I couldn't resist the opportunity to
add my option. I like the compressed format, believe it or not it is easier for ME to read.
Perhaps it's my dyslexia, inability to spell or the fact I read poorly or a left / right brain
thing. The code below is MY preference. One of the problems a lot of folks don't realize with
posting code in any form is that the TABs don't format correctly. So I convert tabs to spaces
before I post the code. That helps preserve the intended formatting.
I must admit that I enjoy looking at your code Michael. It is pleasing to my eye, but I can not
read the code as well as I read the compressed form. Very strange indeed. Perhaps it's lack of
practice on my part. I have noticed that in the earlier years your code was less expanded so I
supposed it is an evolution of sorts.
So while I don't disagree with the format I just wanted to express my thoughts on the subject.
I suspect as time goes by, I consider myself a teenager where LISP is concerned, my code will
expand as well.

Code: [Select]
(defun objecterased (reactor params)
  (if (wcmatch (car params) "ERASE,EXPLODE")
    (foreach handle (vl-remove-if-not
                      (function (lambda (i) (not (entget (handent i)))))
                      kept_list
                    )
      (entdel (handent handle))
    )
  )
)

(defun C:KEEP (/ obj)
  (if (setq obj (vlax-ename->vla-object (car (entsel "\nSelect object to keep: "))))
    (progn
      (if (not (vl-position (vla-get-handle obj) kept_list))
        (setq kept_list (cons (vla-get-handle obj) kept_list))
      )
      (if (not reactor)
        (setq reactor (vlr-editor-reactor "keep reactor"
                                          '((:vlr-commandended . objecterased)))
        )
      )
    )
  )
  (princ)
)
(princ)


PS perhaps this thread should be copied to a new thread on code formating.
Unless You and I are the only ones with an opinion on the subject.
I hope you don't mind my input.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Keep objects (discussion)
« Reply #2 on: August 25, 2005, 08:35:05 AM »
Great input Alan, and surprising to me!

I initially had gone to the vertical format because I had a lot of code that would breach an 80 character line width (deeply nested code), thus when printed, would either be lost, or would wrap real ugly.

So I went vertical so to speak, and like I said, I found I could more quickly discern logic with said format. But I guess it's what one is accustomed to.

Question for friends viewing this thread: Should we prune these posts into a new thread or leave them polluting Luis' initial post?

Almost forgot: Adjusting scorecard.

:)
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

LE

  • Guest
Keep objects (discussion)
« Reply #3 on: August 25, 2005, 10:03:05 AM »
Nice...

I began and stay in the compacted coding format, when I participated provinding code for one book about visual lisp in spanish... today the little code I write in lisp, is like that... normally I use the vlisp editor, and double-click on the parens to grab the portions I want to read.... but that I think is a habit.

Luis.

Amsterdammed

  • Guest
Keep objects (discussion)
« Reply #4 on: August 25, 2005, 10:55:32 AM »
Mike,
I think you should leave the codes all in this one threat, “polluting” Luis’ ones.
It is a great function, but I’m always a bit scared of reactors.  :)


I read the vertical code easier, too. But as Luis, I work with the Vlisp editor and the formatting tool there. I can’t even imagine writing lisp in Notepad as example, I simply need the debug functions in the Vlisp editor.


Bernd

LE

  • Guest
Keep objects (discussion)
« Reply #5 on: August 25, 2005, 11:19:16 AM »
Quote from: Amsterdammed
but I’m always a bit scared of reactors.  :)
Bernd


They are normal... no problem with them, they just need to be treaded nice....  hehe

Luis.

whdjr

  • Guest
Keep objects (discussion)
« Reply #6 on: August 25, 2005, 11:23:20 AM »
This is a little off topic but I have a routine that goes along these lines kinda.  I did not write it, it was written by Randy Kintzley (Autodesk Programmer).  The program redefines the explode command so that it does not explode hatches or any block listed in an external text file.  It is very cool and very handy when you have employees with the mindset "If I don't understand it explode it".  I can't find it right now so after I find it I will post it.

Comparing the two it seems you could redefine the delete command as the before mentioned tool without having the overhead associated with reactors.

However as I myself have never actually written a reactor I may be way off base but it sounds good doesn't it? :)

LE

  • Guest
Keep objects (discussion)
« Reply #7 on: August 25, 2005, 11:34:03 AM »
Quote from: whdjr

Comparing the two it seems you could redefine the delete command as the before mentioned tool without having the overhead associated with reactors.

However as I myself have never actually written a reactor I may be way off base but it sounds good doesn't it? :)


Overhead?

No.... normal or simple reactors and object reactors can be very useful, as I said, if they treaded right, my sample on keeping objects is following a good criteria, when you dealing with vlisp-reactors coding.

One thing in mind is that not everything can be done [even if it does sometimes] with reactors.

I been writing them since vital lisp provide them, and have never encounter a big issue at all.

Now, about redefining a command?.... that can be easy to break [well, in this case I am shooting in the dark since I do not what Randy did]... anyway nothing is totally secure...

In the other hand... for a worst case scenario you can VETO commands calls with arx coding stuff and can be also with normal vlisp reactos too.

Luis.

Amsterdammed

  • Guest
Keep objects (discussion)
« Reply #8 on: August 25, 2005, 11:53:16 AM »
What really is to remember when you use Reactors is that you can’t use any Acad Command with them. Since I’m a drafter I have the intentions to use commands in my codes.

Bernd

LE

  • Guest
Keep objects (discussion)
« Reply #9 on: August 25, 2005, 12:05:36 PM »
Quote from: Amsterdammed
What really is to remember when you use Reactors is that you can’t use any Acad Command with them. Since I’m a drafter I have the intentions to use commands in my codes.

Bernd


There is always a way.... in vlisp we have -> vla-sendcommand

Here is a piece of code to show an example inside any function callback
Code: [Select]

;;; function callback at the command-ended event
;;; reactor: object that called this callback function
;;; params: list of the AutoCAD command completed
(defun callback-commandEnded  (reactor params / bName)

  ;; note:
  ;; we need to delete the previous/temporary object
  ;; because if we call the command insert via
  ;; vla-sendCommand, this reactor will run twice, then
  ;; at the begining we have to delete the temp object

  ;; make a test before doing the delete.
  (if (and
;; is not nil the object?
:obj
;; is a vla-object?
(eq (type :obj) 'vla-object)
;; was not erased?
(not (vlax-erased-p :obj)))
    ;; was true, then do the process
    (progn
      ;; make the temporary object visible
      (vla-put-visible :obj :vlax-true)
      ;; delete the temporary object if is possible
      ;; using vla-catch-xxx functions,
      ;; this will trap any possible exception
      (not (vl-catch-all-error-p
    (vl-catch-all-apply 'vla-delete (list :obj))))

      (setq :obj nil)))

  ;; main part for the reactor
  ;; was the drop-geometry used or a double-click on the icon?
  (if (wcmatch (car params) "DROPGEOM,EXECUTETOOL")
    (progn

      ;; convert to vla-object the block that was just droped.
      (setq :obj (vlax-ename->vla-object (entlast)))

      ;; get the block name
      (setq bName (vla-get-name :obj))

      ;; set the AutoCAD variable "insname" with the block name
      ;; note: this shall work in 2000i thru 2004
;;;      (vla-setVariable
;;;       (thisDwg) ;; <<--- from function utilities!
;;;       "insname"
;;;       (vlax-make-variant bName vlax-vbString))
;;;
;;;      (vla-setVariable
;;;       (thisDwg) ;; <<--- from function utilities!
;;;       "insname"
;;;       bName)

      ;; we are doing the test in a A2004 version
      ;; then there is no problem to use "setvar"
      (setvar "insname" bName)

      ;; make the object invisible
      (vla-put-visible :obj :vlax-false)

      ;; now use the normal insert command
      ;; NOTE: (thisDwg) ;; <<--- from function utilities!
      (vla-sendCommand (thisDwg) "_.-insert \n"))))


The last line, demostrate that inside of the callback, a command is being called...

Now, if we are talking of "work-arounds".... is another issue, I also do not like that, in my early days doing reactors code... I went into that a lot.... I think today, I have avoided that intention.... :[after to many slaps on my face] :)

Luis.

JohnK

  • Administrator
  • Seagull
  • Posts: 10626
Keep objects (discussion)
« Reply #10 on: August 25, 2005, 12:09:56 PM »
As for me, I prefer the 'old style'. I dont know if its easier to read or its just that I dont like the "expanded/vertical" style. However I tend to program a bit diff then most. I create alot of "names" in my programs. (I like the bottom up programing style.)  And I also like to code on the fly--think on paper if you will--and later create a more robust app/proced/function/etc.

Now this MY style, I dont formaly post the code this way, I tend to use external headers for my code and I even have diff symbols I use in my headers so that I can tell what procedure preforms a specific type of task. Wheather it be a "suport procedure" or a "reactor" or a "Main proced." This allows me to quicky jump thur the file and find what im looking for.

Another note I sould make about my "old style" (Most of you wont care about this but its another reason I prefer to code this way and it kinda explains my thought process.) is that it allows me to quicky "fold up" proced's in my editor so I can keep my stuff orginized better.

I'll give a brief example ... this was code laying arround in my "stuff" file I type in all day so the code has nothing to do with anything. *lol* This is what my code looks like before I format it and post it most of the time.


Code: [Select]
(defun gcd (a b)
  ;; Find the greatest comon denom of a number
  (if (= b 0)
      a
      (gcd b (rem a b))) )

(defun make-rat (n d / x)
  ;; support procedure to ''create'' a rational number
  ;; a ''class'' if you will.
  (setq x (gcd n d))
  (list (/ n x) (/ d x)) )

(defun numer (x)
  ;; return the numerator of a rat class.
  (car x) )

(defun denom (x)
  ;; return the denom of a rat class.
  (cadr x) )

(defun print-rat (x)
  ;; support proced to print the rat class in a perdy format.
  (princ "\n ")
   (princ (numer x))
   (princ "/")
   (princ (denom x))(princ) )

(defun add-rat (x y)
  ;; rat class addition.
  (make-rat (+ (* (numer x) (denom y))
               (* (numer y) (denom x)))
            (* (denom x) (denom y))) )

(defun sub-rat (x y)
  ;; rat class subtraction
  (make-rat (- (* (numer x) (denom y))
               (* (numer y) (denom x)))
            (* (denom x) (denom y))) )

(defun mul-rat (x y)
  ;; rat class multiply
  (make-rat (* (numer x) (numer y))
            (* (denom x) (denom y))) )

(defun div-rat (x y)
  ;; rat class divide
  (make-rat (* (numer x) (denom y))
            (* (denom x) (numer y))) )

(defun equal-rat? (x y)
  ;; support proced to see if one rat equals another.
  (= (* (numer x) (denom y))
     (* (numer y) (denom x))) )

;;example of use
(setq one-third (make-rat 1 3))
(print-rat (add-rat one-third one-third))
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Keep objects (discussion)
« Reply #11 on: August 25, 2005, 12:16:56 PM »
I don't care for 'old style' but I do subscribe to the 'divide and conquer' technique. However, functions like (defun foo (x) (car x)) have no value to me. While I'm an advocate of code reuse and redundancy minimization, there's a point where it just starts to produce code that is unnecessarilly obfuscated.

/mileages and opinions vary.

:)
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

JohnK

  • Administrator
  • Seagull
  • Posts: 10626
Keep objects (discussion)
« Reply #12 on: August 25, 2005, 12:42:39 PM »
I like the names cause i think it makes the overall main read alot easier. (I should prolly give an example huh?!)

Code: [Select]
(defun c:main ( / ThisIsTrue Then Otherwise)

  ;; //-- begin suport procedures --//
  (defun ThisIsTrue ()
    (eq (getvar "ctab") "Model") )
  (defun Then ()
    (alert "Good, your in Modelspace") )
  (defun Otherwise ()
    (setvar "ctab" "Model")
    (alert "Sorry, you need to be in Model space to continue.") )
  ;; //-- end support procedures --//

  (if (ThisIsTrue)
    (Then)
    (Otherwise))
 
  (princ)
 
 )


This is my application.

Now if at any time I need to alter the preformace of my "otherwise" in my conditional statment all I have to do is to alter the procedure and reload the app.
Code: [Select]

(defun c:main ( / ThisIsTrue Then Otherwise)

  ;; //-- begin suport procedures --//
  (defun ThisIsTrue ()
    (eq (getvar "ctab") "Model") )
  (defun Then ()
    (alert "Good, your in Modelspace") )
  (defun Otherwise ()
    (setvar "ctab" "Model")
    ;; (alert "Sorry, you need to be in Model space to continue.")
    ;; removed prompt; let the end user fig it out for him/her self.
    )
  ;; //-- end support procedures --//

  (if (ThisIsTrue)
    (Then)
    (Otherwise))
 
  (princ)
 
 )


Now if this procedure was built without the names, here is how it would look.

Code: [Select]
(defun c:main ( / )
  (if
    (eq (getvar "ctab") "Model")
    (alert "Good, your in Modelspace")
    (progn
      (setvar "ctab" "Model")
      (alert "Sorry, you need to be in Model space to continue.")
      )
    )

  (princ)

 )


Now if I wanted to remove the prompt I would have to search thru the code and try to follow where in the conditional I was. (Count the parens...follow the formating.)

I understand your point though, it dose look to be a bit wastefull but I will take the preformace loss--albeit minimal--from creating all those names for maintinece anyday.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Keep objects (discussion)
« Reply #13 on: August 25, 2005, 06:47:04 PM »
Quote from: MP
I don't care for 'old style' but I do subscribe to the 'divide and conquer' technique. However, functions like (defun foo (x) (car x)) have no value to me. While I'm an advocate of code reuse and redundancy minimization, there's a point where it just starts to produce code that is unnecessarilly obfuscated.

/mileages and opinions vary.

:)


I have'ta agree. Intent should be paramount.

Sorry John, to me the code
(if (ThisIsTrue)
    (Then)
    (Otherwise))
is questionable because of the mental gymnastics required to discern intent.
To me, the supposed purpose of black-boxing code is to obviate the necessity for the caller to know the mechanics of what's happening in the box. The way this is written requires the reader to jump back and forwards in the code. ie: it lacks Gestalt.
.... I realise that I'm only considering the reader, which is the purpose of this thread .. performance is another issue.

Perhaps if the naming was a little more indicative of purpose .....

[/just my opinion]
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

JohnK

  • Administrator
  • Seagull
  • Posts: 10626
Keep objects (discussion)
« Reply #14 on: August 25, 2005, 08:58:03 PM »
No, thats cool. ...that's why they call it Style right? 'You have yours and i have mine.'

I mean i understand your point but that was prolly  a bad example to give in the first place. I should have used a more traditional example--in that i used a "DoTo  Widget" procedure call instead of  a "ThisIsTrue"--to make my point but i think the point is still a valid one; but i guess if it wernt a valid point, there would be no reason to ever create a "name" huh?
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org