allow listeners to remove themselves. This is done by marking them
dead and letting the next NasalSys::update() remove all dead listeners.
This commit is contained in:
parent
016750c865
commit
22421f6687
2 changed files with 29 additions and 9 deletions
|
@ -57,6 +57,7 @@ FGNasalSys::FGNasalSys()
|
||||||
_gcHash = naNil();
|
_gcHash = naNil();
|
||||||
_nextGCKey = 0; // Any value will do
|
_nextGCKey = 0; // Any value will do
|
||||||
_callCount = 0;
|
_callCount = 0;
|
||||||
|
_purgeListeners = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does a naCall() in a new context. Wrapped here to make lock
|
// Does a naCall() in a new context. Wrapped here to make lock
|
||||||
|
@ -437,6 +438,21 @@ void FGNasalSys::init()
|
||||||
loadPropertyScripts();
|
loadPropertyScripts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGNasalSys::update(double)
|
||||||
|
{
|
||||||
|
if(_purgeListeners) {
|
||||||
|
_purgeListeners = false;
|
||||||
|
map<int, FGNasalListener *>::iterator it, end = _listener.end();
|
||||||
|
for(it = _listener.end(); --it != end;) {
|
||||||
|
FGNasalListener *nl = it->second;
|
||||||
|
if(nl->_dead) {
|
||||||
|
_listener.erase(it);
|
||||||
|
delete nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Loads the scripts found under /nasal in the global tree
|
// Loads the scripts found under /nasal in the global tree
|
||||||
void FGNasalSys::loadPropertyScripts()
|
void FGNasalSys::loadPropertyScripts()
|
||||||
{
|
{
|
||||||
|
@ -690,20 +706,21 @@ naRef FGNasalSys::setListener(int argc, naRef* args)
|
||||||
naRef FGNasalSys::removeListener(naContext c, int argc, naRef* args)
|
naRef FGNasalSys::removeListener(naContext c, int argc, naRef* args)
|
||||||
{
|
{
|
||||||
naRef id = argc > 0 ? args[0] : naNil();
|
naRef id = argc > 0 ? args[0] : naNil();
|
||||||
int i = int(id.num);
|
map<int, FGNasalListener *>::iterator it = _listener.find(int(id.num));
|
||||||
|
|
||||||
if(!naIsNum(id) || _listener.find(i) == _listener.end()) {
|
if(!naIsNum(id) || it == _listener.end() || it->second->_dead) {
|
||||||
naRuntimeError(c, "removelistener() with invalid listener id");
|
naRuntimeError(c, "removelistener() with invalid listener id");
|
||||||
return naNil();
|
return naNil();
|
||||||
}
|
}
|
||||||
|
|
||||||
FGNasalListener *nl = _listener[i];
|
FGNasalListener *nl = it->second;
|
||||||
if(nl->_active) {
|
if(nl->_active) {
|
||||||
naRuntimeError(c, "trying to remove active listener");
|
nl->_dead = true;
|
||||||
return naNil();
|
_purgeListeners = true;
|
||||||
|
return naNum(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
_listener.erase(i);
|
_listener.erase(it);
|
||||||
delete nl;
|
delete nl;
|
||||||
return naNum(_listener.size());
|
return naNum(_listener.size());
|
||||||
}
|
}
|
||||||
|
@ -718,7 +735,8 @@ FGNasalListener::FGNasalListener(SGPropertyNode_ptr node, naRef handler,
|
||||||
_handler(handler),
|
_handler(handler),
|
||||||
_gcKey(key),
|
_gcKey(key),
|
||||||
_nas(nasal),
|
_nas(nasal),
|
||||||
_active(0)
|
_active(0),
|
||||||
|
_dead(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -731,7 +749,7 @@ FGNasalListener::~FGNasalListener()
|
||||||
void FGNasalListener::valueChanged(SGPropertyNode* node)
|
void FGNasalListener::valueChanged(SGPropertyNode* node)
|
||||||
{
|
{
|
||||||
// drop recursive listener calls
|
// drop recursive listener calls
|
||||||
if (_active)
|
if(_active || _dead)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_active++;
|
_active++;
|
||||||
|
|
|
@ -19,7 +19,7 @@ public:
|
||||||
FGNasalSys();
|
FGNasalSys();
|
||||||
virtual ~FGNasalSys();
|
virtual ~FGNasalSys();
|
||||||
virtual void init();
|
virtual void init();
|
||||||
virtual void update(double dt) { /* noop */ }
|
virtual void update(double dt);
|
||||||
|
|
||||||
// Loads a nasal script from an external file and inserts it as a
|
// Loads a nasal script from an external file and inserts it as a
|
||||||
// global module of the specified name.
|
// global module of the specified name.
|
||||||
|
@ -79,6 +79,7 @@ private:
|
||||||
// Listener
|
// Listener
|
||||||
map<int, FGNasalListener *> _listener;
|
map<int, FGNasalListener *> _listener;
|
||||||
static int _listenerId;
|
static int _listenerId;
|
||||||
|
bool _purgeListeners;
|
||||||
|
|
||||||
void loadPropertyScripts();
|
void loadPropertyScripts();
|
||||||
void hashset(naRef hash, const char* key, naRef val);
|
void hashset(naRef hash, const char* key, naRef val);
|
||||||
|
@ -142,6 +143,7 @@ private:
|
||||||
int _gcKey;
|
int _gcKey;
|
||||||
FGNasalSys* _nas;
|
FGNasalSys* _nas;
|
||||||
unsigned int _active;
|
unsigned int _active;
|
||||||
|
bool _dead;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue