BGE: bookmark option on controller to make them run before all other controllers.
A new bookmark button is available on the controller UI. When set, the controller is guaranteed to execute before all other non-bookmarked controllers, provided it is scheduled for execution. This is useful for initialization scripts that run once at startup or scripts that must set some prerequisite for the other controllers at the start of each logic frame. This feature is also available at python level with the "bookmark" attribute. It can be changed during the game. Note that if several script are bookmarked, their relative order of execution is not guaranteed. Make sure they don't depend on each other.
This commit is contained in:
		@@ -79,6 +79,7 @@ typedef struct bController {
 | 
				
			|||||||
#define CONT_DEL		2
 | 
					#define CONT_DEL		2
 | 
				
			||||||
#define CONT_NEW		4
 | 
					#define CONT_NEW		4
 | 
				
			||||||
#define CONT_MASK		8
 | 
					#define CONT_MASK		8
 | 
				
			||||||
 | 
					#define CONT_PRIO		16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* pyctrl->flag */
 | 
					/* pyctrl->flag */
 | 
				
			||||||
#define CONT_PY_DEBUG	1
 | 
					#define CONT_PY_DEBUG	1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3788,6 +3788,7 @@ void logic_buts(void)
 | 
				
			|||||||
						uiBlockSetEmboss(block, UI_EMBOSSM);
 | 
											uiBlockSetEmboss(block, UI_EMBOSSM);
 | 
				
			||||||
						uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X,	xco, yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Delete Controller");
 | 
											uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X,	xco, yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Delete Controller");
 | 
				
			||||||
						uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Controller settings");
 | 
											uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Controller settings");
 | 
				
			||||||
 | 
											uiDefIconButBitS(block, TOG, CONT_PRIO, B_REDR, ICON_BOOKMARKS, (short)(xco+width-66), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Bookmarl controller to run before all other non-bookmarked controllers on each logic frame");
 | 
				
			||||||
						uiBlockSetEmboss(block, UI_EMBOSSP);
 | 
											uiBlockSetEmboss(block, UI_EMBOSSP);
 | 
				
			||||||
						sprintf(name, "%d", first_bit(cont->state_mask)+1);
 | 
											sprintf(name, "%d", first_bit(cont->state_mask)+1);
 | 
				
			||||||
						uiDefBlockBut(block, controller_state_mask_menu, cont, name, (short)(xco+width-44), yco, 22, 19, "Set controller state index (from 1 to 30)");
 | 
											uiDefBlockBut(block, controller_state_mask_menu, cont, name, (short)(xco+width-44), yco, 22, 19, "Set controller state index (from 1 to 30)");
 | 
				
			||||||
@@ -3796,7 +3797,7 @@ void logic_buts(void)
 | 
				
			|||||||
						if(cont->flag & CONT_SHOW) {
 | 
											if(cont->flag & CONT_SHOW) {
 | 
				
			||||||
							cont->otype= cont->type;
 | 
												cont->otype= cont->type;
 | 
				
			||||||
							uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 70, 19, &cont->type, 0, 0, 0, 0, "Controller type");
 | 
												uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 70, 19, &cont->type, 0, 0, 0, 0, "Controller type");
 | 
				
			||||||
							but= uiDefBut(block, TEX, 1, "", (short)(xco+92), yco, (short)(width-136), 19, cont->name, 0, 31, 0, 0, "Controller name");
 | 
												but= uiDefBut(block, TEX, 1, "", (short)(xco+92), yco, (short)(width-158), 19, cont->name, 0, 31, 0, 0, "Controller name");
 | 
				
			||||||
							uiButSetFunc(but, make_unique_prop_names_cb, cont->name, (void*) 0);
 | 
												uiButSetFunc(but, make_unique_prop_names_cb, cont->name, (void*) 0);
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
							ycoo= yco;
 | 
												ycoo= yco;
 | 
				
			||||||
@@ -3808,7 +3809,7 @@ void logic_buts(void)
 | 
				
			|||||||
							glRecti(xco+22, yco, xco+width-22,yco+19);
 | 
												glRecti(xco+22, yco, xco+width-22,yco+19);
 | 
				
			||||||
							but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 70, 19, cont, 0, 0, 0, 0, "Controller type");
 | 
												but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 70, 19, cont, 0, 0, 0, 0, "Controller type");
 | 
				
			||||||
							uiButSetFunc(but, sca_move_controller, cont, NULL);
 | 
												uiButSetFunc(but, sca_move_controller, cont, NULL);
 | 
				
			||||||
							but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+92), yco,(short)(width-136), 19, cont, 0, 0, 0, 0, "Controller name");
 | 
												but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+92), yco,(short)(width-158), 19, cont, 0, 0, 0, 0, "Controller name");
 | 
				
			||||||
							uiButSetFunc(but, sca_move_controller, cont, NULL);
 | 
												uiButSetFunc(but, sca_move_controller, cont, NULL);
 | 
				
			||||||
							ycoo= yco;
 | 
												ycoo= yco;
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -199,6 +199,7 @@ void BL_ConvertControllers(
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
 | 
								LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
 | 
				
			||||||
			gamecontroller->SetExecutePriority(executePriority++);
 | 
								gamecontroller->SetExecutePriority(executePriority++);
 | 
				
			||||||
 | 
								gamecontroller->SetBookmark((bcontr->flag & CONT_PRIO) != 0);
 | 
				
			||||||
			gamecontroller->SetState(bcontr->state_mask);
 | 
								gamecontroller->SetState(bcontr->state_mask);
 | 
				
			||||||
			STR_String uniquename = bcontr->name;
 | 
								STR_String uniquename = bcontr->name;
 | 
				
			||||||
			uniquename += "#CONTR#";
 | 
								uniquename += "#CONTR#";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -244,6 +244,7 @@ PyAttributeDef SCA_IController::Attributes[] = {
 | 
				
			|||||||
	KX_PYATTRIBUTE_RO_FUNCTION("state", SCA_IController, pyattr_get_state),
 | 
						KX_PYATTRIBUTE_RO_FUNCTION("state", SCA_IController, pyattr_get_state),
 | 
				
			||||||
	KX_PYATTRIBUTE_RO_FUNCTION("sensors", SCA_IController, pyattr_get_sensors),
 | 
						KX_PYATTRIBUTE_RO_FUNCTION("sensors", SCA_IController, pyattr_get_sensors),
 | 
				
			||||||
	KX_PYATTRIBUTE_RO_FUNCTION("actuators", SCA_IController, pyattr_get_actuators),
 | 
						KX_PYATTRIBUTE_RO_FUNCTION("actuators", SCA_IController, pyattr_get_actuators),
 | 
				
			||||||
 | 
						KX_PYATTRIBUTE_BOOL_RW("bookmark",SCA_IController,m_bookmark),
 | 
				
			||||||
	{ NULL }	//Sentinel
 | 
						{ NULL }	//Sentinel
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,6 +45,7 @@ protected:
 | 
				
			|||||||
	std::vector<class SCA_IActuator*>	m_linkedactuators;
 | 
						std::vector<class SCA_IActuator*>	m_linkedactuators;
 | 
				
			||||||
	unsigned int						m_statemask;
 | 
						unsigned int						m_statemask;
 | 
				
			||||||
	bool								m_justActivated;
 | 
						bool								m_justActivated;
 | 
				
			||||||
 | 
						bool								m_bookmark;
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	SCA_IController(SCA_IObject* gameobj,PyTypeObject* T);
 | 
						SCA_IController(SCA_IObject* gameobj,PyTypeObject* T);
 | 
				
			||||||
	virtual ~SCA_IController();
 | 
						virtual ~SCA_IController();
 | 
				
			||||||
@@ -76,13 +77,24 @@ public:
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		m_justActivated = false;
 | 
							m_justActivated = false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						void SetBookmark(bool bookmark)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							m_bookmark = bookmark;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	void Activate(SG_DList& head)
 | 
						void Activate(SG_DList& head)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (QEmpty())
 | 
							if (QEmpty())
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			InsertActiveQList(m_gameobj->m_activeControllers);
 | 
								if (m_bookmark)
 | 
				
			||||||
			head.AddBack(&m_gameobj->m_activeControllers);
 | 
								{
 | 
				
			||||||
 | 
									m_gameobj->m_activeBookmarkedControllers.QAddBack(this);
 | 
				
			||||||
 | 
									head.AddFront(&m_gameobj->m_activeBookmarkedControllers);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									InsertActiveQList(m_gameobj->m_activeControllers);
 | 
				
			||||||
 | 
									head.AddBack(&m_gameobj->m_activeControllers);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,13 +39,12 @@
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0);
 | 
					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_suspended = false;
 | 
						m_suspended = false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
SCA_IObject::~SCA_IObject()
 | 
					SCA_IObject::~SCA_IObject()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -64,11 +64,16 @@ protected:
 | 
				
			|||||||
	// SG_QList: Head of active actuators list on this object
 | 
						// SG_QList: Head of active actuators list on this object
 | 
				
			||||||
	//           Elements: SCA_IActuator
 | 
						//           Elements: SCA_IActuator
 | 
				
			||||||
	SG_QList			   m_activeActuators;
 | 
						SG_QList			   m_activeActuators;
 | 
				
			||||||
	// SG_Dlist: element of objects with active controllers
 | 
						// SG_Dlist: element of list os lists with active controllers
 | 
				
			||||||
	//           Head: SCA_LogicManager::m_activeControllers
 | 
						//           Head: SCA_LogicManager::m_activeControllers
 | 
				
			||||||
	// SG_QList: Head of active controller list on this object
 | 
						// SG_QList: Head of active controller list on this object
 | 
				
			||||||
	//           Elements: SCA_IController
 | 
						//           Elements: SCA_IController
 | 
				
			||||||
	SG_QList			   m_activeControllers;
 | 
						SG_QList			   m_activeControllers;
 | 
				
			||||||
 | 
						// SG_Dlist: element of list of lists of active controllers
 | 
				
			||||||
 | 
						//           Head: SCA_LogicManager::m_activeControllers
 | 
				
			||||||
 | 
						// SG_QList: Head of active bookmarked controller list globally
 | 
				
			||||||
 | 
						//           Elements: SCA_IController with bookmark option
 | 
				
			||||||
 | 
						static SG_QList		   m_activeBookmarkedControllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static class MT_Point3 m_sDummy;
 | 
						static class MT_Point3 m_sDummy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,6 +33,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "SCA_IActuator.h"
 | 
					#include "SCA_IActuator.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Use of SG_DList : element of actuator being deactivated
 | 
				
			||||||
 | 
					 *                   Head: SCA_LogicManager::m_removedActuators
 | 
				
			||||||
 | 
					 * Use of SG_QList : element of global activated state actuator list 
 | 
				
			||||||
 | 
					 *                   Head: KX_StateActuator::m_stateActuatorHead
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
class KX_StateActuator : public SCA_IActuator
 | 
					class KX_StateActuator : public SCA_IActuator
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	Py_Header;
 | 
						Py_Header;
 | 
				
			||||||
@@ -46,6 +53,10 @@ class KX_StateActuator : public SCA_IActuator
 | 
				
			|||||||
		OP_NEG,
 | 
							OP_NEG,
 | 
				
			||||||
		OP_COUNT
 | 
							OP_COUNT
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
						// SG_Dlist: element of objects with active actuators, always put in front of the list
 | 
				
			||||||
 | 
						//           Head: SCA_LogicManager::m_activeActuators
 | 
				
			||||||
 | 
						// SG_QList: Head of active state actuators list globally
 | 
				
			||||||
 | 
						//           Elements: KX_StateActuator
 | 
				
			||||||
	static SG_QList	m_stateActuatorHead;
 | 
						static SG_QList	m_stateActuatorHead;
 | 
				
			||||||
	int				m_operation;
 | 
						int				m_operation;
 | 
				
			||||||
	int				m_mask;
 | 
						int				m_mask;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -240,6 +240,10 @@ class SCA_IController(SCA_ILogicBrick):
 | 
				
			|||||||
						- note: the sensors are not necessarily owned by the same object.
 | 
											- note: the sensors are not necessarily owned by the same object.
 | 
				
			||||||
						- note: when objects are instanced in dupligroups links may be lost from objects outside the dupligroup.
 | 
											- note: when objects are instanced in dupligroups links may be lost from objects outside the dupligroup.
 | 
				
			||||||
	@type actuators: sequence supporting index/string lookups and iteration.
 | 
						@type actuators: sequence supporting index/string lookups and iteration.
 | 
				
			||||||
 | 
						@ivar bookmark: the bookmark option.
 | 
				
			||||||
 | 
						                If set, the controller executes always before all other non-bookmarked controllers.
 | 
				
			||||||
 | 
						                - note: Order of execution between bookmarked controllers is not guaranteed.
 | 
				
			||||||
 | 
						@type bookmark: bool
 | 
				
			||||||
	"""
 | 
						"""
 | 
				
			||||||
#{ Deprecated
 | 
					#{ Deprecated
 | 
				
			||||||
	def getState():
 | 
						def getState():
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user