Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

ArMode.cpp

00001 /*
00002 ActivMedia Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004,2005 ActivMedia Robotics, LLC
00004 
00005 
00006      This program is free software; you can redistribute it and/or modify
00007      it under the terms of the GNU General Public License as published by
00008      the Free Software Foundation; either version 2 of the License, or
00009      (at your option) any later version.
00010 
00011      This program is distributed in the hope that it will be useful,
00012      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014      GNU General Public License for more details.
00015 
00016      You should have received a copy of the GNU General Public License
00017      along with this program; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 If you wish to redistribute ARIA under different terms, contact 
00021 ActivMedia Robotics for information about a commercial version of ARIA at 
00022 robots@activmedia.com or 
00023 ActivMedia Robotics, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
00024 
00025 */
00026 
00027 #include "ArExport.h"
00028 #include "ariaOSDef.h"
00029 #include "ArMode.h"
00030 #include "ArRobot.h"
00031 #include "ariaInternal.h"
00032 
00033 ArMode *ArMode::ourActiveMode = NULL;
00034 ArGlobalFunctor *ArMode::ourHelpCB = NULL;
00035 std::list<ArMode *> ArMode::ourModes;
00036 
00048 ArMode::ArMode(ArRobot *robot, const char *name, char key, 
00049                         char key2) :
00050   myActivateCB(this, &ArMode::activate),
00051   myDeactivateCB(this, &ArMode::deactivate),
00052   myUserTaskCB(this, &ArMode::userTask)
00053 {
00054   ArKeyHandler *keyHandler;
00055   myName = name;
00056   myRobot = robot;
00057   myKey = key;
00058   myKey2 = key2;
00059   // see if there is already a keyhandler, if not make one for ourselves
00060   if ((keyHandler = Aria::getKeyHandler()) == NULL)
00061   {
00062     keyHandler = new ArKeyHandler;
00063     Aria::setKeyHandler(keyHandler);
00064     if (myRobot != NULL)
00065       myRobot->attachKeyHandler(keyHandler);
00066     else
00067       ArLog::log(ArLog::Terse, "ArMode: No robot to attach a keyHandler to, keyHandling won't work... either make your own keyHandler and drive it yourself, make a keyhandler and attach it to a robot, or give this a robot to attach to.");
00068   }  
00069   if (ourHelpCB == NULL)
00070   {
00071     ourHelpCB = new ArGlobalFunctor(&ArMode::baseHelp);
00072     if (!keyHandler->addKeyHandler('h', ourHelpCB))
00073       ArLog::log(ArLog::Terse, "The key handler already has a key for 'h', ArMode will not be invoked on an 'h' keypress.");
00074     if (!keyHandler->addKeyHandler('H', ourHelpCB))
00075       ArLog::log(ArLog::Terse, "The key handler already has a key for 'H', ArMode will not be invoked on an 'H' keypress.");
00076     if (!keyHandler->addKeyHandler('?', ourHelpCB))
00077       ArLog::log(ArLog::Terse, "The key handler already has a key for '?', ArMode will not be invoked on an '?' keypress.");
00078     if (!keyHandler->addKeyHandler('/', ourHelpCB))
00079       ArLog::log(ArLog::Terse, "The key handler already has a key for '/', ArMode will not be invoked on an '/' keypress.");
00080 
00081   }
00082 
00083   // now that we have one, add our keys as callbacks, print out big
00084   // warning messages if they fail
00085   if (myKey != '\0')
00086     if (!keyHandler->addKeyHandler(myKey, &myActivateCB))
00087       ArLog::log(ArLog::Terse, "The key handler already has a key for '%c', ArMode will not work correctly.", myKey);
00088   if (myKey2 != '\0')
00089     if (!keyHandler->addKeyHandler(myKey2, &myActivateCB))
00090       ArLog::log(ArLog::Terse, "The key handler already has a key for '%c', ArMode will not work correctly.", myKey2);
00091 
00092   // toss this mode into our list of modes
00093   ourModes.push_front(this);
00094 }
00095 
00096 ArMode::~ArMode()
00097 {
00098   ArKeyHandler *keyHandler;
00099   if ((keyHandler = Aria::getKeyHandler()) != NULL)
00100   {
00101     if (myKey != '\0')
00102       keyHandler->remKeyHandler(myKey);
00103     if (myKey2 != '\0')
00104       keyHandler->remKeyHandler(myKey2);
00105   }
00106   if (myRobot != NULL)
00107     myRobot->remUserTask(&myUserTaskCB);
00108 }
00109 
00116 bool ArMode::baseActivate(void)
00117 {
00118   if (ourActiveMode == this)
00119     return false;
00120   if (myRobot != NULL)
00121   {
00122     myRobot->addUserTask(myName.c_str(), 50, &myUserTaskCB);
00123   }
00124   if (ourActiveMode != NULL)
00125     ourActiveMode->deactivate();
00126   ourActiveMode = this;
00127   if (myRobot != NULL)
00128   {
00129     myRobot->stop();
00130     myRobot->clearDirectMotion();
00131   }
00132   
00133   baseHelp();
00134   return true;
00135 }
00136 
00141 bool ArMode::baseDeactivate(void)
00142 {
00143   if (myRobot != NULL)
00144     myRobot->remUserTask(&myUserTaskCB);
00145   if (ourActiveMode == this)
00146   {
00147     ourActiveMode = NULL;
00148     return true;
00149   }
00150   return false;
00151 }
00152 
00153 const char *ArMode::getName(void)
00154 {
00155   return myName.c_str();
00156 }
00157 
00158 char ArMode::getKey(void)
00159 {
00160   return myKey;
00161 }
00162 
00163 char ArMode::getKey2(void)
00164 {
00165   return myKey2;
00166 }
00167 
00168 void ArMode::baseHelp(void)
00169 {
00170   std::list<ArMode *>::iterator it;
00171   ArLog::log(ArLog::Terse, "\n\nYou can do these actions with these keys:\n");
00172   ArLog::log(ArLog::Terse, "quit: escape");
00173   ArLog::log(ArLog::Terse, "help: 'h' or 'H' or '?' or '/'");
00174   ArLog::log(ArLog::Terse, "\nYou can switch to other modes with these keys:");
00175   for (it = ourModes.begin(); it != ourModes.end(); ++it)
00176   {
00177     ArLog::log(ArLog::Terse, "%30s mode: '%c' or '%c'", (*it)->getName(), 
00178                (*it)->getKey(), (*it)->getKey2());
00179   }
00180   if (ourActiveMode == NULL)
00181     ArLog::log(ArLog::Terse, "You are in no mode currently.");
00182   else
00183   {
00184     ArLog::log(ArLog::Terse, "You are in '%s' mode currently.\n",
00185                ourActiveMode->getName());
00186     ourActiveMode->help();
00187   }
00188 }
00189 
00190 void ArMode::addKeyHandler(int keyToHandle, ArFunctor *functor)
00191 {
00192   ArKeyHandler *keyHandler;
00193   std::string charStr;
00194 
00195   // see if there is already a keyhandler, if not something is wrong
00196   // (since constructor should make one if there isn't one yet
00197   if ((keyHandler = Aria::getKeyHandler()) == NULL)
00198   {
00199     ArLog::log(ArLog::Terse,"ArMode '%s'::keyHandler: There should already be a key handler, but there isn't... mode won't work right.", getName());
00200     return;
00201   }
00202   if (!keyHandler->addKeyHandler(keyToHandle, functor))
00203   {
00204     switch (keyToHandle) {
00205     case ArKeyHandler::UP:
00206       charStr = "Up";
00207       break;
00208     case ArKeyHandler::DOWN:
00209       charStr = "Down";
00210       break;
00211     case ArKeyHandler::LEFT:
00212       charStr = "Left";
00213       break;
00214     case ArKeyHandler::RIGHT:
00215       charStr = "Right";
00216       break;
00217     case ArKeyHandler::ESCAPE:
00218       charStr = "Escape";
00219       break;
00220     case ArKeyHandler::F1:
00221       charStr = "F1";
00222       break;
00223     case ArKeyHandler::F2:
00224       charStr = "F2";
00225       break;
00226     case ArKeyHandler::F3:
00227       charStr = "F3";
00228       break;
00229     case ArKeyHandler::F4:
00230       charStr = "F4";
00231       break;
00232     case ArKeyHandler::SPACE:
00233       charStr = "Space";
00234       break;
00235     case ArKeyHandler::TAB:
00236       charStr = "Tab";
00237       break;
00238     case ArKeyHandler::ENTER:
00239       charStr = "Enter";
00240       break;
00241     case ArKeyHandler::BACKSPACE:
00242       charStr = "Backspace";
00243       break;
00244     default:
00245       charStr = (char)keyToHandle;
00246       break;
00247     }
00248     ArLog::log(ArLog::Terse,  
00249                "ArMode '%s': The key handler has a duplicate key for '%s' so the mode may not work right.", getName(), charStr.c_str());
00250   }
00251   
00252 }
00253 
00254 void ArMode::remKeyHandler(ArFunctor *functor)
00255 {
00256   ArKeyHandler *keyHandler;
00257   std::string charStr;
00258 
00259   // see if there is already a keyhandler, if not something is wrong
00260   // (since constructor should make one if there isn't one yet
00261   if ((keyHandler = Aria::getKeyHandler()) == NULL)
00262   {
00263     ArLog::log(ArLog::Terse,"ArMode '%s'::keyHandler: There should already be a key handler, but there isn't... mode won't work right.", getName());
00264     return;
00265   }
00266   if (!keyHandler->remKeyHandler(functor))
00267     ArLog::log(ArLog::Terse,  
00268                "ArMode '%s': The key handler already didn't have the given functor so the mode may not be working right.", getName());
00269 }
00270   

Generated on Wed Oct 19 12:56:36 2005 for Aria by  doxygen 1.4.0