📄 federation.cc~
字号:
// -*- 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//// CERTI is free software ; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation ; either version 2 of the License, or// (at your option) any later version.//// CERTI 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 General Public License for more details.//// You should have received a copy of the GNU 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: Federation.cc,v 3.12 2003/03/21 15:06:46 breholee Exp $// ----------------------------------------------------------------------------#include "Federation.hh"namespace certi {class XmlParser ;namespace rtig {static pdCDebug D("FEDERATION", "(Fed.tion) - ");// ----------------------------------------------------------------------------//! Constructor/*! Allocates memory the Name's storage, and read its FED file to store the result in RootObj.*/#ifdef FEDERATION_USES_MULTICASTFederation::Federation(const char *federation_name, FederationHandle federation_handle, SocketServer *socket_server, AuditFile *audit_server, SocketMC *mc_link)#else Federation::Federation(const char *federation_name, FederationHandle federation_handle, SocketServer *socket_server, AuditFile *audit_server)#endif throw (CouldNotOpenRID, ErrorReadingRID, MemoryExhausted, SecurityError, RTIinternalError) : list<Federate *>(){ fedparser::FedParser *fed_reader ; char file_name[MAX_FEDERATION_NAME_LENGTH + 5] ;#ifdef FEDERATION_USES_MULTICAST // ----------------- // Initialize Multicast if (mc_link == NULL) { D.Out(pdExcept, "Null Multicast socket for new Federation."); throw RTIinternalError("NULL Multicast socket for new Federation."); } D.Out(pdInit, "New Federation %d will use Multicast.", federation_handle); MCLink = mc_link ;#endif // FEDERATION_USES_MULTICAST // -------------- // Allocates Name if ((federation_name == 0) || (federation_handle == 0)) throw RTIinternalError("Null init parameter in Federation creation."); if (strlen(federation_name) > MAX_FEDERATION_NAME_LENGTH) throw RTIinternalError("Federation name too long."); name = strdup(federation_name); if (name == 0) throw MemoryExhausted("No memory left for Federation Name."); // Default Attribute values handle = federation_handle ; nextObjectId = (ObjectHandle) 1 ; nextFederateHandle = (FederateHandle) 1 ; D.Out(pdInit, "New Federation created with Handle %d, now reading FOM.", handle); // Initialize the Security Server. server = new SecurityServer(socket_server, audit_server, handle); if (server == NULL) throw RTIinternalError(); // Read FOM File to initialize Root Object. root = new RootObject(server); if (root == 0) throw MemoryExhausted("No memory left for Federation Root Object."); cout << "New federation: " << name << endl ; cout << "Looking for .fed file... " ; string filename = string(name) + ".fed" ; ifstream *fdd = new ifstream(filename.c_str()); if (fdd->is_open()) { cout << "yes" << endl ; fed_reader = new fedparser::FedParser(root); if (fed_reader == 0) throw MemoryExhausted("No memory left to read FED file."); server->Audit->addToLinef(", Fed File : %s", filename.c_str()); try { fed_reader->readFile(filename.c_str()); } catch (Exception *e) { delete fed_reader ; delete server ; server = NULL ; delete root ; root = NULL ; throw e ; } delete fed_reader ; delete fdd ; // Retrieve the FED file last modification time(for Audit) struct stat StatBuffer ; char *MTimeBuffer ; if (stat(file_name, &StatBuffer) == 0) { MTimeBuffer = ctime(&StatBuffer.st_mtime); MTimeBuffer[strlen(MTimeBuffer) - 1] = 0 ; // Remove trailing \n server->Audit->addToLinef("(Last modified %s)", MTimeBuffer); } else server->Audit->addToLinef("(could not retrieve last modif time, " "errno %d).", errno); } else { cout << "no" << endl ; if (XmlParser::exists()) { cout << "Looking for .xml file... " ; filename = string(name) + ".xml" ; fdd = new ifstream(filename.c_str()); if (fdd->is_open()) { cout << "yes" << endl ; XmlParser *parser = new XmlParser(root); server->Audit->addToLinef(", XML File : %s", filename.c_str()); try { parser->parse(filename); } catch (Exception *e) { delete parser ; delete server ; server = NULL ; delete root ; root = NULL ; throw e ; } delete parser ; delete fdd ; } else cout << "no" << endl ; } }}// ----------------------------------------------------------------------------// DestructorFederation::~Federation(){ D.Out(pdInit, "Destroying Federation %d...", handle); // If there are Federates, delete them all! for (list<Federate *>::const_iterator i = begin(); i != end(); i++) { delete(*i); } clear(); // Free local allocations free(name); delete root ; delete server ;#ifdef FEDERATION_USES_MULTICAST FermerConnexion(mc_link); delete mc_link ;#endif}// ----------------------------------------------------------------------------// Get attributesintFederation::getNbFederates(void) const{ return size();}// ----------------------------------------------------------------------------//! Return true if federation is being synchronized.boolFederation::isSynchronizing(void) const{ return !synchronizationLabels.empty();}// ----------------------------------------------------------------------------FederationHandleFederation::getHandle(void) const{ return handle ;}// ----------------------------------------------------------------------------//! getName.const char *Federation::getName(void) const{ return name ;}intFederation::getNbRegulators(void) const{ return regulators.size();}// ----------------------------------------------------------------------------/*! Add the Federate to the Federation, and return its new federate handle. MAX_FEDERATE is the maximum number of federates per federation. Also send Null messages from all others federates to initialize its LBTS, and finally a RequestPause message if the Federation is already paused.*/FederateHandleFederation::add(const char *federate_name, SocketTCP *tcp_link) throw (FederateAlreadyExecutionMember, MemoryExhausted, RTIinternalError){ if (federate_name == 0) { D.Out(pdExcept, "Tried to add a NULL named federate."); throw RTIinternalError("Tried to add NULL federate to federation."); } if (size() >= MAX_FEDERATE) { D.Out(pdExcept, "Federation %d has too many Federates.", handle); throw RTIinternalError("Too many federates in federation."); } try { this->getByName(federate_name); throw FederateAlreadyExecutionMember(); } catch (FederateNotExecutionMember &e) { // Nothing to do. } FederateHandle federate_handle = getNewHandle(); Federate *federate = new Federate(federate_name, federate_handle); push_front(federate); D.Out(pdInit, "Federate %d joined Federation %d.", federate_handle, handle); // Donner au nouveau federe un dernier message nul // de chaque federe(i) contenant son heure logique h(i) // pour que le nouveau puisse calculer son LBTS. NetworkMessage message ; try { for (int i = 1 ; i <= regulators.size(); i++) { message.type = m_MESSAGE_NULL ; message.federation = handle ; regulators.get(i, message.federate, message.date); D.Out(pdTerm, "Sending NULL message(type %d) from %d to new federate.", message.type, message.federate); message.write(tcp_link); } // If federation is synchronizing, put federate in same state. if (isSynchronizing()) { message.type = m_ANNOUNCE_SYNCHRONIZATION_POINT ; message.federate = federate_handle ; message.federation = handle ; std::map<const char *, const char *>::const_iterator i ; i = synchronizationLabels.begin(); for (; i != synchronizationLabels.end(); i++) { message.setLabel((*i).first); message.setTag((*i).second); D.Out(pdTerm, "Sending synchronization message %s (type %d)" " to the new Federate.", (*i).first, message.type); message.write(tcp_link); federate->addSynchronizationLabel((*i).first); } } } catch (NetworkError) { throw RTIinternalError("Network Error while initializing federate."); } return federate_handle ;}// ----------------------------------------------------------------------------// Set Federate's attribute IsConstrained to true./*! FIXME: name/ merge with removeConstrained. */voidFederation::addConstrained(FederateHandle federate_handle) throw (FederateNotExecutionMember, SaveInProgress, RestoreInProgress, RTIinternalError){ // It may throw FederateNotExecutionMember Federate *federate = getByHandle(federate_handle); if (federate->isConstrained()) { D.Out(pdExcept, "Federate %d already constrained.", federate_handle); throw RTIinternalError("Time Regulating already enabled."); } federate->setConstrained(true); D.Out(pdTerm, "Federation %d: Federate %d is now constrained.", handle, federate_handle);}// ----------------------------------------------------------------------------//! Add the Federate to the Regulators List./*! Check if it's already present, but not if the Time 'theTime' is allowed or not.*/voidFederation::addRegulator(FederateHandle federate_handle, FederationTime time) throw (FederateNotExecutionMember, SaveInProgress, RestoreInProgress, RTIinternalError){ // It may throw FederateNotExecutionMember Federate *federate = getByHandle(federate_handle); // It may throw RTIinternalError if Federate was not regulators. regulators.insert(federate_handle, time); federate->setRegulator(true); D.Out(pdTerm, "Federation %d: Federate %d is now a regulator(Time=%f).", handle, federate_handle, time); NetworkMessage msg ; msg.type = m_SET_TIME_REGULATING ; msg.exception = e_NO_EXCEPTION ; msg.federation = handle ; msg.federate = federate_handle ; msg.regulator = RTI_TRUE ; msg.date = time ; this->broadcastAnyMessage(&msg, 0);}// ----------------------------------------------------------------------------//! Broadcast 'msg' to all Federate except the one whose Handle is 'Except'.voidFederation::broadcastAnyMessage(NetworkMessage *msg, FederateHandle except_federate){ Socket *socket = NULL ; // Broadcast the message 'msg' to all Federates in the Federation // except to Federate whose Handle is 'Except_Federate'. for (list<Federate *>::const_iterator i = begin(); i != end(); i++) { if ((*i)->getHandle() != except_federate) { try {#ifdef HLA_USES_UDP socket = server->getSocketLink((*i)->getHandle(), BEST_EFFORT);#else socket = server->getSocketLink((*i)->getHandle());#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.}// ----------------------------------------------------------------------------//! broadcastInteractionvoidFederation::broadcastInteraction(FederateHandle federate_handle, InteractionClassHandle interaction, ParameterHandle *parameter_handles, ParameterValue *parameter_values, UShort list_size, FederationTime time, const char *tag) throw (FederateNotExecutionMember, FederateNotPublishing, InteractionClassNotDefined, InteractionParameterNotDefined, SaveInProgress,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -