Working with different runtime versions.

Started by johnM, October 16, 2009, 01:13:28 PM

Previous topic - Next topic

owenwengerd

The runtime versions are backward compatible, so if another program installs a newer version of the runtime, your program will still work (at least in theory -- there could of course be cases where your code takes advantage of some undocumented or unintended behavior that changes in a newer version).

johnM

That’s what I’m getting at.
I have a package that works great with runtime 4.1.1.2 but it has errors with 6.0.0.8
I don’t want to repackage and submit updates to everybody using it every time there is a change in new runtimes that causes errors in older runtimes.

I personally can work around this issue with the code in my original post but I will have to fix my 4.1.1.2 package with the code and updated my users one time. I was just thinking about my learning curve and how could I make life easer for others like me.
Please don’t get me wrong I really appreciate all the help and advice here

owenwengerd

There were breaking changes from OpenDCL 4 to 5, but that was a special case because OpenDCL 4 applications could not safely coexist with other OpenDCL applications in any case.

Kerry


Regarding updating samples:

I've had a fresh look at the samples.
Unfortunately they are all designed to be run with the "_MasterDemo.lsp" loaded and with the "_OpendclUtils.LSP" loaded.

If any of the samples are loaded and run independently the LoadODCLProj function is not available.
As you know, the LoadODCLProj function's primary purpose is to ensure the  .ODCL files can be found in the  ..\SamplesFolder.

In this regard, the Samples are not really completely simple generic samples.





Perfection is not optional.
My other home is TheSwamp

BazzaCAD

If the samples folder is in the acad support path they should run on there own.
We should try to get them to run from masterdemo & on there own as much as possable.
a.k.a.
Barry Ralphs
barryDOTralphsATgmailDOTcom

owenwengerd

I envision adding a prolog like the following (for e.g. the TreeView sample):
Code (autolisp) Select

