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