Author Topic: Undo on Reactors  (Read 3130 times)

0 Members and 1 Guest are viewing this topic.

Marco Jacinto

  • Newt
  • Posts: 47
Undo on Reactors
« on: November 13, 2007, 08:38:57 PM »
I'm attempting to create a reactor that triggers when the plot command is issued, I already have the commandwillstart reactor and its callback function, in this I make some modifications to my Title Block and other objects.

The problem that I have, is if the user cancells the plot, I like to revert the drawing to the state it was before the plot command. Actually I can do this using the vla-sendcommand function, is there another method?.

In my error handler I use vla-startUndoMark and vla-endUndoMark, but I never asked myself about to programatically undo the tasks, how do you acomplish this?? Via (command "undo" "")?

Hope my English is clear enough.

TIA

Saludos
Marco Jacinto

ronjonp

  • Needs a day job
  • Posts: 7531
Re: Undo on Reactors
« Reply #1 on: November 13, 2007, 09:02:19 PM »
Maybe this can help you:

Code: [Select]
;;COMMAND REACTORS
(if (not *CommandReactors*)
  (setq *CommandReactors*
(vlr-command-reactor
   nil
   '((:vlr-commandWillStart . StrtCMD)
     (:vlr-commandEnded . EndCMD)
     (:vlr-commandCancelled . CnclCMD)
     (:vlr-commandFailed . FaldCMD)
    )
)
  )
)
(defun StrtCMD (calling-reactor StrtCMDInfo / theCMDStrt)
  (setq theCMDStrt (strcase (nth 0 StrtCMDInfo) t))
  (cond
    ((wcmatch theCMDStrt "*plot*")
     ;;do stuff here
    )
  )
)
(defun EndCMD (calling-reactor EndCMDInfo / theCMDEnd)
  (setq theCMDEnd (strcase (nth 0 EndCMDInfo) T))
  (cond
    ((wcmatch
       theCMDEnd
       "*plot*"
     )
     ;;do stuff here
    )
  )
)
(defun CnclCMD (calling-reactor CnclCMDInfo / theCMDCncl)
  (setq theCMDCncl (strcase (nth 0 CnclCMDInfo) T))
  (cond
    ((wcmatch
       theCMDCncl
       "*plot*"
     )
     ;;do stuff here
    )
  )
)
(defun FaldCMD (calling-reactor FaldCMDInfo / theCMDFald)
  (setq theCMDFald (strcase (nth 0 FaldCMDInfo) T))
  (cond
    ((wcmatch
       theCMDFald
       "*plot*"
     )
     ;;do stuff here
    )
  )
)
« Last Edit: November 13, 2007, 09:07:47 PM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

LE

  • Guest
Re: Undo on Reactors
« Reply #2 on: November 14, 2007, 11:02:27 AM »
I'm attempting to create a reactor that triggers when the plot command is issued, I already have the commandwillstart reactor and its callback function, in this I make some modifications to my Title Block and other objects.

The problem that I have, is if the user cancells the plot, I like to revert the drawing to the state it was before the plot command. Actually I can do this using the vla-sendcommand function, is there another method?.

In my error handler I use vla-startUndoMark and vla-endUndoMark, but I never asked myself about to programatically undo the tasks, how do you acomplish this?? Via (command "undo" "")?

Hope my English is clear enough.

TIA

Saludos
Marco Jacinto

Marco;

Si usas un comando de lisp para implementar el reactor, puedes implementar la funcion de *error* y en ella despues de remover tu reactor, usar command undo.

Si, utilizas un reactor global, entonces deberas de pasar los objetos que desees al reactor ya sea como notificadores o dependientes, y dentro de los callbacks o eventos hacer las modificaciones pertinentes [por decir en cuanto comienze el comando plot, guardas el estado de tus objetos y lo utilizas en caso de cancelar]. Por ejemplo si se cancela pues, en ese evento usas vlr-data extraes los objetos y los modificas a su estado anterior.

Se, puede tambien monitorear los objetos con los reactores vlr-acdb-reactor

Haber si entendi.... quieres que el usuario no utilize la llamada de Undo, verdad? - Suerte!

Krushert

  • Seagull
  • Posts: 13679
  • FREE BEER Tomorrow!!
Re: Undo on Reactors
« Reply #3 on: November 14, 2007, 12:35:35 PM »
Marco;

Si usas un comando de lisp para implementar el reactor, puedes implementar la funcion de *error* y en ella despues de remover tu reactor, usar command undo.

Si, utilizas un reactor global, entonces deberas de pasar los objetos que desees al reactor ya sea como notificadores o dependientes, y dentro de los callbacks o eventos hacer las modificaciones pertinentes [por decir en cuanto comienze el comando plot, guardas el estado de tus objetos y lo utilizas en caso de cancelar]. Por ejemplo si se cancela pues, en ese evento usas vlr-data extraes los objetos y los modificas a su estado anterior.

Se, puede tambien monitorear los objetos con los reactores vlr-acdb-reactor

Haber si entendi.... quieres que el usuario no utilize la llamada de Undo, verdad? - Suerte!

[Referee]
**Whistle**
Technical Foul on the grounds that others can not learn from your wisdom.
However, I can imagine that is very enjoying to speak in your native tongue so penalty declined
[/Referee]
 :lol: :lol:

Just me being pita.
 :-)
I + XI = X is true ...  ... if you change your perspective.

I no longer CAD or Model, I just hang out here picking up the empties beer cans

LE

  • Guest
Re: Undo on Reactors
« Reply #4 on: November 14, 2007, 01:24:03 PM »
:-)

Here is now in English, my previous post:

Quote
Marco;

If you use a lisp command that includes reactors, then you can implement the *error* function and have in there the removal of your reactor and after that a call of the command Undo.

Now, if you have your reactor as global, then you need to pass your objects as dependants or notifiers and inside of the callbacks do your pertinent modifications [for example when the plot command starts, save the state of your objects and use them in the canceled callback]. For example if being canceled by the user, in that callback extract from the vlr-data your objects and modify them to their original state.


You can monitor the objects via vlr-acdb-reactor.


Let me see if I understood.... you want to run an undo without any user intervention... no? - Good luck!

Marco Jacinto

  • Newt
  • Posts: 47
Re: Undo on Reactors
« Reply #5 on: November 14, 2007, 03:33:46 PM »
Gracias Luis, tu apreciacion del undo es correcta, se que no debo usar command en el  reactor, por eso utilizo sendcommand, lo que trato de evitar es el eco del mismo en la linea de comandos.

Tu opcion de grabar el estado de los objetos es buena, pero creo que por el momento escapa mis posibilidades. Por lo pronto dejare la rutina tal como esta, y despues regresare para implementar tu sugerencia.

En el control de errores que uso, tambien uso la funcion *error*, y las funciones vla-XXXXundomark, solo queria saber si hay una alternativa al uso del comando Undo, para regresar al estado anterior al error.

Gracias por tu tiempo.

Thanks Luis, your apreciation abuot the usage of undo is correct, I already know that I should not use the command function inside any reactor, instead I use Sendcommand, but what I'm trying to avoi is de echo in command line.

Your opcion about to save the current state of the objects before the Plot comand is great, but by now it is beyond my knowledge. Right now I will let my funtion just the way it is, and later I will try to implement your suggestion.

The error handler I use, has the *error¨* and XXXUndoMark fucntions, I just wanted to now if there is another way to get the previous state before the error happens, without using the command "undo".

Thanks for your time.

Saludos
Marco Jacinto

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Undo on Reactors
« Reply #6 on: November 14, 2007, 03:50:54 PM »
What are you doing in your routine?  I have some plot reactors that work.  The put on a text item if the current space being plotted does not have our border, and if it does, then it populate an attribute.  Once the command is done (by cancel or otherwise) the clean up part runs which deletes the temp text object, or puts the value of the attribute back to an empty string.

Here is my code just incase.
Code: [Select]
;================================================================================================

(defun BeginPlotReactor (Reactor CommandName / ActDoc CurSpace BlkCol AttList InsPt Str TxtHt
                                               tmpList tmpDate)
; Add plot stamp if not added in title block.

(if (vl-string-search "PLOT" (car CommandName))
 (progn
  (setq ActDoc (vla-get-ActiveDocument (vlax-get-Acad-Object)))
  (setq CurSpace (GetCurrentSpace ActDoc))
  (setq tmpDate (GetDate))
  (setq InsPt (list (car (getvar "extmax")) (cadr (getvar "extmin")) (caddr (getvar "extmin"))))
  (setq Str (strcat tmpDate "  -TMW-  " (getvar "dwgprefix") (getvar "dwgname")))
  (if (= (getvar "cvport") 1)
   (setq TxtHt 0.15)
   (setq TxtHt (* 0.15 (getvar "dimscale")))
  )
  (if (= TxtHt 0)
   (setq TxtHt 0.15)
  )
  (setq BlkCol (vla-get-Blocks ActDoc))
  (vlax-for Blk BlkCol
   (if (member (vla-get-Name Blk) '("3M-BORDER-A" "3M-BORDER-B" "3M-BORDER-C" "3M-BORDER-D" "3M-BORDER-E" "3M-BORDER-E1"))
    (setq tmpList (cons (vla-get-Name Blk) tmpList))
   )
  )
  (vlax-for Obj CurSpace
   (if (member (vl-catch-all-apply 'vla-get-Name (list Obj)) tmpList)
    (progn
     (setq AttList (safearray-value (variant-value (vla-GetAttributes Obj))))
     (setq GlbVarPlotAtt (nth 64 AttList))
     (vla-put-TextString GlbVarPlotAtt Str)
    )
   )
  )
  (if (not GlbVarPlotAtt)
   (progn
    (setq GlbVartmpTxt (vla-AddText CurSpace Str (vlax-3d-point InsPt) TxtHt))
    (vla-put-Alignment GlbVartmpTxt 8)
    (vla-put-TextAlignmentPoint GlbVartmpTxt (vlax-3d-point InsPt))
   )
  )
 )
)
)
;--------------------------------------------------------------------------------------
(defun EndPlotReactor (Reactor CommandName / )
; Erase my plot stamp if there.

(if (vl-string-search "PLOT" (car CommandName))
 (progn
  (vl-catch-all-apply 'vla-Delete (list GlbVartmpTxt))
  (vl-catch-all-apply 'vla-put-TextString (list GlbVarPlotAtt ""))
  (setq GlbVartmpTxt nil GlbVarPlotAtt nil)
 )
)
)
;--------------------------------------------------------------------------------------
(if (not tmw:ReactorBeginPlot)
 (setq tmw:ReactorBeginPlot (vlr-command-reactor nil '((:vlr-commandWillStart . BeginPlotReactor))))
)
;--------------------------------------------------------------------------------------
(if (not tmw:ReactorEndPlot)
 (setq tmw:ReactorEndPlot (vlr-command-reactor nil '((:vlr-commandEnded . EndPlotREactor))))
)
;--------------------------------------------------------------------------------------
(if (not tmw:ReactorCancelPlot)
 (setq tmw:ReactorCancelPlot (vlr-command-reactor nil '((:vlr-commandCancelled . EndPlotREactor))))
)
;--------------------------------------------------------------------------------------
(if (not tmw:ReactorFailedPlot)
 (setq tmw:ReactorFailedPlot (vlr-command-reactor nil '((:vlr-commandFailed . EndPlotREactor))))
)
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Marco Jacinto

  • Newt
  • Posts: 47
Re: Undo on Reactors
« Reply #7 on: November 14, 2007, 07:42:31 PM »
What I'm doing is scaling some objects acording to vport scale when the Plot command is fired, I think the only way to not to use sendcommand is what Luis sugested.

Thanks

Saludos
Marco Jacinto

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Undo on Reactors
« Reply #8 on: November 14, 2007, 07:55:48 PM »
What I'm doing is scaling some objects acording to vport scale when the Plot command is fired, I think the only way to not to use sendcommand is what Luis sugested.

Thanks

Saludos
Marco Jacinto

Yea.   I would just put the objects into a global list with the old scale values.  The put them back after the plot ends.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.