openrave.org

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
interface.cpp
Go to the documentation of this file.
1 // -*- coding: utf-8 -*-
2 // Copyright (C) 2006-2011 Rosen Diankov (rosen.diankov@gmail.com)
3 //
4 // This file is part of OpenRAVE.
5 // OpenRAVE is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "libopenrave.h"
18 
19 namespace OpenRAVE {
20 InterfaceBase::InterfaceBase(InterfaceType type, EnvironmentBasePtr penv) : __type(type), __penv(penv)
21 {
22  RaveInitializeFromState(penv->GlobalState()); // make sure global state is set
23  RegisterCommand("help",boost::bind(&InterfaceBase::_GetCommandHelp,this,_1,_2),
24  "display help commands.");
25 }
26 
28 {
29  boost::unique_lock< boost::shared_mutex > lock(_mutexInterface);
30  __mapCommands.clear();
31  __mapUserData.clear();
32  __mapReadableInterfaces.clear();
33  __penv.reset();
34 }
35 
36 void InterfaceBase::SetUserData(const std::string& key, UserDataPtr data) const
37 {
38  UserDataPtr olduserdata;
39  {
40  boost::unique_lock< boost::shared_mutex > lock(_mutexInterface);
41  std::map<std::string, UserDataPtr>::iterator it = __mapUserData.find(key);
42  if( it == __mapUserData.end() ) {
43  __mapUserData[key] = data;
44  }
45  else {
46  olduserdata = it->second;
47  it->second = data;
48  }
49  }
50  olduserdata.reset();
51 }
52 
53 UserDataPtr InterfaceBase::GetUserData(const std::string& key) const
54 {
55  boost::shared_lock< boost::shared_mutex > lock(_mutexInterface);
56  std::map<std::string, UserDataPtr>::const_iterator it = __mapUserData.find(key);
57  if( it == __mapUserData.end() ) {
58  return UserDataPtr();
59  }
60  return it->second;
61 }
62 
63 bool InterfaceBase::RemoveUserData(const std::string& key) const
64 {
65  // have to destroy the userdata pointer outside the lock, otherwise can get into a deadlock
66  UserDataPtr olduserdata;
67  {
68  boost::unique_lock< boost::shared_mutex > lock(_mutexInterface);
69  std::map<std::string, UserDataPtr>::iterator it = __mapUserData.find(key);
70  if( it == __mapUserData.end() ) {
71  return false;
72  }
73  olduserdata = it->second;
74  __mapUserData.erase(it);
75  }
76  olduserdata.reset();
77  return true;
78 }
79 
80 void InterfaceBase::Clone(InterfaceBaseConstPtr preference, int cloningoptions)
81 {
82  if( !preference ) {
83  throw openrave_exception("invalid cloning reference",ORE_InvalidArguments);
84  }
85  __mapUserData = preference->__mapUserData;
86  __struri = preference->__struri;
87  __mapReadableInterfaces = preference->__mapReadableInterfaces;
88  __description = preference->__description;
89 }
90 
91 bool InterfaceBase::SendCommand(ostream& sout, istream& sinput)
92 {
93  string cmd;
94  sinput >> cmd;
95  if( !sinput ) {
96  throw openrave_exception("invalid command",ORE_InvalidArguments);
97  }
98  boost::shared_ptr<InterfaceCommand> interfacecmd;
99  {
100  boost::shared_lock< boost::shared_mutex > lock(_mutexInterface);
101  CMDMAP::iterator it = __mapCommands.find(cmd);
102  if( it == __mapCommands.end() ) {
103  throw openrave_exception(str(boost::format("failed to find command '%s' in interface %s\n")%cmd.c_str()%GetXMLId()),ORE_CommandNotSupported);
104  }
105  interfacecmd = it->second;
106  }
107  if( !interfacecmd->fn(sout,sinput) ) {
108  RAVELOG_VERBOSE(str(boost::format("command failed in interface %s: %s\n")%GetXMLId()%cmd));
109  return false;
110  }
111  return true;
112 }
113 
114 void InterfaceBase::Serialize(BaseXMLWriterPtr writer, int options) const
115 {
116  FOREACHC(it, __mapReadableInterfaces) {
117  it->second->Serialize(writer,options);
118  }
119 }
120 
121 void InterfaceBase::RegisterCommand(const std::string& cmdname, InterfaceBase::InterfaceCommandFn fncmd, const std::string& strhelp)
122 {
123  boost::unique_lock< boost::shared_mutex > lock(_mutexInterface);
124  if((cmdname.size() == 0)|| !utils::IsValidName(cmdname) ||(_stricmp(cmdname.c_str(),"commands") == 0)) {
125  throw openrave_exception(str(boost::format("command '%s' invalid")%cmdname),ORE_InvalidArguments);
126  }
127  if( __mapCommands.find(cmdname) != __mapCommands.end() ) {
128  throw openrave_exception(str(boost::format("command '%s' already registered")%cmdname),ORE_InvalidArguments);
129  }
130  __mapCommands[cmdname] = boost::shared_ptr<InterfaceCommand>(new InterfaceCommand(fncmd, strhelp));
131 }
132 
133 void InterfaceBase::UnregisterCommand(const std::string& cmdname)
134 {
135  boost::unique_lock< boost::shared_mutex > lock(_mutexInterface);
136  CMDMAP::iterator it = __mapCommands.find(cmdname);
137  if( it != __mapCommands.end() ) {
138  __mapCommands.erase(it);
139  }
140 }
141 
142 bool InterfaceBase::_GetCommandHelp(std::ostream& o, std::istream& sinput) const
143 {
144  boost::shared_lock< boost::shared_mutex > lock(_mutexInterface);
145  string cmd, label;
146  CMDMAP::const_iterator it;
147  while(!sinput.eof()) {
148  sinput >> cmd;
149  if( !sinput ) {
150  break;
151  }
152  std::transform(cmd.begin(), cmd.end(), cmd.begin(), ::tolower);
153 
154  if( cmd == "commands" ) {
155  for(it = __mapCommands.begin(); it != __mapCommands.end(); ++it) {
156  o << it->first << " ";
157  }
158  return true;
159  }
160  else if( cmd == "label" ) {
161  sinput >> label;
162  }
163  else {
164  it = __mapCommands.find(cmd);
165  if( it != __mapCommands.end() ) {
166  o << it->second->help;
167  return true;
168  }
169  }
170 
171  if( !sinput ) {
172  RAVELOG_ERROR(str(boost::format("failed processing command %s\n")%cmd));
173  return false;
174  }
175  }
176 
177  // display full help string
178  o << endl << GetXMLId() << " Commands" << endl;
179  for(size_t i = 0; i < GetXMLId().size(); ++i) {
180  o << "=";
181  }
182  o << "=========" << endl << endl;
183  for(it = __mapCommands.begin(); it != __mapCommands.end(); ++it) {
184  if( label.size() > 0 ) {
185  string strlower = it->first;
186  std::transform(strlower.begin(), strlower.end(), strlower.begin(), ::tolower);
187  o << endl << ".. _" << label << strlower << ":" << endl << endl;
188  }
189  o << endl << it->first << endl;
190  for(size_t i = 0; i < it->first.size(); ++i) {
191  o << "~";
192  }
193  o << endl << endl << it->second->help << endl << endl << "~~~~" << endl << endl;
194  }
195  return true;
196 }
197 
198 XMLReadablePtr InterfaceBase::GetReadableInterface(const std::string& xmltag) const
199 {
200  boost::shared_lock< boost::shared_mutex > lock(_mutexInterface);
201  READERSMAP::const_iterator it = __mapReadableInterfaces.find(xmltag);
202  return it != __mapReadableInterfaces.end() ? it->second : XMLReadablePtr();
203 }
204 
206 {
207  boost::unique_lock< boost::shared_mutex > lock(_mutexInterface);
208  READERSMAP::iterator it = __mapReadableInterfaces.find(xmltag);
209  if( it == __mapReadableInterfaces.end() ) {
210  __mapReadableInterfaces[xmltag] = readable;
211  return XMLReadablePtr();
212  }
213  XMLReadablePtr pprev = it->second;
214  it->second = readable;
215  return pprev;
216 }
217 
218 }