Homepage | Demos | Overview | Downloads | Tutorials | Reference | Credits |
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 |