diff engine/core/model/structures/instance.cpp @ 338:d266506ff4f9

Bug fix. It turned out the instance tree contained ghost instances, since InstanceTree.removeInstance sometimes failed. This caused those random crashes in UH. Now the InstanceTree enforces that remove/add Instance work in pairs. A new Exception is raised in case this ever goes wrong again. (InconsitencyDetected) Furthermore the removeInstancheChangeListener stuff had a fix to become reentrant. It is not clear wether this was shadowed by the aforementioned bug or was never triggered.
author phoku@33b003aa-7bff-0310-803a-e67f0ece8222
date Mon, 24 Aug 2009 18:32:03 +0000
parents 7887f3854862
children 0fd74235b34d
line wrap: on
line diff
--- a/engine/core/model/structures/instance.cpp	Mon Aug 24 16:06:30 2009 +0000
+++ b/engine/core/model/structures/instance.cpp	Mon Aug 24 18:32:03 2009 +0000
@@ -152,9 +152,17 @@
 		if (source.m_changeinfo != ICHANGE_NO_CHANGES) {
 			std::vector<InstanceChangeListener*>::iterator i = m_changelisteners.begin();
 			while (i != m_changelisteners.end()) {
-				(*i)->onInstanceChanged(&source, source.m_changeinfo);
+				if (NULL != *i)
+				{
+					(*i)->onInstanceChanged(&source, source.m_changeinfo);
+				}
 				++i;
 			}
+			// Really remove "removed" listeners.
+			m_changelisteners.erase(
+				std::remove(m_changelisteners.begin(),m_changelisteners.end(),
+					(InstanceChangeListener*)NULL),
+				m_changelisteners.end());
 		}
 	}
 
@@ -242,7 +250,7 @@
 		std::vector<InstanceChangeListener*>::iterator i = m_activity->m_changelisteners.begin();
 		while (i != m_activity->m_changelisteners.end()) {
 			if ((*i) == listener) {
-				m_activity->m_changelisteners.erase(i);
+				*i = NULL;
 				return;
 			}
 			++i;
@@ -285,7 +293,7 @@
 		m_activity->m_actioninfo->m_target = new Location(leader->getLocationRef());
 		m_activity->m_actioninfo->m_speed = speed;
 		m_activity->m_actioninfo->m_leader = leader;
-                leader->addDeleteListener(this);
+		leader->addDeleteListener(this);
 		setFacingLocation(*m_activity->m_actioninfo->m_target);
 		FL_DBG(_log, LMsg("starting action ") <<  action_name << " from" << m_location << " to " << *m_activity->m_actioninfo->m_target << " with speed " << speed);
 	}