Marsyas
0.6.0-alpha
|
00001 /* 00002 ** Copyright (C) 1998-2010 George Tzanetakis <gtzan@cs.uvic.ca> 00003 ** 00004 ** This program is free software; you can redistribute it and/or modify 00005 ** it under the terms of the GNU General Public License as published by 00006 ** the Free Software Foundation; either version 2 of the License, or 00007 ** (at your option) any later version. 00008 ** 00009 ** This program is distributed in the hope that it will be useful, 00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 ** GNU General Public License for more details. 00013 ** 00014 ** You should have received a copy of the GNU General Public License 00015 ** along with this program; if not, write to the Free Software 00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 /************************************************************************/ 00020 /* MarControlPtr implementation */ 00021 /************************************************************************/ 00022 00023 #include <marsyas/system/MarControl.h> 00024 #include <marsyas/system/MarControlValue.h> 00025 #include <marsyas/system/MarSystem.h> 00026 00027 #include <cstddef> 00028 00029 using std::ostringstream; 00030 using std::vector; 00031 using std::pair; 00032 using std::size_t; 00033 using std::string; 00034 00035 namespace Marsyas { 00036 00037 00038 #ifdef TRACECONTROLS 00039 std::set<MarControl*> MarControlPtr::controlTracer; 00040 00041 void 00042 MarControlPtr::printControlTracer() 00043 { 00044 std::set<MarControl*>::iterator it; 00045 if (MarControlPtr::controlTracer.size() > 0) 00046 { 00047 cout << "#############################################################" << endl; 00048 cout << "++ Existing MarControls: " << MarControlPtr::controlTracer.size() << endl; 00049 for (it=MarControlPtr::controlTracer.begin(); it!=MarControlPtr::controlTracer.end(); it++) 00050 { 00051 cout << (*it)->getMarSystem()->getPrefix() << (*it)->getName() 00052 << " | ref.count: " << (*it)->getRefCount() << endl; 00053 } 00054 cout << "#############################################################" << endl; 00055 } 00056 } 00057 #endif 00058 00059 MarControlPtr::MarControlPtr() 00060 { 00061 control_ = NULL; 00062 } 00063 00064 MarControlPtr::~MarControlPtr() 00065 { 00066 if (control_) 00067 { 00068 TRACE_REMCONTROL; 00069 control_->unref(); 00070 control_ = NULL; 00071 } 00072 } 00073 00074 /************************************************************************/ 00075 /* MarControl implementation */ 00076 /************************************************************************/ 00077 00078 00079 WAS_INLINE void MarControl::ref() 00080 { 00081 refCount_++; 00082 } 00083 WAS_INLINE void MarControl::unref() 00084 { 00085 if (--refCount_ <= 0) 00086 delete this; 00087 } 00088 int MarControl::getRefCount() const 00089 { 00090 return refCount_; 00091 } 00092 00093 00094 MarControl* 00095 MarControl::clone() 00096 { 00097 return new MarControl(*this); 00098 } 00099 00100 void 00101 MarControl::setMarSystem(MarSystem* msys) 00102 { 00103 msys_ = msys; 00104 } 00105 00106 MarSystem* 00107 MarControl::getMarSystem() const 00108 { 00109 return msys_; 00110 } 00111 00112 void 00113 MarControl::setName(const std::string & cname) 00114 { 00115 cname_ = cname; 00116 string::size_type separator = cname.find('/'); 00117 if (separator != string::npos) 00118 id_ = cname.substr( separator + 1 ); 00119 else 00120 id_.clear(); 00121 } 00122 00123 void 00124 MarControl::setState(bool state) 00125 { 00126 state_ = state; 00127 } 00128 00129 bool 00130 MarControl::hasState() const 00131 { 00132 return state_; 00133 } 00134 00135 mrs_string 00136 MarControl::getType() const 00137 { 00138 return value_->getType(); 00139 } 00140 00141 std::string MarControl::path() const 00142 { 00143 string path; 00144 const MarSystem *system = getMarSystem(); 00145 if (system) 00146 { 00147 path += system->path(); 00148 } 00149 path += id_; 00150 return path; 00151 } 00152 00153 void 00154 MarControl::callMarSystemUpdate() 00155 { 00156 if (state_ && msys_) 00157 { 00158 MarSystem* msys = msys_; 00159 msys->update(this); 00160 return; 00161 } 00162 } 00163 00164 bool 00165 MarControl::linkTo(MarControlPtr ctrl, bool update) 00166 { 00167 if (ctrl.isInvalid()) 00168 { 00169 ostringstream oss; 00170 oss << "MarControl::linkTo() - Linking to an invalid control "; 00171 oss << "(" << ctrl->cname_ << " with " << cname_ << ")."; 00172 MRSWARN(oss.str()); 00173 return false; 00174 } 00175 00176 //check if these controls are already linked 00177 //(i.e. they own the same MarControlValue) 00178 if(value_ == ctrl->value_) 00179 { 00180 return true;//already linked! :-) 00181 } 00182 00183 if (ctrl->value_->type_ != value_->type_) 00184 { 00185 ostringstream oss; 00186 oss << "MarControl::linkTo() - Linking controls of different types "; 00187 oss << "(" << ctrl->cname_ << " with " << cname_ << ")."; 00188 MRSWARN(oss.str()); 00189 return false; 00190 } 00191 00192 //unlink this control (but keeping all links to it) 00193 //before linking it again to the passed control 00194 this->unlinkFromTarget(); 00195 00196 //store a pointer to the (soon to be old) MarControlValue object, 00197 //so we can later delete it from memory 00198 MarControlValue* oldvalue = value_; 00199 //and get a pointer to the new value 00200 MarControlValue* newvalue = ctrl->value_; 00201 00202 //get all the links of our current MarControlValue so we can also 00203 //re-link them to the passed ctrl 00204 vector<pair<MarControl*, MarControl*> >::iterator lit; 00205 for(lit=oldvalue->links_.begin(); lit!=oldvalue->links_.end(); ++lit) 00206 { 00207 //make each linked control now point to the "passed" MarControlValue 00208 lit->first->value_ = newvalue; 00209 00210 // check if this is the root link 00211 if(lit->first == lit->second) 00212 { 00213 //make it "link to" the passed control 00214 newvalue->links_.push_back(pair<MarControl*, MarControl*>(lit->first, ctrl())); 00215 } 00216 else //if not a root link, just copy the table entry unchanged into the new MarControlValue 00217 newvalue->links_.push_back(*lit); 00218 } 00219 00220 //old MarControlValue can and should now be safely deleted from memory 00221 delete oldvalue; 00222 00223 //check if it's needed to call update() 00224 if(update) 00225 value_->callMarSystemsUpdate();//newvalue->callMarSystemsUpdate(); 00226 00227 return true; 00228 } 00229 00230 00231 mrs_string 00232 MarControl::to_string() const 00233 { 00234 if(!this) 00235 { 00236 MRSERR("MarControl::to() - trying to get a value from a NULL MarControl! Returning invalid value..."); 00237 return ""; 00238 } 00239 const MarControlValueT<mrs_string> *ptr = dynamic_cast<const MarControlValueT<mrs_string>*>(value_); 00240 if(ptr) 00241 { 00242 return ptr->get(); 00243 } 00244 else 00245 { 00246 MRSERR("MarControl::to() - Incompatible type requested - " << "expected " << value_->getType() << " for control " << this->getName()) ; 00247 return ""; 00248 } 00249 } 00250 00251 mrs_natural 00252 MarControl::to_natural() const 00253 { 00254 if(!this) 00255 { 00256 MRSERR("MarControl::to() - trying to get a value from a NULL MarControl! Returning invalid value..."); 00257 return 0; 00258 } 00259 const MarControlValueT<mrs_natural> *ptr = dynamic_cast<const MarControlValueT<mrs_natural>*>(value_); 00260 if(ptr) 00261 { 00262 return ptr->get(); 00263 } 00264 else 00265 { 00266 MRSERR("MarControl::to() - Incompatible type requested - " << "expected " << value_->getType() << " for control " << this->getName()) ; 00267 return 0; 00268 } 00269 } 00270 00271 00272 mrs_bool 00273 MarControl::to_bool() const 00274 { 00275 if(!this) 00276 { 00277 MRSERR("MarControl::to() - trying to get a value from a NULL MarControl! Returning invalid value..."); 00278 return 0; 00279 } 00280 const MarControlValueT<mrs_bool> *ptr = dynamic_cast<const MarControlValueT<mrs_bool>*>(value_); 00281 if(ptr) 00282 { 00283 return ptr->get(); 00284 } 00285 else 00286 { 00287 MRSERR("MarControl::to() - Incompatible type requested - " << "expected " << value_->getType() << " for control " << this->getName()) ; 00288 return 0; 00289 } 00290 } 00291 00292 mrs_real 00293 MarControl::to_real() const 00294 { 00295 if(!this) 00296 { 00297 MRSERR("MarControl::to() - trying to get a value from a NULL MarControl! Returning invalid value..."); 00298 return 0.0; 00299 } 00300 const MarControlValueT<mrs_real> *ptr = dynamic_cast<const MarControlValueT<mrs_real>*>(value_); 00301 if(ptr) 00302 { 00303 return ptr->get(); 00304 } 00305 else 00306 { 00307 MRSERR("MarControl::to() - Incompatible type requested - " << "expected " << value_->getType() << " for control " << this->getName()) ; 00308 return 0.0; 00309 } 00310 } 00311 00312 mrs_realvec 00313 MarControl::to_realvec() const 00314 { 00315 if(!this) 00316 { 00317 MRSERR("MarControl::to() - trying to get a value from a NULL MarControl! Returning invalid value..."); 00318 realvec s; 00319 return s; 00320 } 00321 const MarControlValueT<mrs_realvec> *ptr = dynamic_cast<const MarControlValueT<mrs_realvec>*>(value_); 00322 if(ptr) 00323 { 00324 return ptr->get(); 00325 } 00326 else 00327 { 00328 MRSERR("MarControl::to() - Incompatible type requested - " << "expected " << value_->getType() << " for control " << this->getName()) ; 00329 realvec s; 00330 return s; 00331 } 00332 } 00333 00334 00335 00336 void 00337 MarControl::unlinkFromAll() 00338 { 00339 //first unlink this control from all the controls to which 00340 //it links to 00341 this->unlinkFromTarget(); 00342 00343 //get a list of all the controls that target this controls... 00344 vector<pair<MarControl*, MarControl*> >::iterator lit; 00345 vector<MarControl*> linkedControls; 00346 for(lit=value_->links_.begin(); lit!=value_->links_.end(); ++lit) 00347 { 00348 if(lit->second == this && lit->first != lit->second) 00349 linkedControls.push_back(lit->first); 00350 } 00351 //... and now unlink them all from this 00352 for(mrs_natural i=0; i < (mrs_natural)linkedControls.size(); ++i) 00353 linkedControls[i]->unlinkFromTarget(); 00354 } 00355 00356 void 00357 MarControl::unlinkFromTarget() 00358 { 00359 vector<pair<MarControl*, MarControl*> >::iterator lit; 00360 00361 //check if this MarControl is linked 00362 //(i.e. more than one MarControl linking 00363 //to the MarControlValue). 00364 //if not, no point doing unlink - just return. 00365 if(value_->links_.size() <= 1) 00366 return; 00367 00368 MarControlValue* oldvalue = value_; 00369 MarControlValue* newvalue = oldvalue->clone(); 00370 00371 vector<pair<MarControl*, MarControl*> >* inSet = new vector<pair<MarControl*, MarControl*> >; 00372 vector<pair<MarControl*, MarControl*> >* outSet = new vector<pair<MarControl*, MarControl*> >; 00373 00374 size_t toProcess = oldvalue->links_.size(); 00375 bool* processed = new bool[toProcess]; 00376 for(size_t i=0; i < toProcess; ++i) 00377 processed[i] = false; 00378 00379 //iterate over all the links 00380 MarControl* oldRootLink = NULL; 00381 //vector<pair<MarControl*, MarControl*> >::iterator lit; 00382 lit = oldvalue->links_.begin(); 00383 mrs_natural idx = 0; 00384 while(toProcess > 0) 00385 { 00386 //avoid processing processed links 00387 if(!processed[idx]) 00388 { 00389 //check if this is the old root link and send it to the outSet (also as a root link) 00390 if(lit->first == lit->second) 00391 { 00392 oldRootLink = lit->first; 00393 outSet->push_back(*lit); 00394 toProcess --; 00395 processed[idx]=true; 00396 } 00397 //check if this is this same control (i.e. the control to unlink at) 00398 //and set it as the root link of the inSet 00399 else if(lit->first == this) 00400 { 00401 lit->first->value_ = newvalue; //"this" is already locked for writing 00402 inSet->push_back(pair<MarControl*, MarControl*>(lit->first, lit->first)); 00403 toProcess--; 00404 processed[idx]=true; 00405 } 00406 //check if this is directly linked to the old root link and if so, 00407 //send it to the outSet 00408 else if(lit->second == oldRootLink) 00409 { 00410 outSet->push_back(*lit); 00411 toProcess --; 00412 processed[idx]=true; 00413 } 00414 //if this control links directly to the control we want to unlink, send it to the inSet 00415 else if(lit->second == this) 00416 { 00417 lit->first->value_ = newvalue; 00418 inSet->push_back(*lit); 00419 toProcess--; 00420 processed[idx]=true; 00421 } 00422 //This control is not directly connected to any root link, so we have 00423 //to check to which set belongs the control it links to and assign it to 00424 //the same set 00425 else 00426 { 00427 bool found = false; 00428 vector<pair<MarControl*, MarControl*> >::iterator sit; 00429 //do a copy of the inSet because we are using iterators 00430 //and they become invalid if we change the size of the inSet object 00431 //inside the for loop below 00432 vector<pair<MarControl*, MarControl*> > inSet2 = *inSet; 00433 //start by searching in the inSet... 00434 for(sit = inSet2.begin(); sit != inSet2.end(); ++sit) 00435 { 00436 if(lit->second == sit->first) 00437 { 00438 lit->first->value_ = newvalue; 00439 inSet->push_back(*lit); 00440 toProcess--; 00441 processed[idx]=true; 00442 found = true; 00443 } 00444 } 00445 //if not found there, look for it in the outSet... 00446 if(!found) 00447 { 00448 vector<pair<MarControl*, MarControl*> > outSet2 = *outSet; 00449 for(sit = outSet2.begin(); sit != outSet2.end(); ++sit) 00450 { 00451 if(lit->second == sit->first) 00452 { 00453 outSet->push_back(*lit); 00454 toProcess--; 00455 processed[idx]=true; 00456 } 00457 } 00458 } 00459 } 00460 } 00461 00462 //iterate until all links were processed! 00463 if(lit!=oldvalue->links_.end()) 00464 { 00465 lit++; 00466 idx++; 00467 } 00468 else 00469 { 00470 lit=oldvalue->links_.begin(); 00471 idx = 0; 00472 } 00473 } 00474 00475 delete [] processed; 00476 00477 //set the two unlinked tables 00478 oldvalue->links_ = *outSet; 00479 newvalue->links_ = *inSet; 00480 00481 delete inSet; 00482 delete outSet; 00483 00484 //check if newValue has in fact any control 00485 //linking to it 00486 if(newvalue->links_.size() == 0) 00487 delete newvalue; 00488 } 00489 00490 bool 00491 MarControl::isLinked() const 00492 { 00493 //if there is only one link (i.e. this control itself), 00494 //it means that there are no other linked controls 00495 // => return false (i.e. 0) 00496 if(value_->links_.size()-1 == 0) 00497 return false; 00498 else 00499 return true; 00500 } 00501 00502 vector<pair<MarControlPtr, MarControlPtr> > 00503 MarControl::getLinks() 00504 { 00505 vector<pair<MarControlPtr, MarControlPtr> > res; 00506 vector<pair<MarControl*, MarControl*> >::const_iterator lit; 00507 for(lit=value_->links_.begin(); lit != value_->links_.end(); ++lit) 00508 { 00509 res.push_back(pair<MarControlPtr, MarControlPtr>(MarControlPtr(lit->first),MarControlPtr(lit->second))); 00510 } 00511 return res; 00512 } 00513 00514 00515 00516 WAS_INLINE MarControlPtr::MarControlPtr(MarControl control) 00517 { 00518 control_ = new MarControl(control); 00519 control_->ref(); 00520 TRACE_ADDCONTROL; 00521 } 00522 00523 WAS_INLINE MarControlPtr::MarControlPtr(MarControlValue *value) 00524 { 00525 control_ = new MarControl(value); 00526 control_->ref(); 00527 TRACE_ADDCONTROL; 00528 } 00529 00530 WAS_INLINE MarControlPtr::MarControlPtr(int ne) 00531 { 00532 control_ = new MarControl((mrs_natural)ne); 00533 control_->ref(); 00534 TRACE_ADDCONTROL; 00535 } 00536 00537 WAS_INLINE MarControlPtr::MarControlPtr(unsigned int ne) 00538 { 00539 control_ = new MarControl((mrs_natural)ne); 00540 control_->ref(); 00541 TRACE_ADDCONTROL; 00542 } 00543 00544 WAS_INLINE MarControlPtr::MarControlPtr(float ne) 00545 { 00546 control_ = new MarControl(ne); 00547 control_->ref(); 00548 TRACE_ADDCONTROL; 00549 } 00550 00551 00552 WAS_INLINE MarControlPtr::MarControlPtr(mrs_natural ne) 00553 { 00554 control_ = new MarControl(ne); 00555 control_->ref(); 00556 TRACE_ADDCONTROL; 00557 } 00558 00559 WAS_INLINE MarControlPtr::MarControlPtr(double re) 00560 { 00561 control_ = new MarControl(re); 00562 control_->ref(); 00563 TRACE_ADDCONTROL; 00564 } 00565 00566 WAS_INLINE MarControlPtr::MarControlPtr(const char *c) 00567 { 00568 control_ = new MarControl(std::string(c)); 00569 control_->ref(); 00570 TRACE_ADDCONTROL; 00571 } 00572 00573 WAS_INLINE MarControlPtr::MarControlPtr(std::string st) 00574 { 00575 control_ = new MarControl(st); 00576 control_->ref(); 00577 TRACE_ADDCONTROL; 00578 } 00579 00580 WAS_INLINE MarControlPtr::MarControlPtr(mrs_bool be) 00581 { 00582 control_ = new MarControl(be); 00583 control_->ref(); 00584 TRACE_ADDCONTROL; 00585 } 00586 00587 WAS_INLINE MarControlPtr::MarControlPtr(realvec ve) 00588 { 00589 control_ = new MarControl(ve); 00590 control_->ref(); 00591 TRACE_ADDCONTROL; 00592 } 00593 00594 WAS_INLINE std::ostream& operator<<(std::ostream& os, const MarControlPtr& ctrl) 00595 { 00596 return (os << (*ctrl.control_)); 00597 } 00598 00599 WAS_INLINE bool operator==(const MarControlPtr& v1, const MarControlPtr& v2) 00600 { 00601 return (*v1.control_) == (*v2.control_); 00602 } 00603 00604 WAS_INLINE bool operator!=(const MarControlPtr& v1, const MarControlPtr& v2) 00605 { 00606 return (*v1.control_) != (*v2.control_); 00607 } 00608 00609 WAS_INLINE mrs_real operator+(const MarControlPtr& v1, const mrs_real& v2) 00610 { 00611 return (*v1.control_)+v2; 00612 } 00613 00614 WAS_INLINE mrs_real operator+(const mrs_real& v1, const MarControlPtr& v2) 00615 { 00616 return v1+(*v2.control_); 00617 } 00618 00619 WAS_INLINE mrs_real operator-(const MarControlPtr& v1, const mrs_real& v2) 00620 { 00621 return (*v1.control_)-v2; 00622 } 00623 00624 WAS_INLINE mrs_real operator-(const mrs_real& v1, const MarControlPtr& v2) 00625 { 00626 return v1-(*v2.control_); 00627 } 00628 00629 WAS_INLINE mrs_real operator*(const MarControlPtr& v1, const mrs_real& v2) 00630 { 00631 return (*v1.control_)*v2; 00632 } 00633 WAS_INLINE mrs_real operator*(const mrs_real& v1, const MarControlPtr& v2) 00634 { 00635 return v1*(*v2.control_); 00636 } 00637 00638 WAS_INLINE mrs_real operator/(const MarControlPtr& v1, const mrs_real& v2) 00639 { 00640 return (*v1.control_)/v2; 00641 } 00642 00643 WAS_INLINE mrs_real operator/(const mrs_real& v1, const MarControlPtr& v2) 00644 { 00645 return v1/(*v2.control_); 00646 } 00647 00648 WAS_INLINE MarControlPtr operator+(const MarControlPtr& v1, const MarControlPtr& v2) 00649 { 00650 return (*v1.control_)+(*v2.control_); 00651 } 00652 00653 WAS_INLINE MarControlPtr operator-(const MarControlPtr& v1, const MarControlPtr& v2) 00654 { 00655 return (*v1.control_)-(*v2.control_); 00656 } 00657 00658 WAS_INLINE MarControlPtr operator*(const MarControlPtr& v1, const MarControlPtr& v2) 00659 { 00660 return (*v1.control_)*(*v2.control_); 00661 } 00662 00663 WAS_INLINE MarControlPtr operator/(const MarControlPtr& v1, const MarControlPtr& v2) 00664 { 00665 return (*v1.control_)/(*v2.control_); 00666 } 00667 00668 bool operator<(const MarControlPtr& v1, const MarControlPtr& v2) 00669 { 00670 return v1.control_ < v2.control_; 00671 } 00672 00673 //WAS_INLINE 00674 MarControlPtr::MarControlPtr(const MarControlPtr& a) //mutexes? [?] 00675 { 00676 control_ = a.control_; 00677 if (control_) 00678 { 00679 control_->ref(); 00680 TRACE_ADDCONTROL; 00681 } 00682 } 00683 00684 WAS_INLINE 00685 MarControlPtr::MarControlPtr(MarControl *control)//mutexes? [?] 00686 { 00687 control_ = control; 00688 if (control_) 00689 { 00690 control_->ref(); 00691 TRACE_ADDCONTROL; 00692 } 00693 } 00694 00695 WAS_INLINE 00696 MarControlPtr& 00697 MarControlPtr::operator=(const MarControlPtr& a)//mutexes? [?] 00698 { 00699 if (control_) 00700 { 00701 TRACE_REMCONTROL; 00702 control_->unref(); 00703 } 00704 control_ = a.control_; 00705 if (control_) 00706 { 00707 control_->ref(); 00708 TRACE_ADDCONTROL; 00709 } 00710 return *this; 00711 } 00712 00713 WAS_INLINE 00714 bool 00715 MarControlPtr::isInvalid() const 00716 { 00717 return (control_== NULL); 00718 } 00719 00720 WAS_INLINE 00721 bool 00722 MarControlPtr::isEqual(const MarControlPtr& p) 00723 { 00724 return (control_ == p.control_); 00725 } 00726 00727 00728 00729 // default constructor 00730 MarControl::MarControl() : 00731 refCount_(0), 00732 value_(NULL), 00733 msys_(NULL), 00734 state_(false), 00735 is_public_(false) 00736 { 00737 00738 00739 } 00740 00741 00742 WAS_INLINE 00743 MarControl::MarControl(const MarControl& a): 00744 refCount_(0), 00745 value_(a.value_->clone()), 00746 msys_(a.msys_), 00747 cname_(a.cname_), 00748 id_(a.id_), 00749 desc_(a.desc_), 00750 state_(a.state_), 00751 is_public_(a.is_public_) 00752 { 00753 value_->links_.push_back(std::pair<MarControl*, MarControl*>(this, this)); 00754 } 00755 00756 WAS_INLINE 00757 MarControl::MarControl(MarControlValue *value, std::string cname, MarSystem* msys, bool state): 00758 refCount_(0), 00759 value_(value->clone()), 00760 msys_(msys), 00761 state_(state), 00762 is_public_(false) 00763 { 00764 setName(cname); 00765 value_->links_.push_back(std::pair<MarControl*, MarControl*>(this, this)); 00766 } 00767 00768 WAS_INLINE 00769 MarControl::MarControl(double re, std::string cname, MarSystem* msys, bool state): 00770 refCount_(0), 00771 value_(new MarControlValueT<mrs_real>(re)), 00772 msys_(msys), 00773 state_(state), 00774 is_public_(false) 00775 { 00776 setName(cname); 00777 value_->links_.push_back(std::pair<MarControl*, MarControl*>(this, this)); 00778 } 00779 00780 WAS_INLINE 00781 MarControl::MarControl(float re, std::string cname, MarSystem* msys, bool state): 00782 refCount_(0), 00783 value_(new MarControlValueT<mrs_real>(re)), 00784 msys_(msys), 00785 state_(state), 00786 is_public_(false) 00787 { 00788 setName(cname); 00789 value_->links_.push_back(std::pair<MarControl*, MarControl*>(this, this)); 00790 } 00791 00792 00793 WAS_INLINE 00794 MarControl::MarControl(mrs_natural ne, std::string cname, MarSystem* msys, bool state): 00795 refCount_(0), 00796 value_(new MarControlValueT<mrs_natural>(ne)), 00797 msys_(msys), 00798 state_(state), 00799 is_public_(false) 00800 { 00801 setName(cname); 00802 value_->links_.push_back(std::pair<MarControl*, MarControl*>(this, this)); 00803 } 00804 00805 WAS_INLINE 00806 MarControl::MarControl(std::string st, std::string cname, MarSystem* msys, bool state): 00807 refCount_(0), 00808 value_(new MarControlValueT<std::string>(st)), 00809 msys_(msys), 00810 state_(state), 00811 is_public_(false) 00812 { 00813 setName(cname); 00814 value_->links_.push_back(std::pair<MarControl*, MarControl*>(this, this)); 00815 } 00816 00817 WAS_INLINE 00818 MarControl::MarControl(mrs_bool be, std::string cname, MarSystem* msys, bool state): 00819 refCount_(0), 00820 value_(new MarControlValueT<bool>(be)), 00821 msys_(msys), 00822 state_(state), 00823 is_public_(false) 00824 { 00825 setName(cname); 00826 value_->links_.push_back(std::pair<MarControl*, MarControl*>(this, this)); 00827 } 00828 00829 WAS_INLINE 00830 MarControl::MarControl(realvec& ve, std::string cname, MarSystem* msys, bool state): 00831 refCount_(0), 00832 value_(new MarControlValueT<realvec>(ve)), 00833 msys_(msys), 00834 state_(state), 00835 is_public_(false) 00836 { 00837 setName(cname); 00838 value_->links_.push_back(std::pair<MarControl*, MarControl*>(this, this)); 00839 } 00840 00841 WAS_INLINE 00842 MarControl::~MarControl() 00843 { 00844 //first unlink this control from everything 00845 this->unlinkFromAll(); 00846 //now we can safely delete its uniquely owned MarControlValue 00847 delete value_; 00848 value_ = NULL; 00849 } 00850 00851 WAS_INLINE 00852 MarControl& 00853 MarControl::operator=(const MarControl& a) 00854 { 00855 if (this != &a) 00856 this->setValue(a.value_); 00857 00858 return *this; 00859 } 00860 00861 00862 00863 WAS_INLINE 00864 bool 00865 MarControl::setValue(MarControlPtr mc, bool update) 00866 { 00867 if (value_->type_ != mc->value_->type_) 00868 { 00869 std::ostringstream sstr; 00870 sstr << "MarControl::setValue() - Trying to set value of incompatible type " 00871 << "(expected " << value_->type_ << ", given " << mc->value_->type_ << ")"; 00872 MRSWARN(sstr.str()); 00873 return false; 00874 } 00875 00876 if (MarControlPtr(this) == mc) 00877 { 00878 return true; 00879 } 00880 00881 value_->copyValue(*(mc->value_)); 00882 00883 #ifdef MARSYAS_TRACECONTROLS 00884 value_->setDebugValue(); 00885 #endif 00886 00887 //check if it's needed to call update() 00888 if(update) 00889 value_->callMarSystemsUpdate(); 00890 00891 return true; 00892 } 00893 00894 WAS_INLINE 00895 bool 00896 MarControl::setValue(MarControlValue *mcv, bool update) 00897 { 00898 if (value_->type_ != mcv->type_) 00899 { 00900 std::ostringstream sstr; 00901 sstr << "MarControl::setValue() - Trying to set value of incompatible type " 00902 << "(expected " << value_->type_ << ", given " << mcv->type_ << ")"; 00903 MRSWARN(sstr.str()); 00904 return false; 00905 } 00906 00907 if (mcv->isEqual(value_)) 00908 { 00909 return true; 00910 } 00911 00912 value_->copyValue(*(mcv)); 00913 00914 #ifdef MARSYAS_TRACECONTROLS 00915 value_->setDebugValue(); 00916 #endif 00917 00918 //check if it's needed to call update() 00919 if(update) 00920 value_->callMarSystemsUpdate(); 00921 00922 return true; 00923 } 00924 00925 WAS_INLINE 00926 bool 00927 MarControl::setValue(const char *t, bool update) 00928 { 00929 return this->setValue(std::string(t), update); 00930 } 00931 00932 WAS_INLINE 00933 bool 00934 MarControl::setValue(const int t, bool update) 00935 { 00936 return this->setValue((mrs_natural)t, update); 00937 } 00938 00939 00940 00941 WAS_INLINE 00942 std::ostream& 00943 operator<<(std::ostream& os, const MarControl& ctrl) 00944 { 00945 return ctrl.value_->serialize(os); 00946 } 00947 00948 WAS_INLINE 00949 mrs_real 00950 operator+(const MarControl& v1, const mrs_real& v2) 00951 { 00952 mrs_real r1; 00953 MarControlValueT<mrs_real> *ptr = dynamic_cast<MarControlValueT<mrs_real>*>(v1.value_); 00954 if(ptr) 00955 { 00956 r1 = ptr->get(); 00957 } 00958 else 00959 { 00960 std::ostringstream sstr; 00961 sstr << "MarControl::operator + : Trying to get value of incompatible type " 00962 << "(expected " << v1.getType() << ", given " << typeid(mrs_real).name() << ")"; 00963 MRSWARN(sstr.str()); 00964 return false; 00965 } 00966 return r1 + v2; 00967 } 00968 00969 WAS_INLINE 00970 mrs_real 00971 operator+(const mrs_real& v1, const MarControl& v2) 00972 { 00973 mrs_real r2; 00974 MarControlValueT<mrs_real> *ptr = dynamic_cast<MarControlValueT<mrs_real>*>(v2.value_); 00975 if(ptr) 00976 { 00977 r2 = ptr->get(); 00978 } 00979 else 00980 { 00981 std::ostringstream sstr; 00982 sstr << "MarControl::operator + : Trying to get value of incompatible type " 00983 << "(expected " << v2.getType() << ", given " << typeid(mrs_real).name() << ")"; 00984 MRSWARN(sstr.str()); 00985 return false; 00986 } 00987 return v1 + r2; 00988 } 00989 00990 WAS_INLINE 00991 mrs_real 00992 operator-(const MarControl& v1, const mrs_real& v2) 00993 { 00994 mrs_real r1; 00995 MarControlValueT<mrs_real> *ptr = dynamic_cast<MarControlValueT<mrs_real>*>(v1.value_); 00996 if(ptr) 00997 { 00998 r1 = ptr->get(); 00999 } 01000 else 01001 { 01002 std::ostringstream sstr; 01003 sstr << "[MarControl::setValue] Trying to get value of incompatible type " 01004 << "(expected " << v1.getType() << ", given " << typeid(mrs_real).name() << ")"; 01005 MRSWARN(sstr.str()); 01006 return false; 01007 } 01008 return r1 - v2; 01009 } 01010 01011 WAS_INLINE 01012 mrs_real 01013 operator-(const mrs_real& v1, const MarControl& v2) 01014 { 01015 mrs_real r2; 01016 MarControlValueT<mrs_real> *ptr = dynamic_cast<MarControlValueT<mrs_real>*>(v2.value_); 01017 if(ptr) 01018 { 01019 r2 = ptr->get(); 01020 } 01021 else 01022 { 01023 std::ostringstream sstr; 01024 sstr << "[MarControl::setValue] Trying to get value of incompatible type " 01025 << "(expected " << v2.getType() << ", given " << typeid(mrs_real).name() << ")"; 01026 MRSWARN(sstr.str()); 01027 return false; 01028 } 01029 return v1 - r2; 01030 } 01031 01032 WAS_INLINE 01033 mrs_real 01034 operator*(const MarControl& v1, const mrs_real& v2) 01035 { 01036 mrs_real r1; 01037 MarControlValueT<mrs_real> *ptr = dynamic_cast<MarControlValueT<mrs_real>*>(v1.value_); 01038 if(ptr) 01039 { 01040 r1 = ptr->get(); 01041 } 01042 else 01043 { 01044 std::ostringstream sstr; 01045 sstr << "[MarControl::setValue] Trying to get value of incompatible type " 01046 << "(expected " << v1.getType() << ", given " << typeid(mrs_real).name() << ")"; 01047 MRSWARN(sstr.str()); 01048 return false; 01049 } 01050 return r1 * v2; 01051 } 01052 01053 WAS_INLINE 01054 mrs_real 01055 operator*(const mrs_real& v1, const MarControl& v2) 01056 { 01057 mrs_real r2; 01058 MarControlValueT<mrs_real> *ptr = dynamic_cast<MarControlValueT<mrs_real>*>(v2.value_); 01059 if(ptr) 01060 { 01061 r2 = ptr->get(); 01062 } 01063 else 01064 { 01065 std::ostringstream sstr; 01066 sstr << "[MarControl::setValue] Trying to get value of incompatible type " 01067 << "(expected " << v2.getType() << ", given " << typeid(mrs_real).name() << ")"; 01068 MRSWARN(sstr.str()); 01069 return false; 01070 } 01071 return v1 * r2; 01072 } 01073 01074 WAS_INLINE 01075 mrs_real 01076 operator/(const MarControl& v1, const mrs_real& v2) 01077 { 01078 mrs_real r1; 01079 MarControlValueT<mrs_real> *ptr = dynamic_cast<MarControlValueT<mrs_real>*>(v1.value_); 01080 if(ptr) 01081 { 01082 r1 = ptr->get(); 01083 } 01084 else 01085 { 01086 std::ostringstream sstr; 01087 sstr << "[MarControl::setValue] Trying to get value of incompatible type " 01088 << "(expected " << v1.getType() << ", given " << typeid(mrs_real).name() << ")"; 01089 MRSWARN(sstr.str()); 01090 return false; 01091 } 01092 return r1 / v2; 01093 } 01094 01095 WAS_INLINE 01096 mrs_real 01097 operator/(const mrs_real& v1, const MarControl& v2) 01098 { 01099 mrs_real r2; 01100 MarControlValueT<mrs_real> *ptr = dynamic_cast<MarControlValueT<mrs_real>*>(v2.value_); 01101 if(ptr) 01102 { 01103 r2 = ptr->get(); 01104 } 01105 else 01106 { 01107 std::ostringstream sstr; 01108 sstr << "[MarControl::setValue] Trying to get value of incompatible type " 01109 << "(expected " << v2.getType() << ", given " << typeid(mrs_real).name() << ")"; 01110 MRSWARN(sstr.str()); 01111 return false; 01112 } 01113 return v1 / r2; 01114 } 01115 01116 WAS_INLINE 01117 MarControl 01118 operator+(const MarControl& v1, const MarControl& v2) 01119 { 01120 MarControlValue *val = v1.value_->sum(v2.value_); 01121 MarControl ret(val); 01122 delete val; 01123 return ret; 01124 } 01125 01126 WAS_INLINE 01127 MarControl 01128 operator-(const MarControl& v1, const MarControl& v2) 01129 { 01130 MarControlValue *val = v1.value_->subtract(v2.value_); 01131 MarControl ret(val); 01132 delete val; 01133 return ret; 01134 } 01135 01136 WAS_INLINE 01137 MarControl 01138 operator*(const MarControl& v1, const MarControl& v2) 01139 { 01140 MarControlValue *val = v1.value_->multiply(v2.value_); 01141 MarControl ret(val); 01142 delete val; 01143 return ret; 01144 } 01145 01146 WAS_INLINE 01147 MarControl 01148 operator/(const MarControl& v1, const MarControl& v2) 01149 { 01150 MarControlValue *val = v1.value_->divide(v2.value_); 01151 MarControl ret(val); 01152 delete val; 01153 return ret; 01154 } 01155 01156 01157 WAS_INLINE 01158 bool 01159 MarControl::isTrue() 01160 { 01161 MarControlValueT<bool> *ptr = dynamic_cast<MarControlValueT<bool>*>(value_); 01162 if(ptr) 01163 { 01164 return ptr->get(); 01165 } 01166 else 01167 { 01168 std::ostringstream sstr; 01169 sstr << "MarControl::isTrue() - Trying to get use bool-specific method with " << value_->getType(); 01170 MRSWARN(sstr.str()); 01171 return false; 01172 } 01173 } 01174 01175 01176 } // namespace Marsyas