Christoph Thiede uploaded a new version of Monticello to project The Inbox:
http://source.squeak.org/inbox/Monticello-ct.712.mcz ==================== Summary ==================== Name: Monticello-ct.712 Author: ct Time: 14 January 2020, 1:58:10.168813 pm UUID: c048116c-f5ca-8c4d-adab-34d19467565a Ancestors: Monticello-cmm.708 Reuse ToolBuilder utility in MCTool >> #showModally =============== Diff against Monticello-cmm.708 =============== Item was changed: ----- Method: MCTool>>showModally (in category 'morphic ui') ----- showModally modalProcess := Processor activeProcess. self window openInWorldExtent: self defaultExtent. + ToolBuilder default runModal: self window. - [self window world notNil] whileTrue: [ - self window outermostWorldMorph doOneCycle. - ]. morph := nil. ^ modalValue! |
Okay for the time being and certainly not worse. But eventually these dialogs ought to send a message when they are accepted, to continue the workflow. <[hidden email]> schrieb am Di., 14. Jan. 2020, 13:58: Christoph Thiede uploaded a new version of Monticello to project The Inbox: |
(Just merging two threads ... :-)) yes, this is what I also mentioned in the other thread (attached below). I don't like the fact that at the moment, you may evaluate any code that raises an error and kills the modal loop.
You proposed using a promise - I never had the pleasure to meet them until today. Maybe you have a minimum working example for demonstrating your proposal? FutureNodes seem to be used very rarely in Trunk :-)
My first idea would have been something like this:
Of course, a semaphore might be better than the [Processor yield] doWhileTrue: ...
Model could override #windowIsClosing for signaling such a semaphore.
Best,
Christoph
Von: Squeak-dev <[hidden email]> im Auftrag von Jakob Reschke <[hidden email]>
Gesendet: Mittwoch, 15. Januar 2020 08:00 Uhr An: [hidden email] Betreff: Re: [squeak-dev] The Inbox: Monticello-ct.712.mcz
Okay for the time being and certainly not worse.
But eventually these dialogs ought to send a message when they are accepted, to continue the workflow.
<[hidden email]> schrieb am Di., 14. Jan. 2020, 13:58:
Christoph Thiede uploaded a new version of Monticello to project The Inbox: An: The general-purpose Squeak developers list Betreff: Re: [squeak-dev] Closing modal dialogs... Thiede, Christoph <[hidden email]> schrieb am Mo., 13. Jan. 2020, 13:10:
Promises can also be nice. Allows you to write the continuation next to the invocation.
Carpe Squeak!
|
Am Mi., 15. Jan. 2020 um 09:13 Uhr schrieb Thiede, Christoph <[hidden email]>:
I have no minimum example ready, but here is the outline: - Add an instance variable for the promise to the model. - Initialize with `Promise new` when the model is asked to open a view. - Answer the promise to the open message. - In the model's method that is invoked when the dialog is accepted, promise resolveWith: theResultOfWhatHappened - In the method that opens the tool, take the promise and use whenResolved:, whenRejected: (handle the outcome) or then:ifRejected: (handle the outcome and answer another promise -- chaining). Do not attempt to return from the handler blocks, the method will have returned by the time they are evaluated. Of course it is a totally different style of programming than with modal windows. Similar alternative without promises: - Instead of a promise, store a MessageSend in the model. - In the client of the model, store all necessary state to continue in instance variables. - Do not expect a return value from opening the view for the model. - Have the model send the message to self upon continuation. pastedImage.png (161K) Download Attachment |
Since you mentioned the #future, I recently tried to wrap modal dialog (well not really, it is not exclusive, it just has a synchronous API to obtain the result) with a promise interface and came up with the following. If I thought it through correctly, it should not lose the continuation even when the UI process is terminated and replaced (via Ctrl+., abandon, for example). Haven't tested it yet, though. Would anyone like to review? In the model... selectedChangesWithTitle: titleString | builder | builder := ToolBuilder default. view := builder open: self label: titleString. promise ifNil: [promise := Promise new]. self future resumeModalRequest. "will resolve the promise" ^ promise resumeModalRequest view ifNil: [self error: 'Tool was not opened yet']. promise ifNil: [self error: 'Tool was not opened with selectedChangesWithTitle:']. [ToolBuilder default runModal: view] ifCurtailed: ["Make sure we will notice in a new UI process when the view is closed." self future resumeModalRequest]. "If we finally get here, the view was closed." self accepted ifTrue: [promise resolve] ifFalse: [promise reject]. Am Mi., 15. Jan. 2020 um 21:32 Uhr schrieb Jakob Reschke <[hidden email]>:
|
Yes, this programming style sounds really interesting but totally different. :) > Similar alternative without promises:
> - Instead of a promise, store a MessageSend in the model.
> - In the client of the model, store all necessary state to continue in instance variables.
> - Do not expect a return value from opening the view for the model.
> - Have the model send the message to self upon continuation.
And I would append observer pattern to this list, which is just a special case of your last point.
These proposals actually appear a bit easier and more convenient. I would like to use the same solution for DialogWindows as well which suffer from the same problem. But #inform: should be called as usual and hide any concurrent logic from the caller.
How would you identify the object to resume after the information, if you called, for example, nil inform: #foo? I think the only way, without creating an extra DialogWindowModel, would be #spawnNewProcessDuring: ...
Best,
Christoph
Von: Squeak-dev <[hidden email]> im Auftrag von Jakob Reschke <[hidden email]>
Gesendet: Mittwoch, 15. Januar 2020 21:39:33 An: The general-purpose Squeak developers list Betreff: Re: [squeak-dev] The Inbox: Monticello-ct.712.mcz Since you mentioned the #future, I recently tried to wrap modal dialog (well not really, it is not exclusive, it just has a synchronous API to obtain the result) with a promise interface and came up with the following. If I thought it through
correctly, it should not lose the continuation even when the UI process is terminated and replaced (via Ctrl+., abandon, for example). Haven't tested it yet, though. Would anyone like to review?
In the model...
selectedChangesWithTitle: titleString
| builder | builder := ToolBuilder default. view := builder open: self label: titleString. promise ifNil: [promise := Promise new]. self future resumeModalRequest. "will resolve the promise" ^ promise resumeModalRequest
view ifNil: [self error: 'Tool was not opened yet']. promise ifNil: [self error: 'Tool was not opened with selectedChangesWithTitle:']. [ToolBuilder default runModal: view] ifCurtailed: ["Make sure we will notice in a new UI process when the view is closed." self future resumeModalRequest]. "If we finally get here, the view was closed." self accepted ifTrue: [promise resolve] ifFalse: [promise reject]. Am Mi., 15. Jan. 2020 um 21:32 Uhr schrieb Jakob Reschke <[hidden email]>:
Carpe Squeak!
|
Am Do., 16. Jan. 2020 um 09:03 Uhr schrieb Thiede, Christoph <[hidden email]>:
To simulate the synchronous interface, you must not only notify the client, but also block the calling process until the dialog is closed. Quick ideas: - I have never used it, but I heard Seaside implemented proper continuations. Maybe take a look there. - Hacking about thisContext sender or/and suspending the process and resuming it later. - Spawn a new UI process, once the dialog is closed have it signal a semaphore and terminate itself. Let the original UI process wait on that semaphore. Breaks other things which don't support such changes of the UI process, such as the Monticello tools. May have edge cases that leave the world without an unblocked UI process, I don't know. |
Free forum by Nabble | Edit this page |