[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20286] trunk/blender/source/gameengine: BGE logic patch: fix another incompatibility with YF.

Benoit Bolsee benoit.bolsee at online.be
Wed May 20 10:45:45 CEST 2009


Revision: 20286
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20286
Author:   ben2610
Date:     2009-05-20 10:45:42 +0200 (Wed, 20 May 2009)

Log Message:
-----------
BGE logic patch: fix another incompatibility with YF.

Previous patch was not sorting the state actuators. This was causing 
some problems with YoFrankie that relies on the order of actuators
when multiple state actuators are activated at once.

Active state actuators will now be sorted per object. This doesn't
change the fact that state actuators are executed before all other
actuators as before.

Incidently, made the logic loop faster.

Modified Paths:
--------------
    trunk/blender/source/gameengine/GameLogic/SCA_IActuator.cpp
    trunk/blender/source/gameengine/GameLogic/SCA_IActuator.h
    trunk/blender/source/gameengine/GameLogic/SCA_ILogicBrick.h
    trunk/blender/source/gameengine/GameLogic/SCA_IObject.cpp
    trunk/blender/source/gameengine/GameLogic/SCA_IObject.h
    trunk/blender/source/gameengine/GameLogic/SCA_LogicManager.cpp
    trunk/blender/source/gameengine/GameLogic/SCA_LogicManager.h
    trunk/blender/source/gameengine/Ketsji/KX_StateActuator.cpp
    trunk/blender/source/gameengine/SceneGraph/SG_QList.h

Modified: trunk/blender/source/gameengine/GameLogic/SCA_IActuator.cpp
===================================================================
--- trunk/blender/source/gameengine/GameLogic/SCA_IActuator.cpp	2009-05-20 05:35:53 UTC (rev 20285)
+++ trunk/blender/source/gameengine/GameLogic/SCA_IActuator.cpp	2009-05-20 08:45:42 UTC (rev 20286)
@@ -67,6 +67,8 @@
 	}
 }
 
+// this function is only used to deactivate actuators outside the logic loop
+// e.g. when an object is deleted.
 void SCA_IActuator::Deactivate()
 {
 	if (QDelink())

Modified: trunk/blender/source/gameengine/GameLogic/SCA_IActuator.h
===================================================================
--- trunk/blender/source/gameengine/GameLogic/SCA_IActuator.h	2009-05-20 05:35:53 UTC (rev 20285)
+++ trunk/blender/source/gameengine/GameLogic/SCA_IActuator.h	2009-05-20 08:45:42 UTC (rev 20286)
@@ -33,8 +33,7 @@
 #include <vector>
 
 /*
- * Use of SG_DList : element of actuator being deactivated
- *                   Head: SCA_LogicManager::m_removedActuators
+ * Use of SG_DList : None
  * Use of SG_QList : element of activated actuator list of their owner
  *                   Head: SCA_IObject::m_activeActuators
  */

Modified: trunk/blender/source/gameengine/GameLogic/SCA_ILogicBrick.h
===================================================================
--- trunk/blender/source/gameengine/GameLogic/SCA_ILogicBrick.h	2009-05-20 05:35:53 UTC (rev 20285)
+++ trunk/blender/source/gameengine/GameLogic/SCA_ILogicBrick.h	2009-05-20 08:45:42 UTC (rev 20286)
@@ -92,6 +92,34 @@
 		it.add_back(this);
 	}
 
+	// insert in a QList at position corresponding to m_Execute_Priority
+	// inside a longer list that contains elements of other objects. 
+	// Sorting is done only between the elements of the same object.
+	// head is the head of the combined list
+	// current points to the first element of the object in the list, NULL if none yet
+	void			    InsertSelfActiveQList(SG_QList& head, SG_QList** current)
+	{
+		if (!*current)
+		{
+			// first element can be put anywhere
+			head.QAddBack(this);
+			*current = this;
+			return;
+		}
+		// note: we assume current points actually to one o our element, skip the tests
+		SG_QList::iterator<SCA_ILogicBrick> it(head,*current);
+		if (m_Execute_Priority <= (*it)->m_Execute_Priority)
+		{
+			// this element comes before the first
+			*current = this;
+		}
+		else
+		{
+			for(++it; !it.end() && (*it)->m_gameobj == m_gameobj &&  m_Execute_Priority > (*it)->m_Execute_Priority; ++it);
+		}
+		it.add_back(this);
+	}
+
 	virtual	bool		LessComparedTo(SCA_ILogicBrick* other);
 	
 	virtual PyObject* py_getattro(PyObject *attr);

Modified: trunk/blender/source/gameengine/GameLogic/SCA_IObject.cpp
===================================================================
--- trunk/blender/source/gameengine/GameLogic/SCA_IObject.cpp	2009-05-20 05:35:53 UTC (rev 20285)
+++ trunk/blender/source/gameengine/GameLogic/SCA_IObject.cpp	2009-05-20 08:45:42 UTC (rev 20286)
@@ -41,7 +41,8 @@
 MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0);
 SG_QList SCA_IObject::m_activeBookmarkedControllers;
 
-SCA_IObject::SCA_IObject(PyTypeObject* T): CValue(T), m_initState(0), m_state(0)
+SCA_IObject::SCA_IObject(PyTypeObject* T): CValue(T), m_initState(0), m_state(0), m_firstState(NULL)
+
 {
 	m_suspended = false;
 }

Modified: trunk/blender/source/gameengine/GameLogic/SCA_IObject.h
===================================================================
--- trunk/blender/source/gameengine/GameLogic/SCA_IObject.h	2009-05-20 05:35:53 UTC (rev 20285)
+++ trunk/blender/source/gameengine/GameLogic/SCA_IObject.h	2009-05-20 08:45:42 UTC (rev 20286)
@@ -52,6 +52,7 @@
 	Py_Header;
 	
 protected:
