Need ActiveX version of (ade_odgetfield ename table field record) to use in reactor.

Need ActiveX version of (ade_odgetfield ename table field record) to use in reactor.

kerrcad
Contributor Contributor
451 Views
5 Replies
Message 1 of 6

Need ActiveX version of (ade_odgetfield ename table field record) to use in reactor.

kerrcad
Contributor
Contributor

Cross posted to The Swamp.

 

Adding GUIDs to my application entities to enable up and back capability to a GIS system.  In any drawing, upon opening (approx. 4 sec for 35k entities), a lsp routine creates current a list of all relevant entities ((GUID  ename #vla)...).  I have created a reactor which deletes entities from the list when they are erased.

 

I need a similar reactor to replace the (GUID ename #vla) data to the list upon undo.  I have the reactor working, but cannot get the GUID from the restored entity because I do not know how to use activex functions (and in general as well) to pull the data field from the table attached to the entity (aed_od functionality).

 

So I am asking for help, a code snippet if possible, that returns a specific field from a specific table when given "vla-object name".

 

To use the attached code and drawing:

1st: Open the attached dwg and loading the attached lsp.

2nd: Execute c:er command.  It activates the reactors and builds the initial reference list "#MonLst".

3rd: Delete a line from the drawing.  The "Erase Object" reactor removes that pline from the list "#MonLst".

4th: Undo.  The "unErase Object" reactor replaces the all but the GUID from the object in the updated list "#MonLst".

 
Below is the code used (apologies if poorly formatted).
;;; Create list of objects to monitor ;
(defun c:er (/ entmon guid objmon ssmon x)
  (setq ssMon  (ssget x '((0 . "LWPOLYLINE") (8 . "0")))
objMon (ss->VLA ssMon)
entMon (ss->ent ssMon)
#MonLst '()
  )
  (foreach obMon objMon ; attach reactors to ojbects
    (VLR-Object-Reactor (list obMon) "Erase Object" '((:vlr-erased . delobj)))
    (VLR-Object-Reactor (list obMon) "unErase Object" '((:vlr-unerased . undelobj)))
    )
  (foreach en entMon ; make reference list
    (if (setq GUID (ade_odgetfield en "stlGUID" "GUID" 0))
      (setq #MonLst
     (cons
       (list GUID en (vlax-Ename->Vla-Object en))
       #MonLst
     )
      )
    ) ;if
  )
)
;;; Reactor Remove from list - This one works ;
;;; (VLR-Object-Reactor objMon "Erase Object" '((:vlr-erased . delobj)))
(defun delobj (notifier-object reactor-object parameter-list)
 (setq #MonLst (vl-remove-if (setq what (function (lambda (x) (equal (caddr x) notifier-object)))) #MonLst))
)
;;; END ;
 
;;; Reactor Replace in list - This one cannot retrieve the value in the GUID field. ;
;;;     (VLR-Object-Reactor (list obMon) "unErase Object" '((:vlr-unerased . undelobj)))
(defun undelobj (notifier-object reactor-object parameter-list)
    (setq #MonLst
   (cons
     (list
       ;; This line does not work due to using the non-activeX function "ade_odgetfield" and ename
       (ade_odgetfield (vlax-vla-object->ename notifier-object) "stlGUID" "GUID" 0)
       ;; The following two lines work
       (vlax-vla-object->ename notifier-object)
       notifier-object
       ) ; list
     #MonLst) ; cons
  ) ; setq 
)
;;; END ;
 
;;; Many thanks to Lee Mac for the following functions I use everywhere:
(defun ss->vla ( sel / idx lst )
    (if (= 'pickset (type sel))
        (repeat (setq idx (sslength sel))
            (setq lst (cons (vlax-ename->vla-object (ssname sel (setq idx (1- idx)))) lst))
        )
    )
)
 
(defun ss->ent ( ss / i l )
    (if ss
        (repeat (setq i (sslength ss))
            (setq l (cons (ssname ss (setq i (1- i))) l))
        )
    )
)
0 Likes
452 Views
5 Replies
Replies (5)
Message 2 of 6

hosneyalaa
Advisor
Advisor
0 Likes
Message 3 of 6

kerrcad
Contributor
Contributor

Thanks for responding.

I am familiar with all of these functions, yes.  However, a reactor requires the use of ActiveX functions in the callback portion and the native ade_od functions do not appear to work there.  If you run the attached code and examine the changes to the #MonLst, you will see what I mean.

0 Likes
Message 4 of 6

kerrcad
Contributor
Contributor

Over in The Swamp:

https://www.theswamp.org/index.php?topic=59805.msg622382#msg622382

 

VovKa points out that it is quite possible that unerase reactor fires [b]before [/b]object data is restored, therefore inaccessible.

 

Has anyone experienced this?

0 Likes
Message 5 of 6

MrJSmith
Advocate
Advocate

I couldn't figure out how the ade_odgetfield worked or where the data of the "stlGUID" resided. But if it is indeed a race issue, you could try attaching it to the "command as ended" reactor and test whenever the erase command is called? Though that might not cover all instances of data being deleted.

0 Likes
Message 6 of 6

kerrcad
Contributor
Contributor

I neglected to mention that the ade_od functions and data tables are only available in AutoCAD Map and it's verticals, and not vanilla AutoCAD.

 

While the race issue is unresolved (and I am still curious, hoping someone will weigh in), VovKa and ribarm over at The Swamp suggested keeping two lists, one of current items and another of erased items.  Then the two reactors could pass the data back and forth between the lists as items are erased and "undo".  Simple, and solves the real problem which is accurate housekeeping.  You can see their comments here:  https://www.theswamp.org/index.php?topic=59805.new#new

 

Thanks for taking the time to read and respond.  I really appreciate every forum contributor, having learned so much as a "lurker".

0 Likes