#include "Station.h" #include "Simulation.h" #include "Player.h" #include "Otw.h" #include "NetworkIO.h" #include "basic/PairStream.h" #include "basic/Pair.h" #include "basic/Color.h" #include "basic/Number.h" #include "basic/units/Times.h" #include // #define NET_TIMING_TEST namespace Eaagles { namespace Simulation { static const unsigned int DEFAULT_FAST_FORWARD_RATE = 1; #ifdef WIN32 //============================================================================= // Windows Real-time thread //============================================================================= // Static variables static HANDLE hTcThread = 0; // Handle to our R/T Windows thread // DPG -- long term needs non-static solution //----------------------------------------------------------------------------- // tcThreadFunc() -- Time critical Thread function //----------------------------------------------------------------------------- static DWORD WINAPI tcThreadFunc(LPVOID lpParam) { Station* station = (Station*) lpParam; std::cout << "Thread: station = " << station << std::endl; double dt = 1.0/double(station->getRealTimeRate()); if (station->getRealTimePriority() > 0.5f) { // Get handles HANDLE process = GetCurrentProcess(); HANDLE thread = GetCurrentThread(); std::cout << "process handle = " << process << std::endl; std::cout << "thread handles = " << thread << ", " << hTcThread << std::endl; // Make our thread to real-time if (SetPriorityClass(process,REALTIME_PRIORITY_CLASS)) std::cout << "REALTIME_PRIORITY_CLASS set!" << std::endl; else std::cout << "REALTIME_PRIORITY_CLASS failed!" << std::endl; //// Make our thread to "time critical" if (SetThreadPriority(hTcThread,THREAD_PRIORITY_TIME_CRITICAL)) std::cout << "THREAD_PRIORITY_TIME_CRITICAL base set!" << std::endl; else std::cout << "THREAD_PRIORITY_TIME_CRITICAL base failed!" << std::endl; } // System Time of Day double simTime = 0.0; // Simulator time reference double startTime = 0.0; // Time of day (sec) run started std::cout << "Starting T/C main loop ..." << std::endl; int i = 0; while (!station->isShutdown()) { // --- // Time of day that the simulation run is starting // --- if (i == 0) { startTime = getComputerTime(); } // Update our simulation time reference (zero at start of run) if (i > 0) { simTime += dt; } // --- // Update TC Simulation // --- for (unsigned int jj = 0; jj < station->getFastForwardRate(); jj++) { station->tcFrame( LCreal(dt) ); } // --- // Wait for the start of the next frame // --- if (i > 0) { double time = getComputerTime(); // Actual run time (based on time of day) double t0 = (time - startTime); // Simulated run time at start of next frame double t1 = (simTime + dt); // How long should we sleep for double t = t1 - t0; int sleepFor = int(t*1000.0); // wait for the next frame if (sleepFor > 0) Sleep(sleepFor); //if ( ((i / 50) * 50) == i ) { // std::cout << "i,t0,t1= " << i << ", " << t0 << ", " << t1 << std::endl; //} } i++; } return 0; } #else //============================================================================= // Linux Real-time thread //============================================================================= #include #include //----------------------------------------------------------------------------- // tcThreadFunc() -- Time critical Thread function //----------------------------------------------------------------------------- static void* tcThreadFunc(void* lpParam) { Station* station = (Station*) lpParam; std::cout << "Thread: station = " << station << std::endl; double dt = 1.0/double(station->getRealTimeRate()); int sec0 = int(dt); int nsec0 = int((dt - double(sec0)) * 1000000000.0); pthread_cond_t cond = PTHREAD_COND_INITIALIZER; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; std::cout << "Starting T/C main loop ..." << std::endl; pthread_mutex_lock(&mutex); // System Time of Day double simTime = 0.0; // Simulator time reference struct timespec tp; clock_gettime(CLOCK_REALTIME,&tp); double startTime = double(tp.tv_sec) + double(tp.tv_nsec)/1000000000.0; int i = 0; while (!station->isShutdown()) { // --- // Update TC Simulation // --- for (unsigned int jj = 0; jj < station->getFastForwardRate(); jj++) { station->tcFrame( LCreal(dt) ); } // --- // update next frame time // --- tp.tv_nsec += nsec0; if (tp.tv_nsec >= 1000000000) { tp.tv_sec++; tp.tv_nsec -= 1000000000; } // --- // Wait for the start of the next frame // --- pthread_cond_timedwait(&cond, &mutex, &tp); i++; simTime += dt; { struct timespec tp0; clock_gettime(CLOCK_REALTIME,&tp0); double time = double(tp.tv_sec) + double(tp.tv_nsec)/1000000000.0; double stime = time - startTime; //if ( ((i / 50) * 50) == i ) { // std::cout << "tc=" << simTime << ", " << stime << std::endl; //} } } pthread_mutex_unlock(&mutex); return 0; } #endif #ifdef WIN32 //============================================================================= // Windows network thread //============================================================================= //----------------------------------------------------------------------------- // netThreadFunc() -- Network Thread function //----------------------------------------------------------------------------- static DWORD WINAPI netThreadFunc(LPVOID lpParam) { Station* station = (Station*) lpParam; std::cout << "Thread: station = " << station << std::endl; double dt = 1.0/double(station->getNetworkRate()); // System Time of Day double simTime = 0.0; // Simulator time reference double startTime = 0.0; // Time of day (sec) run started double refTime = 0.0; // Ref time std::cout << "Starting network main loop ..." << std::endl; int i = 0; while (!station->isShutdown()) { // --- // Time of day that the simulation run is starting // --- if (i == 0) { startTime = getComputerTime(); refTime = startTime; } // Update our simulation time reference (zero at start of run) double dt1 = dt; if (i > 0) { simTime += dt; double ctime = getComputerTime(); dt1 = ctime - refTime; refTime = ctime; } #ifdef NET_TIMING_TEST LARGE_INTEGER cFreq; QueryPerformanceFrequency(&cFreq); LONGLONG freq = cFreq.QuadPart; LARGE_INTEGER fcnt; QueryPerformanceCounter(&fcnt); LONGLONG startCnt = fcnt.QuadPart; #endif // --- // Update networks // --- { Basic::LcObject::SPtr networks( station->getNetworks() ); if (networks != 0) { Basic::LcList::Item* item = networks->getFirstItem(); while (item != 0) { Basic::LcPair* pair = (Basic::LcPair*)(item->getValue()); NetworkIO* p = (NetworkIO*)( pair->object() ); p->inputFrame( LCreal(dt1) ); // Input p->outputFrame( LCreal(dt1) ); // Output item = item->getNext(); } } } #ifdef NET_TIMING_TEST QueryPerformanceCounter(&fcnt); LONGLONG endCnt = fcnt.QuadPart; double dfreq = freq; double dcnt = endCnt - startCnt; double dtime = dcnt/dfreq; double dtime1 = ( dtime * 1000000.0 ); //std::cout << "dtime1 = " << dtime1 << "uS" << std::endl; //std::cout << dtime1 << std::endl; printf("%8.3f\n", ( dtime * 1000.0 )); #endif // --- // Wait for the start of the next frame // --- if (i > 0) { double time = getComputerTime(); // Actual run time (based on time of day) double t0 = (time - startTime); // Simulated run time at start of next frame double t1 = (simTime + dt); // How long should we sleep for double t = t1 - t0; int sleepFor = int(t*1000.0); // wait for the next frame if (sleepFor > 0) Sleep(sleepFor); } i++; } return 0; } #else //============================================================================= // Linux network thread //============================================================================= #include //----------------------------------------------------------------------------- // netThreadFunc() -- Network Thread function //----------------------------------------------------------------------------- static void* netThreadFunc(void* lpParam) { Station* station = (Station*) lpParam; std::cout << "Thread: station = " << station << std::endl; double dt = 1.0/double(station->getNetworkRate()); int sec0 = int(dt); int nsec0 = int((dt - double(sec0)) * 1000000000.0); pthread_cond_t cond = PTHREAD_COND_INITIALIZER; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; std::cout << "Starting network main loop ..." << std::endl; pthread_mutex_lock(&mutex); // System Time of Day double simTime = 0.0; // Simulator time reference struct timespec tp; clock_gettime(CLOCK_REALTIME,&tp); double startTime = double(tp.tv_sec) + double(tp.tv_nsec)/1000000000.0; int i = 0; while (!station->isShutdown()) { // --- // Update Networks // --- { Basic::LcObject::SPtr networks( station->getNetworks() ); if (networks != 0) { Basic::LcList::Item* item = networks->getFirstItem(); while (item != 0) { Basic::LcPair* pair = (Basic::LcPair*)(item->getValue()); NetworkIO* p = (NetworkIO*)( pair->object() ); p->inputFrame( LCreal(dt) ); // Input p->outputFrame( LCreal(dt) ); // Output item = item->getNext(); } } } // --- // update next frame time // --- tp.tv_nsec += nsec0; if (tp.tv_nsec >= 1000000000) { tp.tv_sec++; tp.tv_nsec -= 1000000000; } // --- // Wait for the start of the next frame // --- pthread_cond_timedwait(&cond, &mutex, &tp); i++; simTime += dt; { struct timespec tp0; clock_gettime(CLOCK_REALTIME,&tp0); double time = double(tp.tv_sec) + double(tp.tv_nsec)/1000000000.0; double stime = time - startTime; //if ( ((i / 50) * 50) == i ) { // std::cout << "net =" << simTime << ", " << stime << std::endl; //} } } pthread_mutex_unlock(&mutex); return 0; } #endif //============================================================================= // Station class //============================================================================= IMPLEMENT_SUBCLASS(Station,"Station") //------------------------------------------------------------------------------ // Slot table //------------------------------------------------------------------------------ BEGIN_SLOTTABLE(Station) "simulation", // 1: Simulation model "networks", // 2: List of Network models "otw", // 3: Out-The-Window (OTW) visual system [ Otw or Basic::LcPairStream ] "ownship", // 4: Player name of our ownship (primary) player "rtRate", // 5: Real-Time (time-critical) rate (Hz) (Basic::LcNumber, default: 50hz) "rtPriority", // 6: Real-Time (time-critical) thread priority (zero(0) is lowest, one(1) is highest) (Basic::LcNumber, default: 1 ) "netRate", // 7: Network thread rate (Hz) (Basic::LcNumber, default: 20 hz) "netPriority", // 8: Network thread priority (zero(0) is lowest, one(1) is highest) (Basic::LcNumber, default: 0.5 ) "startupResetTimer", // 9: Startup (initial) RESET pulse timer value (Basic::LcTime) "fastForwardRate", // 10: Fast forward rate (i.e., number of times updateTC() is called per frame) END_SLOTTABLE(Station) //------------------------------------------------------------------------------ // Slot table SLS //------------------------------------------------------------------------------ BEGIN_SLOT_MAP(Station) ON_SLOT(1, setSimulation, Simulation) ON_SLOT(2, setSlotNetworks, Basic::LcPairStream) ON_SLOT(3, setOutTheWindow, Basic::LcPairStream) ON_SLOT(3, setOutTheWindow, Otw) ON_SLOT(4, setSlotOwnshipName, Basic::LcString) ON_SLOT(5, setSlotRealTimeRate, Basic::LcNumber) ON_SLOT(6, setSlotRealTimePri, Basic::LcNumber) ON_SLOT(7, setSlotNetworkRate, Basic::LcNumber) ON_SLOT(8, setSlotNetworkPri, Basic::LcNumber) ON_SLOT(9, setSlotStartupResetTime, Basic::LcTime) ON_SLOT(10, setSlotFastForwardRate, Basic::LcNumber) END_SLOT_MAP() //------------------------------------------------------------------------------ // Constructor //------------------------------------------------------------------------------ Station::Station() : sim(0), otw(0), networks(0), ownship(0), ownshipName(0) { SET_SLOTTABLE rtRate = 50; // default real-time thread rate rtPri = 1.0f; netRate = 20; // default network thread rate netPri = 0.5f; haveRtThread = false; haveNetThread = false; fastForwardRate = DEFAULT_FAST_FORWARD_RATE; startupResetTimer0 = 0; startupResetTimer = 0.0f; } //------------------------------------------------------------------------------ // copyData() -- copy member data //------------------------------------------------------------------------------ void Station::copyData(const Station& org, const bool cc) { BaseClass::copyData(org); // If copy constructor, init these pointers if (cc) { sim = 0; otw = 0; networks = 0; ownshipName = 0; ownship = 0; startupResetTimer0 = 0; haveRtThread = false; haveNetThread = false; } rtRate = org.rtRate; rtPri = org.rtPri; netRate = org.netRate; netPri = org.netPri; fastForwardRate = org.fastForwardRate; setSlotStartupResetTime(org.startupResetTimer0); startupResetTimer = org.startupResetTimer; // Set the simulation, otw and network pointers setSimulation(org.sim); if (org.otw!= 0) setOutTheWindow( dynamic_cast( org.otw->clone() ) ); else setOutTheWindow((Basic::LcPairStream*)0); if (org.networks!= 0) setSlotNetworks( dynamic_cast( org.networks->clone() ) ); else setSlotNetworks(0); // Unref our old stuff (if any) if (ownshipName != 0) { ownshipName->unref(); ownshipName = 0; } if (ownship != 0) { ownship->unref(); ownship = 0; } // Copy own ownship name if (org.ownshipName != 0) { ownshipName = dynamic_cast (org.ownshipName->clone() ); } // Attach our ownship setOwnshipByName( *ownshipName ); } //------------------------------------------------------------------------------ // deleteData() -- delete member data //------------------------------------------------------------------------------ void Station::deleteData() { // Clear our pointers setSimulation(0); setOutTheWindow((Basic::LcPairStream*)0); setSlotNetworks(0); setOwnshipPlayer(0); BaseClass::deleteData(); } //------------------------------------------------------------------------------ // reset() -- Reset the station //------------------------------------------------------------------------------ void Station::reset() { // Reset our major subsystems if (sim != 0) sim->event(RESET_EVENT); // Reset the OTW subsystems if (otw != 0) { Basic::LcList::Item* item = otw ->getFirstItem(); while (item != 0) { Basic::LcPair* pair = (Basic::LcPair*)(item->getValue()); Otw* p = (Otw*)( pair->object() ); p->event(RESET_EVENT); item = item->getNext(); } } // Reset the networks if (networks != 0) { Basic::LcList::Item* item = networks ->getFirstItem(); while (item != 0) { Basic::LcPair* pair = (Basic::LcPair*)(item->getValue()); NetworkIO* p = (NetworkIO*)( pair->object() ); p->event(RESET_EVENT); item = item->getNext(); } } BaseClass::reset(); } //------------------------------------------------------------------------------ // updateTC() -- update time critical stuff here //------------------------------------------------------------------------------ void Station::updateTC(const LCreal dt) { // If we don't have a simulation then nothing happens if (sim != 0) { // --- // Update the ownship pointer // Try to find our ownship -- we check every pass just in case the // ownship player changed and we didn't see it (e.g., level of fidelity) if (ownshipName != 0 && sim->getPlayers() != 0) { setOwnshipByName( *ownshipName ); if (ownship == 0) { // Ok, we had a list of players and an ownship player name, but still // don't have an ownship pointer -- print an error message. std::cerr << "Simulation::updateTC(): ownship not found: " << *ownshipName << std::endl; ownshipName->unref(); ownshipName = 0; // And make sure we don't waste time checking again } } // Process station inputs inputDevices(dt); // Update the simulation sim->tcFrame(dt); // Process station outputs outputDevices(dt); // Our major subsystems if (otw != 0) { Basic::LcList::Item* item = otw->getFirstItem(); while (item != 0) { Basic::LcPair* pair = (Basic::LcPair*)(item->getValue()); Otw* p = (Otw*)( pair->object() ); // Set ownship & player list p->setOwnship(ownship); SPtr pl( sim->getPlayers() ); p->setPlayerList(pl); // TC frame p->tcFrame(dt); item = item->getNext(); } } } // Startup RESET timer -- // Sends an initial RESET pulse after timeout if (startupResetTimer >= 0) { startupResetTimer -= dt; if (startupResetTimer < 0) { this->event(RESET_EVENT); } } // Update the base class data BaseClass::updateTC(dt); } //------------------------------------------------------------------------------ // inputDevices() -- Process station inputs outputs //------------------------------------------------------------------------------ void Station::inputDevices(const LCreal) { } //------------------------------------------------------------------------------ // outputDevices() -- Process station hardware outputs //------------------------------------------------------------------------------ void Station::outputDevices(const LCreal) { } //------------------------------------------------------------------------------ // createRealTimeProcess() -- Create the time-critical thread //------------------------------------------------------------------------------ void Station::createRealTimeProcess() { if ( !doWeHaveTheRtThread() ) { #ifdef WIN32 // Create Windows thread if (hTcThread == 0) { DWORD dwThreadId; hTcThread = CreateThread( NULL, // no security attributes 0, // use default stack size tcThreadFunc, // thread function this, // argument to thread function 0, // use default creation flags &dwThreadId); // returns the thread identifier } #else // thread attributes pthread_attr_t attr; pthread_attr_init(&attr); if (getRealTimePriority() > 0.5f) { // Schedule priority struct sched_param param; int maxp = sched_get_priority_max(SCHED_RR); int minp = sched_get_priority_min(SCHED_RR); int priority = (maxp + minp)/2; #if 0 // CGB this is the actual variable name under RH(, but below is compatibile param.__sched_priority = priority; #else // CGB this is the way Solaris needs it. // It is #define under RH9 and FC4 for compatibility. param.sched_priority = priority; #endif pthread_attr_setschedpolicy(&attr, SCHED_RR); pthread_attr_setschedparam(&attr, ¶m); } // Create Linux process pthread_t thread; #if 0 #else sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGALRM); pthread_sigmask(SIG_BLOCK, &mask, NULL); #endif int stat = pthread_create(&thread, &attr, tcThreadFunc, this); if (stat != 0) { std::cerr << "pthread_create status = " << stat << std::endl; } #endif setHaveRtThread(true); } } //------------------------------------------------------------------------------ // createNetworkProcess() -- Create the network thread //------------------------------------------------------------------------------ void Station::createNetworkProcess() { if ( !doWeHaveTheNetThread() ) { #ifdef WIN32 // Create Windows threat DWORD dwThreadId; CreateThread( NULL, // no security attributes 0, // use default stack size netThreadFunc, // thread function this, // argument to thread function 0, // use default creation flags &dwThreadId); // returns the thread identifier #else // Create Linux process pthread_t thread; //int stat = pthread_create(&thread, &attr, netThreadFunc, this); int stat = pthread_create(&thread, 0, netThreadFunc, this); if (stat != 0) { std::cerr << "pthread_create status = " << stat << std::endl; } #endif setHaveNetThread(true); } } //------------------------------------------------------------------------------ // getPlayers() -- get the player list //------------------------------------------------------------------------------ Basic::LcPairStream* Station::getPlayers() { return ((getSimulation() != 0) ? getSimulation()->getPlayers() : 0); } const Basic::LcPairStream* Station::getPlayers() const { return ((getSimulation() != 0) ? getSimulation()->getPlayers() : 0); } //------------------------------------------------------------------------------ // updateData() -- update non-time critical stuff here //------------------------------------------------------------------------------ void Station::updateData(const LCreal dt) { // Create a network thread (if needed) if (networks != 0 && !haveNetThread) { createNetworkProcess(); } // Our major subsystems if (sim != 0) sim->updateData(dt); // Our OTW interfaces if (otw != 0) { Basic::LcList::Item* item = otw ->getFirstItem(); while (item != 0) { Basic::LcPair* pair = (Basic::LcPair*)(item->getValue()); Otw* p = (Otw*)( pair->object() ); p->updateData(dt); item = item->getNext(); } } // Update base class data BaseClass::updateData(dt); } //------------------------------------------------------------------------------ // shutdownNotification() -- We're shutting down //------------------------------------------------------------------------------ bool Station::shutdownNotification() { // Tell the networks we're shutting down if (getNetworks() != 0) { Basic::LcList::Item* item = getNetworks()->getFirstItem(); while (item != 0) { Basic::LcPair* pair = (Basic::LcPair*)(item->getValue()); Basic::LcComponent* p = dynamic_cast(pair->object()); p->event(SHUTDOWN_EVENT); item = item->getNext(); } } // Tell our simulation to shut down if (getSimulation() != 0) { getSimulation()->event(SHUTDOWN_EVENT); } // Inform our OTW interfaces if (otw != 0) { Basic::LcList::Item* item = otw ->getFirstItem(); while (item != 0) { Basic::LcPair* pair = (Basic::LcPair*)(item->getValue()); Basic::LcComponent* p = dynamic_cast(pair->object()); p->event(SHUTDOWN_EVENT); item = item->getNext(); } } return BaseClass::shutdownNotification(); } //------------------------------------------------------------------------------ // setOwnshipByName() -- set our ownship by name //------------------------------------------------------------------------------ bool Station::setOwnshipByName(const char* const newOS) { bool set = false; SPtr pl( sim->getPlayers() ); // Look for this ownship in our list of players if (newOS != 0 && pl != 0) { Basic::LcPair* p = pl->findByName(newOS); if (p != 0) { Player* newOwnship = (Player*) p->object(); if (newOwnship != ownship) { // Ok, we found the new ownship and it IS a different // player then the previous ownship ... setOwnshipPlayer( newOwnship ); set = true; } } } return set; } //------------------------------------------------------------------------------ // setOwnshipPlayer() -- set this player as our ownship //------------------------------------------------------------------------------ bool Station::setOwnshipPlayer(Player* const newOS) { // Is it already own ownship? Yes, then nothing else to do. if (newOS == ownship) return true; // When we're just setting a null(0) ownship ... if (newOS == 0) { // Unref the old player if (ownshipName != 0) { ownshipName->unref(); ownshipName = 0; } if (ownship != 0) { ownship->event(ON_OWNSHIP_DISCONNECT); ownship->unref(); ownship = 0; } return true; } // Look for this ownship in our list of players bool set = false; SPtr pl( sim->getPlayers() ); if (pl != 0) { Basic::LcList::Item* item = pl->getFirstItem(); while (item != 0 && !set) { Basic::LcPair* pair = dynamic_cast(item->getValue()); if (pair != 0) { Player* ip = dynamic_cast( pair->object() ); if (ip == newOS && ip->isLocalPlayer()) { // Unref the old stuff if (ownshipName != 0) { ownshipName->unref(); ownshipName = 0; } if (ownship != 0) { ownship->event(ON_OWNSHIP_DISCONNECT); ownship->unref(); ownship = 0; } // Ok, we found the player -- make it our ownship ownship = newOS; ownship->ref(); ownshipName = pair->slot(); ownshipName->ref(); ownship->event(ON_OWNSHIP_CONNECT); set = true; } } item = item->getNext(); } } return set; } //----------------------------------------------------------------------------- // setSimulation() -- Sets a pointer to our simulation subsystem //----------------------------------------------------------------------------- bool Station::setSimulation(Simulation* const p) { if (sim != 0) { sim->container(0); sim->unref(); } sim = p; if (sim != 0) { sim->ref(); sim->container(this); } return true; } //----------------------------------------------------------------------------- // setOutTheWindow() -- Sets a pointer to our Out-The-Window subsystem //----------------------------------------------------------------------------- bool Station::setOutTheWindow(Otw* const p) { Basic::LcPairStream* list = new Basic::LcPairStream(); list->put( new Basic::LcPair("1",p) ); return setOutTheWindow(list); } bool Station::setOutTheWindow(Basic::LcPairStream* const list) { bool ok = true; // Remove the old OTW list if (otw != 0) { // we are no longer the container for these OTW interfaces for (Basic::LcList::Item* item = otw->getFirstItem(); item != 0; item = item->getNext()) { Basic::LcPair* pair = (Basic::LcPair*)(item->getValue()); Otw* p = (Otw*)( pair->object() ); p->container(0); } otw = 0; } // Set our OTW list pointer otw = list; // Make sure the new OTW list is setup correctly if (otw != 0) { for (Basic::LcList::Item* item = otw->getFirstItem(); item != 0; item = item->getNext()) { Basic::LcPair* pair = (Basic::LcPair*)(item->getValue()); Otw* p = dynamic_cast( pair->object() ); if (p != 0) { // We are this OTW's container p->container(this); } else { // Not of the proper type std::cerr << "Player::setOutTheWindow: OTW at slot \"" << pair->slot() << "\" is not of type Otw" << std::endl; ok = false; } } } return ok; } //------------------------------------------------------------------------------ // setSlotOwnshipName() -- sets the ownship name to the new string //------------------------------------------------------------------------------ bool Station::setSlotOwnshipName(const Basic::LcString* const newName) { if (ownshipName != 0) ownshipName->unref(); ownshipName = newName; if (ownshipName != 0) ownshipName->ref(); return true; } //------------------------------------------------------------------------------ // setSlotNetworks() -- Set our list of networks //------------------------------------------------------------------------------ bool Station::setSlotNetworks(Basic::LcPairStream* const a) { bool ok = true; // Remove the old networks list if (networks != 0) { // we are no longer the container for these networks for (Basic::LcList::Item* item = networks->getFirstItem(); item != 0; item = item->getNext()) { Basic::LcPair* pair = (Basic::LcPair*)(item->getValue()); NetworkIO* p = (NetworkIO*)( pair->object() ); p->container(0); } } // Set our network list pointer networks = a; // Make sure the new network list is setup correctly if (networks != 0) { for (Basic::LcList::Item* item = networks->getFirstItem(); item != 0; item = item->getNext()) { Basic::LcPair* pair = (Basic::LcPair*)(item->getValue()); NetworkIO* p = dynamic_cast( pair->object() ); if (p != 0) { // We are this network's container p->container(this); } else { // Not of the proper type std::cerr << "Player::setSlotNetworks: network at slot \"" << pair->slot() << "\" is not of type NetworkIO" << std::endl; ok = false; } } } return ok; } //------------------------------------------------------------------------------ // setSlotRealTimeRate() -- Sets the R/T thread rate (hz) //------------------------------------------------------------------------------ bool Station::setSlotRealTimeRate(const Basic::LcNumber* const num) { bool ok = false; if (num != 0) { int rate = num->getInt(); if (rate > 0 && rate <= 1000) { rtRate = rate; ok = true; } else { std::cerr << "Station::setRealTimeRate: rtRate is invalid, range: [1 .. 1000]" << std::endl; } } return ok; } //------------------------------------------------------------------------------ // setSlotRealTimePri() -- Sets the R/T thread priority //------------------------------------------------------------------------------ bool Station::setSlotRealTimePri(const Basic::LcNumber* const num) { bool ok = false; if (num != 0) { LCreal pri = num->getReal(); if (pri >= 0 && pri <= 1.0f) { rtPri = pri; ok = true; } else { std::cerr << "Station::setRealTimePri: R/T priority is invalid, range: [0 .. 1]" << std::endl; } } return ok; } //------------------------------------------------------------------------------ // setSlotNetworkRate() -- Sets the network thread rate (hz) //------------------------------------------------------------------------------ bool Station::setSlotNetworkRate(const Basic::LcNumber* const num) { bool ok = false; if (num != 0) { int rate = num->getInt(); if (rate > 0 && rate <= 20) { netRate = rate; ok = true; } else { std::cerr << "Station::setNetworkRate: netRate is invalid, range: [1 .. 20]" << std::endl; } } return ok; } //------------------------------------------------------------------------------ // setSlotNetworkPri() -- Sets the network thread priority //------------------------------------------------------------------------------ bool Station::setSlotNetworkPri(const Basic::LcNumber* const num) { bool ok = false; if (num != 0) { LCreal pri = num->getReal(); if (pri >= 0 && pri <= 1.0f) { netPri = pri; ok = true; } else { std::cerr << "Station::setSlotNetworkPri: Network priority is invalid, range: [0 .. 1]" << std::endl; } } return ok; } //------------------------------------------------------------------------------ // setSlotStartupResetTime() -- Sets the startup RESET pulse timer //------------------------------------------------------------------------------ bool Station::setSlotStartupResetTime(const Basic::LcTime* const num) { if (startupResetTimer0 != 0) { startupResetTimer0->unref(); startupResetTimer0 = 0; startupResetTimer = -1.0f; } startupResetTimer0 = num; if (startupResetTimer0 != 0) { startupResetTimer0->ref(); startupResetTimer = Basic::LcSeconds::convertStatic(*startupResetTimer0); } return true; } //------------------------------------------------------------------------------ // Sets the fast forward rate //------------------------------------------------------------------------------ bool Station::setFastForwardRate(const unsigned int r) { fastForwardRate = r; return true; } //------------------------------------------------------------------------------ // Sets the fast forward rate //------------------------------------------------------------------------------ bool Station::setSlotFastForwardRate(const Basic::LcNumber* const msg) { bool ok = true; if (msg != 0) { int ii = msg->getInt(); if (ii >= 0) { ok = setFastForwardRate( ii ); } } return ok; } //------------------------------------------------------------------------------ // getSlotByIndex() //------------------------------------------------------------------------------ Basic::LcObject* Station::getSlotByIndex(const int si) { return BaseClass::getSlotByIndex(si); } //------------------------------------------------------------------------------ // serialize //------------------------------------------------------------------------------ std::ostream& Station::serialize(std::ostream& sout, const int i, const bool slotsOnly) const { int j = 0; if ( !slotsOnly ) { indent(sout,i); sout << "( " << getFormName() << std::endl; j = 4; } // simulation model if (sim != 0) { indent(sout,i+j); sout << "simulation: " << std::endl; sim->serialize(sout,(i+j)); } // OTW model if (otw != 0) { indent(sout,i+j); sout << "otw: {" << std::endl; otw->serialize(sout,i+j+4); indent(sout,i+j); sout << "}" << std::endl; } // networks if (networks != 0) { indent(sout,i+j); sout << "networks: {" << std::endl; networks->serialize(sout,i+j+4); indent(sout,i+j); sout << "}" << std::endl; } // rtRate: Real-Time thread update rate (Hz) indent(sout,i+j); sout << "rtRate: " << rtRate << std::endl; // rtPriority: Real-Time thread priority indent(sout,i+j); sout << "rtPriority: " << rtPri << std::endl; // netRate: Network thread rate (Hz) indent(sout,i+j); sout << "netRate: " << netRate << std::endl; // netPriority: Network thread priority indent(sout,i+j); sout << "netPriority: " << netPri << std::endl; // fastForwardRate: if (fastForwardRate != DEFAULT_FAST_FORWARD_RATE) { indent(sout,i+j); sout << "fastForwardRate: " << fastForwardRate << std::endl; } // startupResetTime: Startup (initial) RESET pulse timer value (Basic::LcTime) if (startupResetTimer0 != 0) { indent(sout,i+j); sout << "startupResetTime: " << *startupResetTimer0 << std::endl; } if (ownshipName != 0) { indent(sout,i+j); sout << "ownship: " << *ownshipName << std::endl; } // don't care about component stuff right now //BaseClass::serialize(sout,i+j,true); if ( !slotsOnly ) { indent(sout,i); sout << ")" << std::endl; } return sout; } } // End Simulation namespace } // End Eaagles namespace