Author Topic: Reactor Problem  (Read 1732 times)

0 Members and 1 Guest are viewing this topic.

Rabbit

  • Guest
Reactor Problem
« on: January 17, 2013, 05:47:24 PM »

I've dipped my toe into a reactor.  It's not behaving like I thought it would.

I've got a parent routine that inserts a block.  I've found this routine below to do some work to the block after it's inserted.  When I run the parent routine, the block is inserted, the reactor kicks in, and starts the Command_Ended_Command subroutine as expected.  When I step through, everything works correctly until I get into a another subroutine before the Command_Ended_Command routine finishes.

Code - Auto/Visual Lisp: [Select]
  1. (if (not Command_Ending_Reactor)
  2.   (setq Command_Ending_Reactor
  3.          (vlr-command-reactor nil '((:vlr-commandended . Command_Ended_Command))) ;_ end of vlr-command-reactor
  4.   ) ;_ end of setq
  5.   () ;_ the reactor is already loaded
  6. ) ;_ end of if you use this first portion of code to make sure the reactor is loaded, the reactor should only be loaded once otherwise you could see some unpleasant consequences
  7.  
  8. (defun Command_Ended_Command (In_ReactorName In_Command / MyKeyWords ModList); then you need to define the callback function (the simpler the name the better)
  9.   (alert (car In_Command )) ;; <-- Remove this line, it shows all incomming command
  10.   (cond; my current version checks for several different input commands to decide which programs to run, it may not be the most efficient, but it works for now (I am open to suggestions to improve my code structure) I have eliminated additional sections for simplicity sake.
  11.     ((or
  12.        (= (car In_Command) "INSERT")
  13.        (= (car In_Command) "-INSERT")
  14.        (= (car In_Command) "PASTECLIP")
  15.        (= (car In_Command) "DROPGEOM")
  16.        (= (car In_Command) "ACDCINSERTBLOCK")
  17.        (= (car In_Command) "EXECUTETOOL")
  18.        (= (car In_Command) "COPY")
  19.        (= (car In_Command) "-COPY")
  20.      ) ;_ end of or finally the commands that are executed when a tool is selected from the tool palette, or even when it is inserted from the original block.
  21.      (if ;<Block has visibility parameter>
  22.      
  23.        ;;;during this if statement, I call another subroutine.  When this routine is finished, I'm returned back to my original parent routine, it finishes, then it goes back to the Command_Ended_Command routine and finishes.  That's not a big deal, but it clears out all my variables and I can't finish here.
  24.  
  25.     );if
  26. ;;;      
  27.     ) ;_ end cond4
  28.   ) ;_ end of cond
  29. ) ;_ end of defun
  30.  

Basically, it seems the reactor is firing and when the sub-subroutine is finished, I go back to my parent routine, it finishes, then the reactor routine finishes.

I hope I've expalin this without too much confusion.  I would post all the code, but it would be way to long.

Rabbit

BlackBox

  • King Gator
  • Posts: 3770
Re: Reactor Problem
« Reply #1 on: January 17, 2013, 06:05:49 PM »
;;;during this if statement, I call another subroutineWhen this routine is finished, I'm returned back to my original parent routine, it finishes, then it goes back to the Command_Ended_Command routine and finishes.  That's not a big deal, but it clears out all my variables and I can't finish here.

Coding preference aside... Did you accidentally included a Command call in the subroutine (which was not posted)?  :? *not sure*
"How we think determines what we do, and what we do determines what we get."

BlackBox

  • King Gator
  • Posts: 3770
Re: Reactor Problem
« Reply #2 on: January 17, 2013, 06:14:27 PM »
Code - Auto/Visual Lisp: [Select]
  1.  
  2. (defun CommandReactor:Start ()
  3.   (or *CommandReactor*
  4.       (setq *CommandReactor*
  5.              (vlr-command-reactor
  6.                "My command reactor"
  7.                '(
  8.                  (:vlr-commandEnded . Callback:CommandEnded)
  9.                 )
  10.              )
  11.       )
  12.   )
  13.   (prompt "\nCommand reactor loaded. ")
  14.   (princ)
  15. )
  16.  
  17. (defun Callback:CommandEnded (rea cmd / cmdName)
  18.   (cond
  19.     ;; condition 1
  20.     ((wcmatch (setq cmdName (strcase (car cmd)))
  21.               "*COPY,*DROPGEOM,*EXECUTETOOL,*INSERT*,*PASTECLIP"
  22.      )
  23.      ;; <-- This is where you should conditionally do your work
  24.      (prompt "\n** Bow ties are cool ** ")
  25.     )
  26.  
  27.     ;; <-- Other conditions
  28.   )
  29. )
  30.  
  31. (defun c:StopR ()
  32.   (if *CommandReactor*
  33.     (progn
  34.       (vlr-remove *CommandReactor*)
  35.       (setq *CommandReactor* nil)
  36.       (prompt "\n** Command reactor stopped ** ")
  37.     )
  38.   )
  39.   (princ)
  40. )
  41.  
  42. (CommandReactor:Start)
  43.  
