DUDS
Distributed Update of Data from Something
duds::ui::menu::MenuView Class Reference

Keeps track of the selected menu item, and updates it based on user input. More...

#include <MenuView.hpp>

Inheritance diagram for duds::ui::menu::MenuView:
Collaboration diagram for duds::ui::menu::MenuView:

Public Member Functions

 MenuView ()
 Constructs a new MenuView without attaching it to a Menu. More...
 
void attach (const std::shared_ptr< Menu > &menu)
 Attaches the view to a menu so that the view can operate on the menu's data, and the menu can inform the view of changes to the menu's items. More...
 
void backward (int dist=1)
 Changes the selection toward the back (last item) of the menu. More...
 
void chose ()
 Queues a request to chose what will be the currently selected menu item during input processing when a MenuOutputAccess object is created. More...
 
const boost::any & context () const
 Returns the arbitrary context object for this view. More...
 
boost::any & context ()
 Returns the arbitrary context object for this view. More...
 
void forward (int dist=1)
 Changes the selection toward the front (first item) of the menu. More...
 
void jump (int pos)
 Jump to a particular option by position index. More...
 
void jumpToFirst ()
 Jumps to the first option in the menu. More...
 
void jumpToLast ()
 Jumps to the last option in the menu. More...
 
const std::shared_ptr< Menu > & menu () const
 Returns the Menu used by this view. More...
 
bool queuedInput ()
 Returns true if any input for the menu view has been queued and is awaiting processing. More...
 
int selectedIndex () const
 Returns the index of the currently selected item. More...
 
std::shared_ptr< MenuViewshared_from_this ()
 Helper function that returns a shared pointer to this object from the base class Page. More...
 
bool update ()
 Updates the view's selected and chosen menu item if there are no MenuOutput objects currently rendering this view. More...
 
- Public Member Functions inherited from duds::ui::Page
 Page ()=default
 Constructs a page with no name. More...
 
 Page (const std::string &t)
 Constructs a page with the given name. More...
 
const std::string & title () const
 Returns the name or title of the page. More...
 

Static Public Member Functions

static std::shared_ptr< MenuViewmake (const std::shared_ptr< Menu > &menu)
 Constructs a new MenuView, attaches it to a Menu, and returns the std::shared_ptr that manages the view. More...
 

Private Member Functions

int adv (int pos)
 Find the first menu item that is selectable, starting at and including pos, and advancing toward the end of the menu. More...
 
void decUser ()
 Decrements the internal count of subviews currently accessing this menu view. More...
 
void incUser ()
 Increments the internal count of subviews currently accessing this menu view. More...
 
void insertion (std::size_t idx)
 Responds to the menu inserting a menu item to a spot other than the end of the menu. More...
 
void removal (std::size_t idx)
 Responds to the menu removing a menu item. More...
 
int retr (int pos)
 Find the first menu item that is selectable, starting at and including pos, and advancing toward the start of the menu. More...
 

Private Attributes

duds::general::Spinlock block
 Protects this object's data from inappropriate modification when used in a multithreaded manner. More...
 
bool choseItem
 Flag used to queue an input request to chose the selected item. More...
 
boost::any ctx
 Arbitrary context data that is available to MenuItem::chose(). More...
 
int currSel
 The index of the currently selected menu item. More...
 
friend Menu
 
friend MenuOutput
 
int nextSel
 The index of the next menu item to select. More...
 
int nextSelOff
 Offset from the next selection. More...
 
int outvUsers
 The number of MenuOutput objects currently using this MenuView. More...
 
std::shared_ptr< Menuparent
 The parent menu that supplies the MenuItems. More...
 
int updateIdx
 The menu's update index value when this subview was last rendered. More...
 

Additional Inherited Members

- Protected Member Functions inherited from duds::ui::Page
void title (const std::string &t)
 Changes the name of the page. More...
 

Detailed Description

Keeps track of the selected menu item, and updates it based on user input.

User input is provided to the backward(), forward(), jump(), and chose() functions. These functions are called in an asynchronous fashion; no access objects are required, and the view may be in use by another thread. The input is evaluated when no other MenuOutputAccess object is using the view and update() is called.

Updating the view requires its update() function to have a brief exclusive lock on the menu data. For output, a shared lock on the menu data is maintained by each MenuOutput object while a corresponding MenuOutputAccess object is in use. This prevents altering the menu while it is being output.

An optional arbitrary object is stored to assist with writing MenuItem::chose() functions that must deal with being invoked from multiple MenuView objects. It is available through the context() function.

Author
Jeff Jackowski
Examples:
bppmenu.cpp.

Definition at line 46 of file MenuView.hpp.

Constructor & Destructor Documentation

◆ MenuView()

duds::ui::menu::MenuView::MenuView ( )

