Author Topic: vlr-remove not removing Object Reactor inside Callback Function  (Read 8990 times)

0 Members and 1 Guest are viewing this topic.

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Having spent some time pulling my hair out whilst trying to figure out why my reactor callback functions were continuously being evaluated, I believe I have isolated the issue to a possible bug with the vlr-remove function wherein object reactors are not actually removed by this function.

I have put together the following simple code to demonstrate the issue I am experiencing:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:addreactor ( / en )
  2.     (if (setq en (car (entsel)))
  3.         (setq object-reactor
  4.             (vlr-object-reactor (list (vlax-ename->vla-object en)) "My Object Reactor"
  5.                '((:vlr-modified . mycallback))
  6.             )
  7.         )
  8.     )
  9.     (princ)
  10. )
  11.  
  12. (defun mycallback ( owner reactor params )
  13.     (princ "\nCallback Evaluated.")
  14.     (print (vlr-remove reactor))
  15.     (princ)
  16. )

Steps to recreate problem:
  • Create a circle in the drawing (or any object in fact)
  • Run the above program 'addreactor' and click on the created circle
  • Move the circle
Now, at this point the circle has been modified and so the reactor callback function will be evaluated, printing the message 'Callback Evaluated' at the command-line.

Within the callback function the calling object reactor is removed using vlr-remove, and hence the callback function should no longer be evaluated if the circle is modified again.

However, I find the following unexpected result:

Code - Auto/Visual Lisp: [Select]
  1. Command: _circle Specify center point for circle or [3P/2P/Ttr (tan tan radius)]:
  2. Specify radius of circle or [Diameter]:
  3. Command: addreactor
  4.  
  5. Select object:
  6. Command: m MOVE 1 found
  7.  
  8. Specify base point or [Displacement] <Displacement>:
  9. Specify second point or <use first point as displacement>:
  10. Callback Evaluated.  ;; <-------------- Callback evaluated as expected, Reactor should now be removed.
  11. #<VLR-Object-Reactor> ;; <-------------- vlr-remove returns Reactor Object, indicating removal is successful
  12. Command: m MOVE 1 found
  13.  
  14. Specify base point or [Displacement] <Displacement>:
  15. Specify second point or <use first point as displacement>:
  16. Callback Evaluated.  ;; <--------------  Callback still being evaluated even after reactor is removed.
  17. nil ;; <-------------- vlr-remove returning nil as reactor has already been removed.

This is even weirder:

Code - Auto/Visual Lisp: [Select]
  1. Command: _circle Specify center point for circle or [3P/2P/Ttr (tan tan radius)]:
  2. Specify radius of circle or [Diameter]:
  3. Command: addreactor
  4.  
  5. Select object:
  6. Command: m MOVE 1 found
  7.  
  8. Specify base point or [Displacement] <Displacement>:
  9. Specify second point or <use first point as displacement>:
  10. Callback Evaluated. ;; <--------------  Reactor should now be removed.
  11. #<VLR-Object-Reactor> ;; <-------------- vlr-remove returns Reactor object, indicating removal is successful
  12. Command: (vlr-added-p object-reactor)
  13. nil ;; <-------------- Verifying that Reactor has been removed
  14.  
  15. nil ;; <-------------- Verifying that no Reactors are running
  16.  
  17. Command: m MOVE 1 found
  18.  
  19. Specify base point or [Displacement] <Displacement>:
  20. Specify second point or <use first point as displacement>:
  21. Callback Evaluated. ;; <-------------- Yet callback STILL being evaluated... WTF
  22. nil

Can any of you guys replicate this behaviour? Or maybe spot a mistake in my method?
« Last Edit: August 26, 2012, 08:10:01 AM by Lee Mac »

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: vlr-remove function not removing Object Reactors
« Reply #1 on: August 25, 2012, 09:18:52 PM »
Same here in ACAD2006.
Using this:
Code: [Select]
(defun c:removeowner (/ en)
  (if (and object-reactor (setq en (car (entsel))))
    (print (vlr-owner-remove object-reactor (vlax-ename->vla-object en)))
  )
  (princ)
)

