Main Page | Modules | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

hlaobjectinstance.h

Go to the documentation of this file.
00001 #ifndef HLA_OBJECT_INSTANCE_H_
00002 #define HLA_OBJECT_INSTANCE_H_
00003 
00004 #include "base/cleancontainers.h"
00005 #include <queue>
00006 
00007 #include "ftk.h"
00008 #include "base/msftypes.h"
00009 
00010 // forward declaration
00011 class HLAObjectClass;
00012 class InstanceClient;
00013 class MessageClient;
00014 class MethodMessage;
00015 
00016 /**
00017  * This class represents an instance of an HLA object.
00018  * @ingroup ftk
00019  */
00020 class HLAObjectInstance
00021 {
00022   public:
00023     /** 
00024      * Constructor - creates an object instance of class @a clname.
00025      *
00026      * This constructor is used by a federate which wants to create
00027      * its own local objects in order to register them with the RFI
00028      * (by using RFI::registerObjectInstance()).
00029      *
00030      * @see               RFI::registerObjectInstance()
00031      */
00032     HLAObjectInstance (const char* clname);
00033       
00034     /** 
00035      * Contructor - creates an object instance having an object handle
00036      * and an HLAObjectClass.
00037      *
00038      * This constructor is used by the Federate Ambassador when it
00039      * discovers an object and wants to add it to the local object list
00040      * (by using RFI::addObjectInstance()). 
00041      *
00042      * @see               RFI::addObjectInstance()
00043      */
00044     HLAObjectInstance (ftk::HANDLE objHandle, ftk::HANDLE classHandle);
00045 
00046     /** 
00047      * Destructor.
00048      *
00049      * Does some cleaning and removes the object instance from the
00050      * federation. 
00051      */
00052     virtual ~HLAObjectInstance (void);
00053 
00054     /** 
00055      * Removes this object from the Federation. 
00056      */
00057     void removeFromFederation (void);
00058 
00059     /** 
00060      * Returns the class (HLAObjectClass) of the object instance.
00061      */
00062     HLAObjectClass* getObjectClass (void);
00063 
00064     /** 
00065      * Returns the class handle for this object instance. 
00066      */
00067     ftk::HANDLE classHandleGet (void);
00068       
00069     /** 
00070      * Returns the class name of this object instance.
00071      */
00072     const char* classNameGet (void);
00073 
00074     /** 
00075      * Sets the handle for this object instance.
00076      * 
00077      * This should be done only by a method which get this handle
00078      * from the RTI. 
00079      */
00080     void handleSet (ftk::HANDLE id);
00081 
00082     /** 
00083      * Returns the handle for this object instance. 
00084      */
00085     ftk::HANDLE handleGet (void);
00086 
00087     /** 
00088      * Sets boolean defining whether or not this object has been 
00089      * discovered.
00090      *
00091      * @param d           @c true signifies that this object has been
00092      *                    discovered.
00093      *                    @c false signifies that this object has been
00094      *                    created by this federate.
00095      */
00096     void discovered (bool d);
00097 
00098     /** 
00099      * Tests whether or not this object has been discovered.
00100      *
00101      * @return            @c true if this object has been discovered by
00102      *                    the federate, @c false if this object was
00103      *                    created by the federate itself. 
00104      */
00105     bool discovered (void);
00106 
00107     /** Mark the instance as zombie or not. 
00108      * An instance is considered as zombie when it still exist in the LRC, but
00109      * not in the RTIexec database. This situation typically occurs after a 
00110      * reset. A zombie instance will not try to remove itself from the 
00111      * federation a destruction. */
00112     void zombie(bool z);
00113 
00114     /** Return the zombie state of the instance (see above method). */
00115     bool zombie();
00116 
00117     bool isAttributeInitialized(ftk::ATTRIBUTE_INDEX index);
00118 
00119     bool isAttributeInitialized(ftk::HANDLE h) {
00120   map<ftk::HANDLE, bool>::iterator it = initialized_attributes.find(h);
00121   if ( it != initialized_attributes.end() ) return (*it).second;
00122   else return false;
00123     }
00124 
00125     /** 
00126      * Returns the data corresponding to the given handle.
00127      *
00128      * This method is purely virtual and has to be implemented by 
00129      * derived classes which know about the queried data.
00130      *
00131      * @param h           attribute handle
00132      * @param data        reference to a pointer to a char buffer
00133      * @param size        the size of the buffer containing the desired
00134      *                    data
00135      * @warning           The caller of this function just provides a
00136      *                    pointer to the buffer. The memory for the data
00137      *                    should then be allocated. (In normal FTK usage
00138      *                    this is done by the XDRmessage.getBuffer(data)
00139      *                    call.) <b>But it is up to the caller to delete the
00140      *                    allocated memory.</b> 
00141      *
00142      * @see               HLAObjectInstance::processPendingUpdates() for
00143      *                    a correct example.
00144      */
00145     virtual bool getAttributeData (ftk::HANDLE h,
00146            char*& data, 
00147            unsigned int& size) = 0;
00148 
00149     /** 
00150      * Sets the data corresponding to a given handle.
00151      *
00152      * This method is purely virtual and has to be implemented by
00153      * derived classes: making this call causes the concerned sub-class
00154      * to set its correct data member (identified by h) with the given 
00155      * data.
00156      *
00157      * @param h           attribute handle
00158      * @param data        pointer to the buffer containing the data to
00159      *                    set
00160      * @param size        size of the data to set
00161      */
00162     virtual bool setAttributeData (ftk::HANDLE h,
00163            const char* data,
00164            unsigned int size) = 0;
00165 
00166     /** 
00167      * Pushes the request for an update for the attribute with the given
00168      * handle to a local queue.
00169      * Clients of this objectinstance will be notified that all updates
00170      * requests have been performed with the attributesInitialized callback.
00171      */
00172     // inline void queueAttributeRequest (ftk::HANDLE handle);
00173     void queueAttributeRequest (ftk::HANDLE handle);
00174 
00175     /** 
00176      * Pushes the action to update the attribute with the given handle to
00177      * a local queue. 
00178      */
00179     // inline void queueAttributeUpdate (ftk::HANDLE handle);
00180     void queueAttributeUpdate (ftk::HANDLE handle);
00181 
00182     /** 
00183      * Pushes the request to acquire the ownership of
00184      * the attribute with the given handle to a local queue. 
00185      * Clients of this objectinstance will be notified that all acquisitions
00186      * requests have been performed with the onwershipsAcquired callback.
00187      */
00188     // inline void queueAttributeAcquisition (ftk::HANDLE handle);
00189     void queueAttributeAcquisition (ftk::HANDLE handle);
00190 
00191     /** 
00192      * Pushes the action to release the ownership of 
00193      * the attribute with the given handle to a local queue. 
00194      */
00195     // inline void queueAttributeRelease (ftk::HANDLE handle);
00196     void queueAttributeRelease (ftk::HANDLE handle);
00197 
00198     /** 
00199      * Processes the pending update actions. 
00200      */
00201     int processPendingUpdates (void);
00202 
00203     /** 
00204      * Processes the pending update request(s). 
00205      */
00206     int processPendingRequests (void);
00207 
00208     /** 
00209      * Processes the pending ownership release(s). 
00210      */
00211     int processPendingReleases (void);
00212 
00213     /** 
00214      * Processes the pending ownership acquisitiions(s). 
00215      */
00216     int processPendingAcquisitions (void);
00217 
00218     /** 
00219      * Processes all the pending actions present in the local queues. 
00220      */
00221     int processPendings (unsigned char what);
00222 
00223     /** 
00224      * Sends a request for ownership of a given set of attributes to the
00225      * RTI.
00226      *
00227      * The attribute ownership acquisition is perfomed on the basis of 
00228      * the priority argument. The federate can acquire the attribute 
00229      * only if the given priority is higher than the priority that
00230      * the owning federate has given to this object class.
00231      */
00232     bool attributeOwnershipAcquisition (set<ftk::ATTRIBUTE_INDEX>& attr, 
00233           unsigned char priority);
00234 
00235     /** 
00236      * Unconditionally releases a set of attributes.
00237      */
00238     bool unconditionalAttributeOwnershipDivestiture (set<ftk::ATTRIBUTE_INDEX>& attr);
00239                    
00240     /** 
00241      * Sets a boolean defining whether or not an object is owned. 
00242      *
00243      * This call assigns the value of @c o to @b all the attributes
00244      * of this object.
00245      */
00246 //       void owned (bool o);
00247 
00248     /** 
00249      * Tests whether or not the attribute with the given handle is owned
00250      * by the federate. 
00251      *
00252      * @return            @c true if the attribute is owned by the 
00253      *                    federate, @c false otherwise
00254      */
00255     bool attributeOwned (ftk::HANDLE h);
00256 
00257     /** 
00258      * Sets the boolean defining whether or not the attribute with the
00259      * given handle is owned by the federate. 
00260      */
00261     void attributeOwned (ftk::HANDLE h, bool o);
00262 
00263     /** Return the number of clients this object instance has. */
00264     size_t getNumberOfClients();
00265 
00266     /** Set a new client of this object instance. 
00267      * Return false if the client is already in the list, true otherwise 
00268      * (after insertion). */
00269     bool addClient(MessageClient *client);
00270 
00271     /** Remove a client from the list of this object instance. 
00272      * Return false if the client was not in the list, false otherwise
00273      * (after deletion). */
00274     bool removeClient(MessageClient *client);
00275 
00276 
00277     bool addClient(InstanceClient *client);
00278 
00279     bool removeClient(InstanceClient *client);
00280 
00281     void notifyRemoval(void);
00282 
00283     /** Return a pointer on the first client of this object instance. */
00284     MessageClient* getFirstClient();
00285 
00286     /** Return a pointer on the next client of this object instance. */
00287     MessageClient* getNextClient();
00288 
00289     /** 
00290      * Tests whether or not the object instance has been marked as 
00291      * identified.
00292      *
00293      * "Identified" means that all the necessary attributes to completely
00294      * identify this object instance have been initialized.
00295      */
00296     bool isIdentified (void) {
00297   return _identified;
00298     }
00299 
00300     /** Returns if the object is ready to use or not.
00301      * The significance of ready is application dependent.
00302      */
00303     bool isReady(void) {
00304   return _ready;
00305     }
00306 
00307     /** 
00308      * Tests whether or not this object instance has been fully
00309      * initialized. 
00310      *
00311      * @return            @c true when all the attributes of this object 
00312      *                    have received at least one valid update,
00313      *                    @c false otherwise.
00314      */
00315     bool isComplete (void) {
00316   return _complete;
00317     }
00318 
00319     /** 
00320      * Tests whether or not this object instance has been represented by
00321      * this federate.
00322      *
00323      * "Represented" could be used for any purpose by the federate. 
00324      * Normally it is used to determine if the federate has created a
00325      * specific object to represent/manage its HLA equivalent. 
00326      */
00327     bool isRepresented (void) {
00328   return _represented;
00329     }
00330 
00331     /** Set the object as represented. */
00332     void setRepresented (void) {
00333   _represented = true;
00334     }
00335 
00336     void setIdentifierAttribute (ftk::HANDLE h);
00337 
00338     void addReadyRequiredAttribute (ftk::HANDLE h);
00339 
00340     /** This method will be called when the instance has been identified.
00341      * This is to derived classes of HLAObjectInstance to initiate this call 
00342      * (for example when it receive an relection for an identifier). The
00343      * method should be implemented by derived classes.
00344      */
00345     virtual void identified(void)  { /* do nothing */ };
00346 
00347     /** This method will be called when the instance is ready to use by a 
00348      * specific federate.
00349      */
00350     virtual void ready(void)  { /* do nothing */ };
00351 
00352     /** This method will be called when all the attributes of this instance
00353      * have been initialized.
00354      * This method is called from the HLAObjectInstance level: developper 
00355      * of derived classes does not have to initiate this call, but can
00356      * implement the method itself.
00357      */
00358     virtual void complete(void) { /* do nothing */ };
00359 
00360 #if defined(_MIPS_SIM)
00361 // Suppress REMARK 3201: The parameter "h" was never referenced.
00362 #pragma set woff 3201
00363 #endif
00364 
00365     /** This method will be called when the federateambassador process
00366      * an attribute reflection. */
00367     virtual void reflect(ftk::HANDLE h) { /* do nothing */ };
00368 
00369     /** This method could be implemented by derived classes to handle
00370      * message attached to an instance. */
00371     virtual void messageReceived(MethodMessage* msg) { /* do nothing */ };
00372 
00373 #if defined(_MIPS_SIM)
00374 #pragma reset woff 3201
00375 #endif
00376 
00377     /** Check if the attribute reflection satisfies any request and make
00378      * the object fully identified and propagate the attribute inside
00379      * the object and its clients. */
00380     void processReflection(ftk::HANDLE h);
00381       
00382     /** Check the status of pendinf acquisitions.
00383   Using the given handle, this method checks if after this ownership
00384   acquisition notification there is still pending acquisitions. If not,
00385   then the method will notify all clients that all the acquisitions
00386   requests have been satisfied (with onwershipsAcquired).
00387     */
00388     void checkPendingAcquisitions(ftk::HANDLE h);
00389 
00390     /** Set the full name of the entity */
00391     void nameSet(std::string name);
00392 
00393     /** Return the full name of the entity (with its hierachy).
00394   K9:HazCam:Physical -> K9:HazCam:Physical 
00395     */
00396     std::string nameGet() const;
00397 
00398     /** Return the short name of the entity.
00399   K9:HazCam:Physical -> Physical
00400     */
00401     std::string entityNameGet(void);
00402       
00403     /** Return the parent full name of the entity. 
00404   K9:HazCam:Physical -> K9:HazCam
00405     */
00406     std::string parentNameGet(void);
00407       
00408     /** Return the depth of the hierachy where this object is located.
00409   K9:HazCam:Physical -> 3
00410     */
00411     size_t hierachyLevelGet(void);
00412       
00413     /** Return the name of the parent at the given level.
00414   (K9:HazCam:Physical,1) -> K9
00415   (K9:HazCam:Physical,2) -> HazCam
00416   (K9:HazCam:Physical,3) -> Physical
00417     */
00418     std::string nameLevelGet(size_t level);
00419       
00420     virtual void print(ostream& w = cout);
00421     //##Documentation
00422     //## Set the time of the attribute update.
00423     void setAttributeTimestamp(
00424         //##Documentation
00425         //## RTI handle of the attribute
00426         ftk::HANDLE attributeHandle, 
00427         //##Documentation
00428         //## Time of the update.
00429         double timeStamp);
00430 
00431 
00432     //##Documentation
00433     //## Return the time of the most recent update or -1
00434     //## if there is no time stamp.
00435     double getAttributeTimestamp(
00436         //##Documentation
00437         //## RTI handle of the desired attribute.
00438         ftk::HANDLE attributeHandle);
00439 
00440   protected:
00441     /** 
00442      * Marks the attribute with the given handle as initialized, then
00443      * checks if all the attributes have been initialized, and if so,
00444      * marks this object as initialized.
00445      * @todo: This method should go in the private section and allow only
00446      * ftkfederateambassador to call it...
00447      */
00448     void checkInitializedAttributes (ftk::HANDLE h);
00449       
00450     /** Check the status of the pending updates.
00451   Using the given handle, this method checks if after this update
00452   there is still pending updates. If not, then the method will
00453   notify all clients that all the update requests have been
00454   satisfied (with attributesInitialized).
00455     */ 
00456     void checkPendingUpdates(ftk::HANDLE h);
00457 
00458     /** Pointer to the class of this object */
00459     HLAObjectClass* _objectClassPtr;
00460 
00461     /** The handle of this object instance (defined by the RTI). */
00462     ftk::HANDLE _objectHandle;
00463 
00464     /** full name of this object instance.
00465   this name should be unique among the  federation.
00466   this name contains the hierachy of objects. */
00467     std::string _name;
00468 
00469     /** name of the object instance without the full hierachy. */
00470     std::string _entityName;
00471 
00472     /** Full name of the parent of this object instance. */
00473     std::string _parentName;
00474 
00475     /** Depth of the hierachy */
00476     size_t _hierarchyLevel;
00477 
00478     /** A queue of the attributes to update.
00479      * This queue is needed because the RTI is not reentrant. Then if the 
00480      * federateAmbassador receive a request to update an attribute, then
00481      * the application can not call right away a method to the rtiAmbassador
00482      * to provide the requested update: the federateAmbassador put 
00483      * this update request in a queue which will then be processed outside
00484      * the federateAmbassador and then avoid the reentrant call to the RTI.
00485      * @todo              Continue comment editing from this point [MDW]
00486      */
00487     set<ftk::HANDLE> attributes2update;
00488 
00489     /** A queue of the attribute for which this object require updates. */
00490     queue<ftk::HANDLE> attributes2request;
00491 
00492     /** A queue of the attributes to release.
00493      * This queue is needed for the same reason than attributes2update.
00494      * In this case, we maintain a queue of all the attributes for which 
00495      * this federate should release the ownership. */
00496     queue<ftk::HANDLE> attributes2release;
00497 
00498     /** A queue of the attributes to acquire. */
00499     queue<ftk::HANDLE> attributes2acquire;
00500 
00501     /** This map maintained a list of the status of each attributes 
00502      * regarding their ownership.
00503      * A @c true value associated with a attribute handle means that this
00504      * attribute is owned by this federate, a @c false value mean that it 
00505      * is not owned by this federate. */
00506     map<ftk::HANDLE, bool> owned_attributes;
00507 
00508     /** List of clients of this message instance. */
00509     list<MessageClient*> _msgClients;
00510 
00511     /** Last returned client. */
00512     list<MessageClient*>::iterator _currentClient;
00513 
00514     list<InstanceClient*> _objClients;
00515 
00516     void markAttributeInitialized(ftk::HANDLE h);
00517       
00518   private:
00519     /** Define if this object been discovered (@ c true) or created by this
00520      * federate (@c false) */
00521     bool _discovered;
00522 
00523     /** Flag to store if this object instance is identified or not. */
00524     bool _identified;
00525 
00526     /** Flag to store if this object instance is ready to be used or not. */
00527     bool _ready;
00528 
00529     /** Flag to store if this object has been fully initialized or not */
00530     bool _complete;
00531 
00532     /** Flag to store if this object instance has been represented or not. */
00533     bool _represented;
00534 
00535     bool _zombie;
00536 
00537     /** This method extract information from the name: entityName, 
00538   parentName and hierachyLevel. */
00539     void parseName(void);      
00540 
00541     /** Handle of the attribute marking the instance as identified. */
00542     ftk::HANDLE _identifierHandle;
00543 
00544     /** Set of handles marking the instance as ready.*/
00545     set<ftk::HANDLE> _readyRequiredHandles;
00546 
00547     /** Map to store if the attributes of this object instance have 
00548      * been initialized or not. */
00549     map<ftk::HANDLE, bool> initialized_attributes;
00550 
00551     set<ftk::HANDLE> _pendingUpdates;
00552     set<ftk::HANDLE> _pendingAcquisitions;
00553     map<ftk::HANDLE,double> _timeStamps;
00554 
00555 
00556 };
00557 
00558 #endif // HLA_OBJECT_INSTANCE_H_
00559 

Generated on Thu Apr 7 18:20:12 2005 for MST API by  doxygen 1.4.1