cgma
CADeferredAttrib.cpp
Go to the documentation of this file.
00001 #include "CADeferredAttrib.hpp"
00002 #include "CubitSimpleAttrib.hpp"
00003 #include "ToolDataUser.hpp"
00004 #include "TDUniqueId.hpp"
00005 #include "CastTo.hpp"
00006 #include "RefEntity.hpp"
00007 #include "DLIList.hpp"
00008 #include "CubitMessage.hpp"
00009 #include <algorithm>
00010 
00011 std::vector<CubitAttrib*> CADeferredAttrib::unactuatedCAs;
00012 std::vector<CADeferredAttrib*> CADeferredAttrib::allCADeferredAttribs;
00013 
00014 CubitAttrib* CADeferredAttrib_creator(RefEntity* entity, const CubitSimpleAttrib& p_csa)
00015 {
00016   CADeferredAttrib *new_attrib = NULL;
00017 
00018   // Deferred attributes are a special case -- they should only get created
00019   // when restoring from a file, in which case p_csa should be non-NULL
00020   if (!p_csa.isEmpty())
00021   {
00022     new_attrib = new CADeferredAttrib(entity, p_csa);
00023   }
00024   return new_attrib;
00025 }
00026 
00027 
00028 CADeferredAttrib::~CADeferredAttrib()
00029 {
00030   allCADeferredAttribs.erase(
00031         std::remove(allCADeferredAttribs.begin(), allCADeferredAttribs.end(), this), allCADeferredAttribs.end()
00032         );
00033 }
00034 
00035 CADeferredAttrib::CADeferredAttrib(RefEntity *, const CubitSimpleAttrib &csa_ptr)
00036         : CubitAttrib(NULL)
00037 {
00038   init_csa(csa_ptr);
00039   hasUpdated = CUBIT_TRUE;
00040 }
00041 
00042 namespace {
00043 struct find_attrib_id
00044 {
00045   int mId;
00046   find_attrib_id(int id)  : mId(id) {}
00047   bool operator()(CADeferredAttrib* attr)
00048   {
00049     return attr->unique_id() == mId;
00050   }
00051 };
00052 
00053 }
00054 
00055 
00056 CubitStatus CADeferredAttrib::init_csa(const CubitSimpleAttrib &csa_ptr)
00057 {
00058   int csa_type = CGMApp::instance()->attrib_manager()->attrib_type(csa_ptr);
00059   if (CA_DEFERRED_ATTRIB != csa_type)
00060   {
00061     assert(false);
00062     return CUBIT_FAILURE;
00063   }
00064 
00065     // initialize this according to csa_ptr
00066 
00067     // first get the uniqueId off the csa
00068   uniqueId = csa_ptr.int_data_list()[0];
00069   assert(uniqueId > 0);
00070 
00071     // now check to see if we have this CADA alreedy; if so, set the
00072     // delete flag and exit
00073   std::vector<CADeferredAttrib*>::iterator iter = std::find_if(allCADeferredAttribs.begin(), allCADeferredAttribs.end(), find_attrib_id(uniqueId));
00074 
00075   if (iter != allCADeferredAttribs.end()) {
00076     deleteAttrib = CUBIT_TRUE;
00077     return CUBIT_SUCCESS;
00078   }
00079 
00080     // copy the info on the csa; need a new one, since
00081     // we don't own the original
00082   thisCSA = csa_from_dcsa(csa_ptr);
00083   assert(!thisCSA.isEmpty());
00084 
00085     // add this to the global list
00086   allCADeferredAttribs.push_back(this);
00087 
00088   return CUBIT_SUCCESS;
00089 }
00090 
00091 CubitStatus CADeferredAttrib::actuate()
00092 {
00093     // test to see if we can assign this CADA to a new owner; set
00094     // flag accordingly
00095   if (assign_to_owner()) {
00096     hasActuated = CUBIT_TRUE;
00097     return CUBIT_SUCCESS;
00098   }
00099   else return CUBIT_FAILURE;
00100 }
00101 
00102 CubitStatus CADeferredAttrib::update()
00103 {
00104     // the hasUpdated flag should always be true by the time
00105     // we get here, since the function that put this CA on the
00106     // owning entity set the flag
00107   assert(hasUpdated == CUBIT_TRUE);
00108   return CUBIT_SUCCESS;
00109 }
00110 
00111 CubitStatus CADeferredAttrib::reset()
00112 {
00113     // do nothing; this CA manages its own duplicates, so no need
00114     // to worry about them in parent code
00115   return CUBIT_SUCCESS;
00116 }
00117 
00118 CubitSimpleAttrib CADeferredAttrib::cubit_simple_attrib()
00119 {
00120   return thisCSA;
00121 }
00122 
00123 CubitStatus CADeferredAttrib::assign_to_owner(CubitAttribUser *owner)
00124 {
00125     //- looks for an entity with the right uid, assigns itself to
00126     //- that entity if found
00127 
00128   if (uniqueId == 0) return CUBIT_FAILURE;
00129   
00130   if (owner == NULL) {
00131     ToolDataUser *tdu = TDUniqueId::find_td_unique_id(uniqueId);
00132     owner = CAST_TO(tdu, CubitAttribUser);
00133   }
00134 
00135   if (owner == NULL) return CUBIT_FAILURE;
00136 
00137     // ok, we have an owner; create a new CA using the csa, assigning
00138     // it to the ref entity
00139   RefEntity *ref_ent = CAST_TO(owner, RefEntity);
00140   assert (ref_ent != 0);
00141 
00142 //  CubitAttrib *new_cubit_attrib =
00143 //    CGMApp::instance()->attrib_manager()->create_cubit_attrib(thisCSA, ref_ent);
00144   int attrib_type = CGMApp::instance()->attrib_manager()->attrib_type(thisCSA);
00145   CubitAttrib *new_cubit_attrib =
00146     CGMApp::instance()->attrib_manager()->create_cubit_attrib(attrib_type, ref_ent, thisCSA);
00147 
00148     // now remove this CADA from the global list and add the new CA
00149     // to the unactuated list
00150   allCADeferredAttribs.erase(
00151         std::remove(allCADeferredAttribs.begin(), allCADeferredAttribs.end(), this), allCADeferredAttribs.end()
00152         );
00153 
00154     // new attribute might be NULL, if there was already one there
00155   if (NULL != new_cubit_attrib)
00156     unactuatedCAs.push_back(new_cubit_attrib);
00157 
00158     // ok, all done
00159   
00160   deleteAttrib = CUBIT_TRUE;
00161   return CUBIT_SUCCESS;
00162 }
00163 
00164 CubitStatus CADeferredAttrib::get_deferred_attribs(const int uid,
00165                                                    std::vector<CADeferredAttrib*> &cada_list)
00166 {
00167     // find a deferred attribute for the entity with the uid passed in
00168   cada_list.clear();
00169 
00170   for(std::vector<CADeferredAttrib*>::iterator iter=allCADeferredAttribs.begin();
00171       iter != allCADeferredAttribs.end(); ++iter)
00172   {
00173     if((*iter)->unique_id() == uid)
00174     {
00175       cada_list.push_back(*iter);
00176     }
00177   }
00178   
00179   if (cada_list.size() > 0) return CUBIT_SUCCESS;
00180   else return CUBIT_FAILURE;
00181 }
00182 
00183 CubitStatus CADeferredAttrib::cleanup_cadas(const CubitBoolean from_constructor,
00184                                             const CubitBoolean after_geom_changes) 
00185 {
00186   CubitStatus status = CUBIT_FAILURE;
00187   
00188   if (CUBIT_TRUE == from_constructor)
00189     status = CADeferredAttrib::cleanup_cadas_private(CUBIT_TRUE, CUBIT_FALSE);
00190   
00191     // exit if we're not to actuate for after_geom_changes
00192   if (CUBIT_TRUE == after_geom_changes) 
00193     status = CADeferredAttrib::cleanup_cadas_private(CUBIT_FALSE, CUBIT_TRUE);
00194 
00195   return status;  
00196 }
00197 
00198 CubitStatus CADeferredAttrib::cleanup_cadas_private(const CubitBoolean from_constructor,
00199                                                     const CubitBoolean after_geom_changes) 
00200 {
00201     // moves between the global CADA list and the unactuated list:
00202     // 
00203     // 1. tries to actuate all CADAs on unactuated list
00204     // 2. tries to assign_to_owner all CADAs on global list
00205     // 
00206     // after each of these steps, if anything happened, the loop is
00207     // repeated
00208     // this function should be called as part of the auto actuate process
00209 
00210     // first call for from_constructor and !after_geom_changes attributes
00211   CubitBoolean done = CUBIT_FALSE;
00212   CubitStatus did_something = CUBIT_FAILURE;
00213 
00214   while (done == CUBIT_FALSE) {
00215     done = CUBIT_TRUE;
00216     for(std::vector<CubitAttrib*>::iterator iter = unactuatedCAs.begin(); iter != unactuatedCAs.end();)
00217     {
00218       CubitAttrib *attrib = *iter;
00219       if( attrib == 0 )
00220       {
00221         ++iter;
00222         continue;
00223       }
00224 
00225         // check the auto actuate flag for this CA; since this function
00226         // is only called from the auto actuating process, we don't need
00227         // to check whether the user requested that this attribute be actuated
00228       if (attrib->auto_actuate_flag() == CUBIT_TRUE &&
00229           (!from_constructor || attrib->actuate_in_constructor()) &&
00230           (after_geom_changes || !attrib->actuate_after_geom_changes()))
00231       {
00232 
00233           // if the attribute has already actuated, but is still in our list,
00234           // count it as doing something
00235         if ( /*attrib->has_actuated()  || */
00236             attrib->actuate() == CUBIT_SUCCESS) {
00237           PRINT_DEBUG_90("Actuated a CADA of type %s\n",
00238                          attrib->att_internal_name());
00239           did_something = CUBIT_SUCCESS;
00240           done = CUBIT_FALSE;
00241           iter = unactuatedCAs.erase(iter);
00242         }
00243         else
00244         {
00245           ++iter;
00246         }
00247       }
00248       else
00249       {
00250         ++iter;
00251       }
00252     }
00253     
00254     if (done == CUBIT_TRUE) break;
00255 
00256       // if we did something in the previous loop, some of our CADAs might
00257       // now have owners; check and see
00258     for (std::vector<CADeferredAttrib*>::iterator iter = allCADeferredAttribs.begin();
00259          iter != allCADeferredAttribs.end(); ++iter)
00260     {
00261       CADeferredAttrib *cada = *iter;
00262       if (cada->assign_to_owner() == CUBIT_SUCCESS) {
00263         PRINT_DEBUG_90("Assigned a CADA to a new owner in CADA::cleanup_cadas\n");
00264         did_something = CUBIT_SUCCESS;
00265         done = CUBIT_FALSE;
00266       }
00267     }
00268   }
00269 
00270     // if there wasn't anthing to do in the first place, we didn't
00271     // really fail
00272   if (did_something == CUBIT_FAILURE && unactuatedCAs.size() == 0)
00273     did_something = CUBIT_SUCCESS;
00274   
00275   return did_something;
00276 }
00277 
00278 CubitStatus CADeferredAttrib::owner_created(RefEntity *new_owner, const int uid) 
00279 {
00280     // for a newly created ref entity, assigns any CADA with the same uid to the
00281     // new entity
00282 
00283     // get any CADAs with the same uid
00284   std::vector<CADeferredAttrib*> attrib_list;
00285   get_deferred_attribs(uid, attrib_list);
00286 
00287     // now assign them to the owner
00288   for (std::vector<CADeferredAttrib*>::iterator iter = attrib_list.begin();
00289        iter != attrib_list.end(); ++iter)
00290   {
00291     (*iter)->assign_to_owner(new_owner);
00292   }
00293 
00294   if (attrib_list.size() > 0) return CUBIT_SUCCESS;
00295   else return CUBIT_FAILURE;
00296 }
00297 /*
00298 CubitBoolean CADeferredAttrib::is_match(CubitSimpleAttrib *csa_ptr,
00299                                         const int uid)
00300 {
00301     //- returns true if the simple attribute is deferred type and matches
00302     //- uid
00303   assert(csa_ptr && uid > 0);
00304   csa_ptr.string_data_list()->reset();
00305   csa_ptr.string_data_list()->step();
00306   csa_ptr.int_data_list()->reset();
00307   if (!strcmp(csa_ptr.string_data_list()->get()->c_str(),
00308               CGMApp::instance()->attrib_manager()->att_internal_name(CA_DEFERRED_ATTRIB)) &&
00309       *csa_ptr.int_data_list()->get() == uid)
00310     return CUBIT_TRUE;
00311   else
00312     return CUBIT_FALSE;
00313 }
00314 */
00315 
00316 
00317 CubitSimpleAttrib CADeferredAttrib::csa_from_dcsa(const CubitSimpleAttrib &csa_ptr,
00318                                                    const int uid)
00319 {
00320   
00321     //- given a deferred csa, convert it to a normal csa by removing
00322     //- first type string and first int; if first int doesn't match
00323     //- uid passed in, NULL is returned
00324   if (csa_ptr.string_data_list()[0] != CGMApp::instance()->attrib_manager()->att_internal_name(CA_DEFERRED_ATTRIB))
00325       // csa isn't deferred type - return
00326     return CubitSimpleAttrib();
00327 
00328   if (uid != 0 && csa_ptr.int_data_list()[0] != uid)
00329       // csa uid doesn't match - return
00330     return CubitSimpleAttrib();
00331 
00332   CubitSimpleAttrib c = csa_ptr;
00333   c.string_data_list().erase(c.string_data_list().begin());
00334   c.int_data_list().erase(c.int_data_list().begin());
00335 
00336     // else we have a match - build new csa
00337   return c;
00338 }
00339 
00340 bool CADeferredAttrib::add_unactuated_ca(CubitAttrib *ca_ptr) 
00341 {
00342   std::vector<CubitAttrib*>::iterator iter = std::find(unactuatedCAs.begin(), unactuatedCAs.end(), ca_ptr);
00343   if(iter == unactuatedCAs.end())
00344   {
00345     unactuatedCAs.push_back(ca_ptr);
00346     return true;
00347   }
00348   return false;
00349 }
00350 
00351 bool CADeferredAttrib::remove_unactuated_ca( CubitAttrib* ca_ptr )
00352 {
00353   std::vector<CubitAttrib*>::iterator iter = std::find(unactuatedCAs.begin(), unactuatedCAs.end(), ca_ptr);
00354   if(iter != unactuatedCAs.end())
00355   {
00356     *iter = NULL;
00357     return true;
00358   }
00359   return false;
00360 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines