I'm making a game menu using a composite pattern. I want to achieve a tree structure game menu, where some leaves are pushing new state on the top of my state machine and another in options should show for example slider to change the volume without making new state and another (exit) should close the game by running sfml method.
Can someone give me a better idea than returning string or enum by operation() method to menu state to run expected action by using value in if/switch?
Here is an example of a menu state table using a struct
:
typedef void (*Function_Pointer)(); // Declares a synonym for Function_Pointer
struct Table_Entry
{
char expected_selection;
char * prompt;
Function_Ptr processing_function;
};
// Forward declarations
void Turn_On_Lights();
void Turn_Right();
void Open_Treasure();
// State table
static const Table_Entry menu1[] =
{
{'1', "Turn on lights", Turn_On_Lights},
{'2', "Turn right (pivot)", Turn_Right},
{'3', "Open Treasure", Open_Treasure},
};
static size_t menu_entry_quantity =
sizeof(menu1) / sizeof(menu1[0]);
void Display_Menu()
{
for (unsigned int i = 0, i < menu_entry_quantity; ++i)
{
std::cout << menu1[i].expected_selection
<< ". "
<< menu1[i].prompt
<< "\n";
}
std::cout << "Enter selection: ";
}
void Execute_Menu_Selection(char selection)
{
for (unsigned int i = 0, i < menu_entry_quantity; ++i)
{
if (selection == menu1[i].expected_selection)
{
(*menu1[i].processing_function)();
break;
}
}
}
The above code allows you to change the quantity of entries or the entry content, without having to retest the functions. (Nice)
Since the data is static constant, it can be accessed directly and doesn't need to be initialized before the program starts.
You can expand this by using a "transition" column or member. For example, list the next states (or menus) to transition to when given a transition ID.