« Last Edit: January 17, 2013, 06:18:13 PM by RenderMan »
"How we think determines what we do, and what we do determines what we get."

Rabbit

  • Guest
Re: Reactor Problem
« Reply #3 on: January 17, 2013, 06:41:24 PM »
Not a COMMAND call, but a KWORD call.  I'll look over your post and see what I can learn from it.

I've decided to post all of it here, so bear with me.  It's ugly, but all of it works except for one part.
If something is missing, like a subroutine, let me know.

Code - Auto/Visual Lisp: [Select]
  1. ;;;------------------------------------------------------------------------------------------------
  2. ;;;------------------------------------------------------------------------------------------------
  3.  
  4.  
  5. ;;;------------------------------------------------------------------------------------------------
  6. ;;                                                                             
  7. ;;  Modifies the last dynamic block inserted into the drawing.                 
  8. ;;  ____________________________________________________________________________
  9. ;;                                                                             
  10. ;;  Parameters:                                                                
  11. ;;  lstProp - a list of parameters and values                                  
  12. ;;                                                                             
  13. ;;  Examples:                                                                  
  14. ;;  (ModifyBlock (list "DynamicBlockParmatername" DynamicBlockValue))          
  15. ;;  (ModifyBlock (list "Angle" 1.5708 "Length" 0.2))                           
  16. ;;
  17.  
  18. ;;;(ModifyBlock (list "HASH STYLE" "4 HOT"))
  19.  
  20. (defun ModifyBlock (lstProp / ename selset index oBkRef sProp oProps i j)
  21.   (setq selset (ssget "L"))
  22.   (setq i 0)
  23.   (while (< i (sslength selset))
  24.     (setq ename  (ssname selset i))
  25.     (setq oBkRef (vlax-ename->vla-object ename))
  26.     (setq oProps (vlax-variant-value (vla-GetDynamicBlockProperties oBkRef)))
  27.     (setq j 0)
  28.     (while (< j (length lstProp))
  29.       (setq sProp (strcase (nth j lstProp)))
  30.       (setPropValue oProps sProp (nth (1+ j) lstProp))
  31.       (setq j (+ 2 j))
  32.     )
  33.     (setq i (1+ i))
  34.   )
  35.   (princ)
  36. )
  37. ;;                                                                             
  38. ;;  Sets the new property of a dynamic block.                                  
  39. ;;                                                                             
  40. (defun setPropValue (oProps sProp Val / i oSBReferenceProperty sPName iFound)
  41.   (setq i (vlax-safearray-get-l-bound oProps 1))
  42.   (setq iFound 0)
  43.   (while (and (<= i (vlax-safearray-get-u-bound oProps 1)) (= iFound 0))
  44.     (setq oSBReferenceProperty (vlax-safearray-get-element oProps i))
  45.     (setq sPName (vla-get-PropertyName oSBReferenceProperty))
  46.     (if (= (strcase sPName) sProp)
  47.       (progn
  48.         (vla-put-value
  49.           oSBReferenceProperty
  50.           (vlax-make-variant
  51.             Val
  52.             (vlax-variant-type (vla-get-value oSBReferenceProperty))
  53.           )
  54.         )
  55.         (setq iFound 1)
  56.       )
  57.     )
  58.     (setq i (1+ i))
  59.   )
  60.   (princ)
  61. )
  62.  
  63. ;;;------------------------------------------------------------------------------------------------
  64. (defun GetDynamicBlockParameters (LastEntitiyName / ParameterCount oSBReferenceProperty)
  65. ;;;  (SETQ LastEntitiyName (CAR (ENTSEL)))
  66.     (setq oSBReferenceProperty (vlax-safearray-get-element
  67.                                  (vlax-variant-value
  68.                                    (vla-GetDynamicBlockProperties
  69.                                      (vlax-ename->vla-object LastEntitiyName)))
  70.                                0)
  71.     );setq
  72.     (setq ParameterName (vla-get-propertyname oSBReferenceProperty))
  73.  
  74. (setq cnt 1)
  75.   (while (/= ParameterName (LM:GetVisibilityParameterName (vlax-ename->vla-object LastEntitiyName)))
  76.     (progn
  77.         (setq oSBReferenceProperty (vlax-safearray-get-element
  78.                                  (vlax-variant-value
  79.                                    (vla-GetDynamicBlockProperties
  80.                                      (vlax-ename->vla-object LastEntitiyName)))
  81.                                cnt)
  82.     );setq
  83.     (setq ParameterName (vla-get-propertyname oSBReferenceProperty))
  84.       (setq cnt (1+ cnt))
  85. )
  86. )
  87.  
  88.  
  89.     (setq ParameterValueList nil)
  90.     (setq ParameterCount (vlax-safearray-get-u-bound
  91.                            (vlax-variant-value
  92.                              (vla-get-allowedvalues oSBReferenceProperty))
  93.                          1))
  94.     (while (> ParameterCount -1)
  95.       (setq ParameterValue (vlax-variant-value
  96.                              (vlax-safearray-get-element
  97.                                (vlax-variant-value
  98.                                  (vla-get-allowedvalues oSBReferenceProperty))
  99.                              ParameterCount))
  100.       );setq    gets elements of a safearray
  101.       (setq ParameterValueList (cons ParameterValue ParameterValueList))
  102.       (setq ParameterCount (1- ParameterCount))
  103.     )
  104.  
  105. );defun
  106.  
  107. ;;;------------------------------------------------------------------------------------------------
  108.  
  109. ;;-----------=={ Get Visibility Parameter Name }==------------;;
  110. ;;                                                            ;;
  111. ;;  Returns the name of the Visibility Parameter of a         ;;
  112. ;;  Dynamic Block (if present).                               ;;
  113. ;;------------------------------------------------------------;;
  114. ;;  Author: Lee Mac, Copyright © 2011 - www.lee-mac.com       ;;
  115. ;;------------------------------------------------------------;;
  116. ;;  Arguments:                                                ;;
  117. ;;  block  -  VLA (Dynamic) Block Reference Object            ;;
  118. ;;------------------------------------------------------------;;
  119. ;;  Returns:  Name of Visibility Parameter, else nil          ;;
  120. ;;------------------------------------------------------------;;
  121.  
  122. (defun LM:GetVisibilityParameterName ( block / visib )  
  123.     (if
  124.         (and
  125.             (vlax-property-available-p block 'effectivename)
  126.             (setq block
  127.                 (vla-item
  128.                     (vla-get-blocks (vla-get-document block))
  129.                     (vla-get-effectivename block)
  130.                 )
  131.             )
  132.             (eq :vlax-true (vla-get-isdynamicblock block))
  133.             (eq :vlax-true (vla-get-hasextensiondictionary block))
  134.             (setq visib
  135.                 (vl-some
  136.                     (function
  137.                         (lambda ( pair )
  138.                             (if
  139.                                 (and
  140.                                     (= 360 (car pair))
  141.                                     (eq "BLOCKVISIBILITYPARAMETER" (cdr (assoc 0 (entget (cdr pair)))))
  142.                                 )
  143.                                 (cdr pair)
  144.                             )
  145.                         )
  146.                     )
  147.                     (dictsearch
  148.                         (vlax-vla-object->ename (vla-getextensiondictionary block))
  149.                         "ACAD_ENHANCEDBLOCK"
  150.                     )
  151.                 )
  152.             )
  153.         )
  154.         (cdr (assoc 301 (entget visib)))
  155.     )
  156. )
  157.  
  158.  
  159. ;;;------------------------------------------------------------------------------------------------
  160. ;;;Only looks for blocks that start with a number
  161. (defun _BLOCKLIST ( / lst)
  162.     (if
  163.       (and
  164.         (= :vlax-false (vla-get-isxref blk))
  165.         (wcmatch (vla-get-name blk) "#*")
  166.       );and
  167.       (setq lst (cons (vla-get-name blk) lst))
  168.     );if
  169.   );vlax-for
  170.   (vl-sort lst '<)
  171. );defun
  172.  
  173. ;;;------------------------------------------------------------------------------------------------
  174. (defun c:IB (/ ZoomCenter ZoomViewSize Block2Insert Block2InsertObject Block2InsertEntity)
  175.   (setvar "OSMODE" (boole 2 (getvar "OSMODE") 16384));osmode on
  176.   (setq Block2Insert (car (listbox "Choose block to insert: " (append '("<PICK BLOCK FROM SCREEN>") (_BLOCKLIST)) nil)))
  177.   (setq ZoomCenter (getvar "viewctr")
  178.         ZoomViewSize (getvar "viewsize"))
  179.   (cond
  180.     ((= nil Block2Insert) (exit))
  181.     ((= "<PICK BLOCK FROM SCREEN>" Block2Insert)
  182.      (setq Block2InsertEntity (car (entsel "\nPick Block to insert: \n")))
  183.      (if (not Block2InsertEntity) (progn (command "_.zoom" "_C" "_non" ZoomCenter ZoomViewSize) (exit)))
  184.      (setq Block2Insert (vla-get-effectivename (setq Block2InsertObject (vlax-ename->vla-object Block2InsertEntity))))
  185.      (command "_Zoom" "C" ZoomCenter ZoomViewSize)
  186.      (setvar "clayer" (vla-get-layer Block2InsertObject))
  187.      (if (= 1 (vlax-get-property (vla-Item (vla-get-blocks (vla-get-ActiveDocument (vlax-get-acad-object))) Block2Insert) 'BlockScaling))
  188.        (command "insert" Block2Insert "\\" (cdr (assoc 41 (entget Block2InsertEntity)))  "\\")
  189.        (command "insert" Block2Insert "\\" (cdr (assoc 41 (entget Block2InsertEntity))) (cdr (assoc 41 (entget Block2InsertEntity))) "\\")
  190.      );if
  191.     );end test
  192.     (T (if (= 1 (vlax-get-property (vla-Item (vla-get-blocks (vla-get-ActiveDocument (vlax-get-acad-object))) Block2Insert) 'BlockScaling))
  193.        (command "insert" Block2Insert "\\" 1  "\\")
  194.        (command "insert" Block2Insert "\\" 1 1 "\\")
  195.      );if
  196.     );T
  197.   );cond
  198. );defun
  199.  
  200. ;;;------------------------------------------------------------------------------------------------
  201. (if (not Command_Ending_Reactor)
  202.   (setq Command_Ending_Reactor
  203.          (vlr-command-reactor nil '((:vlr-commandended . Command_Ended_Command))) ;_ end of vlr-command-reactor
  204.   ) ;_ end of setq
  205.   () ;_ the reactor is already loaded
  206. ) ;_ end of if you use this first portion of code to make sure the reactor is loaded, the reactor should only be loaded once otherwise you could see some unpleasant consequences
  207.  
  208. (defun Command_Ended_Command (In_ReactorName In_Command / ModList); then you need to define the callback function (the simpler the name the better)
  209.   (alert (car In_Command )) ;; <-- Remove this line, it shows all incomming command
  210.   (cond; my current version checks for several different input commands to decide which programs to run, it may not be the most efficient, but it works for now (I am open to suggestions to improve my code structure) I have eliminated additional sections for simplicity sake.
  211.     ((or
  212.        (= (car In_Command) "INSERT")
  213.        (= (car In_Command) "-INSERT")
  214.        (= (car In_Command) "PASTECLIP")
  215.        (= (car In_Command) "DROPGEOM")
  216.        (= (car In_Command) "ACDCINSERTBLOCK")
  217.        (= (car In_Command) "EXECUTETOOL")
  218.        (= (car In_Command) "COPY")
  219.        (= (car In_Command) "-COPY")
  220.      ) ;_ end of or finally the commands that are executed when a tool is selected from the tool palette, or even when it is inserted from the original block.
  221.      (if (LM:GetVisibilityParameterName (vlax-ename->vla-object (entlast)))
  222.       (progn
  223.         (setq DynMode (getvar "dynmode")
  224.               ParameterSetinitget nil
  225.               ParameterSetmessage nil)
  226.         (setvar "dynmode" 3)
  227.         (GetDynamicBlockParameters (entlast))
  228.         (setq MyKeyWords ParameterValueList)
  229.         (setq ModList (mapcar '(lambda ( x ) (vl-string-translate "//" "-" (vl-string-translate " " "-" (vl-string-translate "_" "-" x)))) ParameterValueList))
  230.         (setq ParameterCount (1- (length ParameterValueList)))
  231.         (while (> ParameterCount -1)
  232.           (setq ParameterSetTemp (nth ParameterCount ModList))
  233.           (if (not ParameterSetinitget)
  234.             (setq ParameterSetinitget ParameterSetTemp)
  235.             (setq ParameterSetinitget (strcat ParameterSetTemp " " ParameterSetinitget)))
  236.           (if (not ParameterSetmessage)
  237.             (setq ParameterSetmessage ParameterSetTemp)
  238.             (setq ParameterSetmessage (strcat ParameterSetTemp "/" ParameterSetmessage)))
  239.           (setq ParameterCount (1- ParameterCount))
  240.         );while
  241.         (initget ParameterSetinitget)
  242.  
  243.         ;;;!!!!HERE'S WHERE IT ALL COLLAPSES!!!!
  244.        
  245.         (setq s (getkword
  246.             (strcat "\n" (strcat "\nType [" ParameterSetmessage "]")
  247.                     (cond (StringInput (strcat " <" Answer ">: "))
  248.                           (t ": ")))))
  249.         (setq Answer (cond ((eq s nil) Answer) (t s)))
  250.         (setq  ParameterType (nth (vl-position Answer ModList) MyKeyWords))
  251.         (ModifyBlock (list ParameterName ParameterType))
  252.         (setvar "dynmode" DynMode)
  253.       );progn
  254.     );if
  255.    ) ;_ end cond4
  256.   ) ;_ end of cond
  257. ) ;_ end of defun
  258.  

BlackBox

  • King Gator
  • Posts: 3770
Re: Reactor Problem
« Reply #4 on: January 17, 2013, 07:14:07 PM »
Not a COMMAND call, but a KWORD call.

From AfraLISP in this multi-part series on Reactors:

Quote from: Reactors - Part 2, by Kenny Ramage
You cannot use interactive functions from within a reactor as AutoCAD may still be processing a command at the time the event is triggered. Therefore, avoid the use of input-acquisition methods such as getPoint, ensel, and getkword, as well as "selection set" operations and the command function.
"How we think determines what we do, and what we do determines what we get."