- Main Page
- Namespaces
- Classes
- Files
- Related Pages

# /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