00001 /*!@file Channels/ChannelFacet.H Allow user-configurable "facets" to be associated with arbitrary classes */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00005 // by the University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Channels/ChannelFacet.H $ 00035 // $Id: ChannelFacet.H 9748 2008-05-11 19:21:54Z rjpeters $ 00036 // 00037 00038 #ifndef CHANNELS_CHANNELFACET_H_DEFINED 00039 #define CHANNELS_CHANNELFACET_H_DEFINED 00040 00041 #include "Util/Assert.H" 00042 #include "Util/log.H" 00043 #include "rutz/demangle.h" 00044 #include "rutz/shared_ptr.h" 00045 00046 class ParamMap; 00047 00048 /// Base class for facets that can be held in a ChannelFacetMap 00049 /** ChannelFacet provides a simple mechanism to add extra data and 00050 functions to the channels at runtime. Example usage is to add a 00051 set of weights for the different feature maps. The only default 00052 interface to the ChannelFacet is to provide readFrom() and 00053 writeTo() functions to dump the ChannelFacet data to a 00054 ParamMap. Because this base class is purely virtual, it cannot be 00055 directly implemented but will first need to be derived into an 00056 implementable class. */ 00057 class ChannelFacet 00058 { 00059 protected: 00060 /// Constructor is protected (base class should not be used on its own) 00061 ChannelFacet(); 00062 00063 public: 00064 /// Virtual destructor for safe inheritance 00065 virtual ~ChannelFacet(); 00066 00067 /// Write our data out to a ParamMap 00068 virtual void writeTo(ParamMap& pmap) const = 0; 00069 00070 /// Read our data back in from a ParamMap 00071 virtual void readFrom(const ParamMap& pmap) = 0; 00072 }; 00073 00074 /// Mix-in class designed to be inherited to provide facets to the subclass 00075 /** This map can hold various ChannelFacet elements and provides a 00076 basic interface to add/retrieve ChannelFacet 00077 elements. SingleChannel and ComplexChannel both inherit from 00078 ChannelFacetMap. */ 00079 class ChannelFacetMap 00080 { 00081 public: 00082 /// Default constructor 00083 ChannelFacetMap(); 00084 00085 /// Virtual destructor 00086 virtual ~ChannelFacetMap(); 00087 00088 /// Write our facets out to a ParamMap 00089 void writeFacetsTo(ParamMap& pmap) const; 00090 00091 /// Read our facets back in from a ParamMap 00092 void readFacetsFrom(const ParamMap& pmap); 00093 00094 /// Query if we have a facet of type T 00095 template <class T> inline 00096 bool hasFacet() const; 00097 00098 /// Get the facet of type T 00099 /** Will throw an exception if there is no such facet (check 00100 hasFacet() first). */ 00101 template <class T> inline 00102 rutz::shared_ptr<T> getFacet() const; 00103 00104 /// Install a facet of type T 00105 /** This will replace any previous such facet. */ 00106 template <class T> inline 00107 void setFacet(rutz::shared_ptr<T> f); 00108 00109 /// Number of installed facets 00110 unsigned int numFacets() const; 00111 00112 private: 00113 rutz::shared_ptr<ChannelFacet> getBaseFacet(const std::type_info& tp) const; 00114 00115 void setBaseFacet(const std::type_info& tp, 00116 rutz::shared_ptr<ChannelFacet> f); 00117 00118 ChannelFacetMap(const ChannelFacetMap&); // not implemented 00119 ChannelFacetMap& operator=(const ChannelFacetMap&); // not implemented 00120 00121 struct Impl; 00122 Impl* const rep; 00123 }; 00124 00125 00126 // ###################################################################### 00127 // ##### Implementation of inline functions 00128 // ###################################################################### 00129 template <class T> inline 00130 bool ChannelFacetMap::hasFacet() const 00131 { 00132 return getBaseFacet(typeid(T)).get() != 0; 00133 } 00134 00135 // ###################################################################### 00136 template <class T> inline 00137 rutz::shared_ptr<T> ChannelFacetMap::getFacet() const 00138 { 00139 rutz::shared_ptr<ChannelFacet> f = this->getBaseFacet(typeid(T)); 00140 if (f.get() == 0) 00141 LFATAL("no such facet: %s", rutz::demangled_name(typeid(T))); 00142 00143 // else... 00144 rutz::shared_ptr<T> fnew = rutz::dyn_cast<T>(f); 00145 00146 // this is a hard ASSERT() rather than an LFATAL() because an 00147 // error here represents a design flaw rather than a user error -- 00148 // by design, the facet associated with typeid(T) should always be 00149 // (castable to) type T itself 00150 ASSERT(f.get() != 0); 00151 00152 return fnew; 00153 } 00154 00155 // ###################################################################### 00156 template <class T> inline 00157 void ChannelFacetMap::setFacet(rutz::shared_ptr<T> f) 00158 { 00159 this->setBaseFacet(typeid(T), f); 00160 } 00161 00162 // ###################################################################### 00163 /* So things look consistent in everyone's emacs... */ 00164 /* Local Variables: */ 00165 /* mode: c++ */ 00166 /* indent-tabs-mode: nil */ 00167 /* End: */ 00168 00169 #endif // CHANNELS_CHANNELFACET_H_DEFINED