⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 objectclass.cc

📁 分布式仿真 开放源码
💻 CC
📖 第 1 页 / 共 3 页
字号:
// ----------------------------------------------------------------------------// CERTI - HLA RunTime Infrastructure// Copyright (C) 2002, 2003  ONERA//// This file is part of CERTI-libCERTI//// CERTI-libCERTI is free software ; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public License// as published by the Free Software Foundation ; either version 2 of// the License, or (at your option) any later version.//// CERTI-libCERTI is distributed in the hope that it will be useful, but// WITHOUT ANY WARRANTY ; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public// License along with this program ; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307// USA//// $Id: ObjectClass.cc,v 3.21 2004/03/04 20:19:05 breholee Exp $// ----------------------------------------------------------------------------#include <config.h>#include "ObjectClass.hh"#include "ObjectClassAttribute.hh"#include "SocketTCP.hh"#include "PrettyDebug.hh"#include <iostream>#include <assert.h>using std::cout ;using std::endl ;using std::list ;namespace certi {static pdCDebug D("OBJECTCLASS", "(ObjClass) - ");// ----------------------------------------------------------------------------//! To be used only by CRead, it returns the new Attribute's Handle.AttributeHandleObjectClass::addAttribute(ObjectClassAttribute *theAttribute,                          Boolean is_inherited){    if (theAttribute == NULL)        throw RTIinternalError("Tried to add NULL attribute.");    theAttribute->setHandle(attributeSet.size() + 1);    theAttribute->server = server ;    // If the attribute is inherited, it keeps its security level.    // If not, it takes the default security level of the class.    if (is_inherited != RTI_TRUE)        theAttribute->level = LevelID ;    attributeSet.push_front(theAttribute);    D.Out(pdProtocol, "ObjectClass %u has a new attribute %u.",          handle, theAttribute->getHandle());    return theAttribute->getHandle();}// ----------------------------------------------------------------------------//! Add the class' attributes to the 'Child' Class.voidObjectClass::addAttributesToChild(ObjectClass *the_child){    // The Attribute List is read backwards to respect the same attribute order    // for the child(Attributes are inserted at the beginning of the list).    ObjectClassAttribute *childAttribute = NULL ;    list<ObjectClassAttribute *>::reverse_iterator a ;    for (a = attributeSet.rbegin(); a != attributeSet.rend(); a++) {        assert((*a) != NULL);        childAttribute = new ObjectClassAttribute(*a);        assert(childAttribute != NULL);        D.Out(pdProtocol,              "ObjectClass %u adding new attribute %d to child class %u.",              handle, (*a)->getHandle(), the_child->getHandle());        the_child->addAttribute(childAttribute);        if (childAttribute->getHandle() != (*a)->getHandle())            throw RTIinternalError("Error while copying child's attributes.");    }}// ----------------------------------------------------------------------------/*! Take a Broadcast List and continue to send messages. You should  take a look at ObjectClassSet::RegisterObject to understand  what is going on...*/voidObjectClass::broadcastClassMessage(ObjectClassBroadcastList *ocbList){    // 1. Set ObjectHandle to local class Handle.    ocbList->message->objectClass = handle ;    // 2. Update message attribute list by removing child's attributes.    if ((ocbList->message->type == NetworkMessage::REFLECT_ATTRIBUTE_VALUES) ||        (ocbList->message->type == NetworkMessage::REQUEST_ATTRIBUTE_OWNERSHIP_ASSUMPTION)) {        int attr = 0 ;        while (attr < ocbList->message->handleArraySize) {            // If the attribute is not in that class, remove it from            // the message.            try {                getAttributeWithHandle(ocbList->message->handleArray[attr]);                attr++ ;            }            catch (AttributeNotDefined &e) {                ocbList->message->removeAttribute(attr);            }        }    }    // 3. Add class/attributes subscribers to the list.    switch(ocbList->message->type) {      case NetworkMessage::DISCOVER_OBJECT:      case NetworkMessage::REMOVE_OBJECT: {          // For each federate, add it to list if at least one attribute has          // been subscribed.          FederateHandle federate = 0 ;          for (federate = 1 ; federate <= MaxSubscriberHandle ; federate++) {              if (isFederateSubscriber(federate)) {                  ocbList->addFederate(federate);              }          }      } break ;      case NetworkMessage::REFLECT_ATTRIBUTE_VALUES:      case NetworkMessage::REQUEST_ATTRIBUTE_OWNERSHIP_ASSUMPTION: {          // For each class attribute, update the list be adding federates who          // subscribed to the attribute.          list<ObjectClassAttribute *>::const_iterator a ;          for (a = attributeSet.begin(); a != attributeSet.end(); a++) {              (*a)->updateBroadcastList(ocbList);          }      } break ;      default:        throw RTIinternalError("BroadcastClassMsg: Unknown type.");    }    // 4. Send pending messages.    ocbList->sendPendingMessage(server);}// ----------------------------------------------------------------------------//! sendToFederate.voidObjectClass::sendToFederate(NetworkMessage *msg, FederateHandle theFederate){    // Send the message 'msg' to the Federate which Handle is theFederate.    Socket *socket = NULL ;    try {#ifdef HLA_USES_UDP        socket = server->getSocketLink(theFederate, BEST_EFFORT);#else        socket = server->getSocketLink(theFederate);#endif        msg->write(socket);    }    catch (RTIinternalError &e) {        D.Out(pdExcept,              "Reference to a killed Federate while broadcasting.");    }    catch (NetworkError &e) {        D.Out(pdExcept, "Network error while broadcasting, ignoring.");    }    // BUG: If except = 0, could use Multicast.}// ----------------------------------------------------------------------------//! sendToOwners.voidObjectClass::sendToOwners(CDiffusion *diffusionList,                          ObjectHandle theObjectHandle,                          FederateHandle theFederate,                          const char *theTag,                          NetworkMessage::Type type){    int nbAttributes = diffusionList->size ;    FederateHandle toFederate ;    for (int i = 0 ; i < nbAttributes ; i++) {        toFederate = diffusionList->DiffArray[i].federate ;        if (toFederate != 0) {            NetworkMessage *answer = new NetworkMessage ;            answer->type = type ;            answer->federation = server->federation();            answer->federate = theFederate ;            answer->exception = e_NO_EXCEPTION ;            answer->object = theObjectHandle ;            strcpy(answer->label, theTag);            int index = 0 ;            for (int j = i ; j < nbAttributes ; j++) {                if (diffusionList->DiffArray[j].federate == toFederate) {                    D.Out(pdDebug, "handle : %u",                          diffusionList->DiffArray[j].attribute);                    diffusionList->DiffArray[j].federate = 0 ;                    answer->handleArray[index] = diffusionList                        ->DiffArray[j].attribute ;                    index++ ;                }            }            answer->handleArraySize = index ;            D.Out(pdDebug, "Envoi message type %u ", type);            sendToFederate(answer, toFederate);        }    }}// ----------------------------------------------------------------------------/*! Throw SecurityError if the Federate is not allowed to access the  Object Class, and print an Audit message containing reason.*/voidObjectClass::checkFederateAccess(FederateHandle the_federate,                                 const char *reason)    throw (SecurityError){    D.Out(pdInit, "Beginning of CheckFederateAccess for the federate %d",          the_federate);    // BUG: Should at least but a line in Audit    if (server == NULL)        return ;    Boolean result = server->canFederateAccessData(the_federate, LevelID);    // BUG: Should use Audit.    if (result != RTI_TRUE) {        cout << "Object Class " << handle << " : SecurityError for federate "             << the_federate << '(' << reason << ")." << endl ;        throw SecurityError("Federate should not access Object Class.");    }}// ----------------------------------------------------------------------------//! ObjectClass constructor (only one).ObjectClass::ObjectClass()    : Father(0), server(NULL), Depth(0), Name(NULL), handle(0),      LevelID(PublicLevelID), MaxSubscriberHandle(0){}// ----------------------------------------------------------------------------//! ObjectClass destructor (frees allocated memory).ObjectClass::~ObjectClass(){    if (Name != NULL) {        free(Name);        Name = NULL ;    }    // Deleting instances    if (!objectSet.empty())        D.Out(pdError,              "ObjectClass %d : Instances remaining while exiting...", handle);    // while (!objectSet.empty()) {    // delete objectSet.front();    // objectSet.pop_front();    // }    // Deleting Class Attributes    while (!attributeSet.empty()) {        delete attributeSet.front();        attributeSet.pop_front();    }    // Deleting Sons    while (!sonSet.empty()) {        sonSet.pop_front();    }}// ----------------------------------------------------------------------------/*! Delete the object instance 'theObjectHandle', and starts to  broadcast the RemoveObject message. Return a BroadcastList of  Federates, in order to allow our ObjectClassSet to go on with  the message broadcasting, by giving the list to our parent  class.*/ObjectClassBroadcastList *ObjectClass::deleteInstance(FederateHandle the_federate,                            ObjectHandle the_object,                            const char *the_tag)    throw (DeletePrivilegeNotHeld,           ObjectNotKnown,           RTIinternalError){    // 1. Pre-conditions checking(may throw ObjectNotKnown)    Object *object = getInstanceWithID(the_object);    // Is the Federate really the Object Owner?(Checked only on RTIG)    if ((server != 0) && (object->getOwner() != the_federate)) {        D.Out(pdExcept, "Delete Object %d: Federate %d not owner.",              the_object, the_federate);        throw DeletePrivilegeNotHeld();    }    // 2. Remove Instance from list.    list<Object *>::iterator o ;    for (o = objectSet.begin(); o != objectSet.end(); o++) {        if ((*o)->getHandle() == the_object) {            objectSet.erase(o); // i is dereferenced.            break ;        }    }    // 3. Prepare and broadcast message.    ObjectClassBroadcastList *ocbList = NULL ;    if (server != NULL) {        D.Out(pdRegister,              "Object %u deleted in class %u, now broadcasting...",              the_object, handle);        NetworkMessage *answer = new NetworkMessage ;        answer->type = NetworkMessage::REMOVE_OBJECT ;        answer->federation = server->federation();        answer->federate = the_federate ;        answer->exception = e_NO_EXCEPTION ;        answer->objectClass = handle ; // Class Handle        answer->object = the_object ;        strcpy(answer->label, the_tag);        ocbList = new ObjectClassBroadcastList(answer, 0);        broadcastClassMessage(ocbList);    }    else {        D.Out(pdRegister,              "Object %u deleted in class %u, no broadcast to do.",              the_object, handle);    }    // Return the BroadcastList in case it had to be passed to the parent    // class.    return ocbList ;}// ----------------------------------------------------------------------------//! Print the ObjectClasses tree to the standard output.void ObjectClass::display() const{    cout << " ObjectClass #" << handle << " \"" << Name << "\":" << endl ;    // Display inheritance    cout << " Parent Class Handle: " << Father << endl ;    cout << " Security Level: " << LevelID << endl ;    cout << " " << sonSet.size() << " Child(s):" << endl ;    list<ObjectClassHandle>::const_iterator s = sonSet.begin();    for (int i = 1 ; s != sonSet.end(); s++, i++) {        cout << " Son " << i << " handle: "<< (*s) << endl ;    }    // Display Attributes    cout << " " << attributeSet.size() << " Attribute(s):" << endl ;    list<ObjectClassAttribute *>::const_iterator a ;    for (a = attributeSet.begin(); a != attributeSet.end(); a++) {        (*a)->display();    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -