Login

View Full Version : Reactor Problems



relysoft
2005-03-03, 11:19 PM
Thanks to some of you here on the forum, I was able to implement a couple of reactors that trap text editing operations and modify the color and obliquing angle of the modified text. The drafting supervisor loves it.

However, the reactors are apparently causing ACAD to crash when some large script (.SCR) files that create production drawings are executed. The scripts are fairly involved and call some LISP routines that I have written. The crashes never occurred before the introduction of the reactors. If I disable the reactors, no crashes occur.

The errors reported are along the lines of:

FATAL ERROR: Unhandled access violation reading .....
FATAL ERROR: Unhandled access violation writing ....

My guess would be that I am messing up memory somehow by introducing these reactors, but I cannot see anything wrong with the logic. The code executed when a "commandended" event occurs looks for MTEDIT and DDEDIT commands. The script files never include either of these commands.

The code associated with the reactors is below - anyone care to take a shot at this?

Thanks,
Bob


; Establish reactors for text editing control
;
(setq rxnObjectModified (vlr-acdb-reactor nil
'((:vlr-objectModified . catch_evtobjectModified )))
rxnCommandEnded (vlr-editor-reactor nil
'((:vlr-commandended . evtCommandEnded))))
;
;>>>>>>>>>>
;(trace catch_evtobjectModified)
;
(defun catch_evtobjectModified (objReactor lstObjModified / errobj)
;
; Purpose: An error catching wrapper function for the OjbectModified event
; handler used for text editing. Need this function to catch and
; suppress the reporting of all random errors that are associated
; with handling of the objectModifed events. This is simply a fallout
; of the way reactors work. Not elegant, but effective.
;
; Input: objReactor Object Reactor Object that called the function
;
; lstobjModified ojbect Id of modified ACAD object
;
; Returns: No returned value
;
(setq errobj (vl-catch-all-apply 'evtobjectmodified
(list objReactor lstobjmodified)))
; (if (vl-catch-all-error-p errobj)
; (print (vl-catch-all-error-message errobj))
; )
) ; end defun
;
;
;(trace evtObjectModified)
;
(defun evtObjectModified (objReactor lstObjectModified / objModified)
;
; Purpose: To build a list of object ID's for text objects modified
; This list is subsequently processed in a callback routine
; fired off by the CommandEnded event. That function modifies
; the text objects in the list by changing the obliquing angle,
; plotstyle and color.
;
; Input: objReactor Object Reactor Object that called the function
;
; lstobjModified ojbect Id of modified ACAD object
;
; Returns: No returned value
;
; Note: This function is a reactor callback function that has been
; "wrapped" by an error catching function (catch_evtobjectModified)
; in order to suppress spuious error messages.
;
(setq objModified (vlax-ename->vla-object (cadr lstObjectModified)))
(if (and (wcmatch (vla-get-objectname objModified) "AcDbMText,AcDbText")
(not blnRerun))
(setq lstObjectsModified (cons objModified lstObjectsModified))
) ; end if
(princ)
) ; end defun rxnobj
;
(setq KBS@ "evtObjectModified")
;
;
;>>>>>>>>>>
;(trace evtCommandEnded)
;
(defun evtCommandEnded (evtCall lstCallback / cmd objModified temp tstyle)
(setq cmd (car lstCallBack))
(if (and lstobjectsmodified (or (= cmd "DDEDIT")
(= cmd "MTEDIT")))
(progn
;
; Disable modification reactor before modifying data.
; Otherwise it get called for each property change.
;
(vlr-remove rxnobjectModified)
(setq blnRerun 'T)
(if KBS_GV_USR_TXTEDT
(progn
(foreach objModified lstObjectsModified
(vla-put-color objModified 4)
(if (= 0 (getvar "pstylemode"))
(progn
(vla-put-PlotStyleName objModified "HEAVY")
) ; end progn
) ; end if
;
; For "TEXT" text, change the obliquing angle
; For "MTEXT" text, must change styles
;
(if (vlax-property-available-p objModified "ObliqueAngle")
(vla-put-ObliqueAngle objModified 0.345)
(progn
(if (setq tstyle (kbs_get_oblique_style objModified))
(vla-put-StyleName objModified tstyle)
) ; end if
) ; end progn
) ; end if
) ; end foreach
) ; end progn
) ; end if
;
; Re-enable modification reactor in order to catch next user modification
;
(vlr-add rxnobjectModified)
) ; end progn
) ; end if
(setq blnRerun nil)
(setq lstObjectsModified nil)
(princ)
) ; end defun evtCommandEnded
;
(setq KBS@ "evtCommandEnded")
;

peter
2005-03-04, 12:48 PM
Add a line of code to your routine that makes it skip the reaction when a script is running

(if (= (getvar "cmdactive") 4); means that a script file is active

You will have to play around with it to figure out just where to put it.

Peter Jamtgaard

relysoft
2005-03-04, 02:21 PM
Thanks, Peter.

I will give that a try. I was trying to figure out a way to do something like that, but didn't
know that the "cmdactive" variable was the key.

Thanks again. I'll post an update after I have given it a try.

Bob

relysoft
2005-03-04, 03:55 PM
Peter,

I added code to the front of the callback routines checking the value of "cmdactive". I do not execute the body of those functions if the value is 4 or 5. This appears to solve the problem.

Wish I understood why the crashes when executing these routines during the script execution. But, life calls and I must just accept the success of the work around and move on to the next "opportunity".

Thanks for "being there" for me again.

Bob