Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

/ps/src/dsc/co/mw/mwfwk/cmwfwIOValue.cc

Go to the documentation of this file.
00001 #include "cmwfwList.h"
00002 #include "cmwfw_defs.h"
00003 #include "cmwfwIOValue.h"
00004 #include "cmwfwIOPMapper.h"
00005 
00006 
00007 extern cmwfwIOPMapper framework_iop_mapper;
00008 
00009 
00010 #define FILE "source file:cmwfwIOValue.cc"
00011 #define ID "Contact Steen JENSEN, PS/CO"
00012 #define PROGRAM "Middleware server framework"
00013 #define T(a,b,c,d,e) TRACE(a,"%s(%s): %s %s %s %s\n",myname,FILE,b,c,d,e)
00014 #define E(a,b,c,d) ERROR("%s:%s(%s):ERROR: %s %s %s %s - %s\n",PROGRAM,myname,FILE,a,b,c,d,ID)
00015 //T(CMWFW_TRACE_CALLS,"","","","");
00016 //E("","","","");
00017 
00018 
00019 
00020 
00033 cmwfwIOValue::cmwfwIOValue(const cmwfwIOPoint& iop){
00034   char* myname = "cmwfwIOValue::cmwfwIOValue";
00035   T(CMWFW_TRACE_CALLS,"Entering","","","");
00036 
00037   never_updated          = true;
00038   my_iop                 = new cmwfwIOPoint(iop);
00039   if(!my_iop)heaperr(38);
00040   old_data_is_scalar     = false;
00041   old_vq                 = NOT_SET;
00042   old_acquisitionStamp   = 0;
00043   use_old_io_error       = false;
00044   old_io_error           = new cmwfwIOError("NOT SET",0,"NOT SET");
00045   if(!old_io_error)heaperr(45);
00046   valuechangelisteners   = new vcl_list_type(false); //Do not use mutex
00047   if(!valuechangelisteners)heaperr(48);
00048 
00049   T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00050 };
00051 
00052 
00053 
00054 
00055 
00065 cmwfwIOValue::~cmwfwIOValue(){
00066   char* myname = "cmwfwIOValue::~cmwfwIOValue";
00067   T(CMWFW_TRACE_CALLS,"Entering","","","");
00068 
00069   bool res;
00070   cmwfwValueChangeListener* vcl;
00071 
00072   valuechangelisteners->resetCurrent();
00073   res = valuechangelisteners->getFirst(&vcl);
00074   while(res){
00075         valuechangelisteners->remove(vcl);
00076         res = valuechangelisteners->getNext(&vcl);
00077   };
00078   delete valuechangelisteners;
00079   delete my_iop;
00080   delete old_io_error;
00081 
00082   T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00083 };
00084 
00085 
00096 bool cmwfwIOValue::addListener(cmwfwValueChangeListener* l){
00097   char* myname = "cmwfwIOValue::addListener";
00098   T(CMWFW_TRACE_CALLS,"Entering","","","");
00099 
00100   T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00101   return (valuechangelisteners->insert(l));
00102 };
00103 
00104 
00114 void cmwfwIOValue::removeListener(cmwfwValueChangeListener* l){
00115   char* myname = "cmwfwIOValue::removeListener";
00116   T(CMWFW_TRACE_CALLS,"Entering","","","");
00117 
00118   valuechangelisteners->remove(l);
00119 
00120   T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00121 };
00122 
00123 
00133 void cmwfwIOValue::getIOPoint(cmwfwIOPoint& iop){
00134   char* myname = "cmwfwIOValue::getIOPoint";
00135   T(CMWFW_TRACE_CALLS,"Entering","","","");
00136 
00137   iop = *my_iop;
00138 
00139   T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00140 };
00141 
00142 
00152 bool cmwfwIOValue::hasNoListeners(){
00153   char* myname = "cmwfwIOValue::hasNoListeners";
00154   T(CMWFW_TRACE_CALLS,"Entering","","","");
00155 
00156   int sz = 0;
00157   valuechangelisteners->Size(&sz);
00158   if(sz==0){
00159     T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00160     return true;
00161   };
00162   T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00163   return false;
00164 };
00165 
00166 
00167 
00168 
00169 
00182 void cmwfwIOValue::updateNewListener(cmwfwValueChangeListener* l){
00183   char* myname = "cmwfwIOValue::updateNewListener";
00184   T(CMWFW_TRACE_CALLS,"Entering","","","");
00185 
00186   if( (never_updated) || (!old_data_is_scalar)){  //no valid data
00187     T(CMWFW_TRACE_CALLS,"Returning - no data","","","");
00188         return;
00189   };
00190   if(use_old_io_error){
00191     l->ioFailed(*old_io_error);
00192     T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00193     return;
00194   };
00195 
00196 
00197 //What to do - for a new listener any data is new data, or
00198 //should the new listener be treated as an "old" one ?
00199   switch(old_vq){
00200   case NOT_SET:
00201   case DATA_CHANGED:
00202     l->valueUpdated(old_data,old_data,true);
00203   break;
00204   case DATA_UNCHANGED:
00205     l->valueUpdated(old_data,old_data,false);
00206   break;
00207   default:
00208     T(CMWFW_TRACE_CALLS,"Returning - unknown qualifier switch","","","");
00209     return;
00210   };
00211   T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00212 };
00213 
00214 
00215 
00216 
00217 void cmwfwIOValue::processListeners(const cmwfwData& old_data,
00218                                                                     const cmwfwData& new_data,
00219                                                                         const cmwfwValueQualifier& dataState){
00220   char*                     myname        = "cmwfwIOValue::processListeners";
00221   T(CMWFW_TRACE_CALLS,"Entering","","","");
00222 
00223   bool                      foundListener = false;
00224   cmwfwValueChangeListener* tmp_vcl       = 0;
00225   bool                      dataChanged   = false;
00226 
00227   if(dataState == NOT_SET){
00228 //      E("Undefined data state in value qualifier","","","");
00229     T(CMWFW_TRACE_CALLS,"Returning - unknown qualifier switch","","","");
00230         throw cmwfwBadParameter("Undefined data state in value qualifier");
00231         return;
00232   };
00233 
00234   switch(dataState){
00235   case DATA_CHANGED:
00236         dataChanged = true;
00237     break;
00238   case DATA_UNCHANGED:
00239         dataChanged = false;
00240     break;
00241   default:
00242     break;
00243   };
00244 
00245   valuechangelisteners->resetCurrent();
00246   foundListener = valuechangelisteners->getFirst(&tmp_vcl);
00247   while(foundListener){
00248         tmp_vcl->valueUpdated(old_data,new_data,dataChanged);
00249     foundListener = valuechangelisteners->getNext(&tmp_vcl);
00250     };
00251 
00252   T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00253 };
00254 
00255 
00256 
00257 
00268 void cmwfwIOValue::update(const cmwfwData& data,
00269                                                   const cmwfwValueQualifier& vq){
00270   char*                     myname             = "cmwfwIOValue::update";
00271   T(CMWFW_TRACE_CALLS,"Entering","","","");
00272 
00273   bool                      isScalar           = false;
00274   cmwfwValueQualifier       dataState          = NOT_SET;
00275   cmwfwDataEntry*           valueDataEntry     = 0;
00276   cmwfwDataEntry*           old_valueDataEntry = 0;
00277   double                    acquisitionStamp   = 0;
00278 
00279 
00280 //TODO Is it possible that given an iopoint, the values for that iopoint
00281 //might change between being scalar and arrays ???
00282   if(!data.contains(VAL_TAG)){
00283         processListeners(data,data,DATA_CHANGED);
00284     T(CMWFW_TRACE_CALLS,"Returning - empty data","","","");
00285         return;
00286   };
00287   valueDataEntry     = data.get(VAL_TAG);
00288   if(!valueDataEntry){
00289     T(CMWFW_TRACE_CALLS,"Returning - no data entry","","","");
00290         return;
00291   };
00292 
00293   switch(valueDataEntry->getValueType()){
00294         case valueDataEntry->TYPE_NULL:
00295         case valueDataEntry->TYPE_BOOLEAN:
00296         case valueDataEntry->TYPE_BYTE:
00297         case valueDataEntry->TYPE_SHORT:
00298         case valueDataEntry->TYPE_INT:
00299         case valueDataEntry->TYPE_LONG:
00300         case valueDataEntry->TYPE_FLOAT:
00301         case valueDataEntry->TYPE_DOUBLE:
00302           isScalar = true;
00303         break;
00304         case valueDataEntry->TYPE_STRING:
00305         case valueDataEntry->TYPE_DOUBLE_ARRAY:
00306         case valueDataEntry->TYPE_FLOAT_ARRAY:
00307         case valueDataEntry->TYPE_LONG_ARRAY:
00308         case valueDataEntry->TYPE_INT_ARRAY:
00309         case valueDataEntry->TYPE_SHORT_ARRAY:
00310         case valueDataEntry->TYPE_BYTE_ARRAY:
00311         case valueDataEntry->TYPE_BOOLEAN_ARRAY:
00312         case valueDataEntry->TYPE_STRING_ARRAY:
00313           isScalar           = false;
00314           if(data.contains(CYCLESTAMP_TAG))
00315             acquisitionStamp   = data.extractDouble(CYCLESTAMP_TAG);
00316           break;
00317           default:
00318           break;
00319         };
00320 
00321   if(never_updated || use_old_io_error){
00322         never_updated            = false;
00323         use_old_io_error         = false;
00324         if(!isScalar){
00325           old_data_is_scalar     = false;
00326           old_acquisitionStamp   = acquisitionStamp;
00327         }
00328         else{
00329           old_data_is_scalar     = true;
00330           old_data               = data;
00331           old_acquisitionStamp   = 0;
00332         };
00333 
00334     if(vq != NOT_SET)
00335           processListeners(data,data,vq);
00336         else
00337           processListeners(data,data,DATA_CHANGED);
00338     T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00339         return;
00340   };
00341 
00342 //Now I know that this is not the first update, and that the last update
00343 //was not caused by an ioerror;
00344 
00345 
00346   if(isScalar && old_data_is_scalar){
00347     if(vq != NOT_SET)
00348           processListeners(old_data,data,vq);
00349         else{
00350           if(*valueDataEntry == *old_data.get(VAL_TAG))
00351                 processListeners(old_data,data,DATA_UNCHANGED);
00352           else
00353                 processListeners(old_data,data,DATA_CHANGED);
00354         };
00355 
00356         old_data_is_scalar     = true;
00357         old_data               = data;
00358         old_vq                 = vq;
00359         old_acquisitionStamp   = 0;
00360 
00361     T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00362         return;
00363   };
00364 
00365 
00366   if(isScalar && !old_data_is_scalar){
00367 
00368         if(vq != NOT_SET)
00369           processListeners(data,data,vq);
00370         else
00371           processListeners(data,data,DATA_CHANGED);
00372 
00373         old_data_is_scalar     = true;
00374         old_data               = data;
00375         old_vq                 = vq;
00376         old_acquisitionStamp   = 0;
00377 
00378     T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00379         return;
00380   };
00381 
00382 
00383   if(!isScalar && old_data_is_scalar){
00384 
00385     if(vq != NOT_SET)
00386           processListeners(old_data,data,vq);
00387         else
00388           processListeners(old_data,data,DATA_CHANGED);
00389 
00390         old_data_is_scalar     = false;
00391         old_vq                 = vq;
00392         old_acquisitionStamp   = acquisitionStamp;
00393 
00394     T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00395         return;
00396   };
00397 
00398   if(!isScalar && !old_data_is_scalar){
00399 
00400         cmwfwValueQualifier data_state = NOT_SET;
00401 
00402         if(vq != NOT_SET)
00403           processListeners(data,data,vq);
00404         else{                                              //Use acquisition
00405           if( (old_acquisitionStamp < acquisitionStamp) || //stamp to determine
00406                   (!acquisitionStamp) )                        //if data changed
00407                 data_state = DATA_CHANGED;                     //or not
00408           else
00409                 data_state = DATA_UNCHANGED;
00410           processListeners(data,data,data_state);
00411         };
00412 
00413         old_data_is_scalar     = false;
00414         old_vq                 = vq;
00415         old_acquisitionStamp   = acquisitionStamp;
00416 
00417     T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00418         return;
00419   };
00420 
00421   T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00422 };
00423 
00424 
00435 void cmwfwIOValue::update(const cmwfwIOError& error){
00436   char* myname = "cmwfwIOValue::update";
00437   T(CMWFW_TRACE_CALLS,"Entering","","","");
00438 
00439   cmwfwValueChangeListener* tmp_vcl = 0;
00440   bool foundListener;
00441 
00442   valuechangelisteners->resetCurrent();
00443   foundListener = valuechangelisteners->getFirst(&tmp_vcl);
00444   while(foundListener){
00445     tmp_vcl->ioFailed(error);
00446     foundListener = valuechangelisteners->getNext(&tmp_vcl);
00447   };
00448 
00449   use_old_io_error = true;
00450   *old_io_error = error;
00451   never_updated = false;
00452 
00453   T(CMWFW_TRACE_CALLS,"Returning - all ok","","","");
00454 };
00455 
00456 
00457 
00458 void cmwfwIOValue::heaperr(int line){
00459   char* myname = "cmwfwIOValue";
00460   T(CMWFW_TRACE_CALLS,"Entering","","","");
00461 
00462   char l[30];
00463   itoa(line,l);
00464   E("Out of heap in line ",l,"","");
00465   throw cmwfwInternalError(FILE,line,"Out of heap memory");
00466   T(CMWFW_TRACE_CALLS,"Exiting due to heap allocation error","","","");
00467   exit(-1);
00468 };
00469 
00470 
00471 
00472 
00473 
00474 

Generated at Thu May 10 11:28:58 2001 for C.E.R.N.-PSControlsMiddlewareFramework by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001