It works only if the reactor has not been fired, if it has been fired the circle is returned
but the reactor continues to fire.

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.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: vlr-remove function not removing Object Reactors
« Reply #2 on: August 25, 2012, 09:22:50 PM »
Adding back trace yields nothing useful.
** STRETCH **
Specify stretch point or [Base point/Copy/Undo/eXit]: Backtrace:
[0.18] (VL-BT)
[1.14] (MYCALLBACK #<VLA-OBJECT IAcadCircle 0b8b3a64> #<VLR-Object-Reactor> nil) LAP+7
:CALLBACK-ENTRY.6 (:CALLBACK-ENTRY)
:REACTOR-CALLBACK.3 :REACTOR-CALLBACK

Callback Evaluated.
nil


This is no help
Command: (vlr-remove-all :vlr-object-reactor)
nil

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.

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: vlr-remove function not removing Object Reactors
« Reply #3 on: August 26, 2012, 07:13:22 AM »
Thank you very much for your time spent testing Alan, I appreciate your assistance  :-)

After some more experimentation on my side, I have further isolated the problem and have found that it only occurs when removing the object reactor from within its callback function.

I tried using the following callback function instead :

Code - Auto/Visual Lisp: [Select]
  1. (defun mycallback ( owner reactor params )
  2.    (princ "\nCallback Evaluated.")
  3.    (princ)
  4. )

And here are is my results from the command-line:

Code - Auto/Visual Lisp: [Select]
  1. Command: _circle
  2. Specify center point for circle or [3P/2P/Ttr (tan tan radius)]:
  3. Specify radius of circle or [Diameter]:
  4. Command: addreactor
  5.  
  6. Select object:
  7. Command: m MOVE 1 found
  8.  
  9. Specify base point or [Displacement] <Displacement>:
  10. Specify second point or <use first point as displacement>:
  11. Callback Evaluated. ;; <-------------- Callback evaluated
  12. Command: (vlr-remove object-reactor) ;; <-------------- Reactor now removed 'manually'
  13. #<VLR-Object-Reactor> ;; <-------------- Reactor removed successfully
  14.  
  15. Command: m MOVE 1 found
  16.  
  17. Specify base point or [Displacement] <Displacement>:
  18. Specify second point or <use first point as displacement>:
  19. ;; <-------------- Callback not evaluated!

So in conclusion at this point:

If vlr-remove is evaluated from within the callback function, the Reactor is 'registered' as being removed (i.e. the VLA Reactor Object is returned and the vlr-remove* functions no longer have any effect) but the Reactor isn't actually removed since the callback is still evaluated.
 
« Last Edit: August 26, 2012, 07:19:28 AM by Lee Mac »

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: vlr-remove not Removing Object Reactor inside Callback Function
« Reply #4 on: August 26, 2012, 07:46:18 AM »
After some testing with a Command Reactor, I have found that this problem only appears to apply to removing Object Reactors from within their own callback functions.

Using this code:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:addreactor ( )
  2.     (setq com (vlr-command-reactor "My Command Reactor" '((:vlr-commandended . mycallback))))
  3.     (princ)
  4. )
  5.  
  6. (defun mycallback ( reactor params )
  7.     (princ "\nCallback Evaluated.")
  8.     (vlr-remove reactor)
  9.     (princ)
  10. )

Here are my results:

Code - Auto/Visual Lisp: [Select]
  1. Command: addreactor  ;; <-------------- Command Reactor added.
  2. Command: m MOVE 1 found
  3.  
  4. Specify base point or [Displacement] <Displacement>:
  5. Specify second point or <use first point as displacement>:
  6. Callback Evaluated. ;; <-------------- Callback evaluated, Command Reactor removed.
  7. Command: m MOVE 1 found
  8.  
  9. Specify base point or [Displacement] <Displacement>:
  10. Specify second point or <use first point as displacement>:
  11. ;; <-------------- Callback NOT evaluated

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: vlr-remove not removing Object Reactor inside Callback Function
« Reply #5 on: August 26, 2012, 08:27:18 AM »
Now that I have understood that one cannot disable an Object Reactor from within its own callback function, I have managed to implement a working solution in my application by disabling the Object Reactor from another callback function.

I would like to thank the community for their time on this thread, especially CAB's contribution, and I hope that the thread serves as a guide and explanation for others encountering this issue.

Thanks  :-)