Constructs a new MenuView without attaching it to a Menu.

It must be attached to a Menu prior to use, but this cannot be done within the constructor because it requires the std::shared_ptr that manages the view. The attachment is done by attach().

Note
All MenuView objects must be managed by std::shared_ptr.
See also
make()

Definition at line 17 of file MenuView.cpp.

Member Function Documentation

◆ adv()

int duds::ui::menu::MenuView::adv ( int  pos)
private

Find the first menu item that is selectable, starting at and including pos, and advancing toward the end of the menu.

If nothing is selectable in that direction, the first item in the opposite direction. If nothing at all is selectable, then the first menu item.

Parameters
posThe postiion of the first menu item to inspect.
Returns
The position of a menu item that is selectable, or is the first item in the menu.

Definition at line 32 of file MenuView.cpp.

Referenced by update().

◆ attach()

void duds::ui::menu::MenuView::attach ( const std::shared_ptr< Menu > &  menu)

Attaches the view to a menu so that the view can operate on the menu's data, and the menu can inform the view of changes to the menu's items.

Precondition
The view is not already attached to a menu.
Postcondition
The view is useful.
Parameters
menuThe menu whose items will be viewed.
Exceptions
MenuViewAlreadyAttachedThe view was already attached to a menu.
See also
make(const std::shared_ptr<Menu> &)

Definition at line 21 of file MenuView.cpp.

◆ backward()

void duds::ui::menu::MenuView::backward ( int  dist = 1)

Changes the selection toward the back (last item) of the menu.

The direction may seem to be the reverse of what is expected because the front and back is defined by the container holding the MenuItem objects, either a vector or a list, and the initially selected item is the first, or the front of the container. To call this function "advance" would abstract its result from the ordering of the items, and to call it "forward" would use two definitions of front and back with the same data structure.

Wrapping of the selection between the front and back of the selectable items is implemented. The implementation only wraps at the first and last selectable item. If the currently selected item is not the first or last selectable item, then the selection change will stop at the first or last item. This is to prevent a sudden wrapping of the selection that could seem odd, confusing, or erroneous to the user.

The currently selected item is not changed until after all MenuOutputAccess objects presently using this view are retired or destructed, and then a call to update() is made. Calling backward() and forward() multiple times before the current selection is re-evaluated is allowed, and will change an internal selection offset (nextSelOff) each time.

Between a call to jump() or chose() and update(), this function will have no effect. jump() is intended to select a specific item, so this behavior will prevent another item from being selected in the case that backward() or forward() are called shortly after jump(). The behavior also prevents chosing an item that may not be the intended item by ignoring selction changes after chosing an item.

Parameters
distThe number of selectable items to move toward the back of the item list. If the result would move past the end of the selectable items, the item selected will depend on the currently selected item:
  • If the current selected item is the last selectable item, then the item selected will be the first selectable item.
  • If the current selected item is not the last selectable item, then the item selected will be the last selectable item.

Definition at line 291 of file MenuView.cpp.

Referenced by forward(), and selectedIndex().

◆ chose()

void duds::ui::menu::MenuView::chose ( )

Queues a request to chose what will be the currently selected menu item during input processing when a MenuOutputAccess object is created.

Input changing the selection will be processed first, regardless of the order of function calls to this object. In order to limit any problems this might cause, changes to a selection are ignored after chose() is called until after the next MenuOutputAccess has started the next menu rendering cycle.

Note
If the ordering of keypresses is not known, call chose() after any calls to forward(), backward(), or jump(). If the ordering is known, call the functions in the same order.
Postcondition
Calls to forward(), backward(), and jump() will do nothing until another MenuOutputAccess has started the next menu rendering cycle.

Definition at line 310 of file MenuView.cpp.

Referenced by jumpToLast().

◆ context() [1/2]

const boost::any& duds::ui::menu::MenuView::context ( ) const
inline

Returns the arbitrary context object for this view.

Definition at line 369 of file MenuView.hpp.

◆ context() [2/2]

boost::any& duds::ui::menu::MenuView::context ( )
inline

Returns the arbitrary context object for this view.

Definition at line 375 of file MenuView.hpp.

◆ decUser()

void duds::ui::menu::MenuView::decUser ( )
private

Decrements the internal count of subviews currently accessing this menu view.

Definition at line 286 of file MenuView.cpp.

◆ forward()

void duds::ui::menu::MenuView::forward ( int  dist = 1)
inline

Changes the selection toward the front (first item) of the menu.

The direction may seem to be the reverse of what is expected because the front and back is defined by the container holding the MenuItem objects, either a vector or a list, and the initially selected item is the first, or the front of the container. To call this function "backward" would use two definitions of front and back with the same data structure.

Wrapping of the selection between the front and back of the selectable items is implemented. The implementation only wraps at the first and last selectable item. If the currently selected item is not the first or last selectable item, then the selection change will stop at the first or last item. This is to prevent a sudden wrapping of the selection that could seem odd, confusing, or erroneous to the user.

The currently selected item is not changed until after all MenuOutputAccess objects presently using this view are retired or destructed, and then a call to update() is made. Calling backward() and forward() multiple times before the current selection is re-evaluated is allowed, and will change an internal selection offset (nextSelOff) each time.

Between a call to jump() or chose() and update(), this function will have no effect. jump() is intended to select a specific item, so this behavior will prevent another item from being selected in the case that backward() or forward() are called shortly after jump(). The behavior also prevents chosing an item that may not be the intended item by ignoring selction changes after chosing an item.

Parameters
distThe number of selectable items to move toward the front of the item list. If the result would move past the start of the selectable items, the item selected will depend on the currently selected item:
  • If the current selected item is the first selectable item, then the item selected will be the last selectable item.
  • If the current selected item is not the first selectable item, then the item selected will be the first selectable item.

Definition at line 273 of file MenuView.hpp.

◆ incUser()

void duds::ui::menu::MenuView::incUser ( )
private

Increments the internal count of subviews currently accessing this menu view.

Definition at line 281 of file MenuView.cpp.

◆ insertion()

void duds::ui::menu::MenuView::insertion ( std::size_t  idx)
private

Responds to the menu inserting a menu item to a spot other than the end of the menu.

Precondition
The thread has an exclusive lock on the menu data, so update() cannot be using member data while this function runs.
Bug:
Can run simultaneously with jump(), but cannot lock block because that would cause a deadlock with update() if a menu item responded to MenuItem::chose() by inserting or removing an item.

Definition at line 243 of file MenuView.cpp.

Referenced by duds::ui::menu::Menu::insert().

◆ jump()

void duds::ui::menu::MenuView::jump ( int  pos)

Jump to a particular option by position index.

If negative, the size of the menu will be added so that -1 will jump to the last item, -2 will jump to the next to last item, and so forth. If the option is not selectable, no change will occur.

The currently selected item is not changed until after all MenuOutputAccess objects presently using this view are retired or destructed, and update() is called.

Between a call to this function and update(), calls to backward() and forward() will have no effect. jump() is intended to select a specific item, so this behavior will prevent another item from being selected in the case that backward() or forward() are called shortly after jump(). However, jump() may be called multiple times, but only the last call before calling chose() or update() will affect the selected item.

Parameters
posThe position index to select, but not chose. If the option is not selectable, then the current menu item will remain selected. If the current item is no longer selectable, then the next option backward (toward last item), wrapping to the begining of the menu if needed, that is visible and enabled will be selected.

Definition at line 299 of file MenuView.cpp.

Referenced by forward(), jumpToFirst(), and jumpToLast().

◆ jumpToFirst()

void duds::ui::menu::MenuView::jumpToFirst ( )
inline

Jumps to the first option in the menu.

If the first option is not selectable, no change will occur.

See also
jump()

Definition at line 306 of file MenuView.hpp.

◆ jumpToLast()

void duds::ui::menu::MenuView::jumpToLast ( )
inline

Jumps to the last option in the menu.

If the last option is not selectable, no change will occur.

See also
jump()

Definition at line 314 of file MenuView.hpp.

◆ make()

static std::shared_ptr<MenuView> duds::ui::menu::MenuView::make ( const std::shared_ptr< Menu > &  menu)
inlinestatic

Constructs a new MenuView, attaches it to a Menu, and returns the std::shared_ptr that manages the view.

Parameters
menuThe menu whose items will be viewed.
Examples:
bppmenu.cpp.

Definition at line 160 of file MenuView.hpp.

◆ menu()

const std::shared_ptr<Menu>& duds::ui::menu::MenuView::menu ( ) const
inline

Returns the Menu used by this view.

Definition at line 168 of file MenuView.hpp.

Referenced by attach().

◆ queuedInput()

bool duds::ui::menu::MenuView::queuedInput ( )

Returns true if any input for the menu view has been queued and is awaiting processing.

Input is queued by calls to backward(), forward(), jump(), jumpToFirst(), jumpToLast(), and chose(). It is processed by calling update().

Note
The menu may need to be output again for reasons other than changes from input, such as changes to the underlying menu or its items.

Definition at line 315 of file MenuView.cpp.

Referenced by jumpToLast().

◆ removal()

void duds::ui::menu::MenuView::removal ( std::size_t  idx)
private

Responds to the menu removing a menu item.

Precondition
The thread has an exclusive lock on the menu data, so update() cannot be using member data while this function runs.
Bug:
Can run simultaneously with jump(), but cannot lock block because that would cause a deadlock with update() if a menu item responded to MenuItem::chose() by inserting or removing an item.

Definition at line 262 of file MenuView.cpp.

Referenced by duds::ui::menu::Menu::remove().

◆ retr()

int duds::ui::menu::MenuView::retr ( int  pos)
private

Find the first menu item that is selectable, starting at and including pos, and advancing toward the start of the menu.

If nothing is selectable in that direction, the first item in the opposite direction. If nothing at all is selectable, then returns pos.

Parameters
posThe postiion of the first menu item to inspect.
Returns
The position of a menu item that is selectable, or pos.

Definition at line 57 of file MenuView.cpp.

Referenced by update().

◆ selectedIndex()

int duds::ui::menu::MenuView::selectedIndex ( ) const
inline

Returns the index of the currently selected item.

This value is not changed until after all MenuOutputAccess objects presently using this view are retired or destructed, and a call to update() is made. As a result, the index of an item that is not selectable may be returned if the item was changed and the menu view has not been updated since.

Definition at line 180 of file MenuView.hpp.

◆ shared_from_this()

std::shared_ptr<MenuView> duds::ui::menu::MenuView::shared_from_this ( )
inline

Helper function that returns a shared pointer to this object from the base class Page.

Definition at line 382 of file MenuView.hpp.

Referenced by attach().

◆ update()

bool duds::ui::menu::MenuView::update ( )

Updates the view's selected and chosen menu item if there are no MenuOutput objects currently rendering this view.

This is where the menu resolves the effects of calls to backward(), forward(), jump(), and chose(). MenuItem::chose() functions are called here. Not calling this function will make it appear that the menu is ignoring input. Resolving the effects of input here allows the program to ensure one update between multiple render attempts on the same menu view. It also allows the program to use one MenuOutput object with submenus because the menu to show may change based on input that is resolved here before acquiring a MenuOutputAccess object.

Note
This function uses a MenuAccess object internally, so it will block until it can get exclusive access to the Menu object.
Returns
True if an update could take place, or false if it was delayed because another thread was using the view through a MenuOutputAccess object. A true value does not mean that an update occured because there may not have been a change requiring an update.
Exceptions
exceptionIf an item is chosen, its MenuItem::chose() function is called. If that function throws, the exception will be re-thrown.

Definition at line 87 of file MenuView.cpp.

Referenced by jumpToLast().

Member Data Documentation

◆ block

duds::general::Spinlock duds::ui::menu::MenuView::block
private

Protects this object's data from inappropriate modification when used in a multithreaded manner.

Definition at line 60 of file MenuView.hpp.

Referenced by backward(), chose(), decUser(), incUser(), insertion(), jump(), queuedInput(), removal(), and update().

◆ choseItem

bool duds::ui::menu::MenuView::choseItem
private

Flag used to queue an input request to chose the selected item.

Definition at line 84 of file MenuView.hpp.

Referenced by backward(), chose(), jump(), queuedInput(), and update().

◆ ctx

boost::any duds::ui::menu::MenuView::ctx
private

Arbitrary context data that is available to MenuItem::chose().

Definition at line 51 of file MenuView.hpp.

Referenced by context().

◆ currSel

int duds::ui::menu::MenuView::currSel
private

The index of the currently selected menu item.

Definition at line 64 of file MenuView.hpp.

Referenced by insertion(), queuedInput(), removal(), selectedIndex(), and update().

◆ Menu

friend duds::ui::menu::MenuView::Menu
private

Definition at line 133 of file MenuView.hpp.

◆ MenuOutput

friend duds::ui::menu::MenuView::MenuOutput
private

Definition at line 134 of file MenuView.hpp.

◆ nextSel

int duds::ui::menu::MenuView::nextSel
private

The index of the next menu item to select.

Definition at line 68 of file MenuView.hpp.

Referenced by insertion(), jump(), queuedInput(), removal(), and update().

◆ nextSelOff

int duds::ui::menu::MenuView::nextSelOff
private

Offset from the next selection.

Definition at line 76 of file MenuView.hpp.

Referenced by backward(), jump(), queuedInput(), and update().

◆ outvUsers

int duds::ui::menu::MenuView::outvUsers
private

The number of MenuOutput objects currently using this MenuView.

Definition at line 72 of file MenuView.hpp.

Referenced by decUser(), incUser(), and update().

◆ parent

std::shared_ptr<Menu> duds::ui::menu::MenuView::parent
private

The parent menu that supplies the MenuItems.

Definition at line 55 of file MenuView.hpp.

Referenced by adv(), attach(), menu(), removal(), retr(), and update().

◆ updateIdx

int duds::ui::menu::MenuView::updateIdx
private

The menu's update index value when this subview was last rendered.

Definition at line 80 of file MenuView.hpp.

Referenced by update().


The documentation for this class was generated from the following files: