Any alternative to callbacks for UI programming?
Let's say I have a several step process like during software installation for example.
Each step display a text box and wait for the user to click the "next" button.
The standard way to do it is to have a callback like this:
process
{
Dialog1() // Will call callback2 when closed
}
callback2()
{
Dialog2() // Will call callback3 when closed
}
callbak3()
{
Dialog3() // Will call callback4 when closed
}
This 开发者_开发知识库technique makes the code quite unreadable when there is a lot of steps as you have to divide you process into each successive callback function (not to mention save context from one to another).
What would be an easier to read way to do it ? Ideally the process should read like this:
process()
{
Dialog1()
callback1() // stop method until closed
Dialog2()
callback2() // stop method until closed
Dialog3()
callback3() // stop method until closed
}
Problem with this is that you can't stop the UI thread. Any idea or work around would be very appreciated.
PS: this as to work in C or Objective C
ANSWER
So after having discovered coroutines thanks to Martin B I've found this page: https://stackoverflow.com/posts/4746722/edit and ended up using this code:
define coRoutineBegin static int state=0; switch(state) { case 0:
define yield do { state=__LINE__; return;
case __LINE__:; } while (0);
define coRoutineEnd }
void process()
{
coRoutineBegin
Dialog1()
yield
Dialog2()
yield
Dialog3()
yield
Dialog4()
yield
coRoutineEnd
}
You're looking for coroutines, which provide exactly the concept you're looking for: Yielding control from a function without exiting it. In essence, your code would look like this:
process()
{
Dialog1()
yield
Dialog2()
yield
Dialog3()
}
Unfortunately, coroutines aren't supported natively by C or Objective C and are hard to implement generically without resorting to ugly hacks. However, you may be able to take the concept as a starting point for a special-case construct for your situation.
You could use a Mutex or similar concept where the dialog is opened and run in a different thread.
Here is a post with an example I think is valid:
Synchronization/wait design for cross-thread event signaling (Obj-C)?
I don't quite understand the problem. Why doesn't showing a modal dialog work? Modal dialogs block until they are dismissed so your logic would look like:
Dialog1()
Dialog2()
Dialog3()
Another solution is to have your dialogs or callbacks or whatever send events. You then bind to those events. Your main logic would then look like this (sorry, I don't know how to do GUI examples in C/Objective-C, so I'll use Tcl/Tk because its highly readable):
bind $rootWindow <<Step1>> showDialog1
bind $rootWindow <<Step2>> showDialog2
bind $rootWidow <<Step3>> showDialog3
# kick off the first step
event generate $rootWindow <<Step1>>
The showDialogX functions would do whatever they need to do, then generate an event saying "I'm done, ready for the next step".
精彩评论