last update 20 Sep 2009 |
00001 /* 00002 * Copyright (C) 1998-2004 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * 00006 * This file is part of the Computer Vision and Robotics Library (CVR-Lib) 00007 * 00008 * The CVR-Lib is free software; you can redistribute it and/or 00009 * modify it under the terms of the BSD License. 00010 * 00011 * All rights reserved. 00012 * 00013 * Redistribution and use in source and binary forms, with or without 00014 * modification, are permitted provided that the following conditions are met: 00015 * 00016 * 1. Redistributions of source code must retain the above copyright notice, 00017 * this list of conditions and the following disclaimer. 00018 * 00019 * 2. Redistributions in binary form must reproduce the above copyright notice, 00020 * this list of conditions and the following disclaimer in the documentation 00021 * and/or other materials provided with the distribution. 00022 * 00023 * 3. Neither the name of the authors nor the names of its contributors may be 00024 * used to endorse or promote products derived from this software without 00025 * specific prior written permission. 00026 * 00027 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00028 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00029 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00030 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00031 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00032 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00033 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00034 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00035 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00036 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00037 * POSSIBILITY OF SUCH DAMAGE. 00038 */ 00039 00040 00041 00042 /** 00043 * \file cvrStatus.h 00044 * Contains the class cvr::status, which is the parent class for all 00045 * classes that can provide status information. 00046 * \author Jochen Wickel 00047 * \author Thomas Rusert 00048 * \author Pablo Alvarado 00049 * \date 14.04.2004 00050 * 00051 * $Id: cvrStatus.h,v 1.7 2007/10/07 03:17:00 alvarado Exp $ 00052 */ 00053 00054 #ifndef _CVR_STATUS_H_ 00055 #define _CVR_STATUS_H_ 00056 00057 #include <string> 00058 00059 00060 namespace cvr { 00061 class statusMonitor; 00062 00063 /** 00064 * Base class for all CVR-Lib objects that have a status for error 00065 * handling. 00066 * 00067 * This is sort of an interface, which does not inherit from cvr::object 00068 * interface, since it is assumed that the objects that inherit from this 00069 * class will also directly or indirectly inherit from cvr::object. 00070 * 00071 * You can set a class inherited from cvr::statusMonitor to select how errors 00072 * have to be reported. See the method status::setStatusMonitor and the 00073 * nested class status::object for more information. 00074 * 00075 * @see cvr::statusMonitor, cvr::status::object 00076 * 00077 * \ingroup gInterfaces 00078 */ 00079 class status { 00080 public: 00081 /** 00082 * Class for status string storing and formatting. 00083 * 00084 * The status::statusObject is an abstraction that allows a flexible formatting 00085 * of the status strings and a way of knowing that the string has been 00086 * completed. 00087 * 00088 * When you have a class that inherits from cvs::status the methods of that 00089 * at class can report errors simply by calling 00090 * 00091 * \code 00092 * setStatusString("Invalid arguments detected."); 00093 * \endcode 00094 * 00095 * That method returns an instance of a status::statusObject, which allows 00096 * appending additional information, but only if the string set through 00097 * \c setStatusString has the special tokens \%1 to \%9. 00098 * These tokens are then replaced by some information you provide through 00099 * the operator%. 00100 * 00101 * For instance: 00102 * \code 00103 * int val = 5; 00104 * std::string str = "hello"; 00105 * setStatusString("Val=%1 and the string str=%2")%val%str; 00106 * \endcode 00107 * would produce the status string "Val=5 and the string str=hello". 00108 * 00109 * If you wish to delay providing the parameters you can do: 00110 * \code 00111 * int val = 5; 00112 * std::string str = " 00113 * setStatusString("Val val=%1 and the string str=%2"); 00114 * getStatusObject()%val; 00115 * getStatusObject()%str; 00116 * \endcode 00117 * 00118 * This is an internal class to encapsulate the operator%. Outside this 00119 * object, the operator% means modulus, but in the context of error reports 00120 * it can have its own meaning. If fact, the use of operator% for this 00121 * task is is inspired (remotely) on one of the boost libraries. 00122 */ 00123 class statusObject { 00124 public: 00125 /** 00126 * Constructor 00127 */ 00128 statusObject(); 00129 00130 /** 00131 * Copy constructor 00132 */ 00133 statusObject(const statusObject& other); 00134 00135 /** 00136 * Destructor 00137 */ 00138 ~statusObject(); 00139 00140 /** 00141 * Copy another statusObject instance 00142 */ 00143 statusObject& copy(const statusObject& other); 00144 00145 /** 00146 * Copy another statusObject instance (alias for copy()) 00147 */ 00148 statusObject& operator=(const statusObject& other); 00149 00150 /** 00151 * Set and parse the status string 00152 */ 00153 void set(const std::string& className,const std::string& str); 00154 00155 /** 00156 * Set and parse the status string 00157 */ 00158 void set(const std::string& className,const char* str); 00159 00160 /** 00161 * Get the current status string 00162 */ 00163 const std::string& get() const; 00164 00165 /** 00166 * Fill an integer argument. 00167 */ 00168 statusObject& operator%(const int data); 00169 00170 /** 00171 * Fill a double argument. 00172 */ 00173 statusObject& operator%(const double data); 00174 00175 /** 00176 * Fill a std::string argument. 00177 */ 00178 statusObject& operator%(const std::string& data); 00179 00180 /** 00181 * Fill a const char chain. 00182 */ 00183 statusObject& operator%(const char* data); 00184 00185 /** 00186 * Set Status Monitor. 00187 * 00188 * All functors in the CVR-Lib share this object, which controls what to 00189 * do when the status string is set or changed. You can set it to throw 00190 * an exception (see cvr::statusMonitorException), you can redirect the 00191 * statusString directly to the std::cerr; see cvr::statusMonitorCerr), 00192 * or you can do nothing but store internally the statusString (see 00193 * cvr::statusMonitorInactive), which is the default behaviour. 00194 * 00195 * If you implement an own class for this (like and error-log window) 00196 * ensure that you follow the interface explained in cvr::statusMonitor 00197 * to avoid memory leaks. 00198 * 00199 * You have to ensure that this method is called only once at a 00200 * time in your application, especially if you use several 00201 * threads. 00202 */ 00203 static void setStatusMonitor(statusMonitor& monitor); 00204 00205 private: 00206 00207 /** 00208 * Class name of caller 00209 */ 00210 std::string className_; 00211 00212 /** 00213 * Status text 00214 */ 00215 std::string text_; 00216 00217 /** 00218 * Counter of the argument being processed. 00219 */ 00220 int count_; 00221 00222 /** 00223 * Number of arguments found when parting the status string. 00224 */ 00225 int args_; 00226 00227 /** 00228 * Class that controls what to do with the status string. You can set it 00229 * to throw an exception after a few milliseconds (such that many 00230 * appendStatusStrings can be called before the exception is thrown; see 00231 * cvr::statusMonitorException), you can redirect the statusString 00232 * directly to the std::cerr; see cvr::statusMonitorCerr), or you can do 00233 * nothing but store internally the statusString (see 00234 * cvr::statusMonitorInactive), which is the default behaviour. 00235 */ 00236 static statusMonitor* statusMonitor_; 00237 00238 /** 00239 * Insert the given string at all positions where the %counter_ is found. 00240 */ 00241 void insert(const std::string& data); 00242 }; 00243 00244 /** 00245 * Default constructor 00246 */ 00247 status(); 00248 00249 /** 00250 * Copy constructor 00251 */ 00252 status(const status& other); 00253 00254 /** 00255 * Destructor 00256 */ 00257 virtual ~status(); 00258 00259 /** 00260 * @name Error handling and report 00261 */ 00262 //@{ 00263 /** 00264 * Return the last message set with setStatusString() and modified with 00265 * the operators. 00266 */ 00267 const std::string& getStatusString() const; 00268 00269 /** 00270 * Set a status string. 00271 * 00272 * @param msg the const string to be reported next time by 00273 * getStatusString(). The given string will be copied. 00274 * This message will be usually set within the apply methods to indicate 00275 * an error cause. 00276 * 00277 * Note that the change of the status string is not considered as 00278 * a change in the functor status. 00279 */ 00280 statusObject& setStatusString(const char* msg) const; 00281 00282 /** 00283 * Set a status string. 00284 * 00285 * @param msg the const string to be reported next time by 00286 * getStatusString(). The given string will be copied. 00287 * This message will be usually set within the apply methods to indicate 00288 * an error cause. 00289 * 00290 * Note that the change of the status string is not considered as 00291 * a change in the functor status. 00292 */ 00293 statusObject& setStatusString(const std::string& msg) const; 00294 00295 /** 00296 * Get a reference to the internal statusObject. 00297 */ 00298 statusObject& getStatusObject() const; 00299 00300 /** 00301 * Set Status Monitor. 00302 * 00303 * All functors in the CVR-Lib share this object, which controls what to 00304 * do when the status string is set or changed. You can set it to throw 00305 * an exception after a few milliseconds (such that many 00306 * appendStatusString() calls can be done before the exception is thrown; 00307 * see cvr::statusMonitorException), you can redirect the statusString 00308 * directly to the std::cerr; see cvr::statusMonitorCerr), or you can do 00309 * nothing but store internally the statusString (see 00310 * cvr::statusMonitorInactive), which is the default behaviour. 00311 * 00312 * If you implement an own class for this (like and error-log window) 00313 * ensure that you follow the interface explained in cvr::statusMonitor 00314 * to avoid some memory leaks. 00315 * 00316 * You have to ensure that this method is called only once at a 00317 * time in your application, especially if you use several 00318 * threads. 00319 * 00320 */ 00321 static void setStatusMonitor(statusMonitor& monitor); 00322 //@} 00323 00324 private: 00325 /** 00326 * Generate the class name. 00327 * 00328 * For complex status monitors, they expect to receive as parameter 00329 * the name of the caller class. Since this class serves there only 00330 * as interface, here we don't have access to the name of the caller class 00331 * so that we have to recreate that name again using this wrapper class. 00332 */ 00333 const std::string getClassName() const; 00334 00335 /** 00336 * The status string written with setStatusString 00337 */ 00338 mutable statusObject statusObject_; 00339 }; 00340 00341 /** 00342 * Global function to set the status monitor in all CVR-Lib objects that 00343 * manage a status string, like cvr::functor, cvr::ioHandler, 00344 * cvr::classifier, etc. 00345 */ 00346 void setStatusMonitor(statusMonitor& monitor); 00347 00348 00349 } // namespace cvr 00350 00351 #endif 00352