From d5d9723d9b01e0e8dc19095b80762dd7dacebb90 Mon Sep 17 00:00:00 2001 From: daveluff Date: Wed, 15 Oct 2003 14:06:28 +0000 Subject: [PATCH] Tweaks to the ATC/AI interaction framework --- src/ATC/AIPlane.cxx | 30 ++++++++++++++++++++++-------- src/ATC/AIPlane.hxx | 14 +++++++------- src/ATC/ATC.cxx | 21 +++++++++++++++++++-- src/ATC/ATC.hxx | 8 +++++++- 4 files changed, 55 insertions(+), 18 deletions(-) diff --git a/src/ATC/AIPlane.cxx b/src/ATC/AIPlane.cxx index a2ea436fb..22729b4c5 100644 --- a/src/ATC/AIPlane.cxx +++ b/src/ATC/AIPlane.cxx @@ -37,7 +37,7 @@ FGAIPlane::FGAIPlane() { pending_transmission = ""; _timeout = 0; _pending = false; - _callback = NULL; + _callback_code = 0; _transmit = false; _transmitting = false; voice = false; @@ -53,6 +53,7 @@ void FGAIPlane::Update(double dt) { if(_pending) { if(tuned_station) { if(tuned_station->GetFreqClear()) { + tuned_station->SetFreqInUse(); _pending = false; _transmit = true; _transmitting = false; @@ -82,6 +83,7 @@ void FGAIPlane::Update(double dt) { _counter = 0.0; _max_count = 5.0; // FIXME - hardwired length of message - need to calculate it! + //cout << "Transmission = " << pending_transmission << '\n'; if(freq == user_freq0 || freq == user_freq1) { //cout << "Transmitting..." << endl; // we are on the same frequency, so check distance to the user plane @@ -93,10 +95,18 @@ void FGAIPlane::Update(double dt) { _transmitting = true; } } + // Run the callback regardless of whether on same freq as user or not. + //cout << "_callback_code = " << _callback_code << '\n'; + if(_callback_code) { + ProcessCallback(_callback_code); + } } else if(_transmitting) { if(_counter >= _max_count) { NoRender(plane.callsign); _transmitting = false; + // For now we'll let ATC decide whether to respond + //if(tuned_station) tuned_station->SetResponseReqd(plane.callsign); + if(tuned_station) tuned_station->NotifyTransmissionFinished(plane.callsign); } _counter += dt; } @@ -117,27 +127,31 @@ void FGAIPlane::LevelWings(void) { } } -void FGAIPlane::Transmit(ai_plane_callback_t callback) { +void FGAIPlane::Transmit(int callback_code) { SG_LOG(SG_ATC, SG_INFO, "Transmit called for plane " << plane.callsign << ", msg = " << pending_transmission); _pending = true; - _callback = callback; + _callback_code = callback_code; _timeout = 0.0; } -void FGAIPlane::Transmit(double timeout, ai_plane_callback_t callback) { +void FGAIPlane::ConditionalTransmit(double timeout, int callback_code) { SG_LOG(SG_ATC, SG_INFO, "Timed transmit called for plane " << plane.callsign << ", msg = " << pending_transmission); _pending = true; - _callback = callback; + _callback_code = callback_code; _timeout = timeout; } -void FGAIPlane::ImmediateTransmit(ai_plane_callback_t callback) { +void FGAIPlane::ImmediateTransmit(int callback_code) { Render(plane.callsign, false); - if(_callback) { - (*_callback)(); + if(callback_code) { + ProcessCallback(callback_code); } } +// Derived classes should override this. +void FGAIPlane::ProcessCallback(int code) { +} + // Render a transmission // Outputs the transmission either on screen or as audio depending on user preference // The refname is a string to identify this sample to the sound manager diff --git a/src/ATC/AIPlane.hxx b/src/ATC/AIPlane.hxx index 544212ee0..b87c50864 100644 --- a/src/ATC/AIPlane.hxx +++ b/src/ATC/AIPlane.hxx @@ -85,9 +85,6 @@ public: LandingType GetLandingOption(); protected: - // callback type for derived classes to use - typedef void (*ai_plane_callback_t) (void); - PlaneRec plane; double mag_hdg; // degrees - the heading that the physical aircraft is *pointing* @@ -113,23 +110,26 @@ protected: FGATC* tuned_station; // and this if they are tuned to ATC // Transmit a message when channel becomes free of other dialog - void Transmit(ai_plane_callback_t callback = NULL); + void Transmit(int callback_code = 0); // Transmit a message if channel becomes free within timeout (seconds). timeout of zero implies no limit - void Transmit(double timeout, ai_plane_callback_t callback = NULL); + void ConditionalTransmit(double timeout, int callback_code = 0); // Transmit regardless of other dialog on the channel eg emergency - void ImmediateTransmit(ai_plane_callback_t callback = NULL); + void ImmediateTransmit(int callback_code = 0); void Bank(double angle); void LevelWings(void); + virtual void ProcessCallback(int code); + PatternLeg leg; private: bool _pending; double _timeout; - ai_plane_callback_t _callback; + int _callback_code; // A callback code to be notified and processed by the derived classes + // A value of zero indicates no callback required bool _transmit; // we are to transmit bool _transmitting; // we are transmitting double _counter; diff --git a/src/ATC/ATC.cxx b/src/ATC/ATC.cxx index 4ea5e10f4..0695f7e44 100644 --- a/src/ATC/ATC.cxx +++ b/src/ATC/ATC.cxx @@ -31,6 +31,8 @@ FGATC::FGATC() { freqClear = true; + runResponseCounter = false; + responseReqd = false; } FGATC::~FGATC() { @@ -38,10 +40,12 @@ FGATC::~FGATC() { // Derived classes wishing to use the response counter should call this from their own Update(...). void FGATC::Update(double dt) { - if(responseReqd) { + if(runResponseCounter) { + //cout << responseCounter << '\t' << responseTime << '\n'; if(responseCounter >= responseTime) { - responseReqd = false; + runResponseCounter = false; respond = true; + //cout << "RESPOND\n"; } else { responseCounter += dt; } @@ -49,6 +53,7 @@ void FGATC::Update(double dt) { } void FGATC::SetResponseReqd(string rid) { + receiving = false; responseReqd = true; respond = false; // TODO - this ignores the fact that more than one plane could call this before response // Shouldn't happen with AI only, but user could confuse things?? @@ -57,6 +62,18 @@ void FGATC::SetResponseReqd(string rid) { responseTime = 2.5; // TODO - randomize this slightly. } +void FGATC::NotifyTransmissionFinished(string rid) { + receiving = false; + responseID = rid; + if(responseReqd) { + runResponseCounter = true; + responseCounter = 0.0; + responseTime = 2.5; // TODO - randomize this slightly. + } else { + freqClear = true; + } +} + void FGATC::AddPlane(string pid) { } diff --git a/src/ATC/ATC.hxx b/src/ATC/ATC.hxx index 1c96f86ad..94b6df0b4 100644 --- a/src/ATC/ATC.hxx +++ b/src/ATC/ATC.hxx @@ -126,9 +126,13 @@ public: // Returns true if OK to transmit on this frequency inline bool GetFreqClear() { return freqClear; } // Indicate that the frequency is in use - inline void SetFreqInUse() { freqClear = false; } + inline void SetFreqInUse() { freqClear = false; receiving = true; } // Transmission to the ATC is finished and a response is required void SetResponseReqd(string rid); + // Transmission finished - let ATC decide if a response is reqd and clear freq if necessary + void NotifyTransmissionFinished(string rid); + // Transmission finished and no response required + inline void ReleaseFreq() { freqClear = true; receiving = false; } // TODO - check that the plane releasing the freq is the right one etc. // The above 3 funcs under development!! // The idea is that AI traffic or the user ATC dialog box calls FreqInUse() when they begin transmitting, // and that the tower control sets freqClear back to true following a reply. @@ -188,7 +192,9 @@ protected: FGATCVoice* vPtr; bool freqClear; // Flag to indicate if the frequency is clear of ongoing dialog + bool receiving; // Flag to indicate we are receiving a transmission bool responseReqd; // Flag to indicate we should be responding to a request/report + bool runResponseCounter; // Flag to indicate the response counter should be run double responseTime; // Time to take from end of request transmission to beginning of response // The idea is that this will be slightly random. double responseCounter; // counter to implement the above