1 /*========================================================================= 2 * 3 * Copyright Insight Software Consortium 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0.txt 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 *=========================================================================*/ 18 /*========================================================================= 19 * 20 * Portions of this file are subject to the VTK Toolkit Version 3 copyright. 21 * 22 * Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 23 * 24 * For complete copyright, license and disclaimer of warranty information 25 * please refer to the NOTICE file at the top of the ITK source tree. 26 * 27 *=========================================================================*/ 28 #ifndef itkObjectFactoryBase_h 29 #define itkObjectFactoryBase_h 30 31 #include "itkCreateObjectFunction.h" 32 #include "itkSingletonMacro.h" 33 #include <list> 34 #include <vector> 35 36 namespace itk 37 { 38 /** \class ObjectFactoryBase 39 * \brief Create instances of classes using an object factory. 40 * 41 * ObjectFactoryBase is used to create itk objects. The base class 42 * ObjectFactoryBase contains a static method CreateInstance() that is 43 * used to create itk objects from the list of registerd ObjectFactoryBase 44 * sub-classes. The first time CreateInstance() is called, all dll's or 45 * shared libraries in the environment variable ITK_AUTOLOAD_PATH are loaded 46 * into the current process. The C function itkLoad is called on each dll. 47 * itkLoad should return an instance of the factory sub-class implemented in 48 * the shared library. ITK_AUTOLOAD_PATH is an environment variable 49 * containing a colon separated (semi-colon on win32) list of paths. 50 * 51 * This can be use to overide the creation of any object in ITK. 52 * 53 * \ingroup ITKSystemObjects 54 * \ingroup ITKCommon 55 */ 56 57 // Forward reference because of private implementation 58 class OverRideMap; 59 struct ObjectFactoryBasePrivate; 60 61 class ITKCommon_EXPORT ObjectFactoryBase:public Object 62 { 63 public: 64 ITK_DISALLOW_COPY_AND_ASSIGN(ObjectFactoryBase); 65 66 /** Standard class type aliases. */ 67 using Self = ObjectFactoryBase; 68 using Superclass = Object; 69 using Pointer = SmartPointer< Self >; 70 using ConstPointer = SmartPointer< const Self >; 71 72 /** Run-time type information (and related methods). */ 73 itkTypeMacro(ObjectFactoryBase, Object); 74 75 /** Create and return an instance of the named itk object. 76 * Each loaded ObjectFactoryBase will be asked in the order 77 * the factory was in the ITK_AUTOLOAD_PATH. After the 78 * first factory returns the object no other factories are asked. */ 79 static LightObject::Pointer CreateInstance(const char *itkclassname); 80 81 /** Create and return all possible instances of the named itk object. 82 * Each loaded ObjectFactoryBase will be asked in the order 83 * the factory was in the ITK_AUTOLOAD_PATH. All created objects 84 * will be returned in the list. */ 85 static std::list< LightObject::Pointer > 86 CreateAllInstance(const char *itkclassname); 87 88 /** Re-check the ITK_AUTOLOAD_PATH for new factory libraries. 89 * This calls UnRegisterAll before re-loading. */ 90 static void ReHash(); 91 92 /** Register a factory so it can be used to create itk objects. 93 * This method is intended to be called only for built-in default 94 * factories, not for loadable factories. 95 * 96 * Factories that are registered with this method will be 97 * regisistered after ReHash. 98 */ 99 static void RegisterFactoryInternal(ObjectFactoryBase *); 100 101 /** Position at which the new factory will be registered in the 102 * internal factory container. 103 */ 104 typedef enum 105 { 106 INSERT_AT_FRONT, 107 INSERT_AT_BACK, 108 INSERT_AT_POSITION 109 } InsertionPositionType; 110 111 /** Register a factory so it can be used to create itk objects. 112 * 113 * When INSERT_AT_POSITION is selected, a third argument must be provided 114 * with the actual integer number of the intended position. The position 115 * number must be in the range [0, numberOfRegisteredFactories-1]. 116 * 117 * Usage should be any of the following: 118 * 119 * itk::ObjectFactoryBase::RegisterFactory( newFactory1 ); // at back 120 * itk::ObjectFactoryBase::RegisterFactory( newFactory2, INSERT_AT_FRONT ); 121 * itk::ObjectFactoryBase::RegisterFactory( newFactory3, INSERT_AT_BACK ); 122 * itk::ObjectFactoryBase::RegisterFactory( newFactory4, INSERT_AT_POSITION, 5 ); 123 * 124 * If the position value is out of range, an exception will be 125 * thrown. 126 * Returns true if the factory was successfully registered. 127 * Returns false if factory is already loaded. 128 */ 129 static bool RegisterFactory(ObjectFactoryBase *, 130 InsertionPositionType where=INSERT_AT_BACK, size_t position = 0); 131 132 /** Remove a factory from the list of registered factories. */ 133 static void UnRegisterFactory(ObjectFactoryBase *); 134 135 /** Unregister all factories. */ 136 static void UnRegisterAllFactories(); 137 138 /** Return the list of all registered factories. This is NOT a copy, 139 * do not remove items from this list! */ 140 static std::list< ObjectFactoryBase * > GetRegisteredFactories(); 141 142 /** All sub-classes of ObjectFactoryBase should must return the version of 143 * ITK they were built with. This should be implemented with the macro 144 * ITK_SOURCE_VERSION and NOT a call to Version::GetITKSourceVersion. 145 * As the version needs to be compiled into the file as a string constant. 146 * This is critical to determine possible incompatible dynamic factory loads. */ 147 virtual const char * GetITKSourceVersion() const = 0; 148 149 /** Require the ITK version of this application to exactly match the ITK 150 * version used to compile a dynamic library. When this is set to true, if the 151 * versions do not match, an exception will be thrown. When this is false, and 152 * the versions do not match, only a warning message is printed out in the 153 * console, and the factory is still registered. */ 154 static void SetStrictVersionChecking( bool ); 155 static void StrictVersionCheckingOn(); 156 static void StrictVersionCheckingOff(); 157 static bool GetStrictVersionChecking(); 158 159 /** Return a descriptive string describing the factory. */ 160 virtual const char * GetDescription() const = 0; 161 162 /** Return a list of classes that this factory overrides. */ 163 virtual std::list< std::string > GetClassOverrideNames(); 164 165 /** Return a list of the names of classes that override classes. */ 166 virtual std::list< std::string > GetClassOverrideWithNames(); 167 168 /** Return a list of descriptions for class overrides. */ 169 virtual std::list< std::string > GetClassOverrideDescriptions(); 170 171 /** Return a list of enable flags. */ 172 virtual std::list< bool > GetEnableFlags(); 173 174 /** Set the Enable flag for the specific override of className. */ 175 virtual void SetEnableFlag(bool flag, 176 const char *className, 177 const char *subclassName); 178 179 /** Get the Enable flag for the specific override of className. */ 180 virtual bool GetEnableFlag(const char *className, 181 const char *subclassName); 182 183 /** Set all enable flags for the given class to 0. This will 184 * mean that the factory will stop producing class with the given 185 * name. */ 186 virtual void Disable(const char *className); 187 188 /** This returns the path to a dynamically loaded factory. */ 189 const char * GetLibraryPath(); 190 191 /** \class OverrideInformation 192 * \brief Internal implementation class for ObjectFactorBase. 193 * \ingroup ITKCommon 194 */ 195 struct OverrideInformation { 196 std::string m_Description; 197 std::string m_OverrideWithName; 198 bool m_EnabledFlag; 199 CreateObjectFunctionBase::Pointer m_CreateObject; 200 }; 201 202 protected: 203 void PrintSelf(std::ostream & os, Indent indent) const override; 204 205 /** Register object creation information with the factory. */ 206 void RegisterOverride(const char *classOverride, 207 const char *overrideClassName, 208 const char *description, 209 bool enableFlag, 210 CreateObjectFunctionBase *createFunction); 211 212 /** This method is provided by sub-classes of ObjectFactoryBase. 213 * It should create the named itk object or return 0 if that object 214 * is not supported by the factory implementation. */ 215 virtual LightObject::Pointer CreateObject(const char *itkclassname); 216 217 /** This method creates all the objects with the class overide of 218 * itkclass name, which are provide by this object 219 */ 220 virtual std::list< LightObject::Pointer > 221 CreateAllObject(const char *itkclassname); 222 223 ObjectFactoryBase(); 224 ~ObjectFactoryBase() override; 225 226 private: 227 228 /** Set/Get the pointer to ObjectFactoryBasePrivate. 229 * No concurrent thread safe. */ 230 static void SynchronizeObjectFactoryBase(void * objectFactoryBasePrivate); 231 itkGetGlobalDeclarationMacro(ObjectFactoryBasePrivate, PimplGlobals); 232 233 OverRideMap *m_OverrideMap; 234 235 /** Initialize the static list of Factories. */ 236 static void InitializeFactoryList(); 237 238 /** Initialize the static members of ObjectFactoryBase. 239 * RegisterInternal() and InitializeFactoryList() are called here. */ 240 static void Initialize(); 241 242 /** Register default factories which are not loaded at run time. */ 243 static void RegisterInternal(); 244 245 /** Load dynamic factories from the ITK_AUTOLOAD_PATH */ 246 static void LoadDynamicFactories(); 247 248 /** Load all dynamic libraries in the given path */ 249 static void LoadLibrariesInPath(const char *); 250 251 static void DeleteNonInternalFactory( ObjectFactoryBase * ); 252 253 /** Member variables for a factory set by the base class 254 * at load or register time */ 255 void * m_LibraryHandle; 256 unsigned long m_LibraryDate; 257 std::string m_LibraryPath; 258 259 static ObjectFactoryBasePrivate * m_PimplGlobals; 260 }; 261 262 263 } // end namespace itk 264 265 #endif 266