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
00016
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);
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)){
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
00198
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
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
00281
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
00343
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{
00405 if( (old_acquisitionStamp < acquisitionStamp) ||
00406 (!acquisitionStamp) )
00407 data_state = DATA_CHANGED;
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