MeVisLabToolboxReference
|
00001 // **InsertLicense** code 00002 //---------------------------------------------------------------------------------- 00009 00015 //---------------------------------------------------------------------------------- 00016 00017 00018 00019 #ifndef __mlCopyBase_H 00020 #define __mlCopyBase_H 00021 00022 00023 // ML includes 00024 #ifndef __mlModuleIncludes_H 00025 #include "mlModuleIncludes.h" 00026 #endif 00027 #ifndef __mlEngine_H 00028 #include "mlEngine.h" 00029 #endif 00030 00031 // Local includes 00032 #ifndef __mlBaseInit_H 00033 #include "mlBaseInit.h" 00034 #endif 00035 #ifndef __mlListBase_H 00036 #include "mlListBase.h" 00037 #endif 00038 00039 ML_START_NAMESPACE 00040 00041 00042 // ------------------------------------------------------------------ 00046 // ------------------------------------------------------------------ 00047 template <class BASE_DERIVED_CLASS> 00048 class MLBASEEXPORT CopyBase : public Engine 00049 { 00050 00051 public: 00052 00054 CopyBase(); 00055 00057 ~CopyBase(); 00058 00060 void copyObject(); 00061 00063 void deleteObject(); 00064 00066 typedef enum { 00067 AutoUpdateModeDoNothing = 0, 00068 AutoUpdateModeAutoClear, 00069 AutoUpdateModeAutoUpdate, 00070 AutoUpdateModeCount 00071 } AutoUpdateMode; 00072 00074 static const char* autoUpdateModeNames[]; 00075 00076 protected: 00077 00078 00080 00081 00083 BaseField* _fldInputBase; 00084 00086 BaseField* _fldOutputBase; 00087 00089 StringField* _fldObjectType; 00090 00092 StringField* _fldStatusString; 00093 00096 BoolField* _fldUpToDate; 00097 00099 EnumField* _fldAutoUpdateMode; 00100 00102 NotifyField* _fldUpdate; 00103 00106 NotifyField* _fldClear; 00107 00109 00111 virtual void handleNotification(Field* field); 00112 00114 void setNewOutputObject(BASE_DERIVED_CLASS* newOutObject); 00115 00117 const RuntimeType* checkObjectType(const Base* inputObject) const; 00118 00120 Base* _outputObject; 00121 00122 private: 00123 00124 //------------------------------------------------------------------------------------ 00127 //------------------------------------------------------------------------------------ 00128 CopyBase(const CopyBase &) : Engine(0,0) 00129 { 00130 ML_PRINT_FATAL_ERROR("CopyBase::CopyBase(const CopyBase &)", 00131 ML_PROGRAMMING_ERROR, 00132 "Usage of copy constructor of CopyBase is not supported."); 00133 } 00134 00135 //------------------------------------------------------------------------------------ 00138 //------------------------------------------------------------------------------------ 00139 CopyBase& operator=(const CopyBase &) 00140 { 00141 ML_PRINT_FATAL_ERROR("CopyBase& CopyBase::operator=(const CopyBase &)", 00142 ML_PROGRAMMING_ERROR, 00143 "Usage of assignment operator of CopyBase is not supported."); 00144 return *this; 00145 } 00146 00148 int _lockNotification; 00149 00151 //ML_MODULE_CLASS_HEADER(CopyBase); 00152 00153 }; 00154 00155 00156 00157 00158 //------------------------------------------------------------------------------------------ 00159 00161 class MLBASEEXPORT CopyList : public CopyBase<ListBase> 00162 { 00163 00165 CopyList() : CopyBase<ListBase>(){} 00166 00167 // TODO: Add support for event copying (instead of always copying the entire list) 00168 private: 00169 00171 ML_MODULE_CLASS_HEADER(CopyList); 00172 }; 00173 00174 00175 00176 00177 00178 //------------------------------------------------------------------------------------------ 00179 // implementation follows here in header because of problems with template class implementations in cpp files 00180 // in VC 6.0 00181 00182 //------------------------------------------------------------------------------------------ 00183 // CLASS CopyBase<> 00184 //------------------------------------------------------------------------------------------ 00185 00186 //------------------------------------------------------------------------------------------ 00187 template <class BASE_DERIVED_CLASS> 00188 const char* CopyBase<BASE_DERIVED_CLASS>::autoUpdateModeNames[] = { 00189 "Off", 00190 "AutoClear", 00191 "AutoUpdate" 00192 }; 00193 00194 00195 //------------------------------------------------------------------------------------------ 00197 template <class BASE_DERIVED_CLASS> 00198 CopyBase<BASE_DERIVED_CLASS>::CopyBase() 00199 : Engine(), 00200 _outputObject(NULL), 00201 _lockNotification(1) 00202 { 00203 FieldContainer* fields = getFieldContainer(); 00204 00205 // add fields and assign default values: 00206 00207 _fldInputBase = fields->addBase("inObject");//)->setBaseValue(NULL); 00208 (_fldOutputBase = fields->addBase("outObject"))->setBaseValue(NULL); 00209 (_fldAutoUpdateMode = fields->addEnum("updateMode", autoUpdateModeNames, AutoUpdateModeCount))->setEnumValue(AutoUpdateModeAutoUpdate); 00210 (_fldStatusString = fields->addString("status"))->setStringValue("ok."); 00211 00212 (_fldUpToDate = fields->addBool("upToDate"))->setBoolValue(true); 00213 (_fldObjectType = fields->addString("objectType"))->setStringValue("(NULL)"); 00214 _fldUpdate = fields->addNotify("update"); 00215 _fldClear = fields->addNotify("clear"); 00216 _lockNotification = 0; 00217 } 00218 00219 00220 //------------------------------------------------------------------------------------------ 00222 template <class BASE_DERIVED_CLASS> 00223 CopyBase<BASE_DERIVED_CLASS>::~CopyBase() 00224 { 00225 deleteObject(); 00226 } 00227 00228 //------------------------------------------------------------------------------------------ 00230 template <class BASE_DERIVED_CLASS> 00231 const RuntimeType* CopyBase<BASE_DERIVED_CLASS>::checkObjectType(const Base* inputObject) const { 00232 00233 // check if object is present 00234 if (!inputObject) { 00235 _fldObjectType->setStringValue("(NULL)"); 00236 _fldStatusString->setStringValue("No input object detected."); 00237 return NULL; 00238 } 00239 00240 // check type 00241 const RuntimeType* inType = inputObject->getTypeId(); 00242 if (!inType || !inType->canCreateInstance() || !inType->isDerivedFrom(BASE_DERIVED_CLASS::getClassTypeId())) { 00243 _fldObjectType->setStringValue("(INVALID TYPE)"); 00244 _fldStatusString->setStringValue("Error: Invalid input object type."); 00245 return NULL; 00246 } 00247 00248 _fldObjectType->setStringValue(inType->getName()); 00249 _fldStatusString->setStringValue("Input Object Valid."); 00250 00251 return inType; 00252 } 00253 00254 //------------------------------------------------------------------------------------------ 00256 template <class BASE_DERIVED_CLASS> 00257 void CopyBase<BASE_DERIVED_CLASS>::copyObject() 00258 { 00259 // first delete any existing object: 00260 deleteObject(); 00261 00262 Base* inputObject = _fldInputBase->getBaseValue(); 00263 BASE_DERIVED_CLASS* outputObject = NULL; 00264 00265 // check if object is present and has correct type: 00266 if (!checkObjectType(inputObject)) { 00267 setNewOutputObject(NULL); 00268 _fldUpToDate->setBoolValue(inputObject == NULL); 00269 return; 00270 } 00271 00272 // copy object 00273 outputObject = static_cast<BASE_DERIVED_CLASS*>(inputObject)->clone(); 00274 00275 // update output 00276 setNewOutputObject(outputObject); 00277 _fldUpToDate->setBoolValue(true); 00278 _fldStatusString->setStringValue("ok."); 00279 } 00280 00281 00282 00283 //------------------------------------------------------------------------------------------ 00285 template <class BASE_DERIVED_CLASS> 00286 void CopyBase<BASE_DERIVED_CLASS>::setNewOutputObject(BASE_DERIVED_CLASS* newOutObject) 00287 { 00288 _outputObject = newOutObject; 00289 _fldOutputBase->setBaseValue(_outputObject); 00290 } 00291 00292 00293 00294 //------------------------------------------------------------------------------------------ 00296 template <class BASE_DERIVED_CLASS> 00297 void CopyBase<BASE_DERIVED_CLASS>::deleteObject() 00298 { 00299 if (_outputObject) { 00300 _fldOutputBase->setBaseValue(NULL); 00301 00302 ML_DELETE(_outputObject); 00303 } 00304 } 00305 00306 00307 //------------------------------------------------------------------------------------------ 00309 template <class BASE_DERIVED_CLASS> 00310 void CopyBase<BASE_DERIVED_CLASS>::handleNotification(Field* field) 00311 { 00312 if (!_lockNotification) { 00313 ++_lockNotification; 00314 00315 // output touched, output object possibly modified 00316 if (field == _fldOutputBase) { 00317 _fldUpToDate->setBoolValue(false); 00318 _fldStatusString->setStringValue("Output externally touched, possibly modified."); 00319 } 00320 00321 // input touched 00322 if (field == _fldInputBase) { 00323 switch (_fldAutoUpdateMode->getEnumValue()) { 00324 case AutoUpdateModeDoNothing: 00325 checkObjectType(_fldInputBase->getBaseValue()); 00326 _fldUpToDate->setBoolValue(false); 00327 break; 00328 case AutoUpdateModeAutoClear: 00329 checkObjectType(_fldInputBase->getBaseValue()); 00330 // initiate clear 00331 field = _fldClear; 00332 break; 00333 case AutoUpdateModeAutoUpdate: 00334 // initiate update 00335 field = _fldUpdate; 00336 break; 00337 default: 00338 ML_PRINT_FATAL_ERROR("void CopyBase<BASE_DERIVED_CLASS>::handleNotification(Field* field)", ML_BAD_PARAMETER, "Clearing output!"); 00339 field = _fldClear; 00340 break; 00341 } 00342 } 00343 00344 00345 // clear button pressed 00346 if (field == _fldClear) { 00347 deleteObject(); 00348 _fldStatusString->setStringValue("Output object deleted."); 00349 _fldUpToDate->setBoolValue(_fldInputBase->getBaseValue() == NULL); 00350 00351 } 00352 00353 // update button pressed 00354 if (field == _fldUpdate) { 00355 copyObject(); 00356 } 00357 00358 --_lockNotification; 00359 } 00360 } 00361 00362 00363 ML_END_NAMESPACE 00364 00365 #endif // __mlCopyBase_H 00366