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

📄 federation.cc

📁 分布式仿真 开放源码
💻 CC
📖 第 1 页 / 共 4 页
字号:
// ----------------------------------------------------------------------------// CERTI - HLA RunTime Infrastructure// Copyright (C) 2002, 2003, 2004  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.37 2004/03/04 20:19:04 breholee Exp $// ----------------------------------------------------------------------------#include <config.h>#include "Federation.hh"#include "fed.hh"#include "XmlParser.hh"#include "ObjectClassAttribute.hh"#include "PrettyDebug.hh"#include <map>#include <fstream>#include <iostream>#include <string.h>#include <sys/stat.h>#include <errno.h>using std::pair ;using std::ifstream ;using std::ios ;using std::cout ;using std::endl ;using std::string ;using std::list ;using std::cerr ;using std::vector ;// Definitions#ifdef HAVE_XML#define ROOT_NODE (const xmlChar*) "rtigSaveData"#define NODE_FEDERATION (const xmlChar*) "federation"#define NODE_FEDERATE (const xmlChar*) "federate"#endif // HAVE_XMLnamespace certi {class XmlParser ;namespace rtig {static PrettyDebug D("FEDERATION", __FILE__);// ----------------------------------------------------------------------------//! 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,                           Handle federation_handle,                           SocketServer *socket_server,                           AuditFile *audit_server)#endif    throw (CouldNotOpenRID, ErrorReadingRID, MemoryExhausted, SecurityError,           RTIinternalError)    : federateHandles(1), objectHandles(1), saveInProgress(false),      restoreInProgress(false), saveStatus(true), restoreStatus(true),      verbose(true){    //    fedparser::FedParser *fed_reader ;#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);    // Default Attribute values    handle = federation_handle ;    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);    cout << "New federation: " << name << endl ;    cout << "Looking for .fed file... " ;    string filename = string(name) + ".fed" ;    ifstream fdd(filename.c_str());    if (fdd.is_open()) {	fdd.close();        cout << "yes" << endl ;	int err = fedparser::build(filename.c_str(), root, verbose);	if (err) throw ErrorReadingFED();	            // Retrieve the FED file last modification time(for Audit)        struct stat StatBuffer ;        char *MTimeBuffer ;        if (stat(filename.c_str(), &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.open(filename.c_str());            if (fdd.is_open()) {		fdd.close();                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 ;            }            else {                cout << "no" << endl ;		throw CouldNotOpenFED();	    }        }    }}// ----------------------------------------------------------------------------// 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}// ----------------------------------------------------------------------------//! Returns the number of federates in federation.intFederation::getNbFederates() const{    return size();}// ----------------------------------------------------------------------------//! Return true if federation is being synchronized.boolFederation::isSynchronizing() const{    return !synchronizationLabels.empty();}// ----------------------------------------------------------------------------//! Returns the federation handle.HandleFederation::getHandle() const{    return handle ;}// ----------------------------------------------------------------------------//! Returns the federation name given in 'Create Federation Execution'.const char *Federation::getName() const{    return name ;}// ----------------------------------------------------------------------------//! Returns the number of federates regulator.intFederation::getNbRegulators() 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 = federateHandles.provide();    Federate *federate = new Federate(federate_name, federate_handle);    push_front(federate);    D.Out(pdInit, "Federate %d joined Federation %d.", federate_handle, handle);    // Send, to the newly added federate, a Null message from each regulating    // federate (i) with their logical time h(i). This permits to calculate    // its LBTS.    NetworkMessage message ;    try {        for (unsigned int i = 1 ; i <= regulators.size(); ++i) {            message.type = NetworkMessage::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 = NetworkMessage::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 = NetworkMessage::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[pdExcept] << "Reference to a killed Federate while "                            << "broadcasting." << endl ;            }            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,

⌨️ 快捷键说明

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