command.cc

Go to the documentation of this file.
00001 /** @file tcl/command.cc binds a wrapped c++ function to a
00002     tcl::arg_spec and a tcl::dispatcher */
00003 ///////////////////////////////////////////////////////////////////////
00004 //
00005 // Copyright (c) 1999-2004 California Institute of Technology
00006 // Copyright (c) 2004-2007 University of Southern California
00007 // Rob Peters <rjpeters at usc dot edu>
00008 //
00009 // created: Fri Jun 11 14:50:58 1999
00010 // commit: $Id: command.cc 11876 2009-10-22 15:53:06Z icore $
00011 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/tcl/command.cc $
00012 //
00013 // --------------------------------------------------------------------
00014 //
00015 // This file is part of GroovX
00016 //   [http://ilab.usc.edu/rjpeters/groovx/]
00017 //
00018 // GroovX is free software; you can redistribute it and/or modify it
00019 // under the terms of the GNU General Public License as published by
00020 // the Free Software Foundation; either version 2 of the License, or
00021 // (at your option) any later version.
00022 //
00023 // GroovX is distributed in the hope that it will be useful, but
00024 // WITHOUT ANY WARRANTY; without even the implied warranty of
00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026 // General Public License for more details.
00027 //
00028 // You should have received a copy of the GNU General Public License
00029 // along with GroovX; if not, write to the Free Software Foundation,
00030 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00031 //
00032 ///////////////////////////////////////////////////////////////////////
00033 
00034 #ifndef GROOVX_TCL_COMMAND_CC_UTC20050628162421_DEFINED
00035 #define GROOVX_TCL_COMMAND_CC_UTC20050628162421_DEFINED
00036 
00037 #include "tcl/command.h"
00038 
00039 #include "rutz/fstring.h"
00040 #include "rutz/sfmt.h"
00041 #include "rutz/shared_ptr.h"
00042 
00043 #include "tcl/interp.h"
00044 
00045 #include "rutz/trace.h"
00046 #include "rutz/debug.h"
00047 GVX_DBG_REGISTER
00048 
00049 using rutz::shared_ptr;
00050 
00051 ///////////////////////////////////////////////////////////////////////
00052 //
00053 // tcl::function
00054 //
00055 ///////////////////////////////////////////////////////////////////////
00056 
00057 tcl::function::~function() throw() {}
00058 
00059 ///////////////////////////////////////////////////////////////////////
00060 //
00061 // tcl::arg_dispatcher
00062 //
00063 ///////////////////////////////////////////////////////////////////////
00064 
00065 tcl::arg_dispatcher::~arg_dispatcher() throw() {}
00066 
00067 ///////////////////////////////////////////////////////////////////////
00068 //
00069 // default_dispatcher
00070 //
00071 ///////////////////////////////////////////////////////////////////////
00072 
00073 namespace
00074 {
00075   class default_dispatcher : public tcl::arg_dispatcher
00076   {
00077   public:
00078     virtual void dispatch(tcl::interpreter& interp,
00079                           unsigned int objc, Tcl_Obj* const objv[],
00080                           tcl::function& callback)
00081     {
00082       tcl::call_context ctx(interp, objc, objv);
00083       callback.invoke(ctx);
00084     }
00085   };
00086 
00087   shared_ptr<default_dispatcher>
00088     g_default_dispatcher(new default_dispatcher);
00089 }
00090 
00091 ///////////////////////////////////////////////////////////////////////
00092 //
00093 // tcl::command::impl class definition
00094 //
00095 ///////////////////////////////////////////////////////////////////////
00096 
00097 class tcl::command::impl
00098 {
00099 private:
00100   impl(const impl&);
00101   impl& operator=(const impl&);
00102 
00103 public:
00104   impl(shared_ptr<tcl::function> cback,
00105        const char* usg, const arg_spec& spec)
00106     :
00107     callback(cback),
00108     dispatcher(g_default_dispatcher),
00109     usage(usg ? usg : ""),
00110     argspec(spec)
00111   {}
00112 
00113   ~impl() throw() {}
00114 
00115   // These are set once per command object
00116   shared_ptr<tcl::function>             callback;
00117   shared_ptr<tcl::arg_dispatcher>       dispatcher;
00118   rutz::fstring                   const usage;
00119   arg_spec                        const argspec;
00120 };
00121 
00122 ///////////////////////////////////////////////////////////////////////
00123 //
00124 // tcl::command member definitions
00125 //
00126 ///////////////////////////////////////////////////////////////////////
00127 
00128 tcl::command::command(shared_ptr<tcl::function> callback,
00129                       const char* usage, const arg_spec& spec)
00130   :
00131   rep(new impl(callback, usage, spec))
00132 {
00133 GVX_TRACE("tcl::command::command");
00134 }
00135 
00136 tcl::command::~command() throw()
00137 {
00138 GVX_TRACE("tcl::command::~command");
00139 
00140   delete rep;
00141 }
00142 
00143 bool tcl::command::allows_argc(unsigned int objc) const
00144 {
00145 GVX_TRACE("tcl::command::allows_argc");
00146   return rep->argspec.allows_argc(objc);
00147 }
00148 
00149 bool tcl::command::rejects_argc(unsigned int objc) const
00150 {
00151   return !this->allows_argc(objc);
00152 }
00153 
00154 rutz::fstring tcl::command::usage_string() const
00155 {
00156 GVX_TRACE("tcl::command::usage_string");
00157   if (rep->argspec.argc_min() ==
00158       rep->argspec.argc_max())
00159     return rutz::sfmt("%s (argc=%u)", rep->usage.c_str(),
00160                       rep->argspec.argc_min());
00161 
00162   // else...
00163   return rutz::sfmt("%s (argc=[%u..%u])", rep->usage.c_str(),
00164                     rep->argspec.argc_min(),
00165                     rep->argspec.argc_max());
00166 }
00167 
00168 void tcl::command::call(tcl::interpreter& interp,
00169                         unsigned int objc, Tcl_Obj* const objv[])
00170 {
00171   rep->dispatcher->dispatch(interp, objc, objv, *rep->callback);
00172 }
00173 
00174 shared_ptr<tcl::arg_dispatcher> tcl::command::get_dispatcher() const
00175 {
00176 GVX_TRACE("tcl::command::get_dispatcher");
00177   return rep->dispatcher;
00178 }
00179 
00180 void tcl::command::set_dispatcher(shared_ptr<tcl::arg_dispatcher> dpx)
00181 {
00182 GVX_TRACE("tcl::command::set_dispatcher");
00183   rep->dispatcher = dpx;
00184 }
00185 
00186 
00187 ///////////////////////////////////////////////////////////////////////
00188 //
00189 // tcl::call_context member definitions
00190 //
00191 ///////////////////////////////////////////////////////////////////////
00192 
00193 tcl::call_context::call_context(tcl::interpreter& interp,
00194                                 unsigned int objc, Tcl_Obj* const* objv) :
00195   m_interp(interp),
00196   m_objc(objc),
00197   m_objv(objv)
00198 {}
00199 
00200 tcl::call_context::~call_context() throw()
00201 {}
00202 
00203 void tcl::call_context::set_obj_result(const tcl::obj& obj)
00204 {
00205 GVX_TRACE("tcl::call_context::set_obj_result");
00206   m_interp.set_result(obj);
00207 }
00208 
00209 static const char __attribute__((used)) vcid_groovx_tcl_command_cc_utc20050628162421[] = "$Id: command.cc 11876 2009-10-22 15:53:06Z icore $ $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/tcl/command.cc $";
00210 #endif // !GROOVX_TCL_COMMAND_CC_UTC20050628162421_DEFINED
Generated on Sun May 8 08:42:21 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3