Tweaks to the ATC/AI interaction framework
This commit is contained in:
parent
ee8eb7d6fe
commit
d5d9723d9b
4 changed files with 55 additions and 18 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue