oopdesign-patternsdm-script

How can one set up persistent collaborating objects in DigitalMicrograph via scripting?


I have come to really appreciate the benefits of using objects to deploy a given application within the DigitalMicrograph environment via the DMS language. The object-oriented approach opens the door to the use of reusable design patterns involving collaborating objects, e.g. Model-View-Controller (MVC). However, objects within DM seem to be highly volatile due to the use of automatic reference counting to manage their life cycles. In order for an MVC trio, or any other set of collaborating objects, to stay alive long enough to be useful, at least one of them must be rooted in a non-volatile object managed by the DM application. So far, the only such objects I have come across within DM are those based on the UIFrame class (i.e. modeless dialogs and UI palettes). For MVC implementations, this works out fine since it makes sense to implement the View as a UIFrame object. It's just a bit unconventional in that the View object becomes the root object that keeps the MVC trio alive and functioning. Normally it is the Controller object that is rooted in the application and manages the Model and View objects. But what about design patterns that do not involve UI? Is there any (acceptable) way to give a set of collaborating objects persistence without rooting them in a UIFrame object? Are there other application-rooted object types that can serve this purpose? I assume setting up a reference cycle would not be an acceptable approach due to the inevitable risk of memory leaks.


Solution

  • The third, and by far the best and cleanest solution is to launch your object as a 'listener' to some event. As you are looking for an object which should stay in scope as long as DigitalMicrograph is open, its possibly best to listen to the application itself. By listening for the "about_to_close" message you also get the ideal handle to properly release all resources before shutdown. The code is the following:

    From my 3 answers this is the one I would use. (The others should just illustrate options.)

    class MyPermanentObject 
    {
        MyPermanentObject( object self ) { result("created MyPermanentObject :"+self.ScriptObjectGetID()+"\n");}
        ~MyPermanentObject( object self ) { result("killed MyPermanentObject :"+self.ScriptObjectGetID()+"\n");}
        void DeInitialize( object self, number eventFlags, object appObj ) 
        { 
            OKDialog( "The application is closing now. Deinitialize stuff properly!" ); 
        }
    }
    
    
    {
        object listener = Alloc( MyPermanentObject )
        ApplicationAddEventListener( listener, "application_about_to_close:DeInitialize" )
    }