Search code examples
delphirttidwscript

How best to expose a class instance in DWScript


I am putting together a built-in script capability using the excellent Pascal DWScript. I have also add my own Delphi-side class definition (TDemo) to DWScript using:

dwsUnit.ExposeRTTI( TDemo.ClassInfo  )

This just works and is a great way of quickly adding properties and methods.

I also wish to add an existing instance in a similar way, so I have created my instance FDemo of type TDemo and then performed:

   dwsUnit.ExposeInstanceToUnit( 'Demo', 'TDemo', FDemo );

This looks a promising routine to call but I get an AV from an uninitialised unit table. I've also looked in the unit test code of the SVN source to see the use of this function but to no avail. Can anyone point me at what I should add / change?


Solution

  • ExposeInstanceToUnit has to be used from within the TdwsUnit table initialization, see RTTIExposeTests/ExposeInstancesAfterInitTable for some sample code. It allows directly exposing dynamic instances.

    The other approach is to use the Instances collection of a TdwsUnit component, you get design-time support, and more controls over your instances and their lifetime.

    Also keep in mind you have to make sure the instances you expose will properly behave even if the script misbehaves, f.i. when the user attempts to manually destroys an instance you exposed, and that instance shouldn't be destroyed. By default ExposeRTTI will map the destructors, so you may want to restrict that by specifying eoNoFreeOnCleanup.

    edit: a last approach recently added is to use the TdwsRttiConnector, which basically allows exposing and connection to anything that's reachable through RTTI. That's very lightweight in terms of code to setup, but the downside is you don't get any form of compile-time checks.