MeVisLabToolboxReference
MeVisLab/Standard/Sources/ML/MLBase/mlCopyBase.h
Go to the documentation of this file.
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