Lee

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: vlr-remove not removing Object Reactor inside Callback Function
« Reply #6 on: August 26, 2012, 08:51:12 AM »
Good detective work Lee.
But how can you combine reactors or chain them and be sure which is triggered first?
I'm assuming that is how you did it.
(Rather slow here on the weekends  8-) )
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.

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: vlr-remove not removing Object Reactor inside Callback Function
« Reply #7 on: August 26, 2012, 09:03:20 AM »
Good detective work Lee.

Thanks Alan  :-)

But how can you combine reactors or chain them and be sure which is triggered first?
I'm assuming that is how you did it.
(Rather slow here on the weekends  8-) )

I used a combination of an Object Reactor triggered by the :vlr-modified event and a Command Reactor triggered on the :vlr-commandended event, and disabled the Object Reactor from within the callback function of the Command Reactor (instead of disabling it from the callback function of the Object Reactor, which sparked this thread topic) before performing the necessary modifications to the owner object and re-enabling the Object Reactor (again from the callback function of the Command Reactor).

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: vlr-remove not removing Object Reactor inside Callback Function
« Reply #8 on: August 26, 2012, 09:41:41 AM »
New Development...

I've also just discovered that vlr-remove will fail to remove an Object Reactor if any one of it's owners resides on an Locked Layer.

Steps to recreate this condition:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:addreactor ( / en )
  2.    (if (setq en (car (entsel)))
  3.        (setq object-reactor
  4.            (vlr-object-reactor (list (vlax-ename->vla-object en)) "My Object Reactor"
  5.               '((:vlr-modified . mycallback))
  6.            )
  7.        )
  8.    )
  9.    (princ)
  10. )
  11.  
  12. (defun mycallback ( owner reactor params )
  13.    (princ "\nCallback Evaluated.")
  14.    (princ)
  15. )
  • Create a circle (or any object) in the drawing
  • Run the above code and select the circle
  • Lock the circle's layer
  • Type at the command-line (vlr-remove object-reactor)
  • Unlock the circle's layer and move the circle

Here are my results:
Code - Auto/Visual Lisp: [Select]
  1. Command: _circle
  2. Specify center point for circle or [3P/2P/Ttr (tan tan radius)]:
  3. Specify radius of circle or [Diameter]:
  4. Command: addreactor
  5.  
  6. Select object:
  7.  
  8. ;; <--------- Layer Locked --------->
  9.  
  10. Command: (vlr-remove object-reactor) ;; <-------------- Reactor removed 'manually'
  11. #<VLR-Object-Reactor> ;; <-------------- Indicating reactor has been removed successfully.
  12.  
  13. ;; <--------- Layer Unlocked --------->
  14.  
  15. Command: m MOVE 1 found
  16.  
  17. Specify base point or [Displacement] <Displacement>:
  18. Specify second point or <use first point as displacement>:
  19. Callback Evaluated. ;; <--------------  Callback still being evaluated after reactor is removed.

Note that the Object Reactor is not removed even after using vlr-remove 'manually' at the command-line.

The Solution:

Use vlax-write-enabled-p to check whether owner objects are write enabled before attempting to remove an Object Reactor.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: vlr-remove not removing Object Reactor inside Callback Function
« Reply #9 on: August 26, 2012, 10:24:46 AM »
One solution I pondered was to delete the object which kills the reactor.
Then recreate it, not sure you can do all this from within the call back reactor.
No time this morning to test it. Getting ready for the coming weather.

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.

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: vlr-remove not removing Object Reactor inside Callback Function
« Reply #10 on: August 26, 2012, 03:13:56 PM »
One solution I pondered was to delete the object which kills the reactor.
Then recreate it, not sure you can do all this from within the call back reactor.

