/Users/fpy/titan-1-5-MBARI/Mers/Models/Base/BaseModel.cpp

00001 
00002 //
00003 // Copyright (c) 2004           Model-based Embedded and Robotic Systems Group
00004 // All Rights Reserved          Massachusetts Institute of Technology
00005 //
00006 // This software is provided as is. Model-based Embedded and Robotic Systems
00007 // (MERS) group does not assume any responsibility.
00008 //
00009 // Organization:        Model-based Embedded and Robotic Systems Group
00010 //                                      Massachusetts Institute of Technology
00011 //
00013 
00014 #include "BaseModel.h"
00015 #include "BaseModelUtils.h"
00016 #include "BaseModelDoubleDomain.h"
00017 #include "BaseModelIntegerDomain.h"
00018 #include "BaseModelStringDomain.h"
00019 #include <cstdio>
00020 
00022 
00023 using namespace Mers::Models::Base;
00024 using std::ostream;
00025 using std::endl;
00026 
00028 // Construction/Destruction
00030 
00031 BaseModel::BaseModel(char const * myName) : BaseModelObject(BaseModelObject::BMModel)
00032 {
00033         name = NULL;
00034         setName(myName);
00035         domains = newDomainArray();
00036         if(!domains){
00037                 fprintf(stderr, "Error, Model %s unable to create a domain array\n", myName);
00038         }
00039         variables = newVariableArray();
00040         if(!variables){
00041                 fprintf(stderr, "Error, Model %s unable to create a variable array\n", myName);
00042         }
00043 }
00044 
00046 
00047 BaseModel::BaseModel(BaseModel const &other)
00048 : BaseModelObject(other), name( NULL ), domains( NULL ), variables( NULL )
00049 {
00050         copy( other );
00051 }
00052 
00054 
00055 BaseModel::~BaseModel()
00056 {
00057         destroy();
00058 }
00059 
00061 
00062 int BaseModel::setName(char const * newName)
00063 {
00064         return BaseModelUtils::setName(name, newName);
00065 }
00066 
00068 
00069 char const * BaseModel::getName() const
00070 {
00071         return name;
00072 }
00073 
00075 
00076 int BaseModel::addDomain(char const * domainName, BaseModelValueArray &values,
00077                           BaseModelDomain::DomainType domainType)
00078 {
00079         BaseModelDomain * domain;
00080         domain = newDomain(domainName, domains->getLength(), values, domainType);
00081         
00082         if(NULL == domain){
00083                 fprintf(stderr, "Unable to create a new domain object\n");
00084                 return 1;
00085         }
00086 
00087         // if the values list isn't empty delete everything in it (it means we failed
00088         // to add the new domain object)
00089         values.makeEmpty();
00090 
00091         return addDomain(domain);
00092 }
00093 
00095 
00096 int BaseModel::addDomain(BaseModelDomain * domain)
00097 {
00098         int ret;
00099         ret = domains->pushBack(domain);
00100         domain->setUID( domains->getLength() - 1 );
00101         // if addition failed, delete our object and return the error code
00102         if(ret != 0 && domain != NULL){
00103                 delete domain;
00104         }
00105         return ret;
00106 }
00107 
00109 
00110 BaseModelDomain * BaseModel::getDomain(unsigned int domainUID)
00111 {
00112         return domains->operator [](domainUID);
00113 }
00114 
00116 
00117 BaseModelDomain const * BaseModel::getDomain(unsigned int domainUID) const
00118 {
00119         return domains->operator [](domainUID);
00120 }
00121 
00123 
00124 BaseModelDomain * BaseModel::getDomain(char const * domainName)
00125 {
00126         return domains->find(domainName);
00127 }
00128 
00130 
00131 BaseModelDomain const * BaseModel::getDomain(char const * domainName) const
00132 {
00133         return domains->find(domainName);
00134 }
00135 
00137 
00138 BaseModelDomainArray * BaseModel::getDomains()
00139 {
00140         return domains;
00141 }
00142 
00144 
00145 BaseModelDomainArray const * BaseModel::getDomains() const
00146 {
00147         return domains;
00148 }
00149 
00151 
00152 int BaseModel::addVariable(char const * variableName, 
00153         BaseModelVariable::VariableType variableType, BaseModelDomain * domain)
00154 {
00155         BaseModelVariable * variable;
00156         variable = newVariable(variableName, variables->getLength(), variableType, domain);
00157         
00158         if(NULL == variable){
00159                 fprintf(stderr, "Unable to create a new variable object\n");
00160                 return 1;
00161         }
00162 
00163         return addVariable(variable);
00164 }
00165 
00167 
00168 int BaseModel::addVariable(BaseModelVariable * variable)
00169 {
00170         int ret;
00171         ret = variables->pushBack(variable);
00172         // if addition failed, delete our object and return the error code
00173         if(FAILED(ret) && variable != NULL){
00174                 delete variable;
00175         }
00176         return ret;
00177 }
00178 
00180 
00181 BaseModelVariable * BaseModel::getVariable(unsigned int variableUID)
00182 {
00183         return variables->operator [](variableUID);
00184 }
00185 
00187 
00188 BaseModelVariable const * BaseModel::getVariable(unsigned int variableUID) const
00189 {
00190         return variables->operator [](variableUID);
00191 }
00192 
00194 
00195 BaseModelVariable * BaseModel::getVariable(char const * variableName)
00196 {
00197         return variables->find(variableName);
00198 }
00199 
00201 
00202 BaseModelVariable const * BaseModel::getVariable(char const * variableName) const
00203 {
00204         return variables->find(variableName);
00205 }
00206 
00208 
00209 BaseModelVariableArray * BaseModel::getVariables()
00210 {
00211         return variables;
00212 }
00213 
00215 
00216 BaseModelVariableArray const * BaseModel::getVariables() const
00217 {
00218         return variables;
00219 }
00220 
00222 
00223 BaseModelAssignment * BaseModel::getAssignment(char const * variableName,
00224         char const * valueName, BaseModelAssignment::OperatorType opType) const
00225 {
00226         BaseModelVariable const * variable;
00227         BaseModelValue const * value;
00228 
00229         variable = getVariable(variableName);
00230 
00231         if(NULL == variable){
00232                 fprintf(stderr, "Error, unable to find the variable \"%s\"\n", variableName);
00233                 return NULL;
00234         }
00235 
00236         value = variable->getValue(valueName);
00237         if(NULL == value){
00238                 fprintf(stderr, "Error, unable to find the value \"%s\"\n", valueName);
00239                 fprintf(stderr, "  in the variable \"%s\"\n", variableName);
00240                 return NULL;
00241         }
00242 
00243         BaseModelAssignment * assignment;
00244         // should we just return newAssignment? or print an error message?
00245         assignment = newAssignment(variable, value, opType);
00246         
00247         if(NULL == assignment){
00248                 fprintf(stderr, "Unable to create a new assignment object\n");
00249                 return NULL;
00250         }
00251 
00252         return assignment;
00253 }
00254 
00256 
00257 void BaseModel::clear()
00258 {
00259         destroy();
00260 }
00261 
00263 
00264 BaseModel const & BaseModel::operator =(BaseModel const &other)
00265 {
00266         copy(other);
00267         return other;
00268 }
00269 
00271 
00272 bool BaseModel::operator ==(BaseModel const &other) const
00273 {
00274         // Compare the three things stored in this model.
00275         return (*domains == *other.domains) && (*variables == *other.variables) &&
00276                 strcmp( name, other.name) == 0;
00277 }
00278 
00280 
00281 #ifndef EMBEDDED
00282 
00283 void BaseModel::print(ostream &out) const
00284 {
00285         char const * localName = name;
00286 
00287         if(NULL == localName)
00288                 localName = "NULL Name";
00289 
00290         out << "Model \"" << localName << "\" {"<< endl;
00291         out << "Domains(" << localName << ") {" << endl << domains 
00292                 << endl << "} Domains(" << localName << ")" << endl << endl;
00293         out << "Variables(" << localName << ") {" << endl << variables 
00294                 << endl << "} Variables(" << localName << ")" << endl << endl;
00295         out << "} Model(" << localName << ")" << endl;
00296 }
00297 
00298 #endif
00299 
00301 
00302 BaseModelAssignment * BaseModel::newAssignment(BaseModelVariable const * variable,
00303         BaseModelValue const * value, BaseModelAssignment::OperatorType opType) const
00304 {
00305         return new BaseModelAssignment(variable, value, opType);
00306 }
00307 
00309 
00310 BaseModelVariable * BaseModel::newVariable(char const * variableName, 
00311         unsigned int variableUID, BaseModelVariable::VariableType variableType,
00312         BaseModelDomain * domain)
00313 {
00314         return new BaseModelVariable(variableName, domain, variableType, variableUID);
00315 }
00316 
00318 
00319 BaseModelDomain * BaseModel::newDomain(char const * domainName, unsigned int domainUID, 
00320         BaseModelValueArray &values, BaseModelDomain::DomainType domainType)
00321 {
00322         BaseModelDomain * domain;
00323         switch(domainType){
00324         case BaseModelDomain::Normal:
00325                 domain = new BaseModelDomain(domainName, true, domainUID);
00326                 break;
00327         case BaseModelDomain::Double:
00328                 domain = new BaseModelDoubleDomain(domainName, true, domainUID);
00329                 break;
00330         case BaseModelDomain::Integer:
00331                 domain = new BaseModelIntegerDomain(domainName, true, domainUID);
00332                 break;
00333         case BaseModelDomain::String:
00334                 domain = new BaseModelStringDomain(domainName, true, domainUID);
00335                 break;
00336         default:
00337                 fprintf(stderr, "BaseModel Error, invalid domain type: %d\n", (int) domainType);
00338                 return NULL;
00339         }
00340 
00341         if(NULL == domain)
00342                 return NULL;
00343         
00344         for(unsigned int x = 0; x < values.getLength(); x++){
00345                 if(FAILED(domain->pushBack(values[x]))){
00346                         // this will get deleted by pushBack since it failed
00347                         values[x] = NULL;
00348                         fprintf(stderr, "Error, unable to add another value to the domain\n");
00349                         fprintf(stderr, "%s due to lack of memory\n", domainName);
00350                         values.makeEmpty();
00351                         domain->makeEmpty();
00352                         delete domain;
00353                         return NULL;
00354                 }
00355                 values[x] = NULL;
00356         }
00357 
00358         values.makeEmpty();
00359         return domain;
00360 }
00361 
00363 
00364 BaseModelDomainArray * BaseModel::newDomainArray(BaseModelDomainArray const * other)
00365 {
00366         if(NULL == other)
00367                 return new BaseModelDomainArray(true);
00368         else
00369                 return new BaseModelDomainArray(*other);
00370 }
00371 
00373 
00374 BaseModelVariableArray * BaseModel::newVariableArray(BaseModelVariableArray const * other)
00375 {
00376         if(NULL == other)
00377                 return new BaseModelVariableArray(true);
00378         else
00379                 return new BaseModelVariableArray(*other);
00380 }
00381 
00383 
00384 void BaseModel::destroy()
00385 {
00386         if(NULL != domains){
00387                 domains->makeEmpty();
00388                 delete domains;
00389                 domains = NULL;
00390         }
00391 
00392         if(NULL != variables){
00393                 variables->makeEmpty();
00394                 delete variables;
00395                 variables = NULL;
00396         }
00397 
00398         if(NULL != name)
00399                 delete[] name;
00400         name = NULL;
00401 }
00402 
00404 
00405 int BaseModel::copy(BaseModel const &other)
00406 {
00407         BaseModel::destroy();
00408         domains = newDomainArray(other.domains);
00409         if(NULL == domains || domains->getLength() != other.domains->getLength()){
00410                 fprintf(stderr, "Error, unable to copy the domains\n");
00411                 fprintf(stderr, "from the model %s\n", other.name);
00412                 return 1;
00413         }
00414 
00415         variables = newVariableArray(other.variables);
00416         if(NULL == variables || variables->getLength() != other.variables->getLength()){
00417                 fprintf(stderr, "Error, unable to copy the variables\n");
00418                 fprintf(stderr, "from the model %s\n", other.name);
00419                 return 2;
00420         }
00421 
00422         // Note that this copies the domains of the other object.  We need
00423         // to transfer the domains to this object.
00424         for( unsigned int i = 0; i < variables->getLength(); ++i ) {
00425                 // Get the variable
00426                 BaseModelVariable * var = (*variables)[i];
00427                 // Get the domain UID that we want.
00428                 unsigned int uid = var->getDomain()->getUID();
00429                 var->setDomain( getDomain( uid ) );
00430         }
00431 
00432         if(FAILED(setName(other.name))){
00433                 fprintf(stderr, "Warning, model unable to copy the name\n");
00434                 fprintf(stderr, "from the model %s\n", other.name);
00435                 return -1;
00436         }
00437         return 0;
00438 }
00439 
00441 

Generated on Mon Dec 4 14:16:52 2006 for Mers by  doxygen 1.5.0