Author Topic: Lambda function in reactor  (Read 2357 times)

0 Members and 1 Guest are viewing this topic.

alexeispirit

  • Mosquito
  • Posts: 14
Lambda function in reactor
« on: October 20, 2011, 03:48:18 AM »
Hi, all

Is it possible to use lambda-function in reactor as a callback function.
I'm asking, cause I'm making reactor persistent and its necessary to edit drawings outside the work.
So I'd like to make some anonymous function to check whether callback-function available or not.
Something like this (but it's not working):
Code: [Select]
(setq m_reactor
  (vlr-object-reactor
    (list m_line)
    "LineReactor"
     '((:vlr-modified .
       (function
(lambda (notifier-object reactor-object parameter-list)
   (if callback-function 'callback-function)))))))

Thanks in advance

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Lambda function in reactor
« Reply #1 on: October 20, 2011, 04:13:46 AM »
No I don't think it's going to work. The reactor only saves the name of the function to be called - thus an anonymous function would fail.

You're trying to "embed" the reactor's callback into the DWG aren't you? The only way I can think of doing such is to make your callbacks using the defun-q (so they're uncompiled lists instead of compiled USubr functions). Then you can add the list into a dictionary using vlax-ldata-put.

Unfortunately even after you've done such that defun-q won't get loaded automatically each time that DWG is opened. So you'd still need a LSP file to go with the DWG which would read all the "attached" code and then eval them. At least that way one common LSP could handle all future call-backs.

An alternative I've seen is to embed VBA to eval some lisp. But then why'd you not just use VBA events in the first place? And if the recipient doesn't have the VBA enabler installed nothing would happen anyway.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

alexeispirit

  • Mosquito
  • Posts: 14
Re: Lambda function in reactor
« Reply #2 on: October 20, 2011, 04:42:47 AM »
Yeah, I've read about it. But it's not suitable, cause our employees have no VBA Enabler at home PCs and it is quite difficult to explain them how to install it  ))

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Lambda function in reactor
« Reply #3 on: October 20, 2011, 05:09:06 AM »
Unfortunately then all you can do is go with the dictionary approach and give them a LSP to include in their startup/acaddoc.lsp/mnl/etc. You could even create an installer package using something like InnoSetup to make this as easy as possible (i.e. just a double click on an EXE file).

Especially in this case I'd go with the dictionary approach as you don't want to keep on updating that LSP file to everyone each time you modify / add a reactor.

The reason ADesk never allowed embedding LSP into DWG is due to security. It would be extremely easy for a virus to propagate inside DWG's if this was possible. VBA has a form of signing which allows the user to only enable macros from trusted sources. But there's no such thing for lisp.
 
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

alexeispirit

  • Mosquito
  • Posts: 14
Re: Lambda function in reactor
« Reply #4 on: October 20, 2011, 05:17:27 AM »
I'll think about it. However, using installer packages, I can deploy the program itself, not only test function. Anyway thank you for help.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Lambda function in reactor
« Reply #5 on: October 20, 2011, 05:33:31 AM »
I think you're misunderstanding what I'm referring to. The LSP you'd need to install is an extremely basic thing, and need never change after it's been installed. As an example here's the code to embed a defun-q indo the DWG:
Code: [Select]
(defun Embed-Defun (fSym / fun)
  (if (= (type fSym) 'SYM)
    (if (= (type (setq fun (eval fSym))) 'List)
      (vlax-ldata-put "Embedded Lisp" (vl-symbol-name fSym) fun)
    )
  )
)
You call that with the quoted name of the defun-q. E.g. say your callback function was
Code: [Select]
(defun-p MyCallBack (....Then to embed it you'd run:
Code: [Select]
(Embed-Defun 'MyCallBack)

Then all that you need to actually "install" on all the PC's would be a call to the following function to be loaded for each DWG opened (e.g placed inside a ACADDOC.LSP file):
Code: [Select]
(defun Load-Embedded (/ lst dName)
  (setq dName "Embedded Lisp")
  (if (setq lst (dictsearch (namedobjdict) dName))
    (foreach item (mapcar 'cdr (vl-remove-if-not '(lambda (item) (= (car item) 3)) lst))
      (eval (cons 'defun-q (cons (read item) (vlax-ldata-get dName item))))
    )
  )
)
(Load-Embedded)
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

alexeispirit

  • Mosquito
  • Posts: 14
Re: Lambda function in reactor
« Reply #6 on: October 20, 2011, 05:50:54 AM »
I understood what were you suggesting, but in that way it would be better to distribute all package, cause after changing my objects without real callback other reactions will be useless.
And if I provide a real callback function in a drawing, it would be rather difficult to make changes in it when it is already embedded in a drawing.
I could take it if there was nothing to install at user PC, but if there's no way to do it, it would be better to produce the program itself, IMHO.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Lambda function in reactor
« Reply #7 on: October 20, 2011, 08:28:11 AM »
Probably yes. I'm just thinking that if you've added new reactor callback types, these can very easily be embedded into a DWG and work fine on a PC where you've only got that Load Embedded lisp installed.

BTW, to "modify" an embedded code it's a straight-forward situation of running the Embed-Defun again on that/those DWG(s). I.e. it simply gets overwritten. To remove one you can use the vlax-ldata-delete method. BTW, I was a bit "stupid" about the way I've implemented the Load-Embedded. It could be a lot simpler:
Code: [Select]
(defun Load-Embedded ( / )
  (foreach item (vlax-ldata-list "Embedded Lisp")
    (eval (cons 'defun-q (cons (read (car item)) (cdr item))))
  )
)
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

alexeispirit

  • Mosquito
  • Posts: 14
Re: Lambda function in reactor
« Reply #8 on: October 20, 2011, 09:59:17 AM »
I'll think in that way. It could be more easier if lambda functions were available, but I agree it could also cause huge security problems. Thanks, irneb

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Lambda function in reactor
« Reply #9 on: October 20, 2011, 10:06:48 AM »

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: Lambda function in reactor
« Reply #10 on: October 20, 2011, 10:30:36 AM »
My two cents: let the users keep work at the office and keep their home life at home.  Its tempting to allow them to take work home, but experience says this leads to all sorts of problems: work/home balance issues, biased productivity reporting, questionable time billing, security of client intellectual property/drawings, virii/worms, and so on.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Lambda function in reactor
« Reply #11 on: October 20, 2011, 10:49:56 AM »
To spice up the mix.
Shows how this could be misused!  :pissed: Fortunately that thing only works if the VLX exists somewhere that Acad can find it (i.e. search path or with the DWG). BTW, this is probably also the biggest reason lisp function calls aren't available inside fields. Imagine a field containing a call to defun ... which means each time you open a DWG it could basically do anything to your entire PC / LAN.

I'm with dgorsman though, he makes a good point!  :lmao:
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

alexeispirit

  • Mosquito
  • Posts: 14
Re: Lambda function in reactor
« Reply #12 on: October 20, 2011, 12:05:09 PM »
2Lee Mac: irneb is right. For me it doesn't matter how to deliver application to end-user, whether it would be vlx or acaddoc/mnl or smth else

2dgorsman: You're quite right, but it's a question for a company management. I only have to provide necessary tools for work to be done