Homepage | Demos | Overview | Downloads | Tutorials | Reference | Credits |
ControlBase.hGo 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 00015 * are told when to start and stop. 00016 * 00017 * However, the important difference is that these have to follow a 00018 * much tighter set of guidelines for a more refined purpose - user 00019 * interface. Controls do not directly receive events - the 00020 * Controller will process events for them and call the appropriate 00021 * functions at the appropriate times. Controls are expected to fit 00022 * into a heirarchical scheme, where each control (except the root) 00023 * has a parent which created it, and may return its own children 00024 * where appropriate. 00025 * 00026 * Controls can be very powerful, and a class can be both a behavior 00027 * and a control. This allows integrated user interface to 00028 * controlling a complex behavior. Some controls may simply need 00029 * EventListener access instead to perform a few tricks. Mix and 00030 * match as you see fit. (multiple inheritance can be nice if it's 00031 * planned for, as these have been) 00032 * 00033 * This base class will do most of the work of maintaining submenus 00034 * for you, and will call appropriate virtual functions which you are 00035 * expected to override. Controls generally live in 00036 * <tt>Behaviors/Controls/</tt> as the Controller itself is a 00037 * behavior, and these controls merely its tools. 00038 * 00039 * The ControlBase pointers which are returned at various points are the 00040 * responsibility of the creator. Controller will not delete them upon 00041 * deactivation. 00042 * 00043 * GUI Theory: \n 00044 * There are 3 levels to the user interface. 00045 * -# Robot/Local: Uses the buttons for input, and LEDs and sounds for immediate feedback. No external resources needed 00046 * -# Text: Uses a console to display/request information. 00047 * -# GUI: Uses a graphical interface on a desktop machine 00048 * 00049 * Obviously, higher levels require more technological resources, which also 00050 * means there's more to go wrong and debug. However, another important 00051 * distinction between the first level and the others is that the first level 00052 * does not require the user to lose direct contact with the robot. Requiring 00053 * the user to move back and forth from robot to computer can be much more 00054 * frustrating than decoding LED signals or press head buttons. There are also 00055 * safety issues when triggering behaviors remotely if the robot is out of 00056 * immediate reach. But of course, having a GUI and text output is extremely 00057 * valuable in terms of ease of use and efficiency. 00058 * 00059 * So, the lesson is to try to support all 3 levels so that your interfaces 00060 * will be robust and efficient in a variety of environments. You'll thank 00061 * yourself when you're demoing on the road and you can't get wavelan up, or 00062 * the guest machine you're supposed to use doesn't have Java, or whatever. 00063 * 00064 * @todo ControlBase's should use ReferenceCounter so memory management is not an issue 00065 * @see Controller, NullControl */ 00066 class ControlBase { 00067 public: 00068 00069 //! @name Constructors/Destructors 00070 00071 ControlBase() : name("(null name)"), description(), hilights(), options(), doRewrite(false), display_id(MotionManager::invalid_MC_ID), gui_comm(NULL) {} //!< Contructor 00072 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 00073 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 00074 00075 //! Destructor 00076 virtual ~ControlBase() { 00077 // deactivate(); 00078 //cout << "~ControlBase(): " << name << endl; 00079 clearSlots(); 00080 } 00081 00082 //@} 00083 00084 //! 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). 00085 //! @name Controller Functions 00086 00087 //! Called when the control is activated (or the control system is reactivating) 00088 /*! Takes the id number of a LedMC which the control should use, maintained by Controller. 00089 * Controls share the display which is passed, and may use the socket @a gui to communicate with the GUI controller, if it is connected. 00090 * @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*/ 00091 virtual ControlBase * activate(MotionManager::MC_ID disp_id, Socket * gui); 00092 virtual void pause(); //!< called when a control is being overriden by a child, or the control system is deactivating (e-stop being turned off) 00093 virtual void refresh(); //!< called when the child has deactivated 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 00094 virtual void deactivate(); //!< called when this control is being popped from the control stack 00095 00096 //! when the user has trigger an "open selection" - default is to return the hilighted control*/ 00097 /*! The value which is returned is then activate()ed and pushed on the Controller's stack*/ 00098 virtual ControlBase * doSelect(); 00099 //! when the user wants to increment the control - default is to hilight the first non-null slot after the last hilight, and return @c this 00100 /*! The value which is returned is then activate()ed and pushed on the Controller's stack, so you probably want to return @c this */ 00101 virtual ControlBase * doNextItem(); 00102 //! when the user wants to decrement the control - default is to hilight the last non-null slot before the first hilight, and return @c this 00103 /*! The value which is returned is then activate()ed and pushed on the Controller's stack, so you probably want to return @c this */ 00104 virtual ControlBase * doPrevItem(); 00105 //! when the user wants to cancel - you should almost always return NULL now unless you need to override the cancel in order to confirm something (e.g. "Save changes?") 00106 /*! The value which is returned is then activate()ed and pushed on the Controller's stack, you probably want to return @c NULL */ 00107 virtual ControlBase * doCancel(); 00108 //! prompt the user for text input on the current input device (cin, tekkotsu console (sout), or GUI) 00109 /*! The value which is returned is then activate()ed and pushed on the Controller's stack, so you probably want to return @c this */ 00110 virtual ControlBase * doReadStdIn(const std::string& prompt=std::string()); 00111 //! called when the user has supplied a text string (may or may not have been prompted by doReadStdIn()! May not even be active yet - the user can direct the same input to a set of hilighted menus) 00112 /*! The value which is returned is then activate()ed and pushed on the Controller's stack*/ 00113 virtual ControlBase * takeInput(const std::string& msg); 00114 //! may be called before takeInput to verify this Control can make sense of msg 00115 virtual bool validInput(const std::string& msg); 00116 //@} 00117 00118 //! @name Accessors 00119 00120 virtual ControlBase& setName(const std::string& n) { name=n; return *this; } //!< sets the name of the control 00121 virtual std::string getName() const { return name; } //!< returns the name of the control 00122 00123 virtual ControlBase& setDescription(const std::string d) { description=d; return *this; } //!< sets the description of the control 00124 virtual std::string getDescription() const { return description; } //!< returns a short description of what the control does 00125 00126 virtual const std::vector<ControlBase*>& getSlots() const { return options; } //!< returns the vector of sub-controls 00127 virtual std::string getSlotName(unsigned int i) const; //!< returns the string that will appear in slot @a i 00128 virtual unsigned int slotsSize() const { return options.size(); } //!< returns the number of options available 00129 virtual void setSlot(unsigned int i,ControlBase* o); //!< sets @a i'th element of #options to @a o 00130 virtual void pushSlot(ControlBase* o); //!< sets next unused element of #options to @a o 00131 virtual void clearSlots(); //!< deletes each slot item and clears the slots 00132 00133 virtual const std::vector<unsigned int>& getHilights() const { return hilights; } //!< returns a vector of the indicies of hilighted slots 00134 virtual void setHilights(const std::vector<unsigned int>& hi); //!< sets the hilighted slots 00135 virtual void hilightFirst(); //!< sets the hilight to the first non-null slot 00136 00137 virtual MotionManager::MC_ID getDisplay() { return display_id; } //!< returns display being used 00138 virtual ControlBase& setDisplay(MotionManager::MC_ID d) { display_id=d; return *this; } //!< sets display to use 00139 00140 //@} 00141 00142 protected: 00143 00144 //! clears the display (if use_VT100 is on) 00145 virtual void clearMenu(); 00146 00147 //! returns the average of the hilighted indicies - used to know to play the "next" sound, or the "prev" sound when the hilight changes 00148 float hilightsAvg() const; 00149 00150 std::string name; //!< the name of this control 00151 std::string description; //!< the description of this control 00152 std::vector<unsigned int> hilights; //!< keep sorted - index(es) of current selection - can have multiple if using GUI 00153 std::vector<ControlBase*> options; //!< vector of controls to select from 00154 bool doRewrite; //!< toggles using VT100 codes to reposition the cursor at the beginning of the menu 00155 /*!< we don't always want to do this, any time someone else might have written to 00156 * the display we set this to false so we don't overwrite it. */ 00157 00158 MotionManager::MC_ID display_id; //!< LedMC to use for displaying selection 00159 Socket * gui_comm; //!< socket to communicate with the GUI, if it is connected 00160 00161 private: 00162 ControlBase(const ControlBase&); //!< you can override, but don't call this... 00163 ControlBase& operator=(const ControlBase&); //!< you can override, but don't call this... 00164 }; 00165 00166 /*! @file 00167 * @brief Defines ControlBase from which all items in the control system should inherit 00168 * @author ejt (Creator) 00169 * 00170 * $Author: ejt $ 00171 * $Name: tekkotsu-2_2 $ 00172 * $Revision: 1.21 $ 00173 * $State: Exp $ 00174 * $Date: 2004/10/07 22:15:37 $ 00175 */ 00176 #endif |
Tekkotsu v2.2 |
Generated Tue Oct 19 14:19:13 2004 by Doxygen 1.3.9.1 |