;;;######################################################################
;;;######################################################################
;;;######################################################################
;;;
;;; OpenDCL Sample
;;;
;;; The code in this prolog is designed to allow this sample project
;;; to work with the other sample projects that are installed with
;;; OpenDCL Studio, and is not intended for nor needed in your own
;;; OpenDCL projects.
;;;
(or
  OpenDCL::Samples::#Prefix
  (setq OpenDCL::Samples::#Prefix (vl-registry-read "HKEY_CURRENT_USER\\SOFTWARE\\OpenDCL" "SamplesFolder"))
  (setq OpenDCL::Samples::#Prefix (vl-registry-read "HKEY_LOCAL_MACHINE\\SOFTWARE\\OpenDCL" "SamplesFolder"))
  (setq OpenDCL::Samples::#Prefix (vl-registry-read "HKEY_CURRENT_USER\\SOFTWARE\\Wow6432Node\\OpenDCL" "SamplesFolder"))
  (setq OpenDCL::Samples::#Prefix (vl-registry-read "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\OpenDCL" "SamplesFolder"))
)
(and (not OpenDCL::Samples::#findfile)
  (setq OpenDCL::Samples::#findfile findfile)
  (defun findfile (file / path)
    (if OpenDCL::Samples::#Prefix
      (setq path (OpenDCL::Samples::#findfile (strcat OpenDCL::Samples::#Prefix file)))
    )
    (if path path (OpenDCL::Samples::#findfile file))
  )
)
(and (not OpenDCL::Samples::#dcl_project_load)
  (command "_OPENDCL")
  (setq OpenDCL::Samples::#dcl_project_load dcl_project_load)
  (defun dcl_project_load (file)
    (OpenDCL::Samples::#dcl_project_load (findfile file))
  )
)
(if (not *MasterDemo*) ;; print a banner, unless masterdemo is active
  (princ "\nOpenDCL sample loaded. Enter \"TREE\" to run the sample.\n")
)
;;;
;;;
;;;######################################################################
;;;######################################################################
;;;######################################################################
;;;######################################################################
;;;
;;;
;;; TREE Sample
;;;
;;; This sample demonstrates the tree control and all its events.
;;;


;; this function loads the project & shows the form
(defun c:TREE (/)
  (command "_OPENDCL") ;; ensure OpenDCL Runtime is loaded
  (dcl_Project_Load "TreeView.odcl")
  (dcl_Form_Show TreeView_Main)
  ;; The event handlers manage the form until it is dismissed
  (PRINC)
)

Kerry

#21
Redefining findfile is probably not ideal ...

added : ditto redefining dcl_project_load
Perfection is not optional.
My other home is TheSwamp

owenwengerd

The goal of course was to be able to make the sample code work with or without the prolog. The (findfile) redefinition doesn't bother me, but (dcl_project_load) is a problem because it can accept optional arguments (and being in lisp, the replacement can't). Another idea is to use a hybrid approach that requires a call to a custom findfile function for loading sample files. This isn't so bad; it means the sample code can't be used exactly as-is, but it's reasonable to expect most end user applications to require something exactly like the custom findfile function anyway, so here they just have to plug in their version of the function:

Code (autolisp) Select

;;;######################################################################
;;;######################################################################
;;;######################################################################
;;;
;;; OpenDCL Sample
;;;
;;; This function retrieves the full path to files in the samples
;;; folder by prefixing the filename with the path prefix that was
;;; saved in the registry by the OpenDCL Studio installer.
;;;
(defun ODCL::Samples::FindFile (file / prefix path)
  (setq prefix
(cond
((vl-registry-read "HKEY_CURRENT_USER\\SOFTWARE\\OpenDCL" "SamplesFolder"))
((vl-registry-read "HKEY_LOCAL_MACHINE\\SOFTWARE\\OpenDCL" "SamplesFolder"))
((vl-registry-read "HKEY_CURRENT_USER\\SOFTWARE\\Wow6432Node\\OpenDCL" "SamplesFolder"))
((vl-registry-read "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\OpenDCL" "SamplesFolder"))
)
  )
  (if prefix (setq path (findfile (strcat prefix file))))
  (if path path (findfile file))
)
(if (not *MasterDemo*) ;; print a banner, unless masterdemo is active
  (princ "\nOpenDCL sample loaded. Enter \"TREE\" to run the sample.\n")
)
;;;
;;;
;;;######################################################################
;;;######################################################################
;;;######################################################################
;;;######################################################################
;;;
;;;
;;; TREE Sample
;;;
;;; This sample demonstrates the tree control and all its events.
;;;


;; this function loads the project & shows the form
(defun c:TREE (/)
  (command "_OPENDCL") ;; ensure OpenDCL Runtime is loaded
  (dcl_Project_Load (ODCL::Samples::FindFile "TreeView.odcl"))
  (dcl_Form_Show TreeView_Main)
  ;; The event handlers manage the form until it is dismissed
  (PRINC)
)

Kerry

Would an option be to code the dcl_project_load to look in the Samples if the file is not on the path. ?

oops we posted at the same time ... I'll have a look at your post.
Perfection is not optional.
My other home is TheSwamp

Kerry


That should work Owen I think.
I'm comfortable with it because I do a similar thing in some of my production code.

... and as you indicate, it's only one function call to change to become 'conventional' code. 
Perfection is not optional.
My other home is TheSwamp

owenwengerd

Quote from: Kerry Brown on October 17, 2009, 08:20:15 PM
Would an option be to code the dcl_project_load to look in the Samples if the file is not on the path. ?

That occurred to me, but I think it can be ruled out. The first problem with that approach is that it only works with (dcl_project_load). There are several samples that need to load other kinds of dependent files from the samples folder. The second problem is that such a "ghost" path could cause someone a lot of frustration in certain cases (imagine copying an OpenDCL sample into a folder that is incorrectly thought to be in the support path, editing the copy, and being mystified at why the changes aren't effective when the project is reloaded).

Kerry

I came to a similar conclusion when rethinking the option. :)

Should I wait for a consensus or just plough ahead and make the changes to the samples ?

Perfection is not optional.
My other home is TheSwamp

owenwengerd

I'm all for shooting first and asking questions later. If you're in the mood, have at it.

I'd like to create a set of guidelines for a best practice, then go through each sample line by line and control by control and get everything conforming to the guideline. For now, though, just make identical changes to each sample, in such a way that your changes can easily be revised en masse with the magic of search and replace.

One thought I did have is that the new stuff could go to the end of the file instead of the beginning, thereby giving it less prominence. As a bonus, you could precede the existing event handlers with the "magic" comment (
Code (autolisp) Select
;|«OpenDCL Event Handlers») that signifies where Studio should insert new event handlers.

Kerry

#28
Conforming to a guideLine (and creating a guideline) may be difficult.

for instance :

For modal development I prefer to declare my event handlers local to the main.

This means that my files tend to take this form :

Code (autolisp) Select

(vl-load-com)
(command "_OPENDCL")             ; ensure OpenDCL Runtime is loaded

(defun c:test (/
              ;; vars
              local1 local2 local3
              ;; methods
              *error* _fun1 _fun2 _fun3
               c:event1 c:event2 c:event3)
;;; -------------
;;; LOCAL FUNCTIONS
;;; -------------
 (defun *error* ()
                ;; error trap stuff here
 )
 ;; -------------
 (defun _fun1 ()
              ;; stuff here
 )
 ;; -------------
 (defun _fun2 ()
              ;; stuff here
 )
 ;; -------------
 (defun _fun3 ()
              ;; stuff here
 )
;;; -------------
;;; EVENT HANDLERS
;;; -------------
 (defun c:event1 ()
                 ;; stuff here
 )
 ;; -------------
 (defun c:event2 ()
                 ;; stuff here
 )
 ;; -------------
 (defun c:event3 ()
                 ;; stuff here
 )
;;; -------------
;;; MAIN
;;; -------------
 (dcl_project_load "MySuperDuperSpecial.odcl")
 (setq DialogReturn (dcl_form_show MySuperDuperSpecial_Main))
 ;; The event handlers manage the form until it is dismissed
 ;; Run any post closure routines here
 (error* nil)
 (princ)
)





... but again, this is just me
Perfection is not optional.
My other home is TheSwamp

owenwengerd

I think it's best to leave event handlers global in the samples (for consistency).