+	friend class KX_StateActuator;
 	friend class SCA_IActuator;
 	friend class SCA_IController;
 	SCA_SensorList         m_sensors;
@@ -97,6 +98,11 @@
 	 */
 	unsigned int			m_state;
 
+	/**
+	 * pointer inside state actuator list for sorting
+	 */
+	SG_QList*				m_firstState;
+
 public:
 	
 	SCA_IObject(PyTypeObject* T=&Type);

Modified: trunk/blender/source/gameengine/GameLogic/SCA_LogicManager.cpp
===================================================================
--- trunk/blender/source/gameengine/GameLogic/SCA_LogicManager.cpp	2009-05-20 05:35:53 UTC (rev 20285)
+++ trunk/blender/source/gameengine/GameLogic/SCA_LogicManager.cpp	2009-05-20 08:45:42 UTC (rev 20286)
@@ -212,17 +212,22 @@
 		(*ie)->UpdateFrame();
 
 	SG_DList::iterator<SG_QList> io(m_activeActuators);
-	for (io.begin(); !io.end(); ++io)
+	for (io.begin(); !io.end(); )
 	{
-		SG_QList::iterator<SCA_IActuator> ia(*(*io));
-		for (ia.begin(); !ia.end(); ++ia)
+		SG_QList* ahead = *io;
+		// increment now so that we can remove the current element
+		++io;
+		SG_QList::iterator<SCA_IActuator> ia(*ahead);
+		for (ia.begin(); !ia.end();  )
 		{
 			SCA_IActuator* actua = *ia;
+			// increment first to allow removal of inactive actuators.
+			++ia;
 			if (!actua->Update(curtime, frame))
 			{
-				// cannot deactive the actuator now as it will disturb the list
-				m_removedActuators.AddBack(actua);
-				actua->SetActive(false);
+				// this actuator is not active anymore, remove
+				actua->QDelink(); 
+				actua->SetActive(false); 
 			} else if (actua->IsNoLink())
 			{
 				// This actuator has no more links but it still active
@@ -235,15 +240,12 @@
 				actua->AddEvent(event);
 			}
 		}
+		if (ahead->QEmpty())
+		{
+			// no more active controller, remove from main list
+			ahead->Delink();
+		}
 	}
-
-	for (SCA_IActuator* act = (SCA_IActuator*)m_removedActuators.Remove();
-		act != NULL;
-		act = (SCA_IActuator*)m_removedActuators.Remove())
-	{
-		act->Deactivate();
-		act->SetActive(false);
-	}
 }
 
 

Modified: trunk/blender/source/gameengine/GameLogic/SCA_LogicManager.h
===================================================================
--- trunk/blender/source/gameengine/GameLogic/SCA_LogicManager.h	2009-05-20 05:35:53 UTC (rev 20285)
+++ trunk/blender/source/gameengine/GameLogic/SCA_LogicManager.h	2009-05-20 08:45:42 UTC (rev 20286)
@@ -87,9 +87,6 @@
 
 	GEN_Map<STR_HashedString,void*>		m_map_gamemeshname_to_blendobj;
 	GEN_Map<CHashedPtr,void*>			m_map_blendobj_to_gameobj;
-
-	// head of actuators being deactivated during the logic update
-	SG_DList							m_removedActuators;
 public:
 	SCA_LogicManager();
 	virtual ~SCA_LogicManager();

Modified: trunk/blender/source/gameengine/Ketsji/KX_StateActuator.cpp
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_StateActuator.cpp	2009-05-20 05:35:53 UTC (rev 20285)
+++ trunk/blender/source/gameengine/Ketsji/KX_StateActuator.cpp	2009-05-20 08:45:42 UTC (rev 20286)
@@ -73,7 +73,10 @@
 {
 	bool bNegativeEvent = IsNegativeEvent();
 	unsigned int objMask;
-	
+
+	// execution of state actuator means that we are in the execution phase, reset this pointer
+	// because all the active actuator of this object will be removed for sure.
+	m_gameobj->m_firstState = NULL;
 	RemoveAllEvents();
 	if (bNegativeEvent) return false;
 
@@ -102,6 +105,8 @@
 	return false;
 }
 
+// this function is only used to deactivate actuators outside the logic loop
+// e.g. when an object is deleted.
 void KX_StateActuator::Deactivate()
 {
 	if (QDelink())
@@ -115,9 +120,10 @@
 
 void KX_StateActuator::Activate(SG_DList& head)
 {
-	// no need to sort the state actuators
-	if (m_stateActuatorHead.QAddBack(this))
+	// sort the state actuators per object on the global list
+	if (QEmpty())
 	{
+		InsertSelfActiveQList(m_stateActuatorHead, &m_gameobj->m_firstState);
 		// add front to make sure it runs before other actuators
 		head.AddFront(&m_stateActuatorHead);
 	}

Modified: trunk/blender/source/gameengine/SceneGraph/SG_QList.h
===================================================================
--- trunk/blender/source/gameengine/SceneGraph/SG_QList.h	2009-05-20 05:35:53 UTC (rev 20285)
+++ trunk/blender/source/gameengine/SceneGraph/SG_QList.h	2009-05-20 08:45:42 UTC (rev 20286)
@@ -49,7 +49,7 @@
 		T*			m_current;
 	public:
 		typedef iterator<T> _myT;
-		iterator(SG_QList& head) : m_head(head), m_current(NULL) {}
+		iterator(SG_QList& head, SG_QList* current=NULL) : m_head(head) { m_current = (T*)current; }
 		~iterator() {}
 
 		void begin()





More information about the Bf-blender-cvs mailing list