Reputation:
I am programming some device which has SDK.
Say I want to show some menu on display. You usually proceed like this:
void showSomeMenu()
{
...
drawItem(0, "menu option1");
drawItem(1, "menu option2");
while(1)
{
key = getKey();
if(key == KEY_ENTER)
{
showSomeOtherMenu();
return; // or break
}
}
...
}
You can see, if user clicks enter above, he can open someOtherMenu
. Now say from that someOtherMenu
user wants to go back. Then you implement it like this:
void showSomeOtherMenu()
{
...
// add menu items
while(1)
{
key = getKey();
if(key == KEY_ENTER)
{
showSomeMenu(); // Will open previous menu (implemented in the first snippet)
return;
}
}
...
}
What I find weird in this approach is that: say someone called showSomeMenu
.
Then from that called showSomeOtherMenu
by pressing Enter. Now from showSomeOtherMenu
he clicked
Enter, which will again call showSomeMenu
-- but notice, the first call to the showSomeMenu
never had chance to return.
Even though this approach works and menus will be shown correctly, I am wondering maybe if this will end in a endless loop of functions calling each other. And maybe than I will have stack overflow issues or smth like that.
Am I right to worry? This approach to do it like this was shown in their samples. So I was thinking it should be the correct way to do it.
Upvotes: 0
Views: 48
Reputation: 5930
Each time you hit ENTER you will delve 1 step deeper into the stack, there is no way to return. This is recursion without a base case. Do not do it!
A simple fix would be to modify the code in showSomeOtherMenu()
to 'go back' instead of recursing.
while(1) {
key = getKey();
if(key == KEY_ENTER) {
return;
}
// handle other options here
}
A better approach is to keep a stack of menus that have been accessed. When you enter a menu you push it onto the stack, when you want to go back, you pop the stack and go to the menu that is then on the top of the stack.
e.g:
> Enter menu1 // stack is now [ menu1 ]<- head
> Enter menu2 // stack is now [ menu1, menu2 ]<- head
> Enter menu5 // stack is now [ menu1, menu2, menu5 ]<- head
> Back -> menu2 // stack is now [ menu1, menu2 ]<- head
> Enter menu4 // stack is now [ menu1, menu2, menu4 ]<- head
// etc.
An even better option is to use some kind of tree, such that you only need one function to manage the menu. This is somewhat more complicated, but in essence you have a node for each menu, and a child of that node for each menu item. The nodes must have pointers to their parent node.
Upvotes: 0
Reputation: 399753
Yes, you're right to worry, this seems like horribly bad design.
In general it is much better to design things like this in a data-driven manner, i.e. with passive data structures that describe the hierarchy you want, then just a single function (runMenu()
or something) that interprets the data and keeps track of the current menu and which "moves" are allowed.
Upvotes: 1