lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

Interesting discussion.

I have just a few comments.

First of all, Lua does not preserve order when inserting keys into a 
table. So:

  Menu =
        ["New"] = SubMenu1,
        ["Load Game"] = ID_LOADGAME,
        ["Exit"] = ID_EXIT

is probably not going to do what you want. You are very likely to find 
that it is displayed in some other order:

  |  Exit      |
  |  Load Game |
  |  New...    |

when you really wanted:

  |Main:       |
  |  New...    |
  |  Load Game |
  |  Exit      |

So I think you probably want to use a more complicated object than a 
simple table. It could, for example, be a pair of tables, one of which is 
as you have described, and the second of which is an ordered list of menu 
keys. (Of course, if you are planning on internationalizing, you might not 
want to use the menu text as a key, either. Or you might.)

This would motivate the creation of a Menu object, which implements the 
:add() method. You might then be able to write, for example:
  mainMenu = "Main"
               :add("New", subMenu1)
               :add("Load Game", ID_LOADGAME,
               :add("Exit", ID_EXIT)

Now, you actually could just include the sub-menu without giving it a 
name, using an interface like this:

  mainMenu = "Main"
               :sub "New"
                    :add("New Campaign", ID_CAMPAIGN)
                    :add("New Random Map", ID_RANDOMMAP)
               :add("Load Game", ID_LOADGAME,
               :add("Exit", ID_EXIT)

The call to :sub() automatically adds a Back link to the newly created 
submenu, which is then used by .super
to get back to the previous menu. This solves the problem expressed by 

  > Well, the only thing I dislike about the solution below is that 
  > is effectively split in two parts. If the Menu table is a page long it
  > would be easy to miss that <SubMenu1["Back"] = Menu> while browsing
  > through the file. What if there were 50 sub menus? All of them would
  > be split in at least (but not limited to) two parts and the file
  > can become a real mess with time.

But it doesn't address the question of what happens if a menu is a submenu 
of more than one parent menu, which is certainly a possibility in the 
general case.


    |Maze:         |
    |  Simplify    |
    |  Complicate  |
    |  New...      |\
    +--------------+ \
<---|  Back        +  \
    +--------------+   \
    +==============+     \   +============+
    |Character:    |      -> |From:       +
    +==============+     /   +============+
    |  Empower     |    /    |  CD        |
    |  Kill        |   /     |  Website   |
    |  New...      |>-/      |  File...   |
    +--------------+         +------------+
<---|  Back        +   ? <---|  Back      |
    +--------------+         +------------+

That is, the same "From" menu is used in both the Maze and Character 

This would suggest that Back entries should be added automatically when 
the submenu is presented, rather than when it is first created. A similar 
mechanism would allow addition of contextual information (Recent, for 


Since I've got a dental appointment in 15 minutes, I'll leave 
implementation of the
above interface as an exercise. Hints: 1) every method returns its self 
except for :sub() which returns the new submenu. 2) .super and .separator 
implemented by the __index metamethod; the first one simply returns the 
link, and the second one modifies the object by adding the separator and 
returns the original object. You could avoid the mix of : and . by using .
throughout, and faking the method call by returning a closed function.


Anyway, rough outline code for the first implementation, where "Back" is 
added automatically.