Thank you for the suggestion, but this wouldn't be possible I'm afraid since the owner object is notifying the Object Reactor and hence cannot be deleted whilst notifying.

Given that I now understand the somewhat stricter rules that apply to manipulating Object Reactors over other Reactors, I know where I stand and can write my applications accordingly to account for this behaviour. Coding applications around known bugs can be annoying, but certainly far less frustrating than not knowing the bug exists and scratching your head as to why things are crashing...

No time this morning to test it. Getting ready for the coming weather.

Ah yes, Isaac has been covered in the news over here too - I wish you all the best and hope the storm passes through safely.

PKENEWELL

  • Bull Frog
  • Posts: 317
Re: vlr-remove not removing Object Reactor inside Callback Function
« Reply #11 on: August 27, 2012, 01:31:53 PM »
FYI - I get the same Behavior in AutoCAD Mechnical 2013. I don't know what version you are using, but it looks like Autodesk has not fixed it yet.  :-(

Code - Auto/Visual Lisp: [Select]
  1. Command: ADDREACTOR
  2. Select object:
  3. ** STRETCH **
  4. Specify stretch point or [Base point/Copy/Undo/eXit]:
  5. Callback Evaluated.
  6. #<VLR-Object-Reactor>
  7. ** STRETCH **
  8. Specify stretch point or [Base point/Copy/Undo/eXit]:
  9. Callback Evaluated.
  10. nil
  11. nil
  12. ** STRETCH **
  13. Specify stretch point or [Base point/Copy/Undo/eXit]:
  14. Callback Evaluated.
  15. nil
  16.  

Code - Auto/Visual Lisp: [Select]
  1. Command: (defun mycallback ( owner reactor params )
  2. (_>    (princ "\nCallback Evaluated.")
  3. (_>    (princ)
  4. (_> )
  5. MYCALLBACK
  6. CIRCLE
  7. Specify center point for circle or [3P/2P/Ttr (tan tan radius)]:
  8. Specify radius of circle or [Diameter] <1.9370>:
  9. Command: addreactor
  10. Select object:
  11. ** STRETCH **
  12. Specify stretch point or [Base point/Copy/Undo/eXit]:
  13. Callback Evaluated.
  14. Command: *Cancel*
  15. ((:VLR-Object-Reactor #<VLR-Object-Reactor>))
  16. ** STRETCH **
  17. Specify stretch point or [Base point/Copy/Undo/eXit]:
  18.  
"When you are asked if you can do a job, tell 'em, 'Certainly I can!' Then get busy and find out how to do it." - Theodore Roosevelt

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: vlr-remove not removing Object Reactor inside Callback Function
« Reply #12 on: August 27, 2012, 01:38:26 PM »
Thank you for your time testing it Phil, your results in 2013 and CAB's results in 2006 confirm my suspicions that these are indeed bugs present in most, if not all, versions of AutoCAD and its derivative programs.

Since LISP is no longer in development I very much doubt these issues will be fixed any time soon, though, at least we are now aware of them and can code around them.

Thanks  :-)

PKENEWELL

  • Bull Frog
  • Posts: 317
Re: vlr-remove not removing Object Reactor inside Callback Function
« Reply #13 on: August 27, 2012, 01:49:35 PM »
Thank you for your time testing it Phil, your results in 2013 and CAB's results in 2006 confirm my suspicions that these are indeed bugs present in most, if not all, versions of AutoCAD and its derivative programs.

Since LISP is no longer in development I very much doubt these issues will be fixed any time soon, though, at least we are now aware of them and can code around them.

Thanks  :-)

Very True. Thanks to you as well for discovering the issue. Saves the rest of us the frustration of discovering it ourselves.   :lol:
"When you are asked if you can do a job, tell 'em, 'Certainly I can!' Then get busy and find out how to do it." - Theodore Roosevelt

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: vlr-remove not removing Object Reactor inside Callback Function
« Reply #14 on: August 27, 2012, 02:01:19 PM »
Saves the rest of us the frustration of discovering it ourselves.   :lol:

Believe me... there was frustration in abundance before this thread was started  :ugly: