Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/GameLogic')
-rw-r--r--source/gameengine/GameLogic/CMakeLists.txt1
-rw-r--r--source/gameengine/GameLogic/Joystick/Makefile2
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp63
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_Joystick.h55
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h2
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp50
-rw-r--r--source/gameengine/GameLogic/Makefile1
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.cpp21
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.h3
-rw-r--r--source/gameengine/GameLogic/SCA_ANDController.cpp28
-rw-r--r--source/gameengine/GameLogic/SCA_ANDController.h1
-rw-r--r--source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp10
-rw-r--r--source/gameengine/GameLogic/SCA_ActuatorSensor.cpp17
-rw-r--r--source/gameengine/GameLogic/SCA_ActuatorSensor.h3
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp5
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysSensor.cpp17
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysSensor.h4
-rw-r--r--source/gameengine/GameLogic/SCA_DelaySensor.cpp17
-rw-r--r--source/gameengine/GameLogic/SCA_DelaySensor.h3
-rw-r--r--source/gameengine/GameLogic/SCA_EventManager.cpp7
-rw-r--r--source/gameengine/GameLogic/SCA_EventManager.h5
-rw-r--r--source/gameengine/GameLogic/SCA_ExpressionController.cpp29
-rw-r--r--source/gameengine/GameLogic/SCA_ExpressionController.h1
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.cpp106
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.h47
-rw-r--r--source/gameengine/GameLogic/SCA_IController.cpp249
-rw-r--r--source/gameengine/GameLogic/SCA_IController.h63
-rw-r--r--source/gameengine/GameLogic/SCA_IInputDevice.h1
-rw-r--r--source/gameengine/GameLogic/SCA_ILogicBrick.cpp66
-rw-r--r--source/gameengine/GameLogic/SCA_ILogicBrick.h56
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.cpp81
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.h69
-rw-r--r--source/gameengine/GameLogic/SCA_IScene.cpp2
-rw-r--r--source/gameengine/GameLogic/SCA_IScene.h2
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.cpp176
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.h59
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickManager.cpp11
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickSensor.cpp75
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickSensor.h20
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardManager.cpp7
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.cpp25
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.h3
-rw-r--r--source/gameengine/GameLogic/SCA_LogicManager.cpp305
-rw-r--r--source/gameengine/GameLogic/SCA_LogicManager.h58
-rw-r--r--source/gameengine/GameLogic/SCA_MouseManager.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_MouseSensor.cpp17
-rw-r--r--source/gameengine/GameLogic/SCA_MouseSensor.h3
-rw-r--r--source/gameengine/GameLogic/SCA_NANDController.cpp28
-rw-r--r--source/gameengine/GameLogic/SCA_NANDController.h1
-rw-r--r--source/gameengine/GameLogic/SCA_NORController.cpp28
-rw-r--r--source/gameengine/GameLogic/SCA_NORController.h1
-rw-r--r--source/gameengine/GameLogic/SCA_ORController.cpp26
-rw-r--r--source/gameengine/GameLogic/SCA_ORController.h1
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyActuator.cpp25
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyActuator.h1
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyEventManager.cpp5
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.cpp48
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.h3
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.cpp380
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.h35
-rw-r--r--source/gameengine/GameLogic/SCA_RandomActuator.cpp35
-rw-r--r--source/gameengine/GameLogic/SCA_RandomActuator.h2
-rw-r--r--source/gameengine/GameLogic/SCA_RandomEventManager.cpp5
-rw-r--r--source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp1
-rw-r--r--source/gameengine/GameLogic/SCA_RandomNumberGenerator.h13
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.cpp33
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.h4
-rw-r--r--source/gameengine/GameLogic/SCA_TimeEventManager.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_XNORController.cpp28
-rw-r--r--source/gameengine/GameLogic/SCA_XNORController.h1
-rw-r--r--source/gameengine/GameLogic/SCA_XORController.cpp28
-rw-r--r--source/gameengine/GameLogic/SCA_XORController.h1
-rw-r--r--source/gameengine/GameLogic/SConscript4
73 files changed, 1495 insertions, 1100 deletions
diff --git a/source/gameengine/GameLogic/CMakeLists.txt b/source/gameengine/GameLogic/CMakeLists.txt
index a7519196d50..7e2bc85bd1f 100644
--- a/source/gameengine/GameLogic/CMakeLists.txt
+++ b/source/gameengine/GameLogic/CMakeLists.txt
@@ -31,6 +31,7 @@ SET(INC
../../../source/kernel/gen_system
../../../intern/string
../../../source/gameengine/Expressions
+ ../../../source/gameengine/SceneGraph
../../../intern/moto/include
../../../source/gameengine/Rasterizer
${PYTHON_INC}
diff --git a/source/gameengine/GameLogic/Joystick/Makefile b/source/gameengine/GameLogic/Joystick/Makefile
index 7016f1ed16f..02def1cec62 100644
--- a/source/gameengine/GameLogic/Joystick/Makefile
+++ b/source/gameengine/GameLogic/Joystick/Makefile
@@ -40,5 +40,5 @@ CPPFLAGS += -I$(NAN_STRING)/include
CPPFLAGS += -I$(NAN_MOTO)/include
CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
CPPFLAGS += $(NAN_SDLCFLAGS)
-
+CPPFLAGS += -I../../SceneGraph
CPPFLAGS += -I../../../kernel/gen_system
diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
index c300baa9bd4..d83179d4f80 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
+++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
@@ -38,11 +38,9 @@ SCA_Joystick::SCA_Joystick(short int index)
:
m_joyindex(index),
m_prec(3200),
- m_buttonnum(-2),
m_axismax(-1),
m_buttonmax(-1),
m_hatmax(-1),
- m_hatdir(-2),
m_isinit(0),
m_istrig_axis(0),
m_istrig_button(0),
@@ -50,6 +48,10 @@ SCA_Joystick::SCA_Joystick(short int index)
{
for(int i=0; i<JOYAXIS_MAX; i++)
m_axis_array[i]= 0;
+
+ for(int i=0; i<JOYHAT_MAX; i++)
+ m_hat_array[i]= 0;
+
#ifndef DISABLE_SDL
m_private = new PrivateData();
#endif
@@ -65,6 +67,7 @@ SCA_Joystick::~SCA_Joystick()
}
SCA_Joystick *SCA_Joystick::m_instance[JOYINDEX_MAX];
+int SCA_Joystick::m_joynum = 0;
int SCA_Joystick::m_refCount = 0;
SCA_Joystick *SCA_Joystick::GetInstance( short int joyindex )
@@ -85,6 +88,9 @@ SCA_Joystick *SCA_Joystick::GetInstance( short int joyindex )
echo("Error-Initializing-SDL: " << SDL_GetError());
return NULL;
}
+
+ m_joynum = SDL_NumJoysticks();
+
for (i=0; i<JOYINDEX_MAX; i++) {
m_instance[i] = new SCA_Joystick(i);
m_instance[i]->CreateJoystickDevice();
@@ -152,12 +158,13 @@ bool SCA_Joystick::aAxisIsPositive(int axis_single)
bool SCA_Joystick::aAnyButtonPressIsPositive(void)
{
- return (m_buttonnum==-2) ? false : true;
-}
-
-bool SCA_Joystick::aAnyButtonReleaseIsPositive(void)
-{
- return (m_buttonnum==-2) ? true : false;
+ /* this is needed for the "all events" option
+ * so we know if there are no buttons pressed */
+ for (int i=0; i<m_buttonmax; i++)
+ if (SDL_JoystickGetButton(m_private->m_joystick, i))
+ return true;
+
+ return false;
}
bool SCA_Joystick::aButtonPressIsPositive(int button)
@@ -184,20 +191,9 @@ bool SCA_Joystick::aButtonReleaseIsPositive(int button)
}
-bool SCA_Joystick::aHatIsPositive(int dir)
+bool SCA_Joystick::aHatIsPositive(int hatnum, int dir)
{
- bool result;
- int res = pGetHat(dir);
- res == dir? result = true : result = false;
- return result;
-}
-
-int SCA_Joystick::pGetHat(int direction)
-{
- if(direction == m_hatdir){
- return m_hatdir;
- }
- return 0;
+ return (GetHat(hatnum)==dir) ? true : false;
}
int SCA_Joystick::GetNumberOfAxes()
@@ -220,12 +216,17 @@ int SCA_Joystick::GetNumberOfHats()
bool SCA_Joystick::CreateJoystickDevice(void)
{
#ifdef DISABLE_SDL
+ m_isinit = true;
+ m_axismax = m_buttonmax = m_hatmax = 0;
return false;
#else
if(m_isinit == false){
- if (m_joyindex>=SDL_NumJoysticks()) {
+ if (m_joyindex>=m_joynum) {
// don't print a message, because this is done anyway
//echo("Joystick-Error: " << SDL_NumJoysticks() << " avaiable joystick(s)");
+
+ // Need this so python args can return empty lists
+ m_axismax = m_buttonmax = m_hatmax = 0;
return false;
}
@@ -237,11 +238,16 @@ bool SCA_Joystick::CreateJoystickDevice(void)
/* must run after being initialized */
m_axismax = SDL_JoystickNumAxes(m_private->m_joystick);
- if (m_axismax > JOYAXIS_MAX) m_axismax= JOYAXIS_MAX; /* very unlikely */
-
m_buttonmax = SDL_JoystickNumButtons(m_private->m_joystick);
m_hatmax = SDL_JoystickNumHats(m_private->m_joystick);
+ if (m_axismax > JOYAXIS_MAX) m_axismax= JOYAXIS_MAX; /* very unlikely */
+ else if (m_axismax < 0) m_axismax = 0;
+
+ if (m_hatmax > JOYHAT_MAX) m_hatmax= JOYHAT_MAX; /* very unlikely */
+ else if(m_hatmax<0) m_hatmax= 0;
+
+ if(m_buttonmax<0) m_buttonmax= 0;
}
return true;
@@ -271,15 +277,6 @@ int SCA_Joystick::Connected(void)
return 0;
}
-void SCA_Joystick::pFillAxes()
-{
-#ifndef DISABLE_SDL
- for(int i=0; i<m_axismax; i++)
- m_axis_array[i]= SDL_JoystickGetAxis(m_private->m_joystick, i);
-#endif
-}
-
-
int SCA_Joystick::pGetAxis(int axisnum, int udlr)
{
#ifndef DISABLE_SDL
diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.h b/source/gameengine/GameLogic/Joystick/SCA_Joystick.h
index 53cd65cd495..6324b898247 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.h
+++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.h
@@ -44,6 +44,7 @@ class SCA_Joystick
{
static SCA_Joystick *m_instance[JOYINDEX_MAX];
+ static int m_joynum;
static int m_refCount;
class PrivateData;
@@ -53,9 +54,14 @@ class SCA_Joystick
int m_joyindex;
/*
- *support for 2 axes
+ *support for JOYAXIS_MAX axes (in pairs)
*/
int m_axis_array[JOYAXIS_MAX];
+
+ /*
+ *support for JOYHAT_MAX hats (each is a direction)
+ */
+ int m_hat_array[JOYHAT_MAX];
/*
* Precision or range of the axes
@@ -63,24 +69,6 @@ class SCA_Joystick
int m_prec;
/*
- * multiple axis values stored here
- */
- int m_axisnum;
- int m_axisvalue;
-
- /*
- * max # of axes avail
- */
- /*disabled
- int m_axismax;
- */
-
- /*
- * button values stored here
- */
- int m_buttonnum;
-
- /*
* max # of buttons avail
*/
@@ -88,18 +76,6 @@ class SCA_Joystick
int m_buttonmax;
int m_hatmax;
- /*
- * hat values stored here
- */
- int m_hatnum;
- int m_hatdir;
-
- /*
-
- * max # of hats avail
- disabled
- int m_hatmax;
- */
/* is the joystick initialized ?*/
bool m_isinit;
@@ -136,7 +112,6 @@ class SCA_Joystick
/*
* fills the axis mnember values
*/
- void pFillAxes(void);
void pFillButtons(void);
/*
@@ -149,11 +124,6 @@ class SCA_Joystick
*/
int pGetAxis(int axisnum, int udlr);
- /*
- * gets the current hat direction
- */
- int pGetHat(int direction);
-
SCA_Joystick(short int index);
~SCA_Joystick();
@@ -172,10 +142,9 @@ public:
bool aAxisIsPositive(int axis_single); /* check a single axis only */
bool aAnyButtonPressIsPositive(void);
- bool aAnyButtonReleaseIsPositive(void);
bool aButtonPressIsPositive(int button);
bool aButtonReleaseIsPositive(int button);
- bool aHatIsPositive(int dir);
+ bool aHatIsPositive(int hatnum, int dir);
/*
* precision is default '3200' which is overridden by input
@@ -186,13 +155,9 @@ public:
int GetAxisPosition(int index){
return m_axis_array[index];
}
-
- int GetButton(void){
- return m_buttonnum;
- }
- int GetHat(void){
- return m_hatdir;
+ int GetHat(int index){
+ return m_hat_array[index];
}
int GetThreshold(void){
diff --git a/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h b/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h
index 636c4dd5a42..70619ff337a 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h
+++ b/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h
@@ -40,6 +40,8 @@
#define JOYINDEX_MAX 8
#define JOYAXIS_MAX 16
+#define JOYBUT_MAX 18
+#define JOYHAT_MAX 4
#define JOYAXIS_RIGHT 0
#define JOYAXIS_UP 1
diff --git a/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp b/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp
index 8e190060e95..53d3be35f92 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp
+++ b/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp
@@ -35,44 +35,37 @@
#ifndef DISABLE_SDL
void SCA_Joystick::OnAxisMotion(SDL_Event* sdl_event)
{
- pFillAxes();
- m_axisnum = sdl_event->jaxis.axis;
- m_axisvalue = sdl_event->jaxis.value;
+ if(sdl_event->jaxis.axis >= JOYAXIS_MAX)
+ return;
+
+ m_axis_array[sdl_event->jaxis.axis]= sdl_event->jaxis.value;
m_istrig_axis = 1;
}
-
+/* See notes below in the event loop */
void SCA_Joystick::OnHatMotion(SDL_Event* sdl_event)
{
- m_hatdir = sdl_event->jhat.value;
- m_hatnum = sdl_event->jhat.hat;
+ if(sdl_event->jhat.hat >= JOYHAT_MAX)
+ return;
+
+ m_hat_array[sdl_event->jhat.hat]= sdl_event->jhat.value;
m_istrig_hat = 1;
}
+/* See notes below in the event loop */
void SCA_Joystick::OnButtonUp(SDL_Event* sdl_event)
{
m_istrig_button = 1;
-
- /* this is needed for the "all events" option
- * so we know if there are no buttons pressed */
- int i;
- for (i=0; i<m_buttonmax; i++) {
- if (SDL_JoystickGetButton(m_private->m_joystick, i)) {
- m_buttonnum = i;
- return;
- }
- }
- m_buttonnum = -2;
}
void SCA_Joystick::OnButtonDown(SDL_Event* sdl_event)
{
- if(sdl_event->jbutton.button <= m_buttonmax) /* unsigned int so always above 0 */
- {
- m_istrig_button = 1;
- m_buttonnum = sdl_event->jbutton.button;
- }
+ //if(sdl_event->jbutton.button > m_buttonmax) /* unsigned int so always above 0 */
+ // return;
+ // sdl_event->jbutton.button;
+
+ m_istrig_button = 1;
}
@@ -81,22 +74,27 @@ void SCA_Joystick::OnNothing(SDL_Event* sdl_event)
m_istrig_axis = m_istrig_button = m_istrig_hat = 0;
}
-/* only handle events for 1 joystick */
-
void SCA_Joystick::HandleEvents(void)
{
SDL_Event sdl_event;
int i;
- for (i=0; i<JOYINDEX_MAX; i++) {
+ for (i=0; i<m_joynum; i++) { /* could use JOYINDEX_MAX but no reason to */
if(SCA_Joystick::m_instance[i])
SCA_Joystick::m_instance[i]->OnNothing(&sdl_event);
}
- if(SDL_PollEvent(&sdl_event))
+ while(SDL_PollEvent(&sdl_event))
{
/* Note! m_instance[sdl_event.jaxis.which]
* will segfault if over JOYINDEX_MAX, not too nice but what are the chances? */
+
+ /* Note!, with buttons, this wont care which button is pressed,
+ * only to set 'm_istrig_button', actual pressed buttons are detected by SDL_JoystickGetButton */
+
+ /* Note!, if you manage to press and release a button within 1 logic tick
+ * it wont work as it should */
+
switch(sdl_event.type)
{
case SDL_JOYAXISMOTION:
diff --git a/source/gameengine/GameLogic/Makefile b/source/gameengine/GameLogic/Makefile
index 355ece6e8bd..a1794a60452 100644
--- a/source/gameengine/GameLogic/Makefile
+++ b/source/gameengine/GameLogic/Makefile
@@ -39,6 +39,7 @@ include nan_compile.mk
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
CPPFLAGS += -I../Expressions
+CPPFLAGS += -I../SceneGraph
CPPFLAGS += -I../Rasterizer
CPPFLAGS += -I$(NAN_STRING)/include
CPPFLAGS += -I$(NAN_MOTO)/include
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
index 251a586308e..caed85b9938 100644
--- a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
@@ -64,8 +64,6 @@ CValue* SCA_2DFilterActuator::GetReplica()
{
SCA_2DFilterActuator* replica = new SCA_2DFilterActuator(*this);
replica->ProcessReplica();
- CValue::AddDataToReplica(replica);
-
return replica;
}
@@ -97,7 +95,7 @@ bool SCA_2DFilterActuator::Update()
}
-void SCA_2DFilterActuator::SetShaderText(STR_String text)
+void SCA_2DFilterActuator::SetShaderText(const char *text)
{
m_shaderText = text;
}
@@ -110,8 +108,13 @@ void SCA_2DFilterActuator::SetShaderText(STR_String text)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_2DFilterActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_2DFilterActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -146,8 +149,8 @@ PyMethodDef SCA_2DFilterActuator::Methods[] = {
PyAttributeDef SCA_2DFilterActuator::Attributes[] = {
KX_PYATTRIBUTE_STRING_RW("shaderText", 0, 64000, false, SCA_2DFilterActuator, m_shaderText),
KX_PYATTRIBUTE_SHORT_RW("disableMotionBlur", 0, 1, true, SCA_2DFilterActuator, m_disableMotionBlur),
- KX_PYATTRIBUTE_ENUM_RW("type",RAS_2DFilterManager::RAS_2DFILTER_ENABLED,RAS_2DFilterManager::RAS_2DFILTER_NUMBER_OF_FILTERS,false,SCA_2DFilterActuator,m_type),
- KX_PYATTRIBUTE_INT_RW("passNb", 0, 100, true, SCA_2DFilterActuator, m_int_arg),
+ KX_PYATTRIBUTE_ENUM_RW("mode",RAS_2DFilterManager::RAS_2DFILTER_ENABLED,RAS_2DFilterManager::RAS_2DFILTER_NUMBER_OF_FILTERS,false,SCA_2DFilterActuator,m_type),
+ KX_PYATTRIBUTE_INT_RW("passNumber", 0, 100, true, SCA_2DFilterActuator, m_int_arg),
KX_PYATTRIBUTE_FLOAT_RW("value", 0.0, 100.0, SCA_2DFilterActuator, m_float_arg),
{ NULL } //Sentinel
};
@@ -157,6 +160,10 @@ PyObject* SCA_2DFilterActuator::py_getattro(PyObject *attr)
py_getattro_up(SCA_IActuator);
}
+PyObject* SCA_2DFilterActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
int SCA_2DFilterActuator::py_setattro(PyObject *attr, PyObject* value)
{
py_setattro_up(SCA_IActuator);
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.h b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
index de0201a4b19..13b9997a010 100644
--- a/source/gameengine/GameLogic/SCA_2DFilterActuator.h
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
@@ -60,7 +60,7 @@ public:
PyTypeObject* T=&Type
);
- void SetShaderText(STR_String text);
+ void SetShaderText(const char *text);
virtual ~SCA_2DFilterActuator();
virtual bool Update();
@@ -71,6 +71,7 @@ public:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject* value);
};
diff --git a/source/gameengine/GameLogic/SCA_ANDController.cpp b/source/gameengine/GameLogic/SCA_ANDController.cpp
index 1cb03f375cb..87f7c612e7c 100644
--- a/source/gameengine/GameLogic/SCA_ANDController.cpp
+++ b/source/gameengine/GameLogic/SCA_ANDController.cpp
@@ -66,26 +66,19 @@ void SCA_ANDController::Trigger(SCA_LogicManager* logicmgr)
!(is==m_linkedsensors.end());is++)
{
SCA_ISensor* sensor = *is;
- if (!sensor->IsPositiveTrigger())
+ if (!sensor->GetState())
{
sensorresult = false;
break;
}
}
- CValue* newevent = new CBoolValue(sensorresult);
-
for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
!(i==m_linkedactuators.end());i++)
{
- SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
- logicmgr->AddActiveActuator(actua,newevent);
+ SCA_IActuator* actua = *i;
+ logicmgr->AddActiveActuator(actua,sensorresult);
}
-
- // every actuator that needs the event, has a it's own reference to it now so
- // release it (so to be clear: if there is no actuator, it's deleted right now)
- newevent->Release();
-
}
@@ -94,7 +87,7 @@ CValue* SCA_ANDController::GetReplica()
{
CValue* replica = new SCA_ANDController(*this);
// this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
return replica;
}
@@ -107,8 +100,13 @@ CValue* SCA_ANDController::GetReplica()
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_ANDController::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_ANDController",
sizeof(PyObjectPlus_Proxy),
0,
@@ -145,4 +143,8 @@ PyObject* SCA_ANDController::py_getattro(PyObject *attr) {
py_getattro_up(SCA_IController);
}
+PyObject* SCA_ANDController::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IController);
+}
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ANDController.h b/source/gameengine/GameLogic/SCA_ANDController.h
index fdb93d0fc42..9a359d57cb4 100644
--- a/source/gameengine/GameLogic/SCA_ANDController.h
+++ b/source/gameengine/GameLogic/SCA_ANDController.h
@@ -49,6 +49,7 @@ public:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
};
diff --git a/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp b/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp
index 768a3a45937..a80b2af55c8 100644
--- a/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp
@@ -51,17 +51,19 @@ SCA_ActuatorEventManager::~SCA_ActuatorEventManager()
void SCA_ActuatorEventManager::NextFrame()
{
// check for changed actuator
- for (set<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
+ SG_DList::iterator<SCA_ISensor> it(m_sensors);
+ for (it.begin();!it.end();++it)
{
- (*it)->Activate(m_logicmgr,NULL);
+ (*it)->Activate(m_logicmgr);
}
}
void SCA_ActuatorEventManager::UpdateFrame()
{
// update the state of actuator before executing them
- for (set<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
+ SG_DList::iterator<SCA_ActuatorSensor> it(m_sensors);
+ for (it.begin();!it.end();++it)
{
- ((SCA_ActuatorSensor*)(*it))->Update();
+ (*it)->Update();
}
} \ No newline at end of file
diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp
index acd906ef9dd..4dad65c5a25 100644
--- a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp
@@ -60,7 +60,7 @@ CValue* SCA_ActuatorSensor::GetReplica()
{
SCA_ActuatorSensor* replica = new SCA_ActuatorSensor(*this);
// m_range_expr must be recalculated on replica!
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
replica->Init();
return replica;
@@ -89,7 +89,7 @@ SCA_ActuatorSensor::~SCA_ActuatorSensor()
-bool SCA_ActuatorSensor::Evaluate(CValue* event)
+bool SCA_ActuatorSensor::Evaluate()
{
if (m_actuator)
{
@@ -122,8 +122,13 @@ void SCA_ActuatorSensor::Update()
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_ActuatorSensor::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_ActuatorSensor",
sizeof(PyObjectPlus_Proxy),
0,
@@ -165,6 +170,10 @@ PyObject* SCA_ActuatorSensor::py_getattro(PyObject *attr) {
py_getattro_up(SCA_ISensor);
}
+PyObject* SCA_ActuatorSensor::py_getattro_dict() {
+ py_getattro_dict_up(SCA_ISensor);
+}
+
int SCA_ActuatorSensor::py_setattro(PyObject *attr, PyObject *value) {
py_setattro_up(SCA_ISensor);
}
diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.h b/source/gameengine/GameLogic/SCA_ActuatorSensor.h
index 21960993497..6655e08dc70 100644
--- a/source/gameengine/GameLogic/SCA_ActuatorSensor.h
+++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.h
@@ -52,7 +52,7 @@ public:
virtual ~SCA_ActuatorSensor();
virtual CValue* GetReplica();
virtual void Init();
- virtual bool Evaluate(CValue* event);
+ virtual bool Evaluate();
virtual bool IsPositiveTrigger();
virtual void ReParent(SCA_IObject* parent);
void Update();
@@ -62,6 +62,7 @@ public:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
/* 3. setProperty */
diff --git a/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp b/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
index 4cd2dfba994..dd3b55abcc9 100644
--- a/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
@@ -51,9 +51,10 @@ SCA_AlwaysEventManager::SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr)
void SCA_AlwaysEventManager::NextFrame()
{
- for (set<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
+ SG_DList::iterator<SCA_ISensor> it(m_sensors);
+ for (it.begin();!it.end();++it)
{
- (*i)->Activate(m_logicmgr, NULL);
+ (*it)->Activate(m_logicmgr);
}
}
diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
index b7ecb0233a1..ff02680f191 100644
--- a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
@@ -72,7 +72,7 @@ CValue* SCA_AlwaysSensor::GetReplica()
{
CValue* replica = new SCA_AlwaysSensor(*this);//m_float,GetName());
// this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
return replica;
}
@@ -86,7 +86,7 @@ bool SCA_AlwaysSensor::IsPositiveTrigger()
-bool SCA_AlwaysSensor::Evaluate(CValue* event)
+bool SCA_AlwaysSensor::Evaluate()
{
/* Nice! :) */
//return true;
@@ -105,8 +105,13 @@ bool SCA_AlwaysSensor::Evaluate(CValue* event)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_AlwaysSensor::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_AlwaysSensor",
sizeof(PyObjectPlus_Proxy),
0,
@@ -143,4 +148,8 @@ PyObject* SCA_AlwaysSensor::py_getattro(PyObject *attr) {
py_getattro_up(SCA_ISensor);
}
+PyObject* SCA_AlwaysSensor::py_getattro_dict() {
+ py_getattro_dict_up(SCA_ISensor);
+}
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.h b/source/gameengine/GameLogic/SCA_AlwaysSensor.h
index 87949babf59..0f85a641ef1 100644
--- a/source/gameengine/GameLogic/SCA_AlwaysSensor.h
+++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.h
@@ -43,7 +43,7 @@ public:
PyTypeObject* T =&Type);
virtual ~SCA_AlwaysSensor();
virtual CValue* GetReplica();
- virtual bool Evaluate(CValue* event);
+ virtual bool Evaluate();
virtual bool IsPositiveTrigger();
virtual void Init();
@@ -53,7 +53,7 @@ public:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
-
+ virtual PyObject* py_getattro_dict();
};
diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.cpp b/source/gameengine/GameLogic/SCA_DelaySensor.cpp
index 44a0175d916..dcdae0b4e75 100644
--- a/source/gameengine/GameLogic/SCA_DelaySensor.cpp
+++ b/source/gameengine/GameLogic/SCA_DelaySensor.cpp
@@ -77,7 +77,7 @@ CValue* SCA_DelaySensor::GetReplica()
{
CValue* replica = new SCA_DelaySensor(*this);
// this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
return replica;
}
@@ -89,7 +89,7 @@ bool SCA_DelaySensor::IsPositiveTrigger()
return (m_invert ? !m_lastResult : m_lastResult);
}
-bool SCA_DelaySensor::Evaluate(CValue* event)
+bool SCA_DelaySensor::Evaluate()
{
bool trigger = false;
bool result;
@@ -131,8 +131,13 @@ bool SCA_DelaySensor::Evaluate(CValue* event)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_DelaySensor::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_DelaySensor",
sizeof(PyObjectPlus_Proxy),
0,
@@ -182,6 +187,10 @@ PyObject* SCA_DelaySensor::py_getattro(PyObject *attr) {
py_getattro_up(SCA_ISensor);
}
+PyObject* SCA_DelaySensor::py_getattro_dict() {
+ py_getattro_dict_up(SCA_ISensor);
+}
+
int SCA_DelaySensor::py_setattro(PyObject *attr, PyObject *value) {
py_setattro_up(SCA_ISensor);
}
diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.h b/source/gameengine/GameLogic/SCA_DelaySensor.h
index 8da76ff7189..5ccb33f8a16 100644
--- a/source/gameengine/GameLogic/SCA_DelaySensor.h
+++ b/source/gameengine/GameLogic/SCA_DelaySensor.h
@@ -51,7 +51,7 @@ public:
PyTypeObject* T =&Type);
virtual ~SCA_DelaySensor();
virtual CValue* GetReplica();
- virtual bool Evaluate(CValue* event);
+ virtual bool Evaluate();
virtual bool IsPositiveTrigger();
virtual void Init();
@@ -61,6 +61,7 @@ public:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
/* setProperty */
diff --git a/source/gameengine/GameLogic/SCA_EventManager.cpp b/source/gameengine/GameLogic/SCA_EventManager.cpp
index e4fd0379597..d1301541a0a 100644
--- a/source/gameengine/GameLogic/SCA_EventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_EventManager.cpp
@@ -28,6 +28,7 @@
#include <assert.h>
#include "SCA_EventManager.h"
+#include "SCA_ISensor.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -43,16 +44,18 @@ SCA_EventManager::SCA_EventManager(EVENT_MANAGER_TYPE mgrtype)
SCA_EventManager::~SCA_EventManager()
{
+ // all sensors should be removed
+ assert(m_sensors.Empty());
}
void SCA_EventManager::RegisterSensor(class SCA_ISensor* sensor)
{
- m_sensors.insert(sensor);
+ m_sensors.AddBack(sensor);
}
void SCA_EventManager::RemoveSensor(class SCA_ISensor* sensor)
{
- m_sensors.erase(sensor);
+ sensor->Delink();
}
void SCA_EventManager::NextFrame(double curtime, double fixedtime)
diff --git a/source/gameengine/GameLogic/SCA_EventManager.h b/source/gameengine/GameLogic/SCA_EventManager.h
index 9dbb5a6d24f..5ff55849bfe 100644
--- a/source/gameengine/GameLogic/SCA_EventManager.h
+++ b/source/gameengine/GameLogic/SCA_EventManager.h
@@ -33,11 +33,14 @@
#include <set>
#include <algorithm>
+#include "SG_DList.h"
+
class SCA_EventManager
{
protected:
// use a set to speed-up insertion/removal
- std::set <class SCA_ISensor*> m_sensors;
+ //std::set <class SCA_ISensor*> m_sensors;
+ SG_DList m_sensors;
public:
enum EVENT_MANAGER_TYPE {
diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.cpp b/source/gameengine/GameLogic/SCA_ExpressionController.cpp
index 352a39a6fea..8e044b89c71 100644
--- a/source/gameengine/GameLogic/SCA_ExpressionController.cpp
+++ b/source/gameengine/GameLogic/SCA_ExpressionController.cpp
@@ -70,7 +70,7 @@ CValue* SCA_ExpressionController::GetReplica()
replica->m_exprText = m_exprText;
replica->m_exprCache = NULL;
// this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
return replica;
}
@@ -115,37 +115,14 @@ void SCA_ExpressionController::Trigger(SCA_LogicManager* logicmgr)
value->Release();
}
- //m_exprCache->Release();
- //m_exprCache = NULL;
}
- /*
-
- for (vector<SCA_ISensor*>::const_iterator is=m_linkedsensors.begin();
- !(is==m_linkedsensors.end());is++)
- {
- SCA_ISensor* sensor = *is;
- if (!sensor->IsPositiveTrigger())
- {
- sensorresult = false;
- break;
- }
- }
-
- */
-
- CValue* newevent = new CBoolValue(expressionresult);
-
for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
!(i==m_linkedactuators.end());i++)
{
SCA_IActuator* actua = *i;
- logicmgr->AddActiveActuator(actua,newevent);
+ logicmgr->AddActiveActuator(actua,expressionresult);
}
- //printf("expr %d.",expressionresult);
- // every actuator that needs the event, has a it's own reference to it now so
- // release it (so to be clear: if there is no actuator, it's deleted right now)
- newevent->Release();
}
@@ -161,7 +138,7 @@ CValue* SCA_ExpressionController::FindIdentifier(const STR_String& identifiernam
SCA_ISensor* sensor = *is;
if (sensor->GetName() == identifiername)
{
- identifierval = new CBoolValue(sensor->IsPositiveTrigger());
+ identifierval = new CBoolValue(sensor->GetState());
//identifierval = sensor->AddRef();
}
diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.h b/source/gameengine/GameLogic/SCA_ExpressionController.h
index 2936742be19..6a34d7b2dff 100644
--- a/source/gameengine/GameLogic/SCA_ExpressionController.h
+++ b/source/gameengine/GameLogic/SCA_ExpressionController.h
@@ -60,6 +60,7 @@ public:
/* --------------------------------------------------------------------- */
// virtual PyObject* py_getattro(PyObject *attr);
+// virtual PyObject* py_getattro_dict();
};
diff --git a/source/gameengine/GameLogic/SCA_IActuator.cpp b/source/gameengine/GameLogic/SCA_IActuator.cpp
index 309f3108418..be7c2651686 100644
--- a/source/gameengine/GameLogic/SCA_IActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_IActuator.cpp
@@ -37,53 +37,13 @@ using namespace std;
SCA_IActuator::SCA_IActuator(SCA_IObject* gameobj,
PyTypeObject* T) :
SCA_ILogicBrick(gameobj,T),
- m_links(0)
+ m_links(0),
+ m_posevent(false),
+ m_negevent(false)
{
// nothing to do
}
-
-
-void SCA_IActuator::AddEvent(CValue* event)
-{
- m_events.push_back(event);
-}
-
-
-
-void SCA_IActuator::RemoveAllEvents()
-{ // remove event queue!
- for (vector<CValue*>::iterator i=m_events.begin(); !(i==m_events.end());i++)
- {
- (*i)->Release();
- }
- m_events.clear();
-}
-
-
-
-
-
-bool SCA_IActuator::IsNegativeEvent() const
-{
- bool bPositiveEvent(false);
- bool bNegativeEvent(false);
-
- for (vector<CValue*>::const_iterator i=m_events.begin(); i!=m_events.end();++i)
- {
- if ((*i)->GetNumber() == 0.0f)
- {
- bNegativeEvent = true;
- } else {
- bPositiveEvent = true;
- }
- }
-
- // if at least 1 positive event, return false
-
- return !bPositiveEvent && bNegativeEvent;
-}
-
bool SCA_IActuator::Update(double curtime, bool frame)
{
if (frame)
@@ -98,9 +58,34 @@ bool SCA_IActuator::Update()
return false;
}
+void SCA_IActuator::Activate(SG_DList& head)
+{
+ if (QEmpty())
+ {
+ InsertActiveQList(m_gameobj->m_activeActuators);
+ head.AddBack(&m_gameobj->m_activeActuators);
+ }
+}
+
+// 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())
+ {
+ // the actuator was in the active list
+ if (m_gameobj->m_activeActuators.QEmpty())
+ // the owner object has no more active actuators, remove it from the global list
+ m_gameobj->m_activeActuators.Delink();
+ }
+}
+
+
void SCA_IActuator::ProcessReplica()
{
- m_events.clear();
+ SCA_ILogicBrick::ProcessReplica();
+ RemoveAllEvents();
+ m_linkedcontrollers.clear();
}
@@ -119,3 +104,36 @@ void SCA_IActuator::DecLink()
m_links = 0;
}
}
+
+void SCA_IActuator::LinkToController(SCA_IController* controller)
+{
+ m_linkedcontrollers.push_back(controller);
+}
+
+void SCA_IActuator::UnlinkController(SCA_IController* controller)
+{
+ std::vector<class SCA_IController*>::iterator contit;
+ for (contit = m_linkedcontrollers.begin();!(contit==m_linkedcontrollers.end());++contit)
+ {
+ if ((*contit) == controller)
+ {
+ *contit = m_linkedcontrollers.back();
+ m_linkedcontrollers.pop_back();
+ return;
+ }
+ }
+ printf("Missing link from actuator %s:%s to controller %s:%s\n",
+ m_gameobj->GetName().ReadPtr(), GetName().ReadPtr(),
+ controller->GetParent()->GetName().ReadPtr(), controller->GetName().ReadPtr());
+}
+
+void SCA_IActuator::UnlinkAllControllers()
+{
+ std::vector<class SCA_IController*>::iterator contit;
+ for (contit = m_linkedcontrollers.begin();!(contit==m_linkedcontrollers.end());++contit)
+ {
+ (*contit)->UnlinkActuator(this);
+ }
+ m_linkedcontrollers.clear();
+}
+
diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h
index 51bd6454d92..27afcbc386b 100644
--- a/source/gameengine/GameLogic/SCA_IActuator.h
+++ b/source/gameengine/GameLogic/SCA_IActuator.h
@@ -29,17 +29,32 @@
#ifndef __KX_IACTUATOR
#define __KX_IACTUATOR
-#include "SCA_ILogicBrick.h"
+#include "SCA_IController.h"
#include <vector>
+/*
+ * Use of SG_DList : None
+ * Use of SG_QList : element of activated actuator list of their owner
+ * Head: SCA_IObject::m_activeActuators
+ */
class SCA_IActuator : public SCA_ILogicBrick
{
friend class SCA_LogicManager;
protected:
int m_links; // number of active links to controllers
// when 0, the actuator is automatically stopped
- std::vector<CValue*> m_events;
- void RemoveAllEvents();
+ //std::vector<CValue*> m_events;
+ bool m_posevent;
+ bool m_negevent;
+
+ std::vector<class SCA_IController*> m_linkedcontrollers;
+
+ void RemoveAllEvents()
+ {
+ m_posevent = false;
+ m_negevent = false;
+ }
+
public:
/**
@@ -75,7 +90,15 @@ public:
/**
* Add an event to an actuator.
*/
- void AddEvent(CValue* event);
+ //void AddEvent(CValue* event)
+ void AddEvent(bool event)
+ {
+ if (event)
+ m_posevent = true;
+ else
+ m_negevent = true;
+ }
+
virtual void ProcessReplica();
/**
@@ -84,9 +107,23 @@ public:
* not immediately clear. But usually refers to key-up events
* or events where no action is required.
*/
- bool IsNegativeEvent() const;
+ bool IsNegativeEvent() const
+ {
+ return !m_posevent && m_negevent;
+ }
+
virtual ~SCA_IActuator();
+ /**
+ * remove this actuator from the list of active actuators
+ */
+ virtual void Deactivate();
+ virtual void Activate(SG_DList& head);
+
+ void LinkToController(SCA_IController* controller);
+ void UnlinkController(class SCA_IController* cont);
+ void UnlinkAllControllers();
+
void ClrLink() { m_links=0; }
void IncLink() { m_links++; }
void DecLink();
diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp
index f9c192cae5c..f2c3c83a2d9 100644
--- a/source/gameengine/GameLogic/SCA_IController.cpp
+++ b/source/gameengine/GameLogic/SCA_IController.cpp
@@ -30,6 +30,8 @@
#include "SCA_LogicManager.h"
#include "SCA_IActuator.h"
#include "SCA_ISensor.h"
+#include "PyObjectPlus.h"
+#include "../Ketsji/KX_PythonSeq.h" /* not nice, only need for KX_PythonSeq_CreatePyObject */
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -39,7 +41,8 @@ SCA_IController::SCA_IController(SCA_IObject* gameobj,
PyTypeObject* T)
:
SCA_ILogicBrick(gameobj,T),
- m_statemask(0)
+ m_statemask(0),
+ m_justActivated(false)
{
}
@@ -47,19 +50,19 @@ SCA_IController::SCA_IController(SCA_IObject* gameobj,
SCA_IController::~SCA_IController()
{
- UnlinkAllActuators();
+ //UnlinkAllActuators();
}
-const std::vector<class SCA_ISensor*>& SCA_IController::GetLinkedSensors()
+std::vector<class SCA_ISensor*>& SCA_IController::GetLinkedSensors()
{
return m_linkedsensors;
}
-const std::vector<class SCA_IActuator*>& SCA_IController::GetLinkedActuators()
+std::vector<class SCA_IActuator*>& SCA_IController::GetLinkedActuators()
{
return m_linkedactuators;
}
@@ -68,13 +71,14 @@ const std::vector<class SCA_IActuator*>& SCA_IController::GetLinkedActuators()
void SCA_IController::UnlinkAllSensors()
{
- if (IsActive())
+ std::vector<class SCA_ISensor*>::iterator sensit;
+ for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
{
- std::vector<class SCA_ISensor*>::iterator sensit;
- for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
+ if (IsActive())
{
(*sensit)->DecLink();
}
+ (*sensit)->UnlinkController(this);
}
m_linkedsensors.clear();
}
@@ -83,34 +87,18 @@ void SCA_IController::UnlinkAllSensors()
void SCA_IController::UnlinkAllActuators()
{
- if (IsActive())
+ std::vector<class SCA_IActuator*>::iterator actit;
+ for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
{
- std::vector<class SCA_IActuator*>::iterator actit;
- for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
+ if (IsActive())
{
(*actit)->DecLink();
}
+ (*actit)->UnlinkController(this);
}
m_linkedactuators.clear();
}
-
-
-/*
-void SCA_IController::Trigger(SCA_LogicManager* logicmgr)
-{
- //for (int i=0;i<m_linkedactuators.size();i++)
- for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
- !(i==m_linkedactuators.end());i++)
- {
- SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
-
- logicmgr->AddActiveActuator(actua);
- }
-
-}
-*/
-
void SCA_IController::LinkToActuator(SCA_IActuator* actua)
{
m_linkedactuators.push_back(actua);
@@ -127,18 +115,18 @@ void SCA_IController::UnlinkActuator(class SCA_IActuator* actua)
{
if ((*actit) == actua)
{
- break;
- }
-
- }
- if (!(actit==m_linkedactuators.end()))
- {
- if (IsActive())
- {
- (*actit)->DecLink();
+ if (IsActive())
+ {
+ (*actit)->DecLink();
+ }
+ *actit = m_linkedactuators.back();
+ m_linkedactuators.pop_back();
+ return;
}
- m_linkedactuators.erase(actit);
}
+ printf("Missing link from controller %s:%s to actuator %s:%s\n",
+ m_gameobj->GetName().ReadPtr(), GetName().ReadPtr(),
+ actua->GetParent()->GetName().ReadPtr(), actua->GetName().ReadPtr());
}
void SCA_IController::LinkToSensor(SCA_ISensor* sensor)
@@ -157,20 +145,21 @@ void SCA_IController::UnlinkSensor(class SCA_ISensor* sensor)
{
if ((*sensit) == sensor)
{
- break;
- }
-
- }
- if (!(sensit==m_linkedsensors.end()))
- {
- if (IsActive())
- {
- (*sensit)->DecLink();
+ if (IsActive())
+ {
+ sensor->DecLink();
+ }
+ *sensit = m_linkedsensors.back();
+ m_linkedsensors.pop_back();
+ return;
}
- m_linkedsensors.erase(sensit);
}
+ printf("Missing link from controller %s:%s to sensor %s:%s\n",
+ m_gameobj->GetName().ReadPtr(), GetName().ReadPtr(),
+ sensor->GetParent()->GetName().ReadPtr(), sensor->GetName().ReadPtr());
}
+
void SCA_IController::ApplyState(unsigned int state)
{
std::vector<class SCA_IActuator*>::iterator actit;
@@ -185,13 +174,13 @@ void SCA_IController::ApplyState(unsigned int state)
{
(*actit)->IncLink();
}
+
for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
{
(*sensit)->IncLink();
- // remember that this controller just activated that sensor
- (*sensit)->AddNewController(this);
}
SetActive(true);
+ m_justActivated = true;
}
} else if (IsActive())
{
@@ -204,6 +193,168 @@ void SCA_IController::ApplyState(unsigned int state)
(*sensit)->DecLink();
}
SetActive(false);
+ m_justActivated = false;
}
}
+/* Python api */
+
+PyTypeObject SCA_IController::Type = {
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
+ "SCA_IController",
+ sizeof(PyObjectPlus_Proxy),
+ 0,
+ py_base_dealloc,
+ 0,
+ 0,
+ 0,
+ 0,
+ py_base_repr,
+ 0,0,0,0,0,0,
+ py_base_getattro,
+ py_base_setattro,
+ 0,0,0,0,0,0,0,0,0,
+ Methods
+};
+
+PyParentObject SCA_IController::Parents[] = {
+ &SCA_IController::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_IController::Methods[] = {
+ //Deprecated functions ------>
+ {"getSensor", (PyCFunction) SCA_IController::sPyGetSensor, METH_O},
+ {"getActuator", (PyCFunction) SCA_IController::sPyGetActuator, METH_O},
+ {"getSensors", (PyCFunction) SCA_IController::sPyGetSensors, METH_NOARGS},
+ {"getActuators", (PyCFunction) SCA_IController::sPyGetActuators, METH_NOARGS},
+ {"getState", (PyCFunction) SCA_IController::sPyGetState, METH_NOARGS},
+ //<----- Deprecated
+ {NULL,NULL} //Sentinel
+};
+
+PyAttributeDef SCA_IController::Attributes[] = {
+ KX_PYATTRIBUTE_RO_FUNCTION("state", SCA_IController, pyattr_get_state),
+ KX_PYATTRIBUTE_RO_FUNCTION("sensors", SCA_IController, pyattr_get_sensors),
+ KX_PYATTRIBUTE_RO_FUNCTION("actuators", SCA_IController, pyattr_get_actuators),
+ KX_PYATTRIBUTE_BOOL_RW("useHighPriority",SCA_IController,m_bookmark),
+ { NULL } //Sentinel
+};
+
+PyObject* SCA_IController::py_getattro(PyObject *attr)
+{
+ py_getattro_up(SCA_ILogicBrick);
+}
+
+PyObject* SCA_IController::py_getattro_dict() {
+ py_getattro_dict_up(SCA_ILogicBrick);
+}
+
+int SCA_IController::py_setattro(PyObject *attr, PyObject *value)
+{
+ py_setattro_up(SCA_ILogicBrick);
+}
+
+
+
+PyObject* SCA_IController::PyGetActuators()
+{
+ ShowDeprecationWarning("getActuators()", "the actuators property");
+
+ PyObject* resultlist = PyList_New(m_linkedactuators.size());
+ for (unsigned int index=0;index<m_linkedactuators.size();index++)
+ {
+ PyList_SET_ITEM(resultlist,index, m_linkedactuators[index]->GetProxy());
+ }
+
+ return resultlist;
+}
+
+PyObject* SCA_IController::PyGetSensor(PyObject* value)
+{
+ ShowDeprecationWarning("getSensor(string)", "the sensors[string] property");
+
+ char *scriptArg = PyString_AsString(value);
+ if (scriptArg==NULL) {
+ PyErr_SetString(PyExc_TypeError, "controller.getSensor(string): Python Controller, expected a string (sensor name)");
+ return NULL;
+ }
+
+ for (unsigned int index=0;index<m_linkedsensors.size();index++)
+ {
+ SCA_ISensor* sensor = m_linkedsensors[index];
+ STR_String& realname = sensor->GetName();
+ if (realname == scriptArg)
+ {
+ return sensor->GetProxy();
+ }
+ }
+
+ PyErr_Format(PyExc_AttributeError, "controller.getSensor(string): Python Controller, unable to find requested sensor \"%s\"", scriptArg);
+ return NULL;
+}
+
+PyObject* SCA_IController::PyGetActuator(PyObject* value)
+{
+ ShowDeprecationWarning("getActuator(string)", "the actuators[string] property");
+
+ char *scriptArg = PyString_AsString(value);
+ if (scriptArg==NULL) {
+ PyErr_SetString(PyExc_TypeError, "controller.getActuator(string): Python Controller, expected a string (actuator name)");
+ return NULL;
+ }
+
+ for (unsigned int index=0;index<m_linkedactuators.size();index++)
+ {
+ SCA_IActuator* actua = m_linkedactuators[index];
+ if (actua->GetName() == scriptArg)
+ {
+ return actua->GetProxy();
+ }
+ }
+
+ PyErr_Format(PyExc_AttributeError, "controller.getActuator(string): Python Controller, unable to find requested actuator \"%s\"", scriptArg);
+ return NULL;
+}
+
+PyObject* SCA_IController::PyGetSensors()
+{
+ ShowDeprecationWarning("getSensors()", "the sensors property");
+
+ PyObject* resultlist = PyList_New(m_linkedsensors.size());
+ for (unsigned int index=0;index<m_linkedsensors.size();index++)
+ {
+ PyList_SET_ITEM(resultlist,index, m_linkedsensors[index]->GetProxy());
+ }
+
+ return resultlist;
+}
+
+PyObject* SCA_IController::PyGetState()
+{
+ ShowDeprecationWarning("getState()", "the state property");
+ return PyInt_FromLong(m_statemask);
+}
+
+PyObject* SCA_IController::pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_IController* self= static_cast<SCA_IController*>(self_v);
+ return PyInt_FromLong(self->m_statemask);
+}
+
+PyObject* SCA_IController::pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ return KX_PythonSeq_CreatePyObject((static_cast<SCA_IController*>(self_v))->m_proxy, KX_PYGENSEQ_CONT_TYPE_SENSORS);
+}
+
+PyObject* SCA_IController::pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ return KX_PythonSeq_CreatePyObject((static_cast<SCA_IController*>(self_v))->m_proxy, KX_PYGENSEQ_CONT_TYPE_ACTUATORS);
+}
diff --git a/source/gameengine/GameLogic/SCA_IController.h b/source/gameengine/GameLogic/SCA_IController.h
index f67c0942eb4..a52c57ab3ed 100644
--- a/source/gameengine/GameLogic/SCA_IController.h
+++ b/source/gameengine/GameLogic/SCA_IController.h
@@ -30,28 +30,87 @@
#define __KX_ICONTROLLER
#include "SCA_ILogicBrick.h"
+#include "PyObjectPlus.h"
+/*
+ * Use of SG_DList element: none
+ * Use of SG_QList element: build ordered list of activated controller on the owner object
+ * Head: SCA_IObject::m_activeControllers
+ */
class SCA_IController : public SCA_ILogicBrick
{
+ Py_Header;
protected:
std::vector<class SCA_ISensor*> m_linkedsensors;
std::vector<class SCA_IActuator*> m_linkedactuators;
unsigned int m_statemask;
+ bool m_justActivated;
+ bool m_bookmark;
public:
SCA_IController(SCA_IObject* gameobj,PyTypeObject* T);
virtual ~SCA_IController();
virtual void Trigger(class SCA_LogicManager* logicmgr)=0;
void LinkToSensor(SCA_ISensor* sensor);
void LinkToActuator(SCA_IActuator*);
- const std::vector<class SCA_ISensor*>& GetLinkedSensors();
- const std::vector<class SCA_IActuator*>& GetLinkedActuators();
+ std::vector<class SCA_ISensor*>& GetLinkedSensors();
+ std::vector<class SCA_IActuator*>& GetLinkedActuators();
+ void ReserveActuator(int num)
+ {
+ m_linkedactuators.reserve(num);
+ }
void UnlinkAllSensors();
void UnlinkAllActuators();
void UnlinkActuator(class SCA_IActuator* actua);
void UnlinkSensor(class SCA_ISensor* sensor);
void SetState(unsigned int state) { m_statemask = state; }
void ApplyState(unsigned int state);
+ void Deactivate()
+ {
+ // the controller can only be part of a sensor m_newControllers list
+ Delink();
+ }
+ bool IsJustActivated()
+ {
+ return m_justActivated;
+ }
+ void ClrJustActivated()
+ {
+ m_justActivated = false;
+ }
+ void SetBookmark(bool bookmark)
+ {
+ m_bookmark = bookmark;
+ }
+ void Activate(SG_DList& head)
+ {
+ if (QEmpty())
+ {
+ if (m_bookmark)
+ {
+ m_gameobj->m_activeBookmarkedControllers.QAddBack(this);
+ head.AddFront(&m_gameobj->m_activeBookmarkedControllers);
+ }
+ else
+ {
+ InsertActiveQList(m_gameobj->m_activeControllers);
+ head.AddBack(&m_gameobj->m_activeControllers);
+ }
+ }
+ }
+ virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
+ virtual int py_setattro(PyObject *attr, PyObject *value);
+
+ KX_PYMETHOD_NOARGS(SCA_IController,GetSensors);
+ KX_PYMETHOD_NOARGS(SCA_IController,GetActuators);
+ KX_PYMETHOD_O(SCA_IController,GetSensor);
+ KX_PYMETHOD_O(SCA_IController,GetActuator);
+ KX_PYMETHOD_NOARGS(SCA_IController,GetState);
+
+ static PyObject* pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
};
diff --git a/source/gameengine/GameLogic/SCA_IInputDevice.h b/source/gameengine/GameLogic/SCA_IInputDevice.h
index 66ad457aa03..a0d77ed3c03 100644
--- a/source/gameengine/GameLogic/SCA_IInputDevice.h
+++ b/source/gameengine/GameLogic/SCA_IInputDevice.h
@@ -75,7 +75,6 @@ public:
KX_TIMER0,
KX_TIMER1,
KX_TIMER2,
- KX_TIMER3,
// SYSTEM
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
index 3cd750ff63b..2dc80f54568 100644
--- a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
+++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
@@ -71,13 +71,6 @@ void SCA_ILogicBrick::SetUeberExecutePriority(int execute_Priority)
-SCA_IObject* SCA_ILogicBrick::GetParent()
-{
- return m_gameobj;
-}
-
-
-
void SCA_ILogicBrick::ReParent(SCA_IObject* parent)
{
m_gameobj = parent;
@@ -130,33 +123,17 @@ double SCA_ILogicBrick::GetNumber()
-STR_String SCA_ILogicBrick::GetName()
+STR_String& SCA_ILogicBrick::GetName()
{
return m_name;
}
-void SCA_ILogicBrick::SetName(STR_String name)
-{
- m_name = name;
-}
-
-
-
-void SCA_ILogicBrick::ReplicaSetName(STR_String name)
+void SCA_ILogicBrick::SetName(const char *name)
{
m_name = name;
}
-
-
-
-bool SCA_ILogicBrick::IsActive()
-{
- return m_bActive;
-}
-
-
bool SCA_ILogicBrick::LessComparedTo(SCA_ILogicBrick* other)
{
@@ -165,22 +142,6 @@ bool SCA_ILogicBrick::LessComparedTo(SCA_ILogicBrick* other)
(this->m_Execute_Priority < other->m_Execute_Priority));
}
-
-
-void SCA_ILogicBrick::SetActive(bool active)
-{
- m_bActive=active;
- if (active)
- {
- //m_gameobj->SetDebugColor(GetDrawColor());
- } else
- {
- //m_gameobj->ResetDebugColor();
- }
-}
-
-
-
void SCA_ILogicBrick::RegisterEvent(CValue* eventval)
{
if (m_eventval)
@@ -217,8 +178,13 @@ CValue* SCA_ILogicBrick::GetEvent()
/* python stuff */
PyTypeObject SCA_ILogicBrick::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_ILogicBrick",
sizeof(PyObjectPlus_Proxy),
0,
@@ -256,7 +222,8 @@ PyMethodDef SCA_ILogicBrick::Methods[] = {
PyAttributeDef SCA_ILogicBrick::Attributes[] = {
KX_PYATTRIBUTE_RO_FUNCTION("owner", SCA_ILogicBrick, pyattr_get_owner),
- KX_PYATTRIBUTE_INT_RW("executePriority",0,100000,false,SCA_ILogicBrick,m_Execute_Ueber_Priority),
+ KX_PYATTRIBUTE_INT_RW("executePriority",0,100000,false,SCA_ILogicBrick,m_Execute_Priority),
+ KX_PYATTRIBUTE_STRING_RO("name", SCA_ILogicBrick, m_name),
{NULL} //Sentinel
};
@@ -278,12 +245,15 @@ int SCA_ILogicBrick::CheckProperty(void *self, const PyAttributeDef *attrdef)
return 0;
}
-PyObject*
-SCA_ILogicBrick::py_getattro(PyObject *attr)
+PyObject* SCA_ILogicBrick::py_getattro(PyObject *attr)
{
py_getattro_up(CValue);
}
+PyObject* SCA_ILogicBrick::py_getattro_dict() {
+ py_getattro_dict_up(CValue);
+}
+
int SCA_ILogicBrick::py_setattro(PyObject *attr, PyObject *value)
{
py_setattro_up(CValue);
@@ -316,7 +286,7 @@ PyObject* SCA_ILogicBrick::PySetExecutePriority(PyObject* args)
return NULL;
}
- m_Execute_Ueber_Priority = priority;
+ m_Execute_Priority = priority;
Py_RETURN_NONE;
}
@@ -326,7 +296,7 @@ PyObject* SCA_ILogicBrick::PySetExecutePriority(PyObject* args)
PyObject* SCA_ILogicBrick::PyGetExecutePriority()
{
ShowDeprecationWarning("getExecutePriority()", "the executePriority property");
- return PyInt_FromLong(m_Execute_Ueber_Priority);
+ return PyInt_FromLong(m_Execute_Priority);
}
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h
index e59d05ea051..779e5397a6a 100644
--- a/source/gameengine/GameLogic/SCA_ILogicBrick.h
+++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h
@@ -59,7 +59,8 @@ public:
void SetExecutePriority(int execute_Priority);
void SetUeberExecutePriority(int execute_Priority);
- SCA_IObject* GetParent();
+ SCA_IObject* GetParent() { return m_gameobj; }
+
virtual void ReParent(SCA_IObject* parent);
virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
virtual void Delete() { Release(); }
@@ -70,16 +71,59 @@ public:
virtual const STR_String & GetText();
virtual double GetNumber();
- virtual STR_String GetName();
- virtual void SetName(STR_String name);
- virtual void ReplicaSetName(STR_String name);
+ virtual STR_String& GetName();
+ virtual void SetName(const char *);
- bool IsActive();
- void SetActive(bool active) ;
+ bool IsActive()
+ {
+ return m_bActive;
+ }
+
+ void SetActive(bool active)
+ {
+ m_bActive=active;
+ }
+
+ // insert in a QList at position corresponding to m_Execute_Priority
+ void InsertActiveQList(SG_QList& head)
+ {
+ SG_QList::iterator<SCA_ILogicBrick> it(head);
+ for(it.begin(); !it.end() && m_Execute_Priority > (*it)->m_Execute_Priority; ++it);
+ 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);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
static class SCA_LogicManager* m_sCurrentLogicManager;
diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp
index 75804525e7a..9876f2512c0 100644
--- a/source/gameengine/GameLogic/SCA_IObject.cpp
+++ b/source/gameengine/GameLogic/SCA_IObject.cpp
@@ -39,13 +39,13 @@
#endif
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), m_firstState(NULL)
-SCA_IObject::SCA_IObject(PyTypeObject* T): CValue(T), m_initState(0), m_state(0)
{
m_suspended = false;
}
-
-
SCA_IObject::~SCA_IObject()
{
@@ -70,7 +70,7 @@ SCA_IObject::~SCA_IObject()
}
for (ita = m_actuators.begin(); !(ita==m_actuators.end()); ++ita)
{
- ((CValue*)(*ita))->Release();
+ (*ita)->Delete();
}
//T_InterpolatorList::iterator i;
@@ -79,29 +79,6 @@ SCA_IObject::~SCA_IObject()
//}
}
-
-
-SCA_ControllerList& SCA_IObject::GetControllers()
-{
- return m_controllers;
-}
-
-
-
-SCA_SensorList& SCA_IObject::GetSensors()
-{
- return m_sensors;
-}
-
-
-
-SCA_ActuatorList& SCA_IObject::GetActuators()
-{
- return m_actuators;
-}
-
-
-
void SCA_IObject::AddSensor(SCA_ISensor* act)
{
act->AddRef();
@@ -133,7 +110,7 @@ void SCA_IObject::RegisterActuator(SCA_IActuator* act)
void SCA_IObject::UnregisterActuator(SCA_IActuator* act)
{
SCA_ActuatorList::iterator ita;
- for (ita = m_registeredActuators.begin(); ita != m_registeredActuators.end(); ita++)
+ for (ita = m_registeredActuators.begin(); ita != m_registeredActuators.end(); ++ita)
{
if ((*ita) == act) {
(*ita) = m_registeredActuators.back();
@@ -143,20 +120,6 @@ void SCA_IObject::UnregisterActuator(SCA_IActuator* act)
}
}
-void SCA_IObject::SetIgnoreActivityCulling(bool b)
-{
- m_ignore_activity_culling = b;
-}
-
-
-
-bool SCA_IObject::GetIgnoreActivityCulling()
-{
- return m_ignore_activity_culling;
-}
-
-
-
void SCA_IObject::ReParentLogic()
{
SCA_ActuatorList& oldactuators = GetActuators();
@@ -208,7 +171,7 @@ SCA_ISensor* SCA_IObject::FindSensor(const STR_String& sensorname)
{
SCA_ISensor* foundsensor = NULL;
- for (SCA_SensorList::iterator its = m_sensors.begin();!(its==m_sensors.end());its++)
+ for (SCA_SensorList::iterator its = m_sensors.begin();!(its==m_sensors.end());++its)
{
if ((*its)->GetName() == sensorname)
{
@@ -225,7 +188,7 @@ SCA_IController* SCA_IObject::FindController(const STR_String& controllername)
{
SCA_IController* foundcontroller = NULL;
- for (SCA_ControllerList::iterator itc = m_controllers.begin();!(itc==m_controllers.end());itc++)
+ for (SCA_ControllerList::iterator itc = m_controllers.begin();!(itc==m_controllers.end());++itc)
{
if ((*itc)->GetName() == controllername)
{
@@ -242,7 +205,7 @@ SCA_IActuator* SCA_IObject::FindActuator(const STR_String& actuatorname)
{
SCA_IActuator* foundactuator = NULL;
- for (SCA_ActuatorList::iterator ita = m_actuators.begin();!(ita==m_actuators.end());ita++)
+ for (SCA_ActuatorList::iterator ita = m_actuators.begin();!(ita==m_actuators.end());++ita)
{
if ((*ita)->GetName() == actuatorname)
{
@@ -256,14 +219,6 @@ SCA_IActuator* SCA_IObject::FindActuator(const STR_String& actuatorname)
-void SCA_IObject::SetCurrentTime(float currentTime) {
- //T_InterpolatorList::iterator i;
- //for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
- // (*i)->Execute(currentTime);
- //}
-}
-
-
#if 0
const MT_Point3& SCA_IObject::ConvertPythonPylist(PyObject* pylist)
{
@@ -317,7 +272,7 @@ void SCA_IObject::Suspend()
SCA_SensorList::iterator i = m_sensors.begin();
while (i != m_sensors.end()) {
(*i)->Suspend();
- i++;
+ ++i;
}
}
}
@@ -332,7 +287,7 @@ void SCA_IObject::Resume(void)
SCA_SensorList::iterator i = m_sensors.begin();
while (i != m_sensors.end()) {
(*i)->Resume();
- i++;
+ ++i;
}
}
}
@@ -352,7 +307,7 @@ void SCA_IObject::SetState(unsigned int state)
if (tmpstate != m_state)
{
// update the status of the controllers
- for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++)
+ for (contit = m_controllers.begin(); contit != m_controllers.end(); ++contit)
{
(*contit)->ApplyState(tmpstate);
}
@@ -360,7 +315,7 @@ void SCA_IObject::SetState(unsigned int state)
m_state = state;
if (m_state != tmpstate)
{
- for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++)
+ for (contit = m_controllers.begin(); contit != m_controllers.end(); ++contit)
{
(*contit)->ApplyState(m_state);
}
@@ -375,8 +330,13 @@ void SCA_IObject::SetState(unsigned int state)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_IObject::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_IObject",
sizeof(PyObjectPlus_Proxy),
0,
@@ -418,3 +378,6 @@ PyObject* SCA_IObject::py_getattro(PyObject *attr) {
py_getattro_up(CValue);
}
+PyObject* SCA_IObject::py_getattro_dict() {
+ py_getattro_dict_up(CValue);
+}
diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h
index 44ed3c8f3fe..eae427741ca 100644
--- a/source/gameengine/GameLogic/SCA_IObject.h
+++ b/source/gameengine/GameLogic/SCA_IObject.h
@@ -52,10 +52,30 @@ class SCA_IObject : public CValue
Py_Header;
protected:
+ friend class KX_StateActuator;
+ friend class SCA_IActuator;
+ friend class SCA_IController;
SCA_SensorList m_sensors;
SCA_ControllerList m_controllers;
SCA_ActuatorList m_actuators;
SCA_ActuatorList m_registeredActuators; // actuators that use a pointer to this object
+
+ // SG_Dlist: element of objects with active actuators
+ // Head: SCA_LogicManager::m_activeActuators
+ // SG_QList: Head of active actuators list on this object
+ // Elements: SCA_IActuator
+ SG_QList m_activeActuators;
+ // SG_Dlist: element of list os lists with active controllers
+ // Head: SCA_LogicManager::m_activeControllers
+ // SG_QList: Head of active controller list on this object
+ // Elements: SCA_IController
+ 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;
/**
@@ -78,18 +98,48 @@ protected:
*/
unsigned int m_state;
+ /**
+ * pointer inside state actuator list for sorting
+ */
+ SG_QList* m_firstState;
+
public:
SCA_IObject(PyTypeObject* T=&Type);
virtual ~SCA_IObject();
- SCA_ControllerList& GetControllers();
- SCA_SensorList& GetSensors();
- SCA_ActuatorList& GetActuators();
+ SCA_ControllerList& GetControllers()
+ {
+ return m_controllers;
+ }
+ SCA_SensorList& GetSensors()
+ {
+ return m_sensors;
+ }
+ SCA_ActuatorList& GetActuators()
+ {
+ return m_actuators;
+ }
+ SG_QList& GetActiveActuators()
+ {
+ return m_activeActuators;
+ }
void AddSensor(SCA_ISensor* act);
+ void ReserveSensor(int num)
+ {
+ m_sensors.reserve(num);
+ }
void AddController(SCA_IController* act);
+ void ReserveController(int num)
+ {
+ m_controllers.reserve(num);
+ }
void AddActuator(SCA_IActuator* act);
+ void ReserveActuator(int num)
+ {
+ m_actuators.reserve(num);
+ }
void RegisterActuator(SCA_IActuator* act);
void UnregisterActuator(SCA_IActuator* act);
@@ -97,20 +147,26 @@ public:
SCA_IActuator* FindActuator(const STR_String& actuatorname);
SCA_IController* FindController(const STR_String& controllername);
- void SetCurrentTime(float currentTime);
+ void SetCurrentTime(float currentTime) {}
void ReParentLogic();
/**
* Set whether or not to ignore activity culling requests
*/
- void SetIgnoreActivityCulling(bool b);
+ void SetIgnoreActivityCulling(bool b)
+ {
+ m_ignore_activity_culling = b;
+ }
/**
* Set whether or not this object wants to ignore activity culling
* requests
*/
- bool GetIgnoreActivityCulling();
+ bool GetIgnoreActivityCulling()
+ {
+ return m_ignore_activity_culling;
+ }
/**
* Suspend all progress.
@@ -146,6 +202,7 @@ public:
// here come the python forwarded methods
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int GetGameObjectType() {return -1;}
diff --git a/source/gameengine/GameLogic/SCA_IScene.cpp b/source/gameengine/GameLogic/SCA_IScene.cpp
index 9fbeb706910..86b176a38b0 100644
--- a/source/gameengine/GameLogic/SCA_IScene.cpp
+++ b/source/gameengine/GameLogic/SCA_IScene.cpp
@@ -50,7 +50,7 @@ SCA_IScene::SCA_IScene()
void SCA_IScene::RemoveAllDebugProperties()
{
for (std::vector<SCA_DebugProp*>::iterator it = m_debugList.begin();
- !(it==m_debugList.end());it++)
+ !(it==m_debugList.end());++it)
{
delete (*it);
}
diff --git a/source/gameengine/GameLogic/SCA_IScene.h b/source/gameengine/GameLogic/SCA_IScene.h
index d18778a37c2..b641efc6ee1 100644
--- a/source/gameengine/GameLogic/SCA_IScene.h
+++ b/source/gameengine/GameLogic/SCA_IScene.h
@@ -52,7 +52,7 @@ public:
int lifespan=0)=0;
virtual void RemoveObject(class CValue* gameobj)=0;
virtual void DelayedRemoveObject(class CValue* gameobj)=0;
- virtual void DelayedReleaseObject(class CValue* gameobj)=0;
+ //virtual void DelayedReleaseObject(class CValue* gameobj)=0;
virtual void ReplaceMesh(class CValue* gameobj,
void* meshobj)=0;
diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp
index 68f5653d53a..2783bf14600 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.cpp
+++ b/source/gameengine/GameLogic/SCA_ISensor.cpp
@@ -45,26 +45,28 @@ void SCA_ISensor::ReParent(SCA_IObject* parent)
SCA_ILogicBrick::ReParent(parent);
// will be done when the sensor is activated
//m_eventmgr->RegisterSensor(this);
- this->SetActive(false);
+ //this->SetActive(false);
}
SCA_ISensor::SCA_ISensor(SCA_IObject* gameobj,
class SCA_EventManager* eventmgr,
PyTypeObject* T ) :
- SCA_ILogicBrick(gameobj,T),
- m_triggered(false)
+ SCA_ILogicBrick(gameobj,T)
{
m_links = 0;
m_suspended = false;
m_invert = false;
m_level = false;
+ m_tap = false;
m_reset = false;
m_pos_ticks = 0;
m_neg_ticks = 0;
m_pos_pulsemode = false;
m_neg_pulsemode = false;
m_pulse_frequency = 0;
+ m_state = false;
+ m_prev_state = false;
m_eventmgr = eventmgr;
}
@@ -75,6 +77,12 @@ SCA_ISensor::~SCA_ISensor()
// intentionally empty
}
+void SCA_ISensor::ProcessReplica()
+{
+ SCA_ILogicBrick::ProcessReplica();
+ m_linkedcontrollers.clear();
+}
+
bool SCA_ISensor::IsPositiveTrigger() {
bool result = false;
@@ -104,9 +112,13 @@ void SCA_ISensor::SetLevel(bool lvl) {
m_level = lvl;
}
+void SCA_ISensor::SetTap(bool tap) {
+ m_tap = tap;
+}
+
double SCA_ISensor::GetNumber() {
- return IsPositiveTrigger();
+ return GetState();
}
void SCA_ISensor::Suspend() {
@@ -143,27 +155,80 @@ void SCA_ISensor::RegisterToManager()
{
// sensor is just activated, initialize it
Init();
- m_newControllers.erase(m_newControllers.begin(), m_newControllers.end());
+ m_state = false;
m_eventmgr->RegisterSensor(this);
}
+void SCA_ISensor::LinkToController(SCA_IController* controller)
+{
+ m_linkedcontrollers.push_back(controller);
+}
+
+void SCA_ISensor::UnlinkController(SCA_IController* controller)
+{
+ std::vector<class SCA_IController*>::iterator contit;
+ for (contit = m_linkedcontrollers.begin();!(contit==m_linkedcontrollers.end());++contit)
+ {
+ if ((*contit) == controller)
+ {
+ *contit = m_linkedcontrollers.back();
+ m_linkedcontrollers.pop_back();
+ return;
+ }
+ }
+ printf("Missing link from sensor %s:%s to controller %s:%s\n",
+ m_gameobj->GetName().ReadPtr(), GetName().ReadPtr(),
+ controller->GetParent()->GetName().ReadPtr(), controller->GetName().ReadPtr());
+}
+
+void SCA_ISensor::UnlinkAllControllers()
+{
+ std::vector<class SCA_IController*>::iterator contit;
+ for (contit = m_linkedcontrollers.begin();!(contit==m_linkedcontrollers.end());++contit)
+ {
+ (*contit)->UnlinkSensor(this);
+ }
+ m_linkedcontrollers.clear();
+}
+
void SCA_ISensor::UnregisterToManager()
{
m_eventmgr->RemoveSensor(this);
+ m_links = 0;
+}
+
+void SCA_ISensor::ActivateControllers(class SCA_LogicManager* logicmgr)
+{
+ for(vector<SCA_IController*>::const_iterator c= m_linkedcontrollers.begin();
+ c!=m_linkedcontrollers.end();++c)
+ {
+ SCA_IController* contr = *c;
+ if (contr->IsActive())
+ logicmgr->AddTriggeredController(contr, this);
+ }
}
-void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event)
+void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr)
{
// calculate if a __triggering__ is wanted
// don't evaluate a sensor that is not connected to any controller
if (m_links && !m_suspended) {
- bool result = this->Evaluate(event);
+ bool result = this->Evaluate();
+ // store the state for the rest of the logic system
+ m_prev_state = m_state;
+ m_state = this->IsPositiveTrigger();
if (result) {
- logicmgr->AddActivatedSensor(this);
- // reset these counters so that pulse are synchronized with transition
- m_pos_ticks = 0;
- m_neg_ticks = 0;
+ // the sensor triggered this frame
+ if (m_state || !m_tap) {
+ ActivateControllers(logicmgr);
+ // reset these counters so that pulse are synchronized with transition
+ m_pos_ticks = 0;
+ m_neg_ticks = 0;
+ } else
+ {
+ result = false;
+ }
} else
{
/* First, the pulsing behaviour, if pulse mode is
@@ -172,41 +237,55 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event)
if (m_pos_pulsemode) {
m_pos_ticks++;
if (m_pos_ticks > m_pulse_frequency) {
- if ( this->IsPositiveTrigger() )
+ if ( m_state )
{
- logicmgr->AddActivatedSensor(this);
+ ActivateControllers(logicmgr);
+ result = true;
}
m_pos_ticks = 0;
}
}
-
- if (m_neg_pulsemode)
+ // negative pulse doesn't make sense in tap mode, skip
+ if (m_neg_pulsemode && !m_tap)
{
m_neg_ticks++;
if (m_neg_ticks > m_pulse_frequency) {
- if (!this->IsPositiveTrigger() )
+ if (!m_state )
{
- logicmgr->AddActivatedSensor(this);
+ ActivateControllers(logicmgr);
+ result = true;
}
m_neg_ticks = 0;
}
}
}
- if (!m_newControllers.empty())
+ if (m_tap)
{
- if (!IsActive() && m_level)
+ // in tap mode: we send always a negative pulse immediately after a positive pulse
+ if (!result)
{
- // This level sensor is connected to at least one controller that was just made
- // active but it did not generate an event yet, do it now to those controllers only
- for (std::vector<SCA_IController*>::iterator ci=m_newControllers.begin();
- ci != m_newControllers.end(); ci++)
+ // the sensor did not trigger on this frame
+ if (m_prev_state)
{
- logicmgr->AddTriggeredController(*ci, this);
+ // but it triggered on previous frame => send a negative pulse
+ ActivateControllers(logicmgr);
+ result = true;
}
+ // in any case, absence of trigger means sensor off
+ m_state = false;
+ }
+ }
+ if (!result && m_level)
+ {
+ // This level sensor is connected to at least one controller that was just made
+ // active but it did not generate an event yet, do it now to those controllers only
+ for(vector<SCA_IController*>::const_iterator c= m_linkedcontrollers.begin();
+ c!=m_linkedcontrollers.end();++c)
+ {
+ SCA_IController* contr = *c;
+ if (contr->IsJustActivated())
+ logicmgr->AddTriggeredController(contr, this);
}
- // clear the list. Instead of using clear, which also release the memory,
- // use erase, which keeps the memory available for next time.
- m_newControllers.erase(m_newControllers.begin(), m_newControllers.end());
}
}
}
@@ -221,7 +300,7 @@ const char SCA_ISensor::IsPositive_doc[] =
PyObject* SCA_ISensor::PyIsPositive()
{
ShowDeprecationWarning("isPositive()", "the read-only positive property");
- int retval = IsPositiveTrigger();
+ int retval = GetState();
return PyInt_FromLong(retval);
}
@@ -385,6 +464,7 @@ KX_PYMETHODDEF_DOC_NOARGS(SCA_ISensor, reset,
"\tThe sensor is put in its initial state as if it was just activated.\n")
{
Init();
+ m_prev_state = false;
Py_RETURN_NONE;
}
@@ -393,8 +473,13 @@ KX_PYMETHODDEF_DOC_NOARGS(SCA_ISensor, reset,
/* ----------------------------------------------- */
PyTypeObject SCA_ISensor::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_ISensor",
sizeof(PyObjectPlus_Proxy),
0,
@@ -453,18 +538,25 @@ PyAttributeDef SCA_ISensor::Attributes[] = {
KX_PYATTRIBUTE_BOOL_RW("useNegPulseMode",SCA_ISensor,m_neg_pulsemode),
KX_PYATTRIBUTE_INT_RW("frequency",0,100000,true,SCA_ISensor,m_pulse_frequency),
KX_PYATTRIBUTE_BOOL_RW("invert",SCA_ISensor,m_invert),
- KX_PYATTRIBUTE_BOOL_RW("level",SCA_ISensor,m_level),
+ KX_PYATTRIBUTE_BOOL_RW_CHECK("level",SCA_ISensor,m_level,pyattr_check_level),
+ KX_PYATTRIBUTE_BOOL_RW_CHECK("tap",SCA_ISensor,m_tap,pyattr_check_tap),
KX_PYATTRIBUTE_RO_FUNCTION("triggered", SCA_ISensor, pyattr_get_triggered),
KX_PYATTRIBUTE_RO_FUNCTION("positive", SCA_ISensor, pyattr_get_positive),
+ //KX_PYATTRIBUTE_TODO("links"),
+ //KX_PYATTRIBUTE_TODO("posTicks"),
+ //KX_PYATTRIBUTE_TODO("negTicks"),
{ NULL } //Sentinel
};
-PyObject*
-SCA_ISensor::py_getattro(PyObject *attr)
+PyObject* SCA_ISensor::py_getattro(PyObject *attr)
{
py_getattro_up(SCA_ILogicBrick);
}
+PyObject* SCA_ISensor::py_getattro_dict() {
+ py_getattro_dict_up(SCA_ILogicBrick);
+}
+
int SCA_ISensor::py_setattro(PyObject *attr, PyObject *value)
{
py_setattro_up(SCA_ILogicBrick);
@@ -482,7 +574,23 @@ PyObject* SCA_ISensor::pyattr_get_triggered(void *self_v, const KX_PYATTRIBUTE_D
PyObject* SCA_ISensor::pyattr_get_positive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
SCA_ISensor* self= static_cast<SCA_ISensor*>(self_v);
- return PyInt_FromLong(self->IsPositiveTrigger());
+ return PyInt_FromLong(self->GetState());
+}
+
+int SCA_ISensor::pyattr_check_level(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_ISensor* self= static_cast<SCA_ISensor*>(self_v);
+ if (self->m_level)
+ self->m_tap = false;
+ return 0;
+}
+
+int SCA_ISensor::pyattr_check_tap(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_ISensor* self= static_cast<SCA_ISensor*>(self_v);
+ if (self->m_tap)
+ self->m_level = false;
+ return 0;
}
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h
index 6b1c8cca104..9bbd6ed41e4 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.h
+++ b/source/gameengine/GameLogic/SCA_ISensor.h
@@ -32,18 +32,22 @@
#ifndef __SCA_ISENSOR
#define __SCA_ISENSOR
-#include "SCA_ILogicBrick.h"
+#include "SCA_IController.h"
#include <vector>
/**
* Interface Class for all logic Sensors. Implements
- * pulsemode,pulsefrequency */
+ * pulsemode,pulsefrequency
+ * Use of SG_DList element: link sensors to their respective event manager
+ * Head: SCA_EventManager::m_sensors
+ * Use of SG_QList element: not used
+ */
class SCA_ISensor : public SCA_ILogicBrick
{
Py_Header;
+protected:
class SCA_EventManager* m_eventmgr;
- bool m_triggered;
/** Pulse positive pulses? */
bool m_pos_pulsemode;
@@ -66,6 +70,9 @@ class SCA_ISensor : public SCA_ILogicBrick
/** detect level instead of edge*/
bool m_level;
+ /** tap mode */
+ bool m_tap;
+
/** sensor has been reset */
bool m_reset;
@@ -75,10 +82,24 @@ class SCA_ISensor : public SCA_ILogicBrick
/** number of connections to controller */
int m_links;
- /** list of controllers that have just activated this sensor because of a state change */
- std::vector<class SCA_IController*> m_newControllers;
+ /** current sensor state */
+ bool m_state;
+
+ /** previous state (for tap option) */
+ bool m_prev_state;
+
+ std::vector<class SCA_IController*> m_linkedcontrollers;
public:
+
+ enum sensortype {
+ ST_NONE = 0,
+ ST_TOUCH,
+ ST_NEAR,
+ ST_RADAR,
+ // to be updated as needed
+ };
+
SCA_ISensor(SCA_IObject* gameobj,
class SCA_EventManager* eventmgr,
PyTypeObject* T );;
@@ -89,8 +110,8 @@ public:
/* an implementation on this level. It requires an evaluate on the lower */
/* level of individual sensors. Mapping the old activate()s is easy. */
/* The IsPosTrig() also has to change, to keep things consistent. */
- void Activate(class SCA_LogicManager* logicmgr,CValue* event);
- virtual bool Evaluate(CValue* event) = 0;
+ void Activate(class SCA_LogicManager* logicmgr);
+ virtual bool Evaluate() = 0;
virtual bool IsPositiveTrigger();
virtual void Init();
@@ -109,23 +130,40 @@ public:
void SetInvert(bool inv);
/** set the level detection on or off */
void SetLevel(bool lvl);
+ void SetTap(bool tap);
virtual void RegisterToManager();
virtual void UnregisterToManager();
+ void ReserveController(int num)
+ {
+ m_linkedcontrollers.reserve(num);
+ }
+ void LinkToController(SCA_IController* controller);
+ void UnlinkController(SCA_IController* controller);
+ void UnlinkAllControllers();
+ void ActivateControllers(class SCA_LogicManager* logicmgr);
+
+ virtual void ProcessReplica();
virtual double GetNumber();
+ virtual sensortype GetSensorType() { return ST_NONE; }
+
/** Stop sensing for a while. */
void Suspend();
/** Is this sensor switched off? */
bool IsSuspended();
+ /** get the state of the sensor: positive or negative */
+ bool GetState()
+ {
+ return m_state;
+ }
+
/** Resume sensing. */
void Resume();
- void AddNewController(class SCA_IController* controller)
- { m_newControllers.push_back(controller); }
void ClrLink()
{ m_links = 0; }
void IncLink()
@@ -137,6 +175,7 @@ public:
/* Python functions: */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
//Deprecated functions ----->
@@ -157,6 +196,8 @@ public:
static PyObject* pyattr_get_triggered(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_positive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_check_level(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_check_tap(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
};
#endif //__SCA_ISENSOR
diff --git a/source/gameengine/GameLogic/SCA_JoystickManager.cpp b/source/gameengine/GameLogic/SCA_JoystickManager.cpp
index f3ce549a637..ff8f3b1c81f 100644
--- a/source/gameengine/GameLogic/SCA_JoystickManager.cpp
+++ b/source/gameengine/GameLogic/SCA_JoystickManager.cpp
@@ -59,20 +59,21 @@ SCA_JoystickManager::~SCA_JoystickManager()
void SCA_JoystickManager::NextFrame(double curtime,double deltatime)
{
- if (m_sensors.size()==0) {
+ if (m_sensors.Empty()) {
return;
}
else {
- set<SCA_ISensor*>::iterator it;
+ ;
#ifndef DISABLE_SDL
SCA_Joystick::HandleEvents(); /* Handle all SDL Joystick events */
#endif
- for (it = m_sensors.begin(); it != m_sensors.end(); it++)
+ SG_DList::iterator<SCA_JoystickSensor> it(m_sensors);
+ for (it.begin();!it.end();++it)
{
- SCA_JoystickSensor* joysensor = (SCA_JoystickSensor*)(*it);
+ SCA_JoystickSensor* joysensor = *it;
if(!joysensor->IsSuspended())
{
- joysensor->Activate(m_logicmgr, NULL);
+ joysensor->Activate(m_logicmgr);
}
}
}
diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
index 1c601eded81..336529667d7 100644
--- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
@@ -87,7 +87,7 @@ CValue* SCA_JoystickSensor::GetReplica()
{
SCA_JoystickSensor* replica = new SCA_JoystickSensor(*this);
// this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
replica->Init();
return replica;
}
@@ -102,7 +102,7 @@ bool SCA_JoystickSensor::IsPositiveTrigger()
}
-bool SCA_JoystickSensor::Evaluate(CValue* event)
+bool SCA_JoystickSensor::Evaluate()
{
SCA_Joystick *js = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
bool result = false;
@@ -198,33 +198,20 @@ bool SCA_JoystickSensor::Evaluate(CValue* event)
case KX_JOYSENSORMODE_HAT:
{
/* what is what!
- numberof = m_hat -- max 2
+ numberof = m_hat -- max 4
direction= m_hatf -- max 12
*/
if (!js->IsTrigHat() && !reset) /* No events from SDL? - dont bother */
return false;
- if(m_hat == 1){
- if(js->aHatIsPositive(m_hatf)){
- m_istrig = 1;
- result = true;
- }else{
- if(m_istrig){
- m_istrig = 0;
- result = true;
- }
- }
- }
- if(m_hat == 2){
- if(js->aHatIsPositive(m_hatf)){
- m_istrig = 1;
+ if((m_bAllEvents && js->GetHat(m_hat-1)) || js->aHatIsPositive(m_hat-1, m_hatf)) {
+ m_istrig = 1;
+ result = true;
+ }else{
+ if(m_istrig){
+ m_istrig = 0;
result = true;
- }else{
- if(m_istrig){
- m_istrig = 0;
- result = true;
- }
}
}
break;
@@ -266,8 +253,13 @@ bool SCA_JoystickSensor::isValid(SCA_JoystickSensor::KX_JOYSENSORMODE m)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_JoystickSensor::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_JoystickSensor",
sizeof(PyObjectPlus_Proxy),
0,
@@ -326,11 +318,13 @@ PyAttributeDef SCA_JoystickSensor::Attributes[] = {
KX_PYATTRIBUTE_INT_LIST_RW_CHECK("hat",0,12,true,SCA_JoystickSensor,m_hat,2,CheckHat),
KX_PYATTRIBUTE_RO_FUNCTION("axisValues", SCA_JoystickSensor, pyattr_get_axis_values),
KX_PYATTRIBUTE_RO_FUNCTION("axisSingle", SCA_JoystickSensor, pyattr_get_axis_single),
+ KX_PYATTRIBUTE_RO_FUNCTION("hatValues", SCA_JoystickSensor, pyattr_get_hat_values),
+ KX_PYATTRIBUTE_RO_FUNCTION("hatSingle", SCA_JoystickSensor, pyattr_get_hat_single),
KX_PYATTRIBUTE_RO_FUNCTION("numAxis", SCA_JoystickSensor, pyattr_get_num_axis),
KX_PYATTRIBUTE_RO_FUNCTION("numButtons", SCA_JoystickSensor, pyattr_get_num_buttons),
KX_PYATTRIBUTE_RO_FUNCTION("numHats", SCA_JoystickSensor, pyattr_get_num_hats),
KX_PYATTRIBUTE_RO_FUNCTION("connected", SCA_JoystickSensor, pyattr_get_connected),
-
+ //KX_PYATTRIBUTE_TODO("events"),
{ NULL } //Sentinel
};
@@ -339,6 +333,10 @@ PyObject* SCA_JoystickSensor::py_getattro(PyObject *attr)
py_getattro_up(SCA_ISensor);
}
+PyObject* SCA_JoystickSensor::py_getattro_dict() {
+ py_getattro_dict_up(SCA_ISensor);
+}
+
int SCA_JoystickSensor::py_setattro(PyObject *attr, PyObject *value)
{
py_setattro_up(SCA_ISensor);
@@ -394,6 +392,8 @@ PyObject* SCA_JoystickSensor::PySetAxis( PyObject* args ) {
}
m_axis = axis;
m_axisf = axisflag;
+
+ CheckAxis((void *)this, NULL); /* clamp values */
Py_RETURN_NONE;
}
@@ -535,6 +535,8 @@ PyObject* SCA_JoystickSensor::PySetHat( PyObject* args ) {
}
m_hat = hat;
m_hatf = hatflag;
+
+ CheckHat((void *)this, NULL); /* clamp values */
Py_RETURN_NONE;
}
@@ -608,6 +610,29 @@ PyObject* SCA_JoystickSensor::pyattr_get_axis_single(void *self_v, const KX_PYAT
return PyInt_FromLong(joy->GetAxisPosition(self->m_axis-1));
}
+PyObject* SCA_JoystickSensor::pyattr_get_hat_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
+ SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex);
+
+ int hat_index= joy->GetNumberOfHats();
+ PyObject *list= PyList_New(hat_index);
+
+ while(hat_index--) {
+ PyList_SET_ITEM(list, hat_index, PyInt_FromLong(joy->GetHat(hat_index)));
+ }
+
+ return list;
+}
+
+PyObject* SCA_JoystickSensor::pyattr_get_hat_single(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
+ SCA_Joystick *joy = self->m_pJoystickMgr->GetJoystickDevice(self->m_joyindex);
+
+ return PyInt_FromLong(joy->GetHat(self->m_hat-1));
+}
+
PyObject* SCA_JoystickSensor::pyattr_get_num_axis(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
SCA_JoystickSensor* self= static_cast<SCA_JoystickSensor*>(self_v);
diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.h b/source/gameengine/GameLogic/SCA_JoystickSensor.h
index cf3e7e74414..e6a1d2eef32 100644
--- a/source/gameengine/GameLogic/SCA_JoystickSensor.h
+++ b/source/gameengine/GameLogic/SCA_JoystickSensor.h
@@ -30,6 +30,7 @@
#define __JOYSENSOR_H
#include "SCA_ISensor.h"
+#include "./Joystick/SCA_JoystickDefines.h"
class SCA_JoystickSensor :public SCA_ISensor
{
@@ -37,7 +38,7 @@ class SCA_JoystickSensor :public SCA_ISensor
class SCA_JoystickManager* m_pJoystickMgr;
/**
- * Axis 1-or-2, MUST be followed by m_axisf
+ * Axis 1-JOYAXIS_MAX, MUST be followed by m_axisf
*/
int m_axis;
/**
@@ -53,11 +54,11 @@ class SCA_JoystickSensor :public SCA_ISensor
*/
int m_buttonf;
/**
- * The actual hat. MUST be followed by m_hatf
+ * The actual hat 1-JOYHAT_MAX. MUST be followed by m_hatf
*/
int m_hat;
/**
- * Flag to find direction 0-11, MUST be an int
+ * Flag to find direction 1-12, MUST be an int
*/
int m_hatf;
/**
@@ -110,7 +111,7 @@ public:
virtual ~SCA_JoystickSensor();
virtual CValue* GetReplica();
- virtual bool Evaluate(CValue* event);
+ virtual bool Evaluate();
virtual bool IsPositiveTrigger();
virtual void Init();
@@ -123,6 +124,7 @@ public:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
/* Joystick Index */
@@ -151,6 +153,8 @@ public:
static PyObject* pyattr_get_axis_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_axis_single(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_hat_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_hat_single(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_num_axis(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_num_buttons(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_num_hats(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
@@ -163,8 +167,8 @@ public:
SCA_JoystickSensor* sensor = reinterpret_cast<SCA_JoystickSensor*>(self);
if (sensor->m_axis < 1)
sensor->m_axis = 1;
- else if (sensor->m_axis > 2)
- sensor->m_axis = 2;
+ else if (sensor->m_axis > JOYAXIS_MAX)
+ sensor->m_axis = JOYAXIS_MAX;
return 0;
}
static int CheckHat(void *self, const PyAttributeDef*)
@@ -172,8 +176,8 @@ public:
SCA_JoystickSensor* sensor = reinterpret_cast<SCA_JoystickSensor*>(self);
if (sensor->m_hat < 1)
sensor->m_hat = 1;
- else if (sensor->m_hat > 2)
- sensor->m_hat = 2;
+ else if (sensor->m_hat > JOYHAT_MAX)
+ sensor->m_hat = JOYHAT_MAX;
return 0;
}
diff --git a/source/gameengine/GameLogic/SCA_KeyboardManager.cpp b/source/gameengine/GameLogic/SCA_KeyboardManager.cpp
index 6a96442b124..279adab94d8 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardManager.cpp
+++ b/source/gameengine/GameLogic/SCA_KeyboardManager.cpp
@@ -62,12 +62,11 @@ void SCA_KeyboardManager::NextFrame()
{
//const SCA_InputEvent& event = GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode)=0;
// cerr << "SCA_KeyboardManager::NextFrame"<< endl;
- set<SCA_ISensor*>::iterator it;
- for (it=m_sensors.begin(); it != m_sensors.end(); it++)
+ SG_DList::iterator<SCA_ISensor> it(m_sensors);
+ for (it.begin();!it.end();++it)
{
- (*it)->Activate(m_logicmanager,NULL);
+ (*it)->Activate(m_logicmanager);
}
-
}
bool SCA_KeyboardManager::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
index c946156283f..f8ee8ed8b41 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
@@ -85,7 +85,7 @@ CValue* SCA_KeyboardSensor::GetReplica()
{
SCA_KeyboardSensor* replica = new SCA_KeyboardSensor(*this);
// this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
replica->Init();
return replica;
}
@@ -118,7 +118,7 @@ bool SCA_KeyboardSensor::TriggerOnAllKeys()
-bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
+bool SCA_KeyboardSensor::Evaluate()
{
bool result = false;
bool reset = m_reset && m_level;
@@ -195,6 +195,9 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
}
}
}
+ if (m_tap)
+ // special case for tap mode: only generate event for new activation
+ result = false;
}
@@ -612,8 +615,13 @@ KX_PYMETHODDEF_DOC_O(SCA_KeyboardSensor, getKeyStatus,
/* ------------------------------------------------------------------------- */
PyTypeObject SCA_KeyboardSensor::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_KeyboardSensor",
sizeof(PyObjectPlus_Proxy),
0,
@@ -664,12 +672,15 @@ PyAttributeDef SCA_KeyboardSensor::Attributes[] = {
{ NULL } //Sentinel
};
-PyObject*
-SCA_KeyboardSensor::py_getattro(PyObject *attr)
+PyObject* SCA_KeyboardSensor::py_getattro(PyObject *attr)
{
py_getattro_up(SCA_ISensor);
}
+PyObject* SCA_KeyboardSensor::py_getattro_dict() {
+ py_getattro_dict_up(SCA_ISensor);
+}
+
int SCA_KeyboardSensor::py_setattro(PyObject *attr, PyObject *value)
{
py_setattro_up(SCA_ISensor);
@@ -691,7 +702,7 @@ PyObject* SCA_KeyboardSensor::pyattr_get_events(void *self_v, const KX_PYATTRIBU
{
PyObject* keypair = PyList_New(2);
PyList_SET_ITEM(keypair,0,PyInt_FromLong(i));
- PyList_SetItem(keypair,1,PyInt_FromLong(inevent.m_status));
+ PyList_SET_ITEM(keypair,1,PyInt_FromLong(inevent.m_status));
PyList_Append(resultlist,keypair);
}
}
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h
index 073b3e6dbe0..033225cd9be 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardSensor.h
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h
@@ -102,7 +102,7 @@ public:
short int GetHotkey();
- virtual bool Evaluate(CValue* event);
+ virtual bool Evaluate();
virtual bool IsPositiveTrigger();
bool TriggerOnAllKeys();
@@ -111,6 +111,7 @@ public:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
//Deprecated functions ----->
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp
index b584b37180f..83271288154 100644
--- a/source/gameengine/GameLogic/SCA_LogicManager.cpp
+++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp
@@ -49,37 +49,14 @@ SCA_LogicManager::SCA_LogicManager()
SCA_LogicManager::~SCA_LogicManager()
{
- /* AddRef() is not used when the objects are added to m_mapStringToGameObjects
- so Release() should not be used either. The memory leak big is fixed
- in BL_ConvertBlenderObjects()
-
- int numgameobj = m_mapStringToGameObjects.size();
- for (int i = 0; i < numgameobj; i++)
- {
- CValue** gameobjptr = m_mapStringToGameObjects.at(i);
- assert(gameobjptr);
- if (gameobjptr)
- (*gameobjptr)->Release();
-
- }
- */
- /*for (int i=0;i<m_sensorcontrollermap.size();i++)
- {
- vector<SCA_IController*>* controllerarray = *(m_sensorcontrollermap[i]);
- delete controllerarray;
- }
- */
- for (vector<SCA_EventManager*>::iterator it = m_eventmanagers.begin();!(it==m_eventmanagers.end());it++)
+ for (vector<SCA_EventManager*>::iterator it = m_eventmanagers.begin();!(it==m_eventmanagers.end());++it)
{
delete (*it);
}
m_eventmanagers.clear();
- m_sensorcontrollermapje.clear();
- m_removedActuators.clear();
- m_activeActuators.clear();
+ assert(m_activeActuators.Empty());
}
-
/*
// this kind of fixes bug 398 but breakes games, so better leave it out for now.
// a removed object's gameobject (and logicbricks and stuff) didn't get released
@@ -171,12 +148,7 @@ void* SCA_LogicManager::FindBlendObjByGameMeshName(const STR_String& gamemeshnam
void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor)
{
- controllerlist contlist = m_sensorcontrollermapje[sensor];
- for (controllerlist::const_iterator c= contlist.begin();!(c==contlist.end());c++)
- {
- (*c)->UnlinkSensor(sensor);
- }
- m_sensorcontrollermapje.erase(sensor);
+ sensor->UnlinkAllControllers();
sensor->UnregisterToManager();
}
@@ -184,35 +156,22 @@ void SCA_LogicManager::RemoveController(SCA_IController* controller)
{
controller->UnlinkAllSensors();
controller->UnlinkAllActuators();
- std::map<SCA_ISensor*,controllerlist>::iterator sit;
- for (sit = m_sensorcontrollermapje.begin();!(sit==m_sensorcontrollermapje.end());++sit)
- {
- (*sit).second.remove(controller);
- }
+ controller->Deactivate();
}
-void SCA_LogicManager::RemoveDestroyedActuator(SCA_IActuator* actuator)
+void SCA_LogicManager::RemoveActuator(SCA_IActuator* actuator)
{
- m_removedActuators.push_back(SmartActuatorPtr(actuator,0));
- // take care that no controller can use this actuator again !
-
- std::map<SCA_ISensor*,controllerlist>::const_iterator sit;
- for (sit = m_sensorcontrollermapje.begin();!(sit==m_sensorcontrollermapje.end());++sit)
- {
- controllerlist contlist = (*sit).second;
- for (list<SCA_IController*>::const_iterator c= contlist.begin();!(c==contlist.end());c++)
- {
- (*c)->UnlinkActuator(actuator);
- }
- }
+ actuator->UnlinkAllControllers();
+ actuator->Deactivate();
+ actuator->SetActive(false);
}
void SCA_LogicManager::RegisterToSensor(SCA_IController* controller,SCA_ISensor* sensor)
{
- m_sensorcontrollermapje[sensor].push_back(controller);
+ sensor->LinkToController(controller);
controller->LinkToSensor(sensor);
}
@@ -220,6 +179,7 @@ void SCA_LogicManager::RegisterToSensor(SCA_IController* controller,SCA_ISensor*
void SCA_LogicManager::RegisterToActuator(SCA_IController* controller,SCA_IActuator* actua)
{
+ actua->LinkToController(controller);
controller->LinkToActuator(actua);
}
@@ -230,88 +190,62 @@ void SCA_LogicManager::BeginFrame(double curtime, double fixedtime)
for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin(); !(ie==m_eventmanagers.end()); ie++)
(*ie)->NextFrame(curtime, fixedtime);
- // for this frame, look up for activated sensors, and build the collection of triggered controllers
- // int numsensors = this->m_activatedsensors.size(); /*unused*/
-
- for (vector<SCA_ISensor*>::const_iterator is=m_activatedsensors.begin();
- !(is==m_activatedsensors.end());is++)
+ for(SG_QList* obj = (SG_QList*)m_triggeredControllerSet.Remove();
+ obj != NULL;
+ obj = (SG_QList*)m_triggeredControllerSet.Remove())
{
- SCA_ISensor* sensor = *is;
- controllerlist contlist = m_sensorcontrollermapje[sensor];
- for (list<SCA_IController*>::const_iterator c= contlist.begin();
- !(c==contlist.end());c++)
+ for(SCA_IController* contr = (SCA_IController*)obj->QRemove();
+ contr != NULL;
+ contr = (SCA_IController*)obj->QRemove())
{
- SCA_IController* contr = *c;//controllerarray->at(c);
- if (contr->IsActive())
- {
- m_triggeredControllerSet.insert(SmartControllerPtr(contr,0));
- // So that the controller knows which sensor has activited it.
- // Only needed for the python controller though.
- if (contr->GetType() == &SCA_PythonController::Type)
- {
- SCA_PythonController* pythonController = (SCA_PythonController*)contr;
- pythonController->AddTriggeredSensor(sensor);
- }
- }
+ contr->Trigger(this);
+ contr->ClrJustActivated();
}
- //sensor->SetActive(false);
}
-
-
- // int numtriggered = triggeredControllerSet.size(); /*unused*/
- for (set<SmartControllerPtr>::iterator tit=m_triggeredControllerSet.begin();
- !(tit==m_triggeredControllerSet.end());tit++)
- {
- (*tit)->Trigger(this);
- }
- m_triggeredControllerSet.clear();
}
void SCA_LogicManager::UpdateFrame(double curtime, bool frame)
{
- vector<SmartActuatorPtr>::iterator ra;
- for (ra = m_removedActuators.begin(); !(ra == m_removedActuators.end()); ra++)
- {
- m_activeActuators.erase(*ra);
- (*ra)->SetActive(false);
- }
- m_removedActuators.clear();
-
- // About to run actuators, but before update the sensors for those which depends on actuators
for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin(); !(ie==m_eventmanagers.end()); ie++)
(*ie)->UpdateFrame();
- for (set<SmartActuatorPtr>::iterator ia = m_activeActuators.begin();!(ia==m_activeActuators.end());ia++)
+ SG_DList::iterator<SG_QList> io(m_activeActuators);
+ for (io.begin(); !io.end(); )
{
- //SCA_IActuator* actua = *ia;
- if (!(*ia)->Update(curtime, frame))
+ 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(); )
{
- //*ia = m_activeactuators.back();
- m_removedActuators.push_back(*ia);
-
- (*ia)->SetActive(false);
- //m_activeactuators.pop_back();
- } else if ((*ia)->IsNoLink())
+ SCA_IActuator* actua = *ia;
+ // increment first to allow removal of inactive actuators.
+ ++ia;
+ if (!actua->Update(curtime, frame))
+ {
+ // 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
+ // make sure it will get a negative event on next frame to stop it
+ // Do this check after Update() rather than before to make sure
+ // that all the actuators that are activated at same time than a state
+ // actuator have a chance to execute.
+ bool event = false;
+ actua->RemoveAllEvents();
+ actua->AddEvent(event);
+ }
+ }
+ if (ahead->QEmpty())
{
- // This actuator has no more links but it still active
- // make sure it will get a negative event on next frame to stop it
- // Do this check after Update() rather than before to make sure
- // that all the actuators that are activated at same time than a state
- // actuator have a chance to execute.
- CValue* event = new CBoolValue(false);
- (*ia)->RemoveAllEvents();
- (*ia)->AddEvent(event);
+ // no more active controller, remove from main list
+ ahead->Delink();
}
}
-
- for ( ra = m_removedActuators.begin(); !(ra == m_removedActuators.end()); ra++)
- {
- m_activeActuators.erase(*ra);
- (*ra)->SetActive(false);
- }
- m_removedActuators.clear();
}
@@ -360,39 +294,17 @@ void SCA_LogicManager::RegisterActionName(const STR_String& actname,void* action
void SCA_LogicManager::EndFrame()
{
- for (vector<SCA_ISensor*>::const_iterator is=m_activatedsensors.begin();
- !(is==m_activatedsensors.end());is++)
- {
- SCA_ISensor* sensor = *is;
- sensor->SetActive(false);
- }
- m_activatedsensors.clear();
-
for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin();
!(ie==m_eventmanagers.end());ie++)
{
(*ie)->EndFrame();
}
-
-
}
-
-void SCA_LogicManager::AddActivatedSensor(SCA_ISensor* sensor)
-{
- // each frame, only add sensor once, and to avoid a seek, or bloated container
- // hold a flag in each sensor, with the 'framenr'
- if (!sensor->IsActive())
- {
- sensor->SetActive(true);
- m_activatedsensors.push_back(sensor);
- }
-}
-
void SCA_LogicManager::AddTriggeredController(SCA_IController* controller, SCA_ISensor* sensor)
{
- m_triggeredControllerSet.insert(SmartControllerPtr(controller,0));
+ controller->Activate(m_triggeredControllerSet);
// so that the controller knows which sensor has activited it
// only needed for python controller
if (controller->GetType() == &SCA_PythonController::Type)
@@ -402,19 +314,6 @@ void SCA_LogicManager::AddTriggeredController(SCA_IController* controller, SCA_I
}
}
-
-void SCA_LogicManager::AddActiveActuator(SCA_IActuator* actua,CValue* event)
-{
- if (!actua->IsActive())
- {
- actua->SetActive(true);
- m_activeActuators.insert(SmartActuatorPtr(actua,0));
- }
- actua->AddEvent(event->AddRef());
-}
-
-
-
SCA_EventManager* SCA_LogicManager::FindEventManager(int eventmgrtype)
{
// find an eventmanager of a certain type
@@ -432,109 +331,3 @@ SCA_EventManager* SCA_LogicManager::FindEventManager(int eventmgrtype)
}
return eventmgr;
}
-
-
-
-SmartActuatorPtr::SmartActuatorPtr(const SmartActuatorPtr& other)
-{
- this->m_actuator = other.m_actuator;
- this->m_actuator->AddRef();
-}
-
-
-
-SmartActuatorPtr::SmartActuatorPtr(SCA_IActuator* actua,int dummy)
-: m_actuator(actua)
-{
- actua->AddRef();
-}
-
-
-
-SmartActuatorPtr::~SmartActuatorPtr()
-{
- m_actuator->Release();
-}
-
-
-
-bool SmartActuatorPtr::operator <(const SmartActuatorPtr& other) const
-{
-
- return m_actuator->LessComparedTo(*other);
-}
-
-
-
-bool SmartActuatorPtr::operator ==(const SmartActuatorPtr& other) const
-{
- bool result2 = other->LessComparedTo(m_actuator);
- return (m_actuator->LessComparedTo(*other) && result2);
-}
-
-
-
-SCA_IActuator* SmartActuatorPtr::operator->() const
-{
- return m_actuator;
-}
-
-
-
-SCA_IActuator* SmartActuatorPtr::operator*() const
-{
- return m_actuator;
-}
-
-
-
-SmartControllerPtr::SmartControllerPtr(const SmartControllerPtr& copy)
-{
- this->m_controller = copy.m_controller;
- this->m_controller->AddRef();
-}
-
-
-
-SmartControllerPtr::SmartControllerPtr(SCA_IController* contr,int dummy)
-: m_controller(contr)
-{
- m_controller->AddRef();
-}
-
-
-
-SmartControllerPtr::~SmartControllerPtr()
-{
- m_controller->Release();
-}
-
-
-
-bool SmartControllerPtr::operator <(const SmartControllerPtr& other) const
-{
- return m_controller->LessComparedTo(*other);
-}
-
-
-
-bool SmartControllerPtr::operator ==(const SmartControllerPtr& other) const
-{
- return (m_controller->LessComparedTo(*other) && other->LessComparedTo(m_controller));
-}
-
-
-
-SCA_IController* SmartControllerPtr::operator->() const
-{
- return m_controller;
-}
-
-
-
-SCA_IController* SmartControllerPtr::operator*() const
-{
- return m_controller;
-}
-
-
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.h b/source/gameengine/GameLogic/SCA_LogicManager.h
index 50383879d8f..53e75e1eaee 100644
--- a/source/gameengine/GameLogic/SCA_LogicManager.h
+++ b/source/gameengine/GameLogic/SCA_LogicManager.h
@@ -43,11 +43,13 @@
#include "GEN_Map.h"
#include "STR_HashedString.h"
#include "Value.h"
+#include "SG_QList.h"
#include "KX_HashedPtr.h"
using namespace std;
-typedef list<class SCA_IController*> controllerlist;
+typedef std::list<class SCA_IController*> controllerlist;
+typedef std::map<class SCA_ISensor*,controllerlist > sensormap_t;
/**
* This manager handles sensor, controllers and actuators.
@@ -63,45 +65,19 @@ typedef list<class SCA_IController*> controllerlist;
*/
#include "SCA_ILogicBrick.h"
+#include "SCA_IActuator.h"
-// todo: make this into a template, but first I want to think about what exactly to put in
-class SmartActuatorPtr
-{
- SCA_IActuator* m_actuator;
-public:
- SmartActuatorPtr(SCA_IActuator* actua,int dummy);
- SmartActuatorPtr(const SmartActuatorPtr& other);
- virtual ~SmartActuatorPtr();
- bool operator <(const SmartActuatorPtr& other) const;
- bool operator ==(const SmartActuatorPtr& other) const;
- SCA_IActuator* operator->() const;
- SCA_IActuator* operator*() const;
-
-};
-
-class SmartControllerPtr
-{
- SCA_IController* m_controller;
-public:
- SmartControllerPtr(const SmartControllerPtr& copy);
- SmartControllerPtr(SCA_IController* contr,int dummy);
- virtual ~SmartControllerPtr();
- bool operator <(const SmartControllerPtr& other) const;
- bool operator ==(const SmartControllerPtr& other) const;
- SCA_IController* operator->() const;
- SCA_IController* operator*() const;
-
-};
class SCA_LogicManager
{
vector<class SCA_EventManager*> m_eventmanagers;
- vector<class SCA_ISensor*> m_activatedsensors;
- set<class SmartActuatorPtr> m_activeActuators;
- set<class SmartControllerPtr> m_triggeredControllerSet;
-
- map<SCA_ISensor*,controllerlist > m_sensorcontrollermapje;
+ // SG_DList: Head of objects having activated actuators
+ // element: SCA_IObject::m_activeActuators
+ SG_DList m_activeActuators;
+ // SG_DList: Head of objects having activated controllers
+ // element: SCA_IObject::m_activeControllers
+ SG_DList m_triggeredControllerSet;
// need to find better way for this
// also known as FactoryManager...
@@ -111,11 +87,10 @@ class SCA_LogicManager
GEN_Map<STR_HashedString,void*> m_map_gamemeshname_to_blendobj;
GEN_Map<CHashedPtr,void*> m_map_blendobj_to_gameobj;
-
- vector<SmartActuatorPtr> m_removedActuators;
public:
SCA_LogicManager();
virtual ~SCA_LogicManager();
+
//void SetKeyboardManager(SCA_KeyboardManager* keyboardmgr) { m_keyboardmgr=keyboardmgr;}
void RegisterEventManager(SCA_EventManager* eventmgr);
void RegisterToSensor(SCA_IController* controller,
@@ -126,8 +101,13 @@ public:
void BeginFrame(double curtime, double fixedtime);
void UpdateFrame(double curtime, bool frame);
void EndFrame();
- void AddActivatedSensor(SCA_ISensor* sensor);
- void AddActiveActuator(SCA_IActuator* sensor,class CValue* event);
+ void AddActiveActuator(SCA_IActuator* actua,bool event)
+ {
+ actua->SetActive(true);
+ actua->Activate(m_activeActuators);
+ actua->AddEvent(event);
+ }
+
void AddTriggeredController(SCA_IController* controller, SCA_ISensor* sensor);
SCA_EventManager* FindEventManager(int eventmgrtype);
@@ -138,7 +118,7 @@ public:
*/
void RemoveSensor(SCA_ISensor* sensor);
void RemoveController(SCA_IController* controller);
- void RemoveDestroyedActuator(SCA_IActuator* actuator);
+ void RemoveActuator(SCA_IActuator* actuator);
// for the scripting... needs a FactoryManager later (if we would have time... ;)
diff --git a/source/gameengine/GameLogic/SCA_MouseManager.cpp b/source/gameengine/GameLogic/SCA_MouseManager.cpp
index ca875dad07c..d407647cec3 100644
--- a/source/gameengine/GameLogic/SCA_MouseManager.cpp
+++ b/source/gameengine/GameLogic/SCA_MouseManager.cpp
@@ -75,8 +75,8 @@ void SCA_MouseManager::NextFrame()
{
if (m_mousedevice)
{
- set<SCA_ISensor*>::iterator it;
- for (it=m_sensors.begin(); it!=m_sensors.end(); it++)
+ SG_DList::iterator<SCA_ISensor> it(m_sensors);
+ for (it.begin();!it.end();++it)
{
SCA_MouseSensor* mousesensor = (SCA_MouseSensor*)(*it);
// (0,0) is the Upper Left corner in our local window
@@ -93,7 +93,7 @@ void SCA_MouseManager::NextFrame()
mousesensor->setX(mx);
mousesensor->setY(my);
- mousesensor->Activate(m_logicmanager,NULL);
+ mousesensor->Activate(m_logicmanager);
}
}
}
diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.cpp b/source/gameengine/GameLogic/SCA_MouseSensor.cpp
index 4dbeb156e63..c5e1c3c0441 100644
--- a/source/gameengine/GameLogic/SCA_MouseSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_MouseSensor.cpp
@@ -111,7 +111,7 @@ CValue* SCA_MouseSensor::GetReplica()
{
SCA_MouseSensor* replica = new SCA_MouseSensor(*this);
// this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
replica->Init();
return replica;
@@ -144,7 +144,7 @@ SCA_IInputDevice::KX_EnumInputs SCA_MouseSensor::GetHotKey()
-bool SCA_MouseSensor::Evaluate(CValue* event)
+bool SCA_MouseSensor::Evaluate()
{
bool result = false;
bool reset = m_reset && m_level;
@@ -296,8 +296,13 @@ KX_PYMETHODDEF_DOC_O(SCA_MouseSensor, getButtonStatus,
/* ------------------------------------------------------------------------- */
PyTypeObject SCA_MouseSensor::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_MouseSensor",
sizeof(PyObjectPlus_Proxy),
0,
@@ -342,6 +347,10 @@ PyObject* SCA_MouseSensor::py_getattro(PyObject *attr)
py_getattro_up(SCA_ISensor);
}
+PyObject* SCA_MouseSensor::py_getattro_dict() {
+ py_getattro_dict_up(SCA_ISensor);
+}
+
int SCA_MouseSensor::py_setattro(PyObject *attr, PyObject *value)
{
py_setattro_up(SCA_ISensor);
diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.h b/source/gameengine/GameLogic/SCA_MouseSensor.h
index 2d1c496029d..6d6302b514a 100644
--- a/source/gameengine/GameLogic/SCA_MouseSensor.h
+++ b/source/gameengine/GameLogic/SCA_MouseSensor.h
@@ -97,7 +97,7 @@ class SCA_MouseSensor : public SCA_ISensor
virtual ~SCA_MouseSensor();
virtual CValue* GetReplica();
- virtual bool Evaluate(CValue* event);
+ virtual bool Evaluate();
virtual void Init();
virtual bool IsPositiveTrigger();
short int GetModeKey();
@@ -110,6 +110,7 @@ class SCA_MouseSensor : public SCA_ISensor
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
//Deprecated functions ----->
diff --git a/source/gameengine/GameLogic/SCA_NANDController.cpp b/source/gameengine/GameLogic/SCA_NANDController.cpp
index 703c9c1bbaf..d27aea5e6f7 100644
--- a/source/gameengine/GameLogic/SCA_NANDController.cpp
+++ b/source/gameengine/GameLogic/SCA_NANDController.cpp
@@ -66,26 +66,19 @@ void SCA_NANDController::Trigger(SCA_LogicManager* logicmgr)
!(is==m_linkedsensors.end());is++)
{
SCA_ISensor* sensor = *is;
- if (!sensor->IsPositiveTrigger())
+ if (!sensor->GetState())
{
sensorresult = true;
break;
}
}
- CValue* newevent = new CBoolValue(sensorresult);
-
for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
!(i==m_linkedactuators.end());i++)
{
- SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
- logicmgr->AddActiveActuator(actua,newevent);
+ SCA_IActuator* actua = *i;
+ logicmgr->AddActiveActuator(actua,sensorresult);
}
-
- // every actuator that needs the event, has a it's own reference to it now so
- // release it (so to be clear: if there is no actuator, it's deleted right now)
- newevent->Release();
-
}
@@ -94,7 +87,7 @@ CValue* SCA_NANDController::GetReplica()
{
CValue* replica = new SCA_NANDController(*this);
// this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
return replica;
}
@@ -107,8 +100,13 @@ CValue* SCA_NANDController::GetReplica()
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_NANDController::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_NANDController",
sizeof(PyObjectPlus_Proxy),
0,
@@ -145,4 +143,8 @@ PyObject* SCA_NANDController::py_getattro(PyObject *attr) {
py_getattro_up(SCA_IController);
}
+PyObject* SCA_NANDController::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IController);
+}
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_NANDController.h b/source/gameengine/GameLogic/SCA_NANDController.h
index 11600914a1a..0ae0ff19745 100644
--- a/source/gameengine/GameLogic/SCA_NANDController.h
+++ b/source/gameengine/GameLogic/SCA_NANDController.h
@@ -49,6 +49,7 @@ public:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
};
diff --git a/source/gameengine/GameLogic/SCA_NORController.cpp b/source/gameengine/GameLogic/SCA_NORController.cpp
index 06acae5a81a..6c9141636b2 100644
--- a/source/gameengine/GameLogic/SCA_NORController.cpp
+++ b/source/gameengine/GameLogic/SCA_NORController.cpp
@@ -66,26 +66,19 @@ void SCA_NORController::Trigger(SCA_LogicManager* logicmgr)
!(is==m_linkedsensors.end());is++)
{
SCA_ISensor* sensor = *is;
- if (sensor->IsPositiveTrigger())
+ if (sensor->GetState())
{
sensorresult = false;
break;
}
}
- CValue* newevent = new CBoolValue(sensorresult);
-
for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
!(i==m_linkedactuators.end());i++)
{
- SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
- logicmgr->AddActiveActuator(actua,newevent);
+ SCA_IActuator* actua = *i;
+ logicmgr->AddActiveActuator(actua,sensorresult);
}
-
- // every actuator that needs the event, has a it's own reference to it now so
- // release it (so to be clear: if there is no actuator, it's deleted right now)
- newevent->Release();
-
}
@@ -94,7 +87,7 @@ CValue* SCA_NORController::GetReplica()
{
CValue* replica = new SCA_NORController(*this);
// this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
return replica;
}
@@ -107,8 +100,13 @@ CValue* SCA_NORController::GetReplica()
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_NORController::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_NORController",
sizeof(PyObjectPlus_Proxy),
0,
@@ -145,4 +143,8 @@ PyObject* SCA_NORController::py_getattro(PyObject *attr) {
py_getattro_up(SCA_IController);
}
+PyObject* SCA_NORController::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IController);
+}
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_NORController.h b/source/gameengine/GameLogic/SCA_NORController.h
index fc814e28d37..06cbb70a489 100644
--- a/source/gameengine/GameLogic/SCA_NORController.h
+++ b/source/gameengine/GameLogic/SCA_NORController.h
@@ -49,6 +49,7 @@ public:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
};
diff --git a/source/gameengine/GameLogic/SCA_ORController.cpp b/source/gameengine/GameLogic/SCA_ORController.cpp
index 319ff04f776..42c0a67d657 100644
--- a/source/gameengine/GameLogic/SCA_ORController.cpp
+++ b/source/gameengine/GameLogic/SCA_ORController.cpp
@@ -60,7 +60,7 @@ CValue* SCA_ORController::GetReplica()
{
CValue* replica = new SCA_ORController(*this);
// this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
return replica;
}
@@ -76,21 +76,16 @@ void SCA_ORController::Trigger(SCA_LogicManager* logicmgr)
while ( (!sensorresult) && (!(is==m_linkedsensors.end())) )
{
sensor = *is;
- if (sensor->IsPositiveTrigger()) sensorresult = true;
+ if (sensor->GetState()) sensorresult = true;
is++;
}
- CValue* newevent = new CBoolValue(sensorresult);
-
for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
!(i==m_linkedactuators.end());i++)
{
- SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
- logicmgr->AddActiveActuator(actua,newevent);
+ SCA_IActuator* actua = *i;
+ logicmgr->AddActiveActuator(actua,sensorresult);
}
-
-
- newevent->Release();
}
/* ------------------------------------------------------------------------- */
@@ -99,8 +94,13 @@ void SCA_ORController::Trigger(SCA_LogicManager* logicmgr)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_ORController::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_ORController",
sizeof(PyObjectPlus_Proxy),
0,
@@ -138,4 +138,8 @@ PyObject* SCA_ORController::py_getattro(PyObject *attr) {
py_getattro_up(SCA_IController);
}
+PyObject* SCA_ORController::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IController);
+}
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ORController.h b/source/gameengine/GameLogic/SCA_ORController.h
index fdc81486e74..66f772c739e 100644
--- a/source/gameengine/GameLogic/SCA_ORController.h
+++ b/source/gameengine/GameLogic/SCA_ORController.h
@@ -50,6 +50,7 @@ public:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
};
#endif //__KX_ORCONTROLLER
diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
index c4db723ee89..4faa4b55d4a 100644
--- a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
@@ -186,11 +186,6 @@ GetReplica() {
SCA_PropertyActuator* replica = new SCA_PropertyActuator(*this);
replica->ProcessReplica();
-
- // this will copy properties and so on...
-
- CValue::AddDataToReplica(replica);
-
return replica;
};
@@ -233,8 +228,13 @@ void SCA_PropertyActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_PropertyActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_PropertyActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -270,8 +270,9 @@ PyMethodDef SCA_PropertyActuator::Methods[] = {
};
PyAttributeDef SCA_PropertyActuator::Attributes[] = {
- KX_PYATTRIBUTE_STRING_RW_CHECK("property",0,100,false,SCA_PropertyActuator,m_propname,CheckProperty),
+ KX_PYATTRIBUTE_STRING_RW_CHECK("propName",0,100,false,SCA_PropertyActuator,m_propname,CheckProperty),
KX_PYATTRIBUTE_STRING_RW("value",0,100,false,SCA_PropertyActuator,m_exprtxt),
+ KX_PYATTRIBUTE_INT_RW("mode", KX_ACT_PROP_NODEF+1, KX_ACT_PROP_MAX-1, false, SCA_PropertyActuator, m_type), /* ATTR_TODO add constents to game logic dict */
{ NULL } //Sentinel
};
@@ -279,6 +280,10 @@ PyObject* SCA_PropertyActuator::py_getattro(PyObject *attr) {
py_getattro_up(SCA_IActuator);
}
+PyObject* SCA_PropertyActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
int SCA_PropertyActuator::py_setattro(PyObject *attr, PyObject *value) {
py_setattro_up(SCA_IActuator);
}
@@ -291,7 +296,7 @@ const char SCA_PropertyActuator::SetProperty_doc[] =
"\tof this name, the call is ignored.\n";
PyObject* SCA_PropertyActuator::PySetProperty(PyObject* args, PyObject* kwds)
{
- ShowDeprecationWarning("setProperty()", "the 'property' property");
+ ShowDeprecationWarning("setProperty()", "the 'propName' property");
/* Check whether the name exists first ! */
char *nameArg;
if (!PyArg_ParseTuple(args, "s:setProperty", &nameArg)) {
@@ -316,7 +321,7 @@ const char SCA_PropertyActuator::GetProperty_doc[] =
"\tReturn the property on which the actuator operates.\n";
PyObject* SCA_PropertyActuator::PyGetProperty(PyObject* args, PyObject* kwds)
{
- ShowDeprecationWarning("getProperty()", "the 'property' property");
+ ShowDeprecationWarning("getProperty()", "the 'propName' property");
return PyString_FromString(m_propname);
}
diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.h b/source/gameengine/GameLogic/SCA_PropertyActuator.h
index bb841cf88ad..a8df08dfc6e 100644
--- a/source/gameengine/GameLogic/SCA_PropertyActuator.h
+++ b/source/gameengine/GameLogic/SCA_PropertyActuator.h
@@ -87,6 +87,7 @@ public:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
// python wrapped methods
diff --git a/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp b/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
index e5e3f9cced5..764465309df 100644
--- a/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
@@ -50,8 +50,9 @@ SCA_PropertyEventManager::~SCA_PropertyEventManager()
void SCA_PropertyEventManager::NextFrame()
{
// check for changed properties
- for (set<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
+ SG_DList::iterator<SCA_ISensor> it(m_sensors);
+ for (it.begin();!it.end();++it)
{
- (*it)->Activate(m_logicmgr,NULL);
+ (*it)->Activate(m_logicmgr);
}
}
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
index de8a9fcf03e..3b343af3cba 100644
--- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
@@ -37,6 +37,7 @@
#include "StringValue.h"
#include "SCA_EventManager.h"
#include "SCA_LogicManager.h"
+#include "BoolValue.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -111,7 +112,7 @@ CValue* SCA_PropertySensor::GetReplica()
{
SCA_PropertySensor* replica = new SCA_PropertySensor(*this);
// m_range_expr must be recalculated on replica!
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
replica->Init();
replica->m_range_expr = NULL;
@@ -152,7 +153,7 @@ SCA_PropertySensor::~SCA_PropertySensor()
-bool SCA_PropertySensor::Evaluate(CValue* event)
+bool SCA_PropertySensor::Evaluate()
{
bool result = CheckPropertyCondition();
bool reset = m_reset && m_level;
@@ -182,17 +183,14 @@ bool SCA_PropertySensor::CheckPropertyCondition()
CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
if (!orgprop->IsError())
{
- STR_String testprop = orgprop->GetText();
+ const STR_String& testprop = orgprop->GetText();
// Force strings to upper case, to avoid confusion in
// bool tests. It's stupid the prop's identity is lost
// on the way here...
- if ((testprop == "TRUE") || (testprop == "FALSE")) {
- STR_String checkprop = m_checkpropval;
- checkprop.Upper();
- result = (testprop == checkprop);
- } else {
- result = (orgprop->GetText() == m_checkpropval);
+ if ((&testprop == &CBoolValue::sTrueString) || (&testprop == &CBoolValue::sFalseString)) {
+ m_checkpropval.Upper();
}
+ result = (testprop == m_checkpropval);
}
orgprop->Release();
@@ -232,8 +230,8 @@ bool SCA_PropertySensor::CheckPropertyCondition()
CValue* vallie = m_range_expr->Calculate();
if (vallie)
{
- STR_String errtext = vallie->GetText();
- if (errtext == "TRUE")
+ const STR_String& errtext = vallie->GetText();
+ if (&errtext == &CBoolValue::sTrueString)
{
result = true;
} else
@@ -295,9 +293,8 @@ CValue* SCA_PropertySensor::FindIdentifier(const STR_String& identifiername)
int SCA_PropertySensor::validValueForProperty(void *self, const PyAttributeDef*)
{
- bool result = true;
/* There is no type checking at this moment, unfortunately... */
- return result;
+ return 0;
}
/* ------------------------------------------------------------------------- */
@@ -306,8 +303,13 @@ int SCA_PropertySensor::validValueForProperty(void *self, const PyAttributeDef*)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_PropertySensor::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_PropertySensor",
sizeof(PyObjectPlus_Proxy),
0,
@@ -345,8 +347,8 @@ PyMethodDef SCA_PropertySensor::Methods[] = {
};
PyAttributeDef SCA_PropertySensor::Attributes[] = {
- KX_PYATTRIBUTE_INT_RW("type",KX_PROPSENSOR_NODEF,KX_PROPSENSOR_MAX-1,false,SCA_PropertySensor,m_checktype),
- KX_PYATTRIBUTE_STRING_RW_CHECK("property",0,100,false,SCA_PropertySensor,m_checkpropname,CheckProperty),
+ KX_PYATTRIBUTE_INT_RW("mode",KX_PROPSENSOR_NODEF,KX_PROPSENSOR_MAX-1,false,SCA_PropertySensor,m_checktype),
+ KX_PYATTRIBUTE_STRING_RW_CHECK("propName",0,100,false,SCA_PropertySensor,m_checkpropname,CheckProperty),
KX_PYATTRIBUTE_STRING_RW_CHECK("value",0,100,false,SCA_PropertySensor,m_checkpropval,validValueForProperty),
{ NULL } //Sentinel
};
@@ -356,6 +358,10 @@ PyObject* SCA_PropertySensor::py_getattro(PyObject *attr) {
py_getattro_up(SCA_ISensor);
}
+PyObject* SCA_PropertySensor::py_getattro_dict() {
+ py_getattro_dict_up(SCA_ISensor);
+}
+
int SCA_PropertySensor::py_setattro(PyObject *attr, PyObject *value) {
py_setattro_up(SCA_ISensor);
}
@@ -366,7 +372,7 @@ const char SCA_PropertySensor::GetType_doc[] =
"\tReturns the type of check this sensor performs.\n";
PyObject* SCA_PropertySensor::PyGetType()
{
- ShowDeprecationWarning("getType()", "the type property");
+ ShowDeprecationWarning("getType()", "the mode property");
return PyInt_FromLong(m_checktype);
}
@@ -379,7 +385,7 @@ const char SCA_PropertySensor::SetType_doc[] =
"\tSet the type of check to perform.\n";
PyObject* SCA_PropertySensor::PySetType(PyObject* args)
{
- ShowDeprecationWarning("setType()", "the type property");
+ ShowDeprecationWarning("setType()", "the mode property");
int typeArg;
if (!PyArg_ParseTuple(args, "i:setType", &typeArg)) {
@@ -400,7 +406,7 @@ const char SCA_PropertySensor::GetProperty_doc[] =
"\tReturn the property with which the sensor operates.\n";
PyObject* SCA_PropertySensor::PyGetProperty()
{
- ShowDeprecationWarning("getProperty()", "the 'property' property");
+ ShowDeprecationWarning("getProperty()", "the 'propName' property");
return PyString_FromString(m_checkpropname);
}
@@ -412,7 +418,7 @@ const char SCA_PropertySensor::SetProperty_doc[] =
"\tof this name, the call is ignored.\n";
PyObject* SCA_PropertySensor::PySetProperty(PyObject* args)
{
- ShowDeprecationWarning("setProperty()", "the 'property' property");
+ ShowDeprecationWarning("setProperty()", "the 'propName' property");
/* We should query whether the name exists. Or should we create a prop */
/* on the fly? */
char *propNameArg = NULL;
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.h b/source/gameengine/GameLogic/SCA_PropertySensor.h
index e1e378a973c..538ecd65949 100644
--- a/source/gameengine/GameLogic/SCA_PropertySensor.h
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.h
@@ -81,7 +81,7 @@ public:
void PrecalculateRangeExpression();
bool CheckPropertyCondition();
- virtual bool Evaluate(CValue* event);
+ virtual bool Evaluate();
virtual bool IsPositiveTrigger();
virtual CValue* FindIdentifier(const STR_String& identifiername);
@@ -90,6 +90,7 @@ public:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
/* 1. getType */
diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp
index b8052555528..80e4f54c9c5 100644
--- a/source/gameengine/GameLogic/SCA_PythonController.cpp
+++ b/source/gameengine/GameLogic/SCA_PythonController.cpp
@@ -48,12 +48,18 @@ SCA_PythonController* SCA_PythonController::m_sCurrentController = NULL;
SCA_PythonController::SCA_PythonController(SCA_IObject* gameobj,
+ int mode,
PyTypeObject* T)
: SCA_IController(gameobj, T),
m_bytecode(NULL),
+ m_function(NULL),
+ m_function_argc(0),
m_bModified(true),
+ m_debug(false),
+ m_mode(mode),
m_pythondictionary(NULL)
{
+
}
/*
@@ -74,15 +80,12 @@ int SCA_PythonController::Release()
SCA_PythonController::~SCA_PythonController()
{
- if (m_bytecode)
- {
- //
- //printf("released python byte script\n");
- Py_DECREF(m_bytecode);
- }
+ //printf("released python byte script\n");
- if (m_pythondictionary)
- {
+ Py_XDECREF(m_bytecode);
+ Py_XDECREF(m_function);
+
+ if (m_pythondictionary) {
// break any circular references in the dictionary
PyDict_Clear(m_pythondictionary);
Py_DECREF(m_pythondictionary);
@@ -94,8 +97,12 @@ SCA_PythonController::~SCA_PythonController()
CValue* SCA_PythonController::GetReplica()
{
SCA_PythonController* replica = new SCA_PythonController(*this);
- // Copy the compiled bytecode if possible.
+
+ /* why is this needed at all??? - m_bytecode is NULL'd below so this doesnt make sense
+ * but removing it crashes blender (with YoFrankie). so leave in for now - Campbell */
Py_XINCREF(replica->m_bytecode);
+
+ Py_XINCREF(replica->m_function); // this is ok since its not set to NULL
replica->m_bModified = replica->m_bytecode == NULL;
// The replica->m_pythondictionary is stolen - replace with a copy.
@@ -110,7 +117,7 @@ CValue* SCA_PythonController::GetReplica()
*/
// this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
return replica;
}
@@ -140,6 +147,11 @@ void SCA_PythonController::SetDictionary(PyObject* pythondictionary)
Py_DECREF(m_pythondictionary);
}
m_pythondictionary = PyDict_Copy(pythondictionary); /* new reference */
+
+ /* Without __file__ set the sys.argv[0] is used for the filename
+ * which ends up with lines from the blender binary being printed in the console */
+ PyDict_SetItemString(m_pythondictionary, "__file__", PyString_FromString(m_scriptName.Ptr()));
+
}
int SCA_PythonController::IsTriggered(class SCA_ISensor* sensor)
@@ -150,13 +162,14 @@ int SCA_PythonController::IsTriggered(class SCA_ISensor* sensor)
return 0;
}
-#if 0
-static const char* sPyGetCurrentController__doc__;
-#endif
-
/* warning, self is not the SCA_PythonController, its a PyObjectPlus_Proxy */
PyObject* SCA_PythonController::sPyGetCurrentController(PyObject *self)
{
+ if(m_sCurrentController==NULL)
+ {
+ PyErr_SetString(PyExc_SystemError, "GameLogic.getCurrentController(), this function is being run outside the python controllers context, or blenders internal state is corrupt.");
+ return NULL;
+ }
return m_sCurrentController->GetProxy();
}
@@ -170,15 +183,15 @@ SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value)
if (PyString_Check(value)) {
/* get the actuator from the name */
char *name= PyString_AsString(value);
- for(it = lacts.begin(); it!= lacts.end(); it++) {
+ for(it = lacts.begin(); it!= lacts.end(); ++it) {
if( name == (*it)->GetName() ) {
return *it;
}
}
}
else if (BGE_PROXY_CHECK_TYPE(value)) {
- PyObjectPlus *value_plus= BGE_PROXY_REF(value); /* Expecting an actuator type */ // XXX TODO - CHECK TYPE
- for(it = lacts.begin(); it!= lacts.end(); it++) {
+ PyObjectPlus *value_plus= BGE_PROXY_REF(value);
+ for(it = lacts.begin(); it!= lacts.end(); ++it) {
if( static_cast<SCA_IActuator*>(value_plus) == (*it) ) {
return *it;
}
@@ -193,13 +206,11 @@ SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value)
return false;
}
-#if 0
-static const char* sPyAddActiveActuator__doc__;
-#endif
-
/* warning, self is not the SCA_PythonController, its a PyObjectPlus_Proxy */
PyObject* SCA_PythonController::sPyAddActiveActuator(PyObject* self, PyObject* args)
{
+ ShowDeprecationWarning("GameLogic.addActiveActuator(act, bool)", "controller.activate(act) or controller.deactivate(act)");
+
PyObject* ob1;
int activate;
if (!PyArg_ParseTuple(args, "Oi:addActiveActuator", &ob1,&activate))
@@ -209,20 +220,22 @@ PyObject* SCA_PythonController::sPyAddActiveActuator(PyObject* self, PyObject* a
if(actu==NULL)
return NULL;
- CValue* boolval = new CBoolValue(activate!=0);
+ bool boolval = (activate!=0);
m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu,boolval);
- boolval->Release();
Py_RETURN_NONE;
}
-
const char* SCA_PythonController::sPyGetCurrentController__doc__ = "getCurrentController()";
const char* SCA_PythonController::sPyAddActiveActuator__doc__= "addActiveActuator(actuator,bool)";
-const char SCA_PythonController::GetActuators_doc[] = "getActuator";
PyTypeObject SCA_PythonController::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_PythonController",
sizeof(PyObjectPlus_Proxy),
0,
@@ -249,59 +262,137 @@ PyMethodDef SCA_PythonController::Methods[] = {
{"activate", (PyCFunction) SCA_PythonController::sPyActivate, METH_O},
{"deactivate", (PyCFunction) SCA_PythonController::sPyDeActivate, METH_O},
- {"getActuators", (PyCFunction) SCA_PythonController::sPyGetActuators, METH_NOARGS, (PY_METHODCHAR)SCA_PythonController::GetActuators_doc},
- {"getActuator", (PyCFunction) SCA_PythonController::sPyGetActuator, METH_O, (PY_METHODCHAR)SCA_PythonController::GetActuator_doc},
- {"getSensors", (PyCFunction) SCA_PythonController::sPyGetSensors, METH_NOARGS, (PY_METHODCHAR)SCA_PythonController::GetSensors_doc},
- {"getSensor", (PyCFunction) SCA_PythonController::sPyGetSensor, METH_O, (PY_METHODCHAR)SCA_PythonController::GetSensor_doc},
//Deprecated functions ------>
{"setScript", (PyCFunction) SCA_PythonController::sPySetScript, METH_O},
{"getScript", (PyCFunction) SCA_PythonController::sPyGetScript, METH_NOARGS},
- {"getState", (PyCFunction) SCA_PythonController::sPyGetState, METH_NOARGS},
//<----- Deprecated
{NULL,NULL} //Sentinel
};
PyAttributeDef SCA_PythonController::Attributes[] = {
- KX_PYATTRIBUTE_RO_FUNCTION("state", SCA_PythonController, pyattr_get_state),
KX_PYATTRIBUTE_RW_FUNCTION("script", SCA_PythonController, pyattr_get_script, pyattr_set_script),
+ KX_PYATTRIBUTE_INT_RO("mode", SCA_PythonController, m_mode),
{ NULL } //Sentinel
};
-bool SCA_PythonController::Compile()
+void SCA_PythonController::ErrorPrint(const char *error_msg)
{
+ // didn't compile, so instead of compile, complain
+ // something is wrong, tell the user what went wrong
+ printf("%s - controller \"%s\":\n", error_msg, GetName().Ptr());
+ //PyRun_SimpleString(m_scriptText.Ptr());
+ PyErr_Print();
+
+ /* Added in 2.48a, the last_traceback can reference Objects for example, increasing
+ * their user count. Not to mention holding references to wrapped data.
+ * This is especially bad when the PyObject for the wrapped data is free'd, after blender
+ * has alredy dealocated the pointer */
+ PySys_SetObject( (char *)"last_traceback", NULL);
+ PyErr_Clear(); /* just to be sure */
+}
+
+bool SCA_PythonController::Compile()
+{
//printf("py script modified '%s'\n", m_scriptName.Ptr());
+ m_bModified= false;
// if a script already exists, decref it before replace the pointer to a new script
- if (m_bytecode)
- {
+ if (m_bytecode) {
Py_DECREF(m_bytecode);
m_bytecode=NULL;
}
+
// recompile the scripttext into bytecode
m_bytecode = Py_CompileString(m_scriptText.Ptr(), m_scriptName.Ptr(), Py_file_input);
- m_bModified=false;
- if (m_bytecode)
- {
-
+ if (m_bytecode) {
return true;
+ } else {
+ ErrorPrint("Python error compiling script");
+ return false;
}
- else {
- // didn't compile, so instead of compile, complain
- // something is wrong, tell the user what went wrong
- printf("Python compile error from controller \"%s\": \n", GetName().Ptr());
- //PyRun_SimpleString(m_scriptText.Ptr());
- PyErr_Print();
+}
+
+bool SCA_PythonController::Import()
+{
+ //printf("py module modified '%s'\n", m_scriptName.Ptr());
+ m_bModified= false;
+
+ /* incase we re-import */
+ Py_XDECREF(m_function);
+ m_function= NULL;
+
+ vector<STR_String> py_function_path = m_scriptText.Explode('.');
+
+ if(py_function_path.size() < 2) {
+ printf("Python module name formatting error \"%s\":\n\texpected \"SomeModule.Func\", got \"%s\"\n", GetName().Ptr(), m_scriptText.Ptr());
+ return false;
+ }
+
+ PyObject *mod = PyImport_ImportModule((char *)py_function_path[0].Ptr());
+ /* Dont reload yet, do this within the loop so packages reload too */
+
+ if(mod==NULL) {
+ ErrorPrint("Python module not found");
+ return false;
+ }
+ /* 'mod' will be DECREF'd as 'base'
+ * 'm_function' will be left holding a reference that the controller owns */
+
+ PyObject *base= mod;
+
+ for(unsigned int i=1; i < py_function_path.size(); i++) {
+ if(m_debug && PyModule_Check(base)) { /* base could be a class */
+ Py_DECREF(base); /* getting a new one so dont hold a ref to the old one */
+ base= PyImport_ReloadModule(base);
+ if (base==NULL) {
+ m_function= NULL;
+ break;
+ }
+ }
- /* Added in 2.48a, the last_traceback can reference Objects for example, increasing
- * their user count. Not to mention holding references to wrapped data.
- * This is especially bad when the PyObject for the wrapped data is free'd, after blender
- * has alredy dealocated the pointer */
- PySys_SetObject( (char *)"last_traceback", NULL);
- PyErr_Clear(); /* just to be sure */
+ m_function = PyObject_GetAttrString(base, py_function_path[i].Ptr());
+ Py_DECREF(base);
+ base = m_function; /* for the next loop if there is on */
+ if(m_function==NULL) {
+ break;
+ }
+ }
+
+ if(m_function==NULL) {
+ if(PyErr_Occurred())
+ ErrorPrint("Python controller found the module but could not access the function");
+ else
+ printf("Python module error \"%s\":\n \"%s\" module found but function missing\n", GetName().Ptr(), m_scriptText.Ptr());
+ return false;
+ }
+
+ if(!PyCallable_Check(m_function)) {
+ Py_DECREF(m_function);
+ printf("Python module function error \"%s\":\n \"%s\" not callable\n", GetName().Ptr(), m_scriptText.Ptr());
+ return false;
+ }
+
+ m_function_argc = 0; /* rare cases this could be a function that isnt defined in python, assume zero args */
+ if (PyFunction_Check(m_function)) {
+ PyObject *py_arg_count = PyObject_GetAttrString(PyFunction_GET_CODE(m_function), "co_argcount");
+ if(py_arg_count) {
+ m_function_argc = PyLong_AsLong(py_arg_count);
+ Py_DECREF(py_arg_count);
+ }
+ else {
+ PyErr_Clear(); /* unlikely to fail but just incase */
+ }
+ }
+
+ if(m_function_argc > 1) {
+ Py_DECREF(m_function);
+ printf("Python module function has \"%s\":\n \"%s\" takes %d args, should be zero or 1 controller arg\n", GetName().Ptr(), m_scriptText.Ptr(), m_function_argc);
return false;
}
+
+ return true;
}
void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
@@ -309,16 +400,18 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
m_sCurrentController = this;
m_sCurrentLogicManager = logicmgr;
- if (m_bModified)
+ PyObject *excdict= NULL;
+ PyObject* resultobj= NULL;
+
+ switch(m_mode) {
+ case SCA_PYEXEC_SCRIPT:
{
- if (Compile()==false) // sets m_bModified to false
+ if (m_bModified)
+ if (Compile()==false) // sets m_bModified to false
+ return;
+ if (!m_bytecode)
return;
- }
- if (!m_bytecode) {
- return;
- }
-
/*
* This part here with excdict is a temporary patch
* to avoid python/gameengine crashes when python
@@ -337,10 +430,36 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
* should always ensure excdict is cleared).
*/
- PyObject *excdict= PyDict_Copy(m_pythondictionary);
- PyObject* resultobj = PyEval_EvalCode((PyCodeObject*)m_bytecode,
- excdict, excdict);
-
+ excdict= PyDict_Copy(m_pythondictionary);
+ resultobj = PyEval_EvalCode((PyCodeObject*)m_bytecode, excdict, excdict);
+ /* PyRun_SimpleString(m_scriptText.Ptr()); */
+ break;
+ }
+ case SCA_PYEXEC_MODULE:
+ {
+ if (m_bModified || m_debug)
+ if (Import()==false) // sets m_bModified to false
+ return;
+ if (!m_function)
+ return;
+
+ PyObject *args= NULL;
+
+ if(m_function_argc==1) {
+ args = PyTuple_New(1);
+ PyTuple_SET_ITEM(args, 0, GetProxy());
+ }
+
+ resultobj = PyObject_CallObject(m_function, args);
+ Py_XDECREF(args);
+ break;
+ }
+
+ } /* end switch */
+
+
+
+ /* Free the return value and print the error */
if (resultobj)
{
Py_DECREF(resultobj);
@@ -348,7 +467,7 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
else
{
// something is wrong, tell the user what went wrong
- printf("Python script error from controller \"%s\": \n", GetName().Ptr());
+ printf("Python script error from controller \"%s\":\n", GetName().Ptr());
PyErr_Print();
/* Added in 2.48a, the last_traceback can reference Objects for example, increasing
@@ -357,15 +476,17 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
* has alredy dealocated the pointer */
PySys_SetObject( (char *)"last_traceback", NULL);
PyErr_Clear(); /* just to be sure */
-
- //PyRun_SimpleString(m_scriptText.Ptr());
}
-
- // clear after PyErrPrint - seems it can be using
- // something in this dictionary and crash?
- PyDict_Clear(excdict);
- Py_DECREF(excdict);
- m_triggeredSensors.erase(m_triggeredSensors.begin(), m_triggeredSensors.end());
+
+ if(excdict) /* Only for SCA_PYEXEC_SCRIPT types */
+ {
+ /* clear after PyErrPrint - seems it can be using
+ * something in this dictionary and crash? */
+ PyDict_Clear(excdict);
+ Py_DECREF(excdict);
+ }
+
+ m_triggeredSensors.clear();
m_sCurrentController = NULL;
}
@@ -376,6 +497,10 @@ PyObject* SCA_PythonController::py_getattro(PyObject *attr)
py_getattro_up(SCA_IController);
}
+PyObject* SCA_PythonController::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IController);
+}
+
int SCA_PythonController::py_setattro(PyObject *attr, PyObject *value)
{
py_setattro_up(SCA_IController);
@@ -383,104 +508,32 @@ int SCA_PythonController::py_setattro(PyObject *attr, PyObject *value)
PyObject* SCA_PythonController::PyActivate(PyObject *value)
{
- SCA_IActuator* actu = LinkedActuatorFromPy(value);
- if(actu==NULL)
+ if(m_sCurrentController != this) {
+ PyErr_SetString(PyExc_SystemError, "Cannot add an actuator from a non-active controller");
return NULL;
+ }
- CValue* boolval = new CBoolValue(true);
- m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, boolval);
- boolval->Release();
- Py_RETURN_NONE;
-}
-
-PyObject* SCA_PythonController::PyDeActivate(PyObject *value)
-{
SCA_IActuator* actu = LinkedActuatorFromPy(value);
if(actu==NULL)
return NULL;
- CValue* boolval = new CBoolValue(false);
- m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, boolval);
- boolval->Release();
+ m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, true);
Py_RETURN_NONE;
}
-PyObject* SCA_PythonController::PyGetActuators()
-{
- PyObject* resultlist = PyList_New(m_linkedactuators.size());
- for (unsigned int index=0;index<m_linkedactuators.size();index++)
- {
- PyList_SET_ITEM(resultlist,index, m_linkedactuators[index]->GetProxy());
- }
-
- return resultlist;
-}
-
-const char SCA_PythonController::GetSensor_doc[] =
-"getSensor (char sensorname) return linked sensor that is named [sensorname]\n";
-PyObject*
-SCA_PythonController::PyGetSensor(PyObject* value)
+PyObject* SCA_PythonController::PyDeActivate(PyObject *value)
{
-
- char *scriptArg = PyString_AsString(value);
- if (scriptArg==NULL) {
- PyErr_SetString(PyExc_TypeError, "controller.getSensor(string): Python Controller, expected a string (sensor name)");
+ if(m_sCurrentController != this) {
+ PyErr_SetString(PyExc_SystemError, "Cannot add an actuator from a non-active controller");
return NULL;
}
- for (unsigned int index=0;index<m_linkedsensors.size();index++)
- {
- SCA_ISensor* sensor = m_linkedsensors[index];
- STR_String realname = sensor->GetName();
- if (realname == scriptArg)
- {
- return sensor->GetProxy();
- }
- }
-
- PyErr_Format(PyExc_AttributeError, "controller.getSensor(string): Python Controller, unable to find requested sensor \"%s\"", scriptArg);
- return NULL;
-}
-
-
-
-const char SCA_PythonController::GetActuator_doc[] =
-"getActuator (char sensorname) return linked actuator that is named [actuatorname]\n";
-PyObject*
-SCA_PythonController::PyGetActuator(PyObject* value)
-{
-
- char *scriptArg = PyString_AsString(value);
- if (scriptArg==NULL) {
- PyErr_SetString(PyExc_TypeError, "controller.getActuator(string): Python Controller, expected a string (actuator name)");
+ SCA_IActuator* actu = LinkedActuatorFromPy(value);
+ if(actu==NULL)
return NULL;
- }
- for (unsigned int index=0;index<m_linkedactuators.size();index++)
- {
- SCA_IActuator* actua = m_linkedactuators[index];
- if (actua->GetName() == scriptArg)
- {
- return actua->GetProxy();
- }
- }
-
- PyErr_Format(PyExc_AttributeError, "controller.getActuator(string): Python Controller, unable to find requested actuator \"%s\"", scriptArg);
- return NULL;
-}
-
-
-const char SCA_PythonController::GetSensors_doc[] = "getSensors returns a list of all attached sensors";
-PyObject*
-SCA_PythonController::PyGetSensors()
-{
- PyObject* resultlist = PyList_New(m_linkedsensors.size());
- for (unsigned int index=0;index<m_linkedsensors.size();index++)
- {
- PyList_SET_ITEM(resultlist,index, m_linkedsensors[index]->GetProxy());
- }
-
- return resultlist;
+ m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, false);
+ Py_RETURN_NONE;
}
/* 1. getScript */
@@ -510,19 +563,6 @@ PyObject* SCA_PythonController::PySetScript(PyObject* value)
Py_RETURN_NONE;
}
-/* 1. getScript */
-PyObject* SCA_PythonController::PyGetState()
-{
- ShowDeprecationWarning("getState()", "the state property");
- return PyInt_FromLong(m_statemask);
-}
-
-PyObject* SCA_PythonController::pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
-{
- SCA_PythonController* self= static_cast<SCA_PythonController*>(self_v);
- return PyInt_FromLong(self->m_statemask);
-}
-
PyObject* SCA_PythonController::pyattr_get_script(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
SCA_PythonController* self= static_cast<SCA_PythonController*>(self_v);
@@ -537,14 +577,14 @@ int SCA_PythonController::pyattr_set_script(void *self_v, const KX_PYATTRIBUTE_D
if (scriptArg==NULL) {
PyErr_SetString(PyExc_TypeError, "controller.script = string: Python Controller, expected a string script text");
- return -1;
+ return PY_SET_ATTR_FAIL;
}
/* set scripttext sets m_bModified to true,
so next time the script is needed, a reparse into byte code is done */
self->SetScriptText(scriptArg);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h
index f10c4e47ebb..0c2af79c3a3 100644
--- a/source/gameengine/GameLogic/SCA_PythonController.h
+++ b/source/gameengine/GameLogic/SCA_PythonController.h
@@ -42,23 +42,37 @@ class SCA_IObject;
class SCA_PythonController : public SCA_IController
{
Py_Header;
- struct _object * m_bytecode;
+ struct _object * m_bytecode; /* SCA_PYEXEC_SCRIPT only */
+ PyObject* m_function; /* SCA_PYEXEC_MODULE only */
+ int m_function_argc;
bool m_bModified;
+ bool m_debug; /* use with SCA_PYEXEC_MODULE for reloading every logic run */
+ int m_mode;
+
protected:
STR_String m_scriptText;
STR_String m_scriptName;
- PyObject* m_pythondictionary;
+ PyObject* m_pythondictionary; /* for SCA_PYEXEC_SCRIPT only */
+ PyObject* m_pythonfunction; /* for SCA_PYEXEC_MODULE only */
+
std::vector<class SCA_ISensor*> m_triggeredSensors;
+
+ public:
+ enum SCA_PyExecMode
+ {
+ SCA_PYEXEC_SCRIPT = 0,
+ SCA_PYEXEC_MODULE,
+ SCA_PYEXEC_MAX
+ };
- public:
static SCA_PythonController* m_sCurrentController; // protected !!!
//for debugging
//virtual CValue* AddRef();
//virtual int Release(); // Release a reference to this value (when reference count reaches 0, the value is removed from the heap)
- SCA_PythonController(SCA_IObject* gameobj,PyTypeObject* T = &Type);
+ SCA_PythonController(SCA_IObject* gameobj, int mode, PyTypeObject* T = &Type);
virtual ~SCA_PythonController();
virtual CValue* GetReplica();
@@ -67,10 +81,14 @@ class SCA_PythonController : public SCA_IController
void SetScriptText(const STR_String& text);
void SetScriptName(const STR_String& name);
void SetDictionary(PyObject* pythondictionary);
+ void SetDebug(bool debug) { m_debug = debug; }
void AddTriggeredSensor(class SCA_ISensor* sensor)
{ m_triggeredSensors.push_back(sensor); }
int IsTriggered(class SCA_ISensor* sensor);
bool Compile();
+ bool Import();
+ void ErrorPrint(const char *error_msg);
+
static const char* sPyGetCurrentController__doc__;
static PyObject* sPyGetCurrentController(PyObject* self);
@@ -78,21 +96,18 @@ class SCA_PythonController : public SCA_IController
static PyObject* sPyAddActiveActuator(PyObject* self,
PyObject* args);
static SCA_IActuator* LinkedActuatorFromPy(PyObject *value);
+
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
KX_PYMETHOD_O(SCA_PythonController,Activate);
KX_PYMETHOD_O(SCA_PythonController,DeActivate);
- KX_PYMETHOD_DOC_NOARGS(SCA_PythonController,GetSensors);
- KX_PYMETHOD_DOC_NOARGS(SCA_PythonController,GetActuators);
- KX_PYMETHOD_DOC_O(SCA_PythonController,GetSensor);
- KX_PYMETHOD_DOC_O(SCA_PythonController,GetActuator);
KX_PYMETHOD_O(SCA_PythonController,SetScript);
KX_PYMETHOD_NOARGS(SCA_PythonController,GetScript);
- KX_PYMETHOD_NOARGS(SCA_PythonController,GetState);
+
- static PyObject* pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_script(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_script(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.cpp b/source/gameengine/GameLogic/SCA_RandomActuator.cpp
index 3a72d9b7652..a722590dd10 100644
--- a/source/gameengine/GameLogic/SCA_RandomActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomActuator.cpp
@@ -58,7 +58,6 @@ SCA_RandomActuator::SCA_RandomActuator(SCA_IObject *gameobj,
m_parameter2(para2),
m_distribution(mode)
{
- // m_base is never deleted, probably a memory leak!
m_base = new SCA_RandomNumberGenerator(seed);
m_counter = 0;
enforceConstraints();
@@ -68,7 +67,7 @@ SCA_RandomActuator::SCA_RandomActuator(SCA_IObject *gameobj,
SCA_RandomActuator::~SCA_RandomActuator()
{
- /* intentionally empty */
+ m_base->Release();
}
@@ -78,11 +77,16 @@ CValue* SCA_RandomActuator::GetReplica()
SCA_RandomActuator* replica = new SCA_RandomActuator(*this);
// replication just copy the m_base pointer => common random generator
replica->ProcessReplica();
- CValue::AddDataToReplica(replica);
-
return replica;
}
+void SCA_RandomActuator::ProcessReplica()
+{
+ SCA_IActuator::ProcessReplica();
+ // increment reference count so that we can release the generator at the end
+ m_base->AddRef();
+}
+
bool SCA_RandomActuator::Update()
@@ -312,8 +316,13 @@ void SCA_RandomActuator::enforceConstraints() {
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_RandomActuator::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_RandomActuator",
sizeof(PyObjectPlus_Proxy),
0,
@@ -367,7 +376,7 @@ PyAttributeDef SCA_RandomActuator::Attributes[] = {
KX_PYATTRIBUTE_FLOAT_RO("para1",SCA_RandomActuator,m_parameter1),
KX_PYATTRIBUTE_FLOAT_RO("para2",SCA_RandomActuator,m_parameter2),
KX_PYATTRIBUTE_ENUM_RO("distribution",SCA_RandomActuator,m_distribution),
- KX_PYATTRIBUTE_STRING_RW_CHECK("property",0,100,false,SCA_RandomActuator,m_propname,CheckProperty),
+ KX_PYATTRIBUTE_STRING_RW_CHECK("propName",0,100,false,SCA_RandomActuator,m_propname,CheckProperty),
KX_PYATTRIBUTE_RW_FUNCTION("seed",SCA_RandomActuator,pyattr_get_seed,pyattr_set_seed),
{ NULL } //Sentinel
};
@@ -384,10 +393,10 @@ int SCA_RandomActuator::pyattr_set_seed(void *self, const struct KX_PYATTRIBUTE_
if (PyInt_Check(value)) {
int ival = PyInt_AsLong(value);
act->m_base->SetSeed(ival);
- return 0;
+ return PY_SET_ATTR_SUCCESS;
} else {
PyErr_SetString(PyExc_TypeError, "actuator.seed = int: Random Actuator, expected an integer");
- return 1;
+ return PY_SET_ATTR_FAIL;
}
}
@@ -395,6 +404,10 @@ PyObject* SCA_RandomActuator::py_getattro(PyObject *attr) {
py_getattro_up(SCA_IActuator);
}
+PyObject* SCA_RandomActuator::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IActuator);
+}
+
int SCA_RandomActuator::py_setattro(PyObject *attr, PyObject *value)
{
py_setattro_up(SCA_IActuator);
@@ -470,7 +483,7 @@ const char SCA_RandomActuator::SetProperty_doc[] =
"\tSet the property to which the random value is assigned. If the \n"
"\tgenerator and property types do not match, the assignment is ignored.\n";
PyObject* SCA_RandomActuator::PySetProperty(PyObject* args) {
- ShowDeprecationWarning("setProperty()", "the 'property' property");
+ ShowDeprecationWarning("setProperty()", "the 'propName' property");
char *nameArg;
if (!PyArg_ParseTuple(args, "s:setProperty", &nameArg)) {
return NULL;
@@ -494,7 +507,7 @@ const char SCA_RandomActuator::GetProperty_doc[] =
"\tgenerator and property types do not match, the assignment is ignored.\n";
PyObject* SCA_RandomActuator::PyGetProperty()
{
- ShowDeprecationWarning("getProperty()", "the 'property' property");
+ ShowDeprecationWarning("getProperty()", "the 'propName' property");
return PyString_FromString(m_propname);
}
diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.h b/source/gameengine/GameLogic/SCA_RandomActuator.h
index 8f58ed0dcec..59863589b60 100644
--- a/source/gameengine/GameLogic/SCA_RandomActuator.h
+++ b/source/gameengine/GameLogic/SCA_RandomActuator.h
@@ -91,12 +91,14 @@ class SCA_RandomActuator : public SCA_IActuator
virtual bool Update();
virtual CValue* GetReplica();
+ virtual void ProcessReplica();
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
static PyObject* pyattr_get_seed(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
diff --git a/source/gameengine/GameLogic/SCA_RandomEventManager.cpp b/source/gameengine/GameLogic/SCA_RandomEventManager.cpp
index 156478d866d..976597aa812 100644
--- a/source/gameengine/GameLogic/SCA_RandomEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomEventManager.cpp
@@ -50,9 +50,10 @@ SCA_RandomEventManager::SCA_RandomEventManager(class SCA_LogicManager* logicmgr)
void SCA_RandomEventManager::NextFrame()
{
- for (set<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
+ SG_DList::iterator<SCA_ISensor> it(m_sensors);
+ for (it.begin();!it.end();++it)
{
- (*i)->Activate(m_logicmgr, NULL);
+ (*it)->Activate(m_logicmgr);
}
}
diff --git a/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp
index 06b5cca6ce9..0267cc8ebbf 100644
--- a/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp
@@ -59,6 +59,7 @@
SCA_RandomNumberGenerator::SCA_RandomNumberGenerator(long seed) {
// int mti = N + 1; /*unused*/
m_seed = seed;
+ m_refcount = 1;
SetStartVector();
}
diff --git a/source/gameengine/GameLogic/SCA_RandomNumberGenerator.h b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.h
index b9311d31af6..842a0331752 100644
--- a/source/gameengine/GameLogic/SCA_RandomNumberGenerator.h
+++ b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.h
@@ -36,6 +36,9 @@
class SCA_RandomNumberGenerator {
+ /* reference counted for memleak */
+ int m_refcount;
+
/** base seed */
long m_seed;
@@ -56,6 +59,16 @@ class SCA_RandomNumberGenerator {
float DrawFloat();
long GetSeed();
void SetSeed(long newseed);
+ SCA_RandomNumberGenerator* AddRef()
+ {
+ ++m_refcount;
+ return this;
+ }
+ void Release()
+ {
+ if (--m_refcount == 0)
+ delete this;
+ }
};
#endif /* __KX_RANDOMNUMBERGENERATOR */
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
index 5ead82db428..d5cbeef01ae 100644
--- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
@@ -50,7 +50,6 @@ SCA_RandomSensor::SCA_RandomSensor(SCA_EventManager* eventmgr,
PyTypeObject* T)
: SCA_ISensor(gameobj,eventmgr, T)
{
- // m_basegenerator is never deleted => memory leak
m_basegenerator = new SCA_RandomNumberGenerator(startseed);
Init();
}
@@ -59,7 +58,7 @@ SCA_RandomSensor::SCA_RandomSensor(SCA_EventManager* eventmgr,
SCA_RandomSensor::~SCA_RandomSensor()
{
- /* Nothing to be done here. */
+ m_basegenerator->Release();
}
void SCA_RandomSensor::Init()
@@ -74,13 +73,18 @@ void SCA_RandomSensor::Init()
CValue* SCA_RandomSensor::GetReplica()
{
CValue* replica = new SCA_RandomSensor(*this);
- // replication copies m_basegenerator pointer => share same generator
// this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
return replica;
}
+void SCA_RandomSensor::ProcessReplica()
+{
+ SCA_ISensor::ProcessReplica();
+ // increment reference count so that we can release the generator at this end
+ m_basegenerator->AddRef();
+}
bool SCA_RandomSensor::IsPositiveTrigger()
@@ -89,7 +93,7 @@ bool SCA_RandomSensor::IsPositiveTrigger()
}
-bool SCA_RandomSensor::Evaluate(CValue* event)
+bool SCA_RandomSensor::Evaluate()
{
/* Random generator is the generator from Line 25 of Table 1 in */
/* [KNUTH 1981, The Art of Computer Programming Vol. 2 */
@@ -127,8 +131,13 @@ bool SCA_RandomSensor::Evaluate(CValue* event)
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_RandomSensor::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_RandomSensor",
sizeof(PyObjectPlus_Proxy),
0,
@@ -154,9 +163,11 @@ PyParentObject SCA_RandomSensor::Parents[] = {
};
PyMethodDef SCA_RandomSensor::Methods[] = {
+ //Deprecated functions ----->
{"setSeed", (PyCFunction) SCA_RandomSensor::sPySetSeed, METH_VARARGS, (PY_METHODCHAR)SetSeed_doc},
{"getSeed", (PyCFunction) SCA_RandomSensor::sPyGetSeed, METH_NOARGS, (PY_METHODCHAR)GetSeed_doc},
{"getLastDraw", (PyCFunction) SCA_RandomSensor::sPyGetLastDraw, METH_NOARGS, (PY_METHODCHAR)GetLastDraw_doc},
+ //<----- Deprecated
{NULL,NULL} //Sentinel
};
@@ -170,6 +181,10 @@ PyObject* SCA_RandomSensor::py_getattro(PyObject *attr) {
py_getattro_up(SCA_ISensor);
}
+PyObject* SCA_RandomSensor::py_getattro_dict() {
+ py_getattro_dict_up(SCA_ISensor);
+}
+
int SCA_RandomSensor::py_setattro(PyObject *attr, PyObject *value)
{
py_setattro_up(SCA_ISensor);
@@ -225,10 +240,10 @@ int SCA_RandomSensor::pyattr_set_seed(void *self_v, const KX_PYATTRIBUTE_DEF *at
SCA_RandomSensor* self= static_cast<SCA_RandomSensor*>(self_v);
if (!PyInt_Check(value)) {
PyErr_SetString(PyExc_TypeError, "sensor.seed = int: Random Sensor, expected an integer");
- return -1;
+ return PY_SET_ATTR_FAIL;
}
self->m_basegenerator->SetSeed(PyInt_AsLong(value));
- return 0;
+ return PY_SET_ATTR_SUCCESS;
}
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h
index 764692600c3..b2bf2440966 100644
--- a/source/gameengine/GameLogic/SCA_RandomSensor.h
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.h
@@ -52,7 +52,8 @@ public:
PyTypeObject* T=&Type);
virtual ~SCA_RandomSensor();
virtual CValue* GetReplica();
- virtual bool Evaluate(CValue* event);
+ virtual void ProcessReplica();
+ virtual bool Evaluate();
virtual bool IsPositiveTrigger();
virtual void Init();
@@ -61,6 +62,7 @@ public:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
virtual int py_setattro(PyObject *attr, PyObject *value);
/* 1. setSeed */
diff --git a/source/gameengine/GameLogic/SCA_TimeEventManager.cpp b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp
index b7fadd3d62c..911ea772bef 100644
--- a/source/gameengine/GameLogic/SCA_TimeEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp
@@ -52,7 +52,7 @@ SCA_TimeEventManager::SCA_TimeEventManager(SCA_LogicManager* logicmgr)
SCA_TimeEventManager::~SCA_TimeEventManager()
{
for (vector<CValue*>::iterator it = m_timevalues.begin();
- !(it == m_timevalues.end()); it++)
+ !(it == m_timevalues.end()); ++it)
{
(*it)->Release();
}
@@ -80,7 +80,7 @@ void SCA_TimeEventManager::NextFrame(double curtime, double fixedtime)
// update sensors, but ... need deltatime !
for (vector<CValue*>::iterator it = m_timevalues.begin();
- !(it == m_timevalues.end()); it++)
+ !(it == m_timevalues.end()); ++it)
{
float newtime = (*it)->GetNumber() + fixedtime;
floatval->SetFloat(newtime);
@@ -104,7 +104,7 @@ void SCA_TimeEventManager::AddTimeProperty(CValue* timeval)
void SCA_TimeEventManager::RemoveTimeProperty(CValue* timeval)
{
for (vector<CValue*>::iterator it = m_timevalues.begin();
- !(it == m_timevalues.end()); it++)
+ !(it == m_timevalues.end()); ++it)
{
if ((*it) == timeval)
{
diff --git a/source/gameengine/GameLogic/SCA_XNORController.cpp b/source/gameengine/GameLogic/SCA_XNORController.cpp
index e9bb37ee958..aee8e26c21a 100644
--- a/source/gameengine/GameLogic/SCA_XNORController.cpp
+++ b/source/gameengine/GameLogic/SCA_XNORController.cpp
@@ -66,7 +66,7 @@ void SCA_XNORController::Trigger(SCA_LogicManager* logicmgr)
!(is==m_linkedsensors.end());is++)
{
SCA_ISensor* sensor = *is;
- if (sensor->IsPositiveTrigger())
+ if (sensor->GetState())
{
if (sensorresult == false)
{
@@ -77,19 +77,12 @@ void SCA_XNORController::Trigger(SCA_LogicManager* logicmgr)
}
}
- CValue* newevent = new CBoolValue(sensorresult);
-
for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
!(i==m_linkedactuators.end());i++)
{
- SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
- logicmgr->AddActiveActuator(actua,newevent);
+ SCA_IActuator* actua = *i;
+ logicmgr->AddActiveActuator(actua,sensorresult);
}
-
- // every actuator that needs the event, has a it's own reference to it now so
- // release it (so to be clear: if there is no actuator, it's deleted right now)
- newevent->Release();
-
}
@@ -98,7 +91,7 @@ CValue* SCA_XNORController::GetReplica()
{
CValue* replica = new SCA_XNORController(*this);
// this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
return replica;
}
@@ -111,8 +104,13 @@ CValue* SCA_XNORController::GetReplica()
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_XNORController::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_XNORController",
sizeof(PyObjectPlus_Proxy),
0,
@@ -149,4 +147,8 @@ PyObject* SCA_XNORController::py_getattro(PyObject *attr) {
py_getattro_up(SCA_IController);
}
+PyObject* SCA_XNORController::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IController);
+}
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_XNORController.h b/source/gameengine/GameLogic/SCA_XNORController.h
index c992d5f1834..4aad5763cb0 100644
--- a/source/gameengine/GameLogic/SCA_XNORController.h
+++ b/source/gameengine/GameLogic/SCA_XNORController.h
@@ -49,6 +49,7 @@ public:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
};
diff --git a/source/gameengine/GameLogic/SCA_XORController.cpp b/source/gameengine/GameLogic/SCA_XORController.cpp
index 791a139975f..5afb3a750f5 100644
--- a/source/gameengine/GameLogic/SCA_XORController.cpp
+++ b/source/gameengine/GameLogic/SCA_XORController.cpp
@@ -66,7 +66,7 @@ void SCA_XORController::Trigger(SCA_LogicManager* logicmgr)
!(is==m_linkedsensors.end());is++)
{
SCA_ISensor* sensor = *is;
- if (sensor->IsPositiveTrigger())
+ if (sensor->GetState())
{
if (sensorresult == true)
{
@@ -77,19 +77,12 @@ void SCA_XORController::Trigger(SCA_LogicManager* logicmgr)
}
}
- CValue* newevent = new CBoolValue(sensorresult);
-
for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
!(i==m_linkedactuators.end());i++)
{
- SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
- logicmgr->AddActiveActuator(actua,newevent);
+ SCA_IActuator* actua = *i;
+ logicmgr->AddActiveActuator(actua,sensorresult);
}
-
- // every actuator that needs the event, has a it's own reference to it now so
- // release it (so to be clear: if there is no actuator, it's deleted right now)
- newevent->Release();
-
}
@@ -98,7 +91,7 @@ CValue* SCA_XORController::GetReplica()
{
CValue* replica = new SCA_XORController(*this);
// this will copy properties and so on...
- CValue::AddDataToReplica(replica);
+ replica->ProcessReplica();
return replica;
}
@@ -111,8 +104,13 @@ CValue* SCA_XORController::GetReplica()
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_XORController::Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
+#if (PY_VERSION_HEX >= 0x02060000)
+ PyVarObject_HEAD_INIT(NULL, 0)
+#else
+ /* python 2.5 and below */
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+#endif
"SCA_XORController",
sizeof(PyObjectPlus_Proxy),
0,
@@ -149,4 +147,8 @@ PyObject* SCA_XORController::py_getattro(PyObject *attr) {
py_getattro_up(SCA_IController);
}
+PyObject* SCA_XORController::py_getattro_dict() {
+ py_getattro_dict_up(SCA_IController);
+}
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_XORController.h b/source/gameengine/GameLogic/SCA_XORController.h
index 065b31fd901..feb9f2ed07c 100644
--- a/source/gameengine/GameLogic/SCA_XORController.h
+++ b/source/gameengine/GameLogic/SCA_XORController.h
@@ -49,6 +49,7 @@ public:
/* --------------------------------------------------------------------- */
virtual PyObject* py_getattro(PyObject *attr);
+ virtual PyObject* py_getattro_dict();
};
diff --git a/source/gameengine/GameLogic/SConscript b/source/gameengine/GameLogic/SConscript
index ebf225f728f..91843eef586 100644
--- a/source/gameengine/GameLogic/SConscript
+++ b/source/gameengine/GameLogic/SConscript
@@ -5,7 +5,7 @@ sources = env.Glob('*.cpp') + env.Glob('Joystick/*.cpp')
incs = '. #/source/kernel/gen_system #/intern/string'
incs += ' #/source/gameengine/Expressions #/intern/moto/include'
-incs += ' #/source/gameengine/Rasterizer'
+incs += ' #/source/gameengine/Rasterizer #/source/gameengine/SceneGraph'
incs += ' ' + env['BF_PYTHON_INC']
@@ -22,4 +22,4 @@ if env['OURPLATFORM']=='win32-vc':
cxxflags.append ('/GR')
cxxflags.append ('/O2')
-env.BlenderLib ( 'bf_logic', sources, Split(incs), Split(defs), libtype=['game','player'], priority=[30, 110], cxx_compileflags=cxxflags )
+env.BlenderLib ( 'bf_logic', sources, Split(incs), Split(defs), libtype=['core','player'], priority=[330, 100], cxx_compileflags=cxxflags )