objectclass.cc~
来自「certi-SHM-3.0.tar 不错的开源的分布式方针软件 大家多多支持 他」· CC~ 代码 · 共 1,185 行 · 第 1/3 页
CC~
1,185 行
// -*- mode:C++ ; tab-width:4 ; c-basic-offset:4 ; indent-tabs-mode:nil -*-// ----------------------------------------------------------------------------// 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.12 2003/03/04 09:47:04 breholee Exp $// ----------------------------------------------------------------------------#include "ObjectClass.hh"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->LevelID = 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 == m_REFLECT_ATTRIBUTE_VALUES) || (ocbList->message->type == m_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 m_DISCOVER_OBJECT: case m_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) == RTI_TRUE) { ocbList->addFederate(federate); } } } break ; case m_REFLECT_ATTRIBUTE_VALUES: case m_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 ; printf("avant getSocketLink dans sendToFederate\n"); 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, TypeNetworkMessage 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(void) : handle(0), Father(0), server(NULL), Depth(0), Name(NULL), LevelID(PublicLevelID), MaxSubscriberHandle(0){}// ----------------------------------------------------------------------------//! ObjectClass destructor (frees allocated memory).ObjectClass::~ObjectClass(void){ 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 theFederateHandle, ObjectHandle theObjectHandle, const char *theUserTag) throw (DeletePrivilegeNotHeld, ObjectNotKnown, RTIinternalError){ // 1. Pre-conditions checking(may throw ObjectNotKnown) Object *object = getInstanceWithID(theObjectHandle); // Is the Federate really the Object Owner?(Checked only on RTIG) if ((server != NULL) && (object->Owner != theFederateHandle)) { D.Out(pdExcept, "Delete Object %d: Federate %d not owner.", theObjectHandle, theFederateHandle); throw DeletePrivilegeNotHeld(); } // 2. Remove Instance list<Object *>::iterator o ; list<Object *>::iterator tmp ; for (o = objectSet.begin(); o != objectSet.end(); o++) { if ((*o)->getHandle() == theObjectHandle) { tmp = o ; tmp-- ; delete (*o); objectSet.erase(o); // i is dereferenced. o = tmp ; // loop will increment o // A break may be enough ?! } } // 3. Prepare and broadcast message. ObjectClassBroadcastList *ocbList = NULL ; if (server != NULL) { D.Out(pdRegister, "Object %u deleted in class %u, now broadcasting...", theObjectHandle, handle); NetworkMessage *answer = new NetworkMessage ; answer->type = m_REMOVE_OBJECT ; answer->federation = server->federation(); answer->federate = theFederateHandle ; answer->exception = e_NO_EXCEPTION ; answer->objectClass = handle ; // Class Handle answer->object = theObjectHandle ; strcpy(answer->label, theUserTag); ocbList = new ObjectClassBroadcastList(answer, 0); broadcastClassMessage(ocbList); } else { D.Out(pdRegister, "Object %u deleted in class %u, no broadcast to do.", theObjectHandle, 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(void) 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(); } // Display Instances cout << " " << objectSet.size() << " Instances(s):" << endl ; list<Object *>::const_iterator o ; for (o = objectSet.begin(); o != objectSet.end(); o++) { (*o)->display(); }}// ----------------------------------------------------------------------------//! getAttributeHandle.AttributeHandleObjectClass::getAttributeHandle(const char *the_name) const throw (AttributeNotDefined, RTIinternalError){ list<ObjectClassAttribute *>::const_iterator a ; for (a = attributeSet.begin(); a != attributeSet.end(); a++) { if (strcmp((*a)->getName(), the_name) == 0) return (*a)->getHandle(); } D.Out(pdExcept, "ObjectClass %u: Attribute \"%s\" not defined.", handle, the_name); throw AttributeNotDefined();}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?