Homepage Demos Overview Downloads Tutorials Reference
Credits

ControlBase.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_ControlBase_h
00003 #define INCLUDED_ControlBase_h
00004 
00005 #include "Events/EventBase.h"
00006 #include "Motion/MotionManager.h"
00007 #include "SoundPlay/SoundManager.h"
00008 #include "Shared/Config.h"
00009 #include "Wireless/Socket.h"
00010 #include <string>
00011 #include <vector>
00012 
00013 //! Base class for all items in the Controller hierarchy.
00014 /*! These are similar to behaviors in that they can do processing and are told
00015  *  when to start and stop.
00016  *
00017  *  However, the important difference is that these have to follow a much
00018  *  tighter set of guidelines for a more refined purpose - user interface.
00019  *  Controls do not directly receive events - the Controller will process events
00020  *  for them and call the appropriate functions at the appropriate times.
00021  *  Controls are expected to fit into a heirarchical scheme, where each control
00022  *  (except the root) has a parent which created it, and may return its own
00023  *  children where appropriate.
00024  *
00025  *  This base class will do most of the work of maintain submenus for you, and
00026  *  will call appropriate virtual functions which you can override.  Controls
00027  *  generally live in Behaviors/Controls/ as the Controller itself is a
00028  *  behavior, and these controls merely its tools.
00029  *
00030  *  The ControlBase pointers which are returned at various points are the
00031  *  responsibility of the creator.  Controller will not delete them upon
00032  *  deactivation.
00033  *
00034  *  GUI Theory: \n
00035  *  There are 3 levels to the user interface.
00036  *  -# Robot/Local: Uses the LEDs and sounds for immediate feedback.  No external resources needed
00037  *  -# Text: Uses a console to display/request information.
00038  *  -# GUI: Uses a graphical interface on an external screen
00039  *
00040  *  Obviously, higher levels require more technological resources, which also
00041  *  means there's more to go wrong and debug.  However, another important
00042  *  distinction between the first level and the others is that the first level
00043  *  does not require the user to lose direct contact with the robot.  Requiring
00044  *  the user to move back and forth from robot to computer can be much more
00045  *  frustrating than decoding LED signals or press head buttons.  There are
00046  *  safety issues when triggering behaviors remotely if the robot is out of
00047  *  immediate reach.  But of course, having a GUI and text output is extremely
00048  *  valuable in terms of ease of use and efficiency.
00049  *
00050  *  So, the lesson is to try to support all 3 levels so that your interfaces
00051  *  will be robust and efficient in a variety of environments.  You'll thank
00052  *  yourself when you're demoing on the road and you can't get wavelan up, or
00053  *  the guest machine you're supposed to use doesn't have Java, or whatever.
00054  *
00055  * @todo ControlBase's should use ReferenceCounter so memory management is not an issue
00056  * @see Controller, NullControl */
00057 class ControlBase {
00058 public:
00059   
00060   ControlBase() : name("(null name)"), description(), hilights(), options(), doRewrite(false), display_id(MotionManager::invalid_MC_ID), gui_comm(NULL) {} //!< Contructor
00061   ControlBase(const std::string& n) : name(n), description(), hilights(), options(), doRewrite(false), display_id(MotionManager::invalid_MC_ID), gui_comm(NULL) {} //!< Contructor, initializes with a name
00062   ControlBase(const std::string& n, const std::string& d) : name(n), description(d), hilights(), options(), doRewrite(false), display_id(MotionManager::invalid_MC_ID), gui_comm(NULL) {} //!< Contructor, initializes with a name
00063 
00064   //! Destructor
00065   virtual ~ControlBase() {
00066     //    deactivate();
00067     clearSlots();
00068   }
00069 
00070   //! You probably want to override some of these, call the ControlBase functions from your code if you want default sound effects (or look in Config::controller_config).
00071   //! @name Controller Functions
00072 
00073   //! Called when the control is activated (or the control system is reactivating)
00074   /*! Takes the id number of a LedMC which the control should use, maintained by Controller.
00075    *  Controls share the display which is passed, and may use the socket @a gui to communicate with the GUI controller, if it is connected.
00076    *  @return a ControlBase pointer.  Return: @li @a this if the control should stay active (if it's not a one-shot command) @li @c NULL to return to parent @li other address to spawn a child control*/
00077   virtual ControlBase * activate(MotionManager::MC_ID disp_id, Socket * gui);
00078   virtual void pause();      //!< called when a control is being overriden by a child, or the control system is deactivating (e-stop being turned off)
00079   virtual void refresh();    //!< called when the child has died and this control should refresh its display, or some other event (such as the user pressing the refresh button) has happened to cause a refresh to be needed
00080   virtual void deactivate(); //!< called when this control is being popped from the control stack
00081 
00082   virtual ControlBase * doSelect();   //!< when the user has trigger an "open selection" - default is to return the hilighted control
00083   virtual ControlBase * doNextItem(); //!< when the user wants to increment the control - default is to return the first non-null slot after the last hilight
00084   virtual ControlBase * doPrevItem(); //!< when the user wants to decrement the control - default is to return the last non-null slot before the first hilight
00085   virtual ControlBase * doCancel();   //!< when the user wants to cancel - you should almost always return NULL now unless you need to confirm something (e.g. "Save changes?")
00086   virtual ControlBase * doReadStdIn(const std::string& prompt=std::string()); //!< prompt the user for text input on the current input device (cin, tekkotsu console (sout), or GUI)
00087   virtual ControlBase * takeInput(const std::string& msg); //!< called when the user has supplied a text string (may not have been prompted by doReadStdIn()!)
00088   virtual bool validInput(const std::string& msg); //!< may be called before takeInput to verify this Control can make sense of msg
00089   //@}
00090   
00091   virtual ControlBase& setName(const std::string& n) { name=n; return *this; } //!< sets the name of the control
00092   virtual std::string getName() const { return name; } //!< returns the name of the control
00093 
00094   virtual ControlBase& setDescription(const std::string d) { description=d; return *this; } //!< sets the description of the control
00095   virtual std::string getDescription() const { return description; } //!< returns a short description of what the control does
00096 
00097   const std::vector<ControlBase*>& getSlots() const { return options; } //!< returns the vector of controls
00098   std::string getSlotName(unsigned int i) const; //!< returns the string that will appear in slot @a i
00099   unsigned int slotsSize() const { return options.size(); } //!< returns the number of options available
00100   void setSlot(unsigned int i,ControlBase* o); //!< sets @a i'th element of ::options to @a o
00101   void pushSlot(ControlBase* o); //!< sets next unused element of ::options to @a o
00102   void clearSlots(); //!< deletes each slot item and clears the slots
00103 
00104   virtual const std::vector<unsigned int>& getHilights() const { return hilights; } //!< returns a vector of the indicies of hilighted slots
00105   virtual void setHilights(const std::vector<unsigned int>& hi); //!< sets the hilighted slots
00106   virtual void hilightFirst(); //!< sets the hilight to the first non-null slot
00107 
00108   virtual MotionManager::MC_ID getDisplay() { return display_id; } //!< returns display being used
00109   virtual ControlBase& setDisplay(MotionManager::MC_ID d) { display_id=d; return *this; } //!< sets display to use
00110 
00111 protected:
00112     
00113   //! clears the display (if use_VT100 is on)
00114   virtual void clearMenu();
00115 
00116   //! returns the average of the hilighted indicies - used to know to play the "next" sound, or the "prev" sound when the hilight changes
00117   float hilightsAvg() const;
00118 
00119   std::string name; //!< the name of this control
00120   std::string description; //!< the description of this control
00121   std::vector<unsigned int> hilights; //!< keep sorted - index(es) of current selection - can have multiple if using GUI
00122   std::vector<ControlBase*> options; //!< vector of controls to select from
00123   bool doRewrite; //!< toggles using VT100 codes to reposition the cursor at the beginning of the menu
00124                   /*!< we don't always want to do this, any time someone else might have written to
00125                    *   the display we set this to false so we don't overwrite it. */
00126 
00127   MotionManager::MC_ID display_id; //!< LedMC to use for displaying selection
00128   Socket * gui_comm; //!< socket to communicate with the GUI, if it is connected
00129   
00130 private:
00131   ControlBase(const ControlBase&); //!< you can override, but don't call this...
00132   ControlBase& operator=(const ControlBase&); //!< you can override, but don't call this...
00133 };
00134 
00135 /*! @file
00136  * @brief Defines ControlBase from which all items in the control system should inherit
00137  * @author ejt (Creator)
00138  *
00139  * $Author: ejt $
00140  * $Name: tekkotsu-2_0 $
00141  * $Revision: 1.17 $
00142  * $State: Exp $
00143  * $Date: 2004/01/08 22:39:53 $
00144  */
00145 #endif

Tekkotsu v2.0
Generated Wed Jan 21 03:20:28 2004 by Doxygen 1.3.4