OOP: Managing a time-consuming model action from the UI

classic Classic list List threaded Threaded
1 message Options
Sean P. DeNigris Sean P. DeNigris
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

OOP: Managing a time-consuming model action from the UI

I'm creating a media library service in Pharo. I have a DVDMorph class, with DVD as a model. One feature is to cache a DVD locally as a compressed disk image, which usually takes about 5 minutes.

The ways I thought of were:
1. use announcements
2. pass blocks for updating and cancelling
3. immediately return some kind of DiskImageProxy that would stand in for the DiskImage until processing was done, and then replace (maybe with become?).

I chose #2 because it seemed the easiest for my simple needs (I don't need multiple views); but it definitely made the API uglier, as I have to pass the update and cancel blocks through 3-4 methods.

What do you think would be the best approach?

Here's a simplified version of what I wrote (not refactored)...
DVDMorph>>cache
        updateBlock := [ :progress |
                WorldState addDeferredUIMessage: [ progressMorph contents: progress asString ] ].
        [ self dvd cacheUpdating: updateBlock cancelIf: [ self shouldCancel ] ] forkAt: Processor userBackgroundPriority.

DVD>>cacheUpdating: aBlock cancelIf: cancelPredicate
        Resources library importAs: imageFileName after: [ :fileReference |
                CreateDiskImage
                        from: self deviceFile
                        to: fileReference
                        updating: aBlock
                        cancelIf: cancelPredicate.
                diskImage := fileReference ].

CreateDiskImage >>from:to:updating:cancelIf:
        process := PipeableOSProcess command: 'hdiutil create -srcfolder ', from, ' ', to.
        [ process isComplete ] whileFalse: [
                self shouldCancel ifTrue: [
                        process processProxy sigint.
                        ^ self ].
                self updateStatus.
                (Delay forSeconds: 1) wait ]

Thanks.
Sean
Loading...