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/SCA_Joystick.cpp333
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_Joystick.h260
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h8
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp89
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_JoystickPrivate.h7
-rw-r--r--source/gameengine/GameLogic/Makefile2
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.cpp118
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.h44
-rw-r--r--source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp67
-rw-r--r--source/gameengine/GameLogic/SCA_ActuatorEventManager.h51
-rw-r--r--source/gameengine/GameLogic/SCA_ActuatorSensor.cpp196
-rw-r--r--source/gameengine/GameLogic/SCA_ActuatorSensor.h74
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp11
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysEventManager.h1
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysSensor.cpp7
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysSensor.h2
-rw-r--r--source/gameengine/GameLogic/SCA_DelaySensor.cpp257
-rw-r--r--source/gameengine/GameLogic/SCA_DelaySensor.h77
-rw-r--r--source/gameengine/GameLogic/SCA_EventManager.cpp17
-rw-r--r--source/gameengine/GameLogic/SCA_EventManager.h10
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.cpp10
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.h17
-rw-r--r--source/gameengine/GameLogic/SCA_IController.cpp99
-rw-r--r--source/gameengine/GameLogic/SCA_IController.h4
-rw-r--r--source/gameengine/GameLogic/SCA_ILogicBrick.cpp21
-rw-r--r--source/gameengine/GameLogic/SCA_ILogicBrick.h7
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.cpp104
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.h39
-rw-r--r--source/gameengine/GameLogic/SCA_IScene.cpp22
-rw-r--r--source/gameengine/GameLogic/SCA_IScene.h3
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.cpp163
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.h53
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickManager.cpp43
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickManager.h5
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickSensor.cpp331
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickSensor.h54
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardManager.cpp15
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardManager.h1
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.cpp191
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.h2
-rw-r--r--source/gameengine/GameLogic/SCA_LogicManager.cpp92
-rw-r--r--source/gameengine/GameLogic/SCA_LogicManager.h9
-rw-r--r--source/gameengine/GameLogic/SCA_MouseManager.cpp14
-rw-r--r--source/gameengine/GameLogic/SCA_MouseManager.h1
-rw-r--r--source/gameengine/GameLogic/SCA_MouseSensor.cpp51
-rw-r--r--source/gameengine/GameLogic/SCA_MouseSensor.h2
-rw-r--r--source/gameengine/GameLogic/SCA_NANDController.cpp144
-rw-r--r--source/gameengine/GameLogic/SCA_NANDController.h56
-rw-r--r--source/gameengine/GameLogic/SCA_NORController.cpp144
-rw-r--r--source/gameengine/GameLogic/SCA_NORController.h56
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyActuator.cpp63
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyActuator.h8
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyEventManager.cpp11
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyEventManager.h1
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.cpp73
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.h2
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.cpp172
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.h30
-rw-r--r--source/gameengine/GameLogic/SCA_RandomActuator.cpp74
-rw-r--r--source/gameengine/GameLogic/SCA_RandomEventManager.cpp11
-rw-r--r--source/gameengine/GameLogic/SCA_RandomEventManager.h1
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.cpp54
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.h2
-rw-r--r--source/gameengine/GameLogic/SCA_TimeEventManager.cpp5
-rw-r--r--source/gameengine/GameLogic/SCA_TimeEventManager.h1
-rw-r--r--source/gameengine/GameLogic/SCA_XNORController.cpp148
-rw-r--r--source/gameengine/GameLogic/SCA_XNORController.h56
-rw-r--r--source/gameengine/GameLogic/SCA_XORController.cpp148
-rw-r--r--source/gameengine/GameLogic/SCA_XORController.h56
-rw-r--r--source/gameengine/GameLogic/SConscript12
71 files changed, 3313 insertions, 1000 deletions
diff --git a/source/gameengine/GameLogic/CMakeLists.txt b/source/gameengine/GameLogic/CMakeLists.txt
index 6af37b746da..a7519196d50 100644
--- a/source/gameengine/GameLogic/CMakeLists.txt
+++ b/source/gameengine/GameLogic/CMakeLists.txt
@@ -32,6 +32,7 @@ SET(INC
../../../intern/string
../../../source/gameengine/Expressions
../../../intern/moto/include
+ ../../../source/gameengine/Rasterizer
${PYTHON_INC}
${SDL_INC}
)
diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
index aa5fc9eb8f3..e8e29fb2769 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
+++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
@@ -24,14 +24,18 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
+#ifndef DISABLE_SDL
#include <SDL.h>
+#endif
+
+#include <stdio.h>
#include "SCA_Joystick.h"
#include "SCA_JoystickPrivate.h"
-
-SCA_Joystick::SCA_Joystick()
+SCA_Joystick::SCA_Joystick(short int index)
:
+ m_joyindex(index),
m_axis10(0),
m_axis11(0),
m_axis20(0),
@@ -40,78 +44,100 @@ SCA_Joystick::SCA_Joystick()
m_buttonnum(-2),
m_hatdir(-2),
m_isinit(0),
- m_istrig(0)
+ m_istrig_axis(0),
+ m_istrig_button(0),
+ m_istrig_hat(0),
+ m_axismax(-1),
+ m_buttonmax(-1),
+ m_hatmax(-1)
{
+#ifndef DISABLE_SDL
m_private = new PrivateData();
+#endif
}
SCA_Joystick::~SCA_Joystick()
{
+#ifndef DISABLE_SDL
delete m_private;
+#endif
}
+SCA_Joystick *SCA_Joystick::m_instance[JOYINDEX_MAX];
+int SCA_Joystick::m_refCount = 0;
-bool SCA_Joystick::CreateJoystickDevice()
+SCA_Joystick *SCA_Joystick::GetInstance( short int joyindex )
{
- bool init = false;
- init = pCreateJoystickDevice();
- return init;
-}
-
+#ifdef DISABLE_SDL
+ return NULL;
+#else
+ if (joyindex < 0 || joyindex >= JOYINDEX_MAX) {
+ echo("Error-invalid joystick index: " << joyindex);
+ return NULL;
+ }
-void SCA_Joystick::DestroyJoystickDevice()
-{
- if(m_isinit)
- pDestroyJoystickDevice();
+ if (m_refCount == 0)
+ {
+ int i;
+ // do this once only
+ if(SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO ) == -1 ){
+ echo("Error-Initializing-SDL: " << SDL_GetError());
+ return NULL;
+ }
+ for (i=0; i<JOYINDEX_MAX; i++) {
+ m_instance[i] = new SCA_Joystick(i);
+ m_instance[i]->CreateJoystickDevice();
+ }
+ m_refCount = 1;
+ }
+ else
+ {
+ m_refCount++;
+ }
+ return m_instance[joyindex];
+#endif
}
-
-void SCA_Joystick::HandleEvents()
+void SCA_Joystick::ReleaseInstance()
{
- if(m_isinit)
+ if (--m_refCount == 0)
{
- if(SDL_PollEvent(&m_private->m_event))
- {
- switch(m_private->m_event.type)
- {
- case SDL_JOYAXISMOTION:
- HANDLE_AXISMOTION(OnAxisMotion);
- break;
- case SDL_JOYHATMOTION:
- HANDLE_HATMOTION(OnHatMotion);
- break;
- case SDL_JOYBUTTONUP:
- HANDLE_BUTTONUP(OnButtonUp);
- break;
- case SDL_JOYBUTTONDOWN:
- HANDLE_BUTTONDOWN(OnButtonDown);
- break;
- case SDL_JOYBALLMOTION:
- HANDLE_BALLMOTION(OnBallMotion);
- break;
- default:
- HANDLE_NOEVENT(OnNothing);
- break;
+#ifndef DISABLE_SDL
+ int i;
+ for (i=0; i<JOYINDEX_MAX; i++) {
+ if (m_instance[i]) {
+ m_instance[i]->DestroyJoystickDevice();
+ delete m_instance[i];
}
+ m_instance[i]= NULL;
}
+
+ SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO );
+#endif
}
}
-
void SCA_Joystick::cSetPrecision(int val)
{
m_prec = val;
}
+bool SCA_Joystick::aAnyAxisIsPositive(int axis)
+{
+ bool result;
+ int res = pAxisTest(axis);
+ res > m_prec? result = true: result = false;
+ return result;
+}
+
bool SCA_Joystick::aRightAxisIsPositive(int axis)
{
bool result;
int res = pGetAxis(axis,1);
res > m_prec? result = true: result = false;
- m_istrig = result;
return result;
}
@@ -121,7 +147,6 @@ bool SCA_Joystick::aUpAxisIsPositive(int axis)
bool result;
int res = pGetAxis(axis,0);
res < -m_prec? result = true : result = false;
- m_istrig = result;
return result;
}
@@ -131,7 +156,6 @@ bool SCA_Joystick::aLeftAxisIsPositive(int axis)
bool result;
int res = pGetAxis(axis,1);
res < -m_prec ? result = true : result = false;
- m_istrig = result;
return result;
}
@@ -141,26 +165,40 @@ bool SCA_Joystick::aDownAxisIsPositive(int axis)
bool result;
int res = pGetAxis(axis,0);
res > m_prec ? result = true:result = false;
- m_istrig = result;
return result;
}
+bool SCA_Joystick::aAnyButtonPressIsPositive(void)
+{
+ return (m_buttonnum==-2) ? false : true;
+}
+
+bool SCA_Joystick::aAnyButtonReleaseIsPositive(void)
+{
+ return (m_buttonnum==-2) ? true : false;
+}
bool SCA_Joystick::aButtonPressIsPositive(int button)
{
+#ifdef DISABLE_SDL
+ return false;
+#else
bool result;
SDL_JoystickGetButton(m_private->m_joystick, button)? result = true:result = false;
- m_istrig = result;
return result;
+#endif
}
bool SCA_Joystick::aButtonReleaseIsPositive(int button)
{
+#ifdef DISABLE_SDL
+ return false;
+#else
bool result;
SDL_JoystickGetButton(m_private->m_joystick, button)? result = false : result = true;
- m_istrig = result;
return result;
+#endif
}
@@ -169,27 +207,9 @@ bool SCA_Joystick::aHatIsPositive(int dir)
bool result;
int res = pGetHat(dir);
res == dir? result = true : result = false;
- m_istrig = result;
return result;
}
-
-int SCA_Joystick::pGetButtonPress(int button)
-{
- if(button == m_buttonnum)
- return m_buttonnum;
- return -2;
-}
-
-
-int SCA_Joystick::pGetButtonRelease(int button)
-{
- if(button == m_buttonnum)
- return m_buttonnum;
- return -2;
-}
-
-
int SCA_Joystick::pGetHat(int direction)
{
if(direction == m_hatdir){
@@ -198,174 +218,121 @@ int SCA_Joystick::pGetHat(int direction)
return 0;
}
-
-bool SCA_Joystick::GetJoyAxisMotion()
-{
- bool result = false;
- if(m_isinit){
- if(SDL_PollEvent(&m_private->m_event)){
- switch(m_private->m_event.type)
- {
- case SDL_JOYAXISMOTION:
- result = true;
- break;
- }
- }
- }
- return result;
-}
-
-
-bool SCA_Joystick::GetJoyButtonPress()
-{
- bool result = false;
- if(m_isinit){
- if(SDL_PollEvent(&m_private->m_event)){
- switch(m_private->m_event.type)
- {
- case SDL_JOYBUTTONDOWN:
- result = true;
- break;
- }
- }
- }
- return result;
-}
-
-
-bool SCA_Joystick::GetJoyButtonRelease()
-{
- bool result = false;
- if(m_isinit)
- {
- if(SDL_PollEvent(&m_private->m_event)){
- switch(m_private->m_event.type)
- {
- case SDL_JOYBUTTONUP:
- result = true;
- break;
- }
- }
- }
- return result;
-}
-
-
-bool SCA_Joystick::GetJoyHatMotion()
-{
- bool result = false;
- if(m_isinit){
- if(SDL_PollEvent(&m_private->m_event)){
- switch(m_private->m_event.type)
- {
- case SDL_JOYHATMOTION:
- result = true;
- break;
- }
- }
- }
- return 0;
-}
-
-
int SCA_Joystick::GetNumberOfAxes()
{
- int number;
- if(m_isinit){
- if(m_private->m_joystick){
- number = SDL_JoystickNumAxes(m_private->m_joystick);
- return number;
- }
- }
- return -1;
+ return m_axismax;
}
int SCA_Joystick::GetNumberOfButtons()
{
- int number;
- if(m_isinit){
- if(m_private->m_joystick){
- number = SDL_JoystickNumButtons(m_private->m_joystick);
- return number;
- }
- }
- return -1;
+ return m_buttonmax;
}
int SCA_Joystick::GetNumberOfHats()
{
- int number;
- if(m_isinit){
- if(m_private->m_joystick){
- number = SDL_JoystickNumHats(m_private->m_joystick);
- return number;
- }
- }
- return -1;
+ return m_hatmax;
}
-bool SCA_Joystick::pCreateJoystickDevice()
+bool SCA_Joystick::CreateJoystickDevice(void)
{
+#ifdef DISABLE_SDL
+ return false;
+#else
if(m_isinit == false){
- if(SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO ) == -1 ){
- echo("Error-Initializing-SDL: " << SDL_GetError());
- return false;
- }
- if(SDL_NumJoysticks() > 0){
- for(int i=0; i<SDL_NumJoysticks();i++){
- m_private->m_joystick = SDL_JoystickOpen(i);
- SDL_JoystickEventState(SDL_ENABLE);
- m_numjoys = i;
- }
- echo("Joystick-initialized");
- m_isinit = true;
- return true;
- }else{
- echo("Joystick-Error: " << SDL_NumJoysticks() << " avaiable joystick(s)");
+ if (m_joyindex>=SDL_NumJoysticks()) {
+ // don't print a message, because this is done anyway
+ //echo("Joystick-Error: " << SDL_NumJoysticks() << " avaiable joystick(s)");
return false;
}
+
+ m_private->m_joystick = SDL_JoystickOpen(m_joyindex);
+ SDL_JoystickEventState(SDL_ENABLE);
+ m_isinit = true;
+
+ echo("Joystick " << m_joyindex << " initialized");
+
+ /* must run after being initialized */
+ m_axismax = SDL_JoystickNumAxes(m_private->m_joystick);
+ m_buttonmax = SDL_JoystickNumButtons(m_private->m_joystick);
+ m_hatmax = SDL_JoystickNumHats(m_private->m_joystick);
}
- return false;
+ return true;
+#endif
}
-void SCA_Joystick::pDestroyJoystickDevice()
+void SCA_Joystick::DestroyJoystickDevice(void)
{
- echo("Closing-");
- for(int i=0; i<SDL_NumJoysticks(); i++){
- if(SDL_JoystickOpened(i)){
+#ifndef DISABLE_SDL
+ if (m_isinit){
+ if(SDL_JoystickOpened(m_joyindex)){
+ echo("Closing-joystick " << m_joyindex);
SDL_JoystickClose(m_private->m_joystick);
}
+ m_isinit = false;
}
- SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO );
+#endif
}
+int SCA_Joystick::Connected(void)
+{
+#ifndef DISABLE_SDL
+ if (m_isinit && SDL_JoystickOpened(m_joyindex))
+ return 1;
+#endif
+ return 0;
+}
void SCA_Joystick::pFillAxes()
{
- if(GetNumberOfAxes() == 1){
+#ifndef DISABLE_SDL
+ if(m_axismax == 1){
m_axis10 = SDL_JoystickGetAxis(m_private->m_joystick, 0);
m_axis11 = SDL_JoystickGetAxis(m_private->m_joystick, 1);
- }else if(GetNumberOfAxes() > 1){
+ }else if(m_axismax > 1){
m_axis10 = SDL_JoystickGetAxis(m_private->m_joystick, 0);
m_axis11 = SDL_JoystickGetAxis(m_private->m_joystick, 1);
m_axis20 = SDL_JoystickGetAxis(m_private->m_joystick, 2);
m_axis21 = SDL_JoystickGetAxis(m_private->m_joystick, 3);
}else{
- m_axis10 = 0;m_axis11 = 0;
- m_axis20 = 0;m_axis21 = 0;
+ m_axis10 = m_axis11 = m_axis20 = m_axis21 = 0;
}
+#endif
}
int SCA_Joystick::pGetAxis(int axisnum, int udlr)
{
+#ifndef DISABLE_SDL
if(axisnum == 1 && udlr == 1)return m_axis10; //u/d
if(axisnum == 1 && udlr == 0)return m_axis11; //l/r
if(axisnum == 2 && udlr == 0)return m_axis20; //...
if(axisnum == 2 && udlr == 1)return m_axis21;
+#endif
+ return 0;
+}
+
+int SCA_Joystick::pAxisTest(int axisnum)
+{
+#ifndef DISABLE_SDL
+ short i1,i2;
+ if(axisnum == 1) {
+ i1 = m_axis10; i2 = m_axis11;
+ }
+ else if(axisnum == 2) {
+ i1 = m_axis20; i2 = m_axis21;
+ }
+ /* long winded way to do
+ * return MAX2(abs(i1), abs(i2))
+ * avoid abs from math.h */
+ if (i1 < 0) i1 = -i1;
+ if (i2 < 0) i2 = -i2;
+ if (i1 <i2) return i2;
+ else return i1;
+#else
return 0;
+#endif
}
diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.h b/source/gameengine/GameLogic/Joystick/SCA_Joystick.h
index a76edc73b44..8335d5538ad 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.h
+++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.h
@@ -1,304 +1,189 @@
/**
-
* ***** BEGIN GPL LICENSE BLOCK *****
-
*
-
* This program is free software; you can redistribute it and/or
-
* modify it under the terms of the GNU General Public License
-
* as published by the Free Software Foundation; either version 2
-
* of the License, or (at your option) any later version.
-
-
-
-
*
-
* This program is distributed in the hope that it will be useful,
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-
* GNU General Public License for more details.
-
*
-
* You should have received a copy of the GNU General Public License
-
* along with this program; if not, write to the Free Software Foundation,
-
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
*
-
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-
* All rights reserved.
-
*
-
* The Original Code is: all of this file.
-
*
-
* Contributor(s): snailrose.
-
*
-
* ***** END GPL LICENSE BLOCK *****
-
*/
#ifndef _SCA_JOYSTICK_H_
-
#define _SCA_JOYSTICK_H_
-
-
#include "SCA_JoystickDefines.h"
-
-
-
-
+#ifndef DISABLE_SDL
+#include "SDL.h"
+#endif
/*
-
* Basic Joystick class
-
+ * I will make this class a singleton because there should be only one joystick
+ * even if there are more than one scene using it and count how many scene are using it.
+ * The underlying joystick should only be removed when the last scene is removed
*/
class SCA_Joystick
{
+ static SCA_Joystick *m_instance[JOYINDEX_MAX];
+ static int m_refCount;
class PrivateData;
-
+#ifndef DISABLE_SDL
PrivateData *m_private;
-
+#endif
int m_joyindex;
- /*!
-
- * the number of avail joysticks
-
- */
-
- int m_numjoys;
-
/*
-
*support for 2 axes
-
*/
int m_axis10,m_axis11;
-
int m_axis20,m_axis21;
- /*
-
+ /*
* Precision or range of the axes
-
*/
-
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
-
*/
-
+
+ int m_axismax;
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;
+ /* is triggered for each event type */
+ bool m_istrig_axis;
+ bool m_istrig_button;
+ bool m_istrig_hat;
- /* is triggered */
-
- bool m_istrig;
-
+#ifndef DISABLE_SDL
/*
-
- * Open the joystick
-
+ * event callbacks
*/
-
- bool pCreateJoystickDevice(void);
-
+ void OnAxisMotion(SDL_Event *sdl_event);
+ void OnHatMotion(SDL_Event *sdl_event);
+ void OnButtonUp(SDL_Event *sdl_event);
+ void OnButtonDown(SDL_Event *sdl_event);
+ void OnNothing(SDL_Event *sdl_event);
+ void OnBallMotion(SDL_Event *sdl_event){}
+#endif
/*
-
- * Close the joystick
-
+ * Open the joystick
*/
-
- void pDestroyJoystickDevice(void);
-
-
+ bool CreateJoystickDevice(void);
/*
-
- * event callbacks
-
+ * Close the joystick
*/
-
- void OnAxisMotion(void);
-
- void OnHatMotion(void);
-
- void OnButtonUp(void);
-
- void OnButtonDown(void);
-
- void OnNothing(void);
-
- void OnBallMotion(void){}
+ void DestroyJoystickDevice(void);
/*
-
* fills the axis mnember values
-
*/
-
void pFillAxes(void);
-
-
-
void pFillButtons(void);
/*
-
* returns m_axis10,m_axis11...
-
*/
- int pGetAxis(int axisnum, int udlr);
-
+ int pAxisTest(int axisnum);
/*
-
- * gets the current button
-
- */
-
- int pGetButtonPress(int button);
-
- /*
-
- * returns if no button is pressed
-
+ * returns m_axis10,m_axis11...
*/
-
- int pGetButtonRelease(int button);
+ int pGetAxis(int axisnum, int udlr);
/*
-
* gets the current hat direction
-
*/
-
int pGetHat(int direction);
-
-
-public:
-
- SCA_Joystick();
+ SCA_Joystick(short int index);
~SCA_Joystick();
-
+public:
- bool CreateJoystickDevice(void);
-
- void DestroyJoystickDevice(void);
-
- void HandleEvents();
+ static SCA_Joystick *GetInstance( short int joyindex );
+ static void HandleEvents( void );
+ void ReleaseInstance();
+
/*
-
*/
-
+ bool aAnyAxisIsPositive(int axis);
bool aUpAxisIsPositive(int axis);
-
bool aDownAxisIsPositive(int axis);
-
bool aLeftAxisIsPositive(int axis);
-
bool aRightAxisIsPositive(int axis);
+ bool aAnyButtonPressIsPositive(void);
+ bool aAnyButtonReleaseIsPositive(void);
bool aButtonPressIsPositive(int button);
-
bool aButtonReleaseIsPositive(int button);
-
bool aHatIsPositive(int dir);
/*
-
* precision is default '3200' which is overridden by input
-
*/
void cSetPrecision(int val);
-
-
int GetAxis10(void){
return m_axis10;
@@ -306,80 +191,57 @@ public:
}
int GetAxis11(void){
-
return m_axis11;
-
}
int GetAxis20(void){
-
return m_axis20;
-
}
int GetAxis21(void){
-
return m_axis21;
-
}
int GetButton(void){
-
return m_buttonnum;
-
}
int GetHat(void){
-
return m_hatdir;
-
}
int GetThreshold(void){
-
return m_prec;
-
}
- bool IsTrig(void){
-
- return m_istrig;
-
+ bool IsTrigAxis(void){
+ return m_istrig_axis;
}
-
+ bool IsTrigButton(void){
+ return m_istrig_button;
+ }
+
+ bool IsTrigHat(void){
+ return m_istrig_hat;
+ }
/*
-
- * returns true if an event is being processed
-
- */
-
- bool GetJoyAxisMotion(void);
-
- bool GetJoyButtonPress(void);
-
- bool GetJoyButtonRelease(void);
-
- bool GetJoyHatMotion(void);
-
- /*
-
* returns the # of...
-
*/
int GetNumberOfAxes(void);
-
int GetNumberOfButtons(void);
-
int GetNumberOfHats(void);
-
-
+ /*
+ * Test if the joystick is connected
+ */
+ int Connected(void);
};
-
-
+#ifndef DISABLE_SDL
+void Joystick_HandleEvents( void );
+#endif
#endif
diff --git a/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h b/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h
index 15a421188b9..73ffe1406d9 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h
+++ b/source/gameengine/GameLogic/Joystick/SCA_JoystickDefines.h
@@ -38,12 +38,6 @@
#define echo(x) std::cout << x << std::endl;
#endif
-/* function callbacks */
-#define HANDLE_AXISMOTION(fn) ((fn)(), 0L)
-#define HANDLE_HATMOTION(fn) ((fn)(), 0L)
-#define HANDLE_BUTTONUP(fn) ((fn)(), 0L)
-#define HANDLE_BUTTONDOWN(fn) ((fn)(), 0L)
-#define HANDLE_BALLMOTION(fn) ((fn)(), 0L)
-#define HANDLE_NOEVENT(fn) ((fn)(), 0L)
+#define JOYINDEX_MAX 8
#endif
diff --git a/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp b/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp
index ab523470e21..73ca288861d 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp
+++ b/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp
@@ -24,47 +24,100 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
+#ifndef DISABLE_SDL
#include <SDL.h>
+#endif
+
#include "SCA_Joystick.h"
#include "SCA_JoystickPrivate.h"
-
-void SCA_Joystick::OnAxisMotion(void)
+#ifndef DISABLE_SDL
+void SCA_Joystick::OnAxisMotion(SDL_Event* sdl_event)
{
pFillAxes();
- m_axisnum = m_private->m_event.jaxis.axis;
- m_axisvalue = m_private->m_event.jaxis.value;
- m_istrig = 1;
+ m_axisnum = sdl_event->jaxis.axis;
+ m_axisvalue = sdl_event->jaxis.value;
+ m_istrig_axis = 1;
}
-void SCA_Joystick::OnHatMotion(void)
+void SCA_Joystick::OnHatMotion(SDL_Event* sdl_event)
{
- m_hatdir = m_private->m_event.jhat.value;
- m_hatnum = m_private->m_event.jhat.hat;
- m_istrig = 1;
+ m_hatdir = sdl_event->jhat.value;
+ m_hatnum = sdl_event->jhat.hat;
+ m_istrig_hat = 1;
}
-
-void SCA_Joystick::OnButtonUp(void)
+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(void)
+void SCA_Joystick::OnButtonDown(SDL_Event* sdl_event)
{
- m_buttonmax = GetNumberOfButtons();
- if(m_private->m_event.jbutton.button >= 1 || m_private->m_event.jbutton.button <= m_buttonmax)
+ if(sdl_event->jbutton.button >= 0 || sdl_event->jbutton.button <= m_buttonmax)
{
- m_istrig = 1;
- m_buttonnum = m_private->m_event.jbutton.button;
+ m_istrig_button = 1;
+ m_buttonnum = sdl_event->jbutton.button;
}
}
-void SCA_Joystick::OnNothing(void)
+void SCA_Joystick::OnNothing(SDL_Event* sdl_event)
{
- m_istrig = 0;
+ 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++) {
+ if(SCA_Joystick::m_instance[i])
+ SCA_Joystick::m_instance[i]->OnNothing(&sdl_event);
+ }
+
+ if(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? */
+ switch(sdl_event.type)
+ {
+ case SDL_JOYAXISMOTION:
+ SCA_Joystick::m_instance[sdl_event.jaxis.which]->OnAxisMotion(&sdl_event);
+ break;
+ case SDL_JOYHATMOTION:
+ SCA_Joystick::m_instance[sdl_event.jhat.which]->OnHatMotion(&sdl_event);
+ break;
+ case SDL_JOYBUTTONUP:
+ SCA_Joystick::m_instance[sdl_event.jbutton.which]->OnButtonUp(&sdl_event);
+ break;
+ case SDL_JOYBUTTONDOWN:
+ SCA_Joystick::m_instance[sdl_event.jbutton.which]->OnButtonDown(&sdl_event);
+ break;
+ case SDL_JOYBALLMOTION:
+ SCA_Joystick::m_instance[sdl_event.jball.which]->OnBallMotion(&sdl_event);
+ break;
+ default:
+ printf("SCA_Joystick::HandleEvents, Unknown SDL event, this should not happen\n");
+ break;
+ }
+ }
}
+#endif
diff --git a/source/gameengine/GameLogic/Joystick/SCA_JoystickPrivate.h b/source/gameengine/GameLogic/Joystick/SCA_JoystickPrivate.h
index 23fad3cd55d..acbbcae9cd7 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_JoystickPrivate.h
+++ b/source/gameengine/GameLogic/Joystick/SCA_JoystickPrivate.h
@@ -29,14 +29,11 @@
#define __SCA_JOYSTICKPRIVATE_H__
#include "SCA_Joystick.h"
+#ifndef DISABLE_SDL
class SCA_Joystick::PrivateData
{
public:
/*
- * SDL events structure
- */
- SDL_Event m_event;
- /*
* The Joystick
*/
SDL_Joystick* m_joystick;
@@ -47,3 +44,5 @@ public:
}
};
#endif
+
+#endif
diff --git a/source/gameengine/GameLogic/Makefile b/source/gameengine/GameLogic/Makefile
index bf4cb5afea7..355ece6e8bd 100644
--- a/source/gameengine/GameLogic/Makefile
+++ b/source/gameengine/GameLogic/Makefile
@@ -39,8 +39,10 @@ include nan_compile.mk
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
CPPFLAGS += -I../Expressions
+CPPFLAGS += -I../Rasterizer
CPPFLAGS += -I$(NAN_STRING)/include
CPPFLAGS += -I$(NAN_MOTO)/include
+CPPFLAGS += -I../../blender/makesdna
CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
CPPFLAGS += $(NAN_SDLCFLAGS)
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
new file mode 100644
index 00000000000..9ec4ea00337
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
@@ -0,0 +1,118 @@
+#include "SCA_IActuator.h"
+
+#include "SCA_2DFilterActuator.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <iostream>
+
+SCA_2DFilterActuator::~SCA_2DFilterActuator()
+{
+}
+
+SCA_2DFilterActuator::SCA_2DFilterActuator(
+ SCA_IObject *gameobj,
+ RAS_2DFilterManager::RAS_2DFILTER_MODE type,
+ short flag,
+ float float_arg,
+ int int_arg,
+ RAS_IRasterizer* rasterizer,
+ RAS_IRenderTools* rendertools,
+ PyTypeObject* T)
+ : SCA_IActuator(gameobj, T),
+ m_type(type),
+ m_flag(flag),
+ m_float_arg(float_arg),
+ m_int_arg(int_arg),
+ m_rasterizer(rasterizer),
+ m_rendertools(rendertools)
+{
+ m_gameObj = NULL;
+ if(gameobj){
+ m_propNames = gameobj->GetPropertyNames();
+ m_gameObj = gameobj;
+ }
+}
+
+void SCA_2DFilterActuator::SetShaderText(STR_String text)
+{
+ m_shaderText = text;
+}
+
+
+
+CValue* SCA_2DFilterActuator::GetReplica()
+{
+ SCA_2DFilterActuator* replica = new SCA_2DFilterActuator(*this);
+ replica->ProcessReplica();
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+bool SCA_2DFilterActuator::Update()
+{
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+
+
+ if (bNegativeEvent)
+ return false; // do nothing on negative events
+
+ if( m_type == RAS_2DFilterManager::RAS_2DFILTER_MOTIONBLUR )
+ {
+ if(!m_flag)
+ m_rasterizer->EnableMotionBlur(m_float_arg);
+ else
+ m_rasterizer->DisableMotionBlur();
+
+ return false;
+ }
+ else if(m_type < RAS_2DFilterManager::RAS_2DFILTER_NUMBER_OF_FILTERS)
+ {
+ m_rendertools->Update2DFilter(m_propNames, m_gameObj, m_type, m_int_arg, m_shaderText);
+ }
+ return true;
+}
+
+
+PyTypeObject SCA_2DFilterActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_2DFilterActuator",
+ sizeof(SCA_2DFilterActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0,
+ __repr,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+
+PyParentObject SCA_2DFilterActuator::Parents[] = {
+ &SCA_2DFilterActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+
+PyMethodDef SCA_2DFilterActuator::Methods[] = {
+ /* add python functions to deal with m_msg... */
+ {NULL,NULL}
+};
+
+
+PyObject* SCA_2DFilterActuator::_getattr(const STR_String& attr) {
+ _getattr_up(SCA_IActuator);
+}
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.h b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
new file mode 100644
index 00000000000..7ec07cf5b19
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
@@ -0,0 +1,44 @@
+#ifndef __SCA_2DFILETRACTUATOR_H__
+#define __SCA_2DFILETRACTUATOR_H__
+
+#include "RAS_IRasterizer.h"
+#include "RAS_IRenderTools.h"
+#include "SCA_IActuator.h"
+
+class SCA_2DFilterActuator : public SCA_IActuator
+{
+ Py_Header;
+
+private:
+ vector<STR_String> m_propNames;
+ void * m_gameObj;
+ RAS_2DFilterManager::RAS_2DFILTER_MODE m_type;
+ short m_flag;
+ float m_float_arg;
+ int m_int_arg;
+ STR_String m_shaderText;
+ RAS_IRasterizer* m_rasterizer;
+ RAS_IRenderTools* m_rendertools;
+
+public:
+
+ SCA_2DFilterActuator(
+ class SCA_IObject* gameobj,
+ RAS_2DFilterManager::RAS_2DFILTER_MODE type,
+ short flag,
+ float float_arg,
+ int int_arg,
+ RAS_IRasterizer* rasterizer,
+ RAS_IRenderTools* rendertools,
+ PyTypeObject* T=&Type
+ );
+
+ void SetShaderText(STR_String text);
+ virtual ~SCA_2DFilterActuator();
+ virtual bool Update();
+
+ virtual CValue* GetReplica();
+ virtual PyObject* _getattr(const STR_String& attr);
+
+};
+#endif
diff --git a/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp b/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp
new file mode 100644
index 00000000000..768a3a45937
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp
@@ -0,0 +1,67 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "SCA_ISensor.h"
+#include "SCA_ActuatorEventManager.h"
+#include "SCA_ActuatorSensor.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+SCA_ActuatorEventManager::SCA_ActuatorEventManager(class SCA_LogicManager* logicmgr)
+ : SCA_EventManager(ACTUATOR_EVENTMGR),
+ m_logicmgr(logicmgr)
+{
+}
+
+
+
+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++)
+ {
+ (*it)->Activate(m_logicmgr,NULL);
+ }
+}
+
+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++)
+ {
+ ((SCA_ActuatorSensor*)(*it))->Update();
+ }
+} \ No newline at end of file
diff --git a/source/gameengine/GameLogic/SCA_ActuatorEventManager.h b/source/gameengine/GameLogic/SCA_ActuatorEventManager.h
new file mode 100644
index 00000000000..a7d61627c23
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ActuatorEventManager.h
@@ -0,0 +1,51 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __KX_ACTUATOREVENTMANAGER
+#define __KX_ACTUATOREVENTMANAGER
+
+#include "SCA_EventManager.h"
+
+#include <vector>
+
+using namespace std;
+
+class SCA_ActuatorEventManager : public SCA_EventManager
+{
+ class SCA_LogicManager* m_logicmgr;
+
+public:
+ SCA_ActuatorEventManager(class SCA_LogicManager* logicmgr);
+ virtual ~SCA_ActuatorEventManager();
+ virtual void NextFrame();
+ virtual void UpdateFrame();
+ //SCA_LogicManager* GetLogicManager() { return m_logicmgr;}
+};
+
+#endif //__KX_ACTUATOREVENTMANAGER
+
diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp
new file mode 100644
index 00000000000..7c37b237d60
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp
@@ -0,0 +1,196 @@
+/**
+ * Actuator sensor
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <iostream>
+#include "SCA_ActuatorSensor.h"
+#include "SCA_EventManager.h"
+#include "SCA_LogicManager.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+SCA_ActuatorSensor::SCA_ActuatorSensor(SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ const STR_String& actname,
+ PyTypeObject* T )
+ : SCA_ISensor(gameobj,eventmgr,T),
+ m_checkactname(actname)
+{
+ m_actuator = GetParent()->FindActuator(m_checkactname);
+ Init();
+}
+
+void SCA_ActuatorSensor::Init()
+{
+ m_lastresult = m_invert?true:false;
+ m_midresult = m_lastresult;
+ m_reset = true;
+}
+
+CValue* SCA_ActuatorSensor::GetReplica()
+{
+ SCA_ActuatorSensor* replica = new SCA_ActuatorSensor(*this);
+ // m_range_expr must be recalculated on replica!
+ CValue::AddDataToReplica(replica);
+ replica->Init();
+
+ return replica;
+}
+
+void SCA_ActuatorSensor::ReParent(SCA_IObject* parent)
+{
+ m_actuator = parent->FindActuator(m_checkactname);
+ SCA_ISensor::ReParent(parent);
+}
+
+bool SCA_ActuatorSensor::IsPositiveTrigger()
+{
+ bool result = m_lastresult;
+ if (m_invert)
+ result = !result;
+
+ return result;
+}
+
+
+
+SCA_ActuatorSensor::~SCA_ActuatorSensor()
+{
+}
+
+
+
+bool SCA_ActuatorSensor::Evaluate(CValue* event)
+{
+ if (m_actuator)
+ {
+ bool result = m_actuator->IsActive();
+ bool reset = m_reset && m_level;
+
+ m_reset = false;
+ if (m_lastresult != result || m_midresult != result)
+ {
+ m_lastresult = m_midresult = result;
+ return true;
+ }
+ return (reset) ? true : false;
+ }
+ return false;
+}
+
+void SCA_ActuatorSensor::Update()
+{
+ if (m_actuator)
+ {
+ m_midresult = m_actuator->IsActive() && !m_actuator->IsNegativeEvent();
+ }
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_ActuatorSensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_ActuatorSensor",
+ sizeof(SCA_ActuatorSensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_ActuatorSensor::Parents[] = {
+ &SCA_ActuatorSensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_ActuatorSensor::Methods[] = {
+ {"getActuator", (PyCFunction) SCA_ActuatorSensor::sPyGetActuator, METH_NOARGS, (PY_METHODCHAR)GetActuator_doc},
+ {"setActuator", (PyCFunction) SCA_ActuatorSensor::sPySetActuator, METH_VARARGS, (PY_METHODCHAR)SetActuator_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_ActuatorSensor::_getattr(const STR_String& attr) {
+ _getattr_up(SCA_ISensor); /* implicit return! */
+}
+
+/* 3. getActuator */
+const char SCA_ActuatorSensor::GetActuator_doc[] =
+"getActuator()\n"
+"\tReturn the Actuator with which the sensor operates.\n";
+PyObject* SCA_ActuatorSensor::PyGetActuator(PyObject* self)
+{
+ return PyString_FromString(m_checkactname);
+}
+
+/* 4. setActuator */
+const char SCA_ActuatorSensor::SetActuator_doc[] =
+"setActuator(name)\n"
+"\t- name: string\n"
+"\tSets the Actuator with which to operate. If there is no Actuator\n"
+"\tof this name, the call is ignored.\n";
+PyObject* SCA_ActuatorSensor::PySetActuator(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ /* We should query whether the name exists. Or should we create a prop */
+ /* on the fly? */
+ char *actNameArg = NULL;
+
+ if (!PyArg_ParseTuple(args, "s", &actNameArg)) {
+ return NULL;
+ }
+
+ SCA_IActuator* act = GetParent()->FindActuator(STR_String(actNameArg));
+ if (act) {
+ m_checkactname = actNameArg;
+ m_actuator = act;
+ } else {
+ ; /* error: bad actuator name */
+ }
+ Py_Return;
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.h b/source/gameengine/GameLogic/SCA_ActuatorSensor.h
new file mode 100644
index 00000000000..a71145f6852
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.h
@@ -0,0 +1,74 @@
+/**
+ * Actuator sensor
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_ACTUATORSENSOR
+#define __KX_ACTUATORSENSOR
+
+#include "SCA_ISensor.h"
+#include "SCA_IActuator.h"
+
+class SCA_ActuatorSensor : public SCA_ISensor
+{
+ Py_Header;
+ STR_String m_checkactname;
+ bool m_lastresult;
+ bool m_midresult;
+ protected:
+ SCA_IActuator* m_actuator;
+public:
+ SCA_ActuatorSensor(class SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ const STR_String& actname,
+ PyTypeObject* T=&Type );
+
+ virtual ~SCA_ActuatorSensor();
+ virtual CValue* GetReplica();
+ virtual void Init();
+ virtual bool Evaluate(CValue* event);
+ virtual bool IsPositiveTrigger();
+ virtual void ReParent(SCA_IObject* parent);
+ void Update();
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(const STR_String& attr);
+
+ /* 3. setProperty */
+ KX_PYMETHOD_DOC(SCA_ActuatorSensor,SetActuator);
+ /* 4. getProperty */
+ KX_PYMETHOD_DOC_NOARGS(SCA_ActuatorSensor,GetActuator);
+
+};
+
+#endif
+
diff --git a/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp b/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
index ab3bc2cc4ee..4cd2dfba994 100644
--- a/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
@@ -51,16 +51,9 @@ SCA_AlwaysEventManager::SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr)
void SCA_AlwaysEventManager::NextFrame()
{
- for (vector<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
+ for (set<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
{
- SCA_ISensor* sensor = *i;
- sensor->Activate(m_logicmgr, NULL);
+ (*i)->Activate(m_logicmgr, NULL);
}
}
-
-
-void SCA_AlwaysEventManager::RegisterSensor(SCA_ISensor* sensor)
-{
- m_sensors.push_back(sensor);
-}
diff --git a/source/gameengine/GameLogic/SCA_AlwaysEventManager.h b/source/gameengine/GameLogic/SCA_AlwaysEventManager.h
index 28c71512875..a619eecddd4 100644
--- a/source/gameengine/GameLogic/SCA_AlwaysEventManager.h
+++ b/source/gameengine/GameLogic/SCA_AlwaysEventManager.h
@@ -39,7 +39,6 @@ class SCA_AlwaysEventManager : public SCA_EventManager
public:
SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr);
virtual void NextFrame();
- virtual void RegisterSensor(SCA_ISensor* sensor);
};
diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
index 67df5d091ab..f9fbf2387c4 100644
--- a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
@@ -53,10 +53,13 @@ SCA_AlwaysSensor::SCA_AlwaysSensor(class SCA_EventManager* eventmgr,
: SCA_ISensor(gameobj,eventmgr, T)
{
//SetDrawColor(255,0,0);
- m_alwaysresult = true;
+ Init();
}
-
+void SCA_AlwaysSensor::Init()
+{
+ m_alwaysresult = true;
+}
SCA_AlwaysSensor::~SCA_AlwaysSensor()
{
diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.h b/source/gameengine/GameLogic/SCA_AlwaysSensor.h
index 474ed025432..8bf2a8aa98e 100644
--- a/source/gameengine/GameLogic/SCA_AlwaysSensor.h
+++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.h
@@ -45,6 +45,8 @@ public:
virtual CValue* GetReplica();
virtual bool Evaluate(CValue* event);
virtual bool IsPositiveTrigger();
+ virtual void Init();
+
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.cpp b/source/gameengine/GameLogic/SCA_DelaySensor.cpp
new file mode 100644
index 00000000000..f15d4c7249f
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_DelaySensor.cpp
@@ -0,0 +1,257 @@
+/**
+ * Delay trigger
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef WIN32
+// This warning tells us about truncation of __long__ stl-generated names.
+// It can occasionally cause DevStudio to have internal compiler warnings.
+#pragma warning( disable : 4786 )
+#endif
+
+#include "SCA_DelaySensor.h"
+#include "SCA_LogicManager.h"
+#include "SCA_EventManager.h"
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_DelaySensor::SCA_DelaySensor(class SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ int delay,
+ int duration,
+ bool repeat,
+ PyTypeObject* T)
+ : SCA_ISensor(gameobj,eventmgr, T),
+ m_delay(delay),
+ m_duration(duration),
+ m_repeat(repeat)
+{
+ Init();
+}
+
+void SCA_DelaySensor::Init()
+{
+ m_lastResult = false;
+ m_frameCount = -1;
+ m_reset = true;
+}
+
+SCA_DelaySensor::~SCA_DelaySensor()
+{
+ /* intentionally empty */
+}
+
+CValue* SCA_DelaySensor::GetReplica()
+{
+ CValue* replica = new SCA_DelaySensor(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+bool SCA_DelaySensor::IsPositiveTrigger()
+{
+ return (m_invert ? !m_lastResult : m_lastResult);
+}
+
+bool SCA_DelaySensor::Evaluate(CValue* event)
+{
+ bool trigger = false;
+ bool result;
+
+ if (m_frameCount==-1) {
+ // this is needed to ensure ON trigger in case delay==0
+ // and avoid spurious OFF trigger when duration==0
+ m_lastResult = false;
+ m_frameCount = 0;
+ }
+
+ if (m_frameCount<m_delay) {
+ m_frameCount++;
+ result = false;
+ } else if (m_duration > 0) {
+ if (m_frameCount < m_delay+m_duration) {
+ m_frameCount++;
+ result = true;
+ } else {
+ result = false;
+ if (m_repeat)
+ m_frameCount = -1;
+ }
+ } else {
+ result = true;
+ if (m_repeat)
+ m_frameCount = -1;
+ }
+ if ((m_reset && m_level) || result != m_lastResult)
+ trigger = true;
+ m_reset = false;
+ m_lastResult = result;
+ return trigger;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_DelaySensor::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_DelaySensor",
+ sizeof(SCA_DelaySensor),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_DelaySensor::Parents[] = {
+ &SCA_DelaySensor::Type,
+ &SCA_ISensor::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_DelaySensor::Methods[] = {
+ /* setProperty */
+ {"setDelay", (PyCFunction) SCA_DelaySensor::sPySetDelay, METH_VARARGS, (PY_METHODCHAR)SetDelay_doc},
+ {"setDuration", (PyCFunction) SCA_DelaySensor::sPySetDuration, METH_VARARGS, (PY_METHODCHAR)SetDuration_doc},
+ {"setRepeat", (PyCFunction) SCA_DelaySensor::sPySetRepeat, METH_VARARGS, (PY_METHODCHAR)SetRepeat_doc},
+ /* getProperty */
+ {"getDelay", (PyCFunction) SCA_DelaySensor::sPyGetDelay, METH_NOARGS, (PY_METHODCHAR)GetDelay_doc},
+ {"getDuration", (PyCFunction) SCA_DelaySensor::sPyGetDuration, METH_NOARGS, (PY_METHODCHAR)GetDuration_doc},
+ {"getRepeat", (PyCFunction) SCA_DelaySensor::sPyGetRepeat, METH_NOARGS, (PY_METHODCHAR)GetRepeat_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_DelaySensor::_getattr(const STR_String& attr) {
+ _getattr_up(SCA_ISensor);
+}
+
+const char SCA_DelaySensor::SetDelay_doc[] =
+"setDelay(delay)\n"
+"\t- delay: length of the initial OFF period as number of frame\n"
+"\t 0 for immediate trigger\n"
+"\tSet the initial delay before the positive trigger\n";
+PyObject* SCA_DelaySensor::PySetDelay(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int delay;
+
+ if(!PyArg_ParseTuple(args, "i", &delay)) {
+ return NULL;
+ }
+ if (delay < 0) {
+ PyErr_SetString(PyExc_ValueError, "Delay cannot be negative");
+ return NULL;
+ }
+ m_delay = delay;
+ Py_Return;
+}
+
+const char SCA_DelaySensor::SetDuration_doc[] =
+"setDuration(duration)\n"
+"\t- duration: length of the ON period in number of frame after the initial off period\n"
+"\t 0 for no ON period\n"
+"\tSet the duration of the ON pulse after initial delay.\n"
+"\tIf > 0, a negative trigger is fired at the end of the ON pulse.\n";
+PyObject* SCA_DelaySensor::PySetDuration(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int duration;
+
+ if(!PyArg_ParseTuple(args, "i", &duration)) {
+ return NULL;
+ }
+ if (duration < 0) {
+ PyErr_SetString(PyExc_ValueError, "Duration cannot be negative");
+ return NULL;
+ }
+ m_duration = duration;
+ Py_Return;
+}
+
+const char SCA_DelaySensor::SetRepeat_doc[] =
+"setRepeat(repeat)\n"
+"\t- repeat: 1 if the initial OFF-ON cycle should be repeated indefinately\n"
+"\t 0 if the initial OFF-ON cycle should run only once\n"
+"\tSet the sensor repeat mode\n";
+PyObject* SCA_DelaySensor::PySetRepeat(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int repeat;
+
+ if(!PyArg_ParseTuple(args, "i", &repeat)) {
+ return NULL;
+ }
+ m_repeat = (repeat != 0);
+ Py_Return;
+}
+
+const char SCA_DelaySensor::GetDelay_doc[] =
+"getDelay()\n"
+"\tReturn the delay parameter value\n";
+PyObject* SCA_DelaySensor::PyGetDelay(PyObject* self)
+{
+ return PyInt_FromLong(m_delay);
+}
+
+const char SCA_DelaySensor::GetDuration_doc[] =
+"getDuration()\n"
+"\tReturn the duration parameter value\n";
+PyObject* SCA_DelaySensor::PyGetDuration(PyObject* self)
+{
+ return PyInt_FromLong(m_duration);
+}
+
+const char SCA_DelaySensor::GetRepeat_doc[] =
+"getRepeat()\n"
+"\tReturn the repeat parameter value\n";
+PyObject* SCA_DelaySensor::PyGetRepeat(PyObject* self)
+{
+ return BoolToPyArg(m_repeat);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.h b/source/gameengine/GameLogic/SCA_DelaySensor.h
new file mode 100644
index 00000000000..a997fabe3cd
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_DelaySensor.h
@@ -0,0 +1,77 @@
+/**
+ * SCA_DelaySensor.h
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_DELAYSENSOR
+#define __KX_DELAYSENSOR
+#include "SCA_ISensor.h"
+
+class SCA_DelaySensor : public SCA_ISensor
+{
+ Py_Header;
+ bool m_lastResult;
+ bool m_repeat;
+ int m_delay;
+ int m_duration;
+ int m_frameCount;
+
+public:
+ SCA_DelaySensor(class SCA_EventManager* eventmgr,
+ SCA_IObject* gameobj,
+ int delay,
+ int duration,
+ bool repeat,
+ PyTypeObject* T =&Type);
+ virtual ~SCA_DelaySensor();
+ virtual CValue* GetReplica();
+ virtual bool Evaluate(CValue* event);
+ virtual bool IsPositiveTrigger();
+ virtual void Init();
+
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(const STR_String& attr);
+
+ /* setProperty */
+ KX_PYMETHOD_DOC(SCA_DelaySensor,SetDelay);
+ KX_PYMETHOD_DOC(SCA_DelaySensor,SetDuration);
+ KX_PYMETHOD_DOC(SCA_DelaySensor,SetRepeat);
+ /* getProperty */
+ KX_PYMETHOD_DOC_NOARGS(SCA_DelaySensor,GetDelay);
+ KX_PYMETHOD_DOC_NOARGS(SCA_DelaySensor,GetDuration);
+ KX_PYMETHOD_DOC_NOARGS(SCA_DelaySensor,GetRepeat);
+
+};
+
+#endif //__KX_ALWAYSSENSOR
+
diff --git a/source/gameengine/GameLogic/SCA_EventManager.cpp b/source/gameengine/GameLogic/SCA_EventManager.cpp
index 1ca88182ddc..e4fd0379597 100644
--- a/source/gameengine/GameLogic/SCA_EventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_EventManager.cpp
@@ -45,17 +45,14 @@ SCA_EventManager::~SCA_EventManager()
{
}
-
+void SCA_EventManager::RegisterSensor(class SCA_ISensor* sensor)
+{
+ m_sensors.insert(sensor);
+}
void SCA_EventManager::RemoveSensor(class SCA_ISensor* sensor)
{
- std::vector<SCA_ISensor*>::iterator i =
- std::find(m_sensors.begin(), m_sensors.end(), sensor);
- if (!(i == m_sensors.end()))
- {
- std::swap(*i, m_sensors.back());
- m_sensors.pop_back();
- }
+ m_sensors.erase(sensor);
}
void SCA_EventManager::NextFrame(double curtime, double fixedtime)
@@ -72,7 +69,9 @@ void SCA_EventManager::EndFrame()
{
}
-
+void SCA_EventManager::UpdateFrame()
+{
+}
int SCA_EventManager::GetType()
{
diff --git a/source/gameengine/GameLogic/SCA_EventManager.h b/source/gameengine/GameLogic/SCA_EventManager.h
index 89731497f6f..9dbb5a6d24f 100644
--- a/source/gameengine/GameLogic/SCA_EventManager.h
+++ b/source/gameengine/GameLogic/SCA_EventManager.h
@@ -30,12 +30,14 @@
#define __KX_EVENTMANAGER
#include <vector>
+#include <set>
#include <algorithm>
class SCA_EventManager
{
protected:
- std::vector <class SCA_ISensor*> m_sensors;
+ // use a set to speed-up insertion/removal
+ std::set <class SCA_ISensor*> m_sensors;
public:
enum EVENT_MANAGER_TYPE {
@@ -49,7 +51,8 @@ public:
RAY_EVENTMGR,
RADAR_EVENTMGR,
NETWORK_EVENTMGR,
- JOY_EVENTMGR
+ JOY_EVENTMGR,
+ ACTUATOR_EVENTMGR
};
SCA_EventManager(EVENT_MANAGER_TYPE mgrtype);
@@ -58,8 +61,9 @@ public:
virtual void RemoveSensor(class SCA_ISensor* sensor);
virtual void NextFrame(double curtime, double fixedtime);
virtual void NextFrame();
+ virtual void UpdateFrame();
virtual void EndFrame();
- virtual void RegisterSensor(class SCA_ISensor* sensor)=0;
+ virtual void RegisterSensor(class SCA_ISensor* sensor);
int GetType();
protected:
diff --git a/source/gameengine/GameLogic/SCA_IActuator.cpp b/source/gameengine/GameLogic/SCA_IActuator.cpp
index 568d0eb4a89..eeca2d7b44c 100644
--- a/source/gameengine/GameLogic/SCA_IActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_IActuator.cpp
@@ -36,6 +36,7 @@ using namespace std;
SCA_IActuator::SCA_IActuator(SCA_IObject* gameobj,
PyTypeObject* T) :
+ m_links(0),
SCA_ILogicBrick(gameobj,T)
{
// nothing to do
@@ -109,3 +110,12 @@ SCA_IActuator::~SCA_IActuator()
RemoveAllEvents();
}
+void SCA_IActuator::DecLink()
+{
+ m_links--;
+ if (m_links < 0)
+ {
+ printf("Warning: actuator %s has negative m_links: %d\n", m_name.Ptr(), m_links);
+ m_links = 0;
+ }
+}
diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h
index bff32dcebaa..7ffb21b5490 100644
--- a/source/gameengine/GameLogic/SCA_IActuator.h
+++ b/source/gameengine/GameLogic/SCA_IActuator.h
@@ -34,8 +34,11 @@
class SCA_IActuator : public SCA_ILogicBrick
{
+ friend class SCA_LogicManager;
protected:
std::vector<CValue*> m_events;
+ int m_links; // number of active links to controllers
+ // when 0, the actuator is automatically stopped
void RemoveAllEvents();
public:
@@ -47,6 +50,15 @@ public:
PyTypeObject* T =&Type);
/**
+ * UnlinkObject(...)
+ * Certain actuator use gameobject pointers (like TractTo actuator)
+ * This function can be called when an object is removed to make
+ * sure that the actuator will not use it anymore.
+ */
+
+ virtual bool UnlinkObject(SCA_IObject* clientobj) { return false; }
+
+ /**
* Update(...)
* Update the actuator based upon the events received since
* the last call to Update, the current time and deltatime the
@@ -74,6 +86,11 @@ public:
*/
bool IsNegativeEvent() const;
virtual ~SCA_IActuator();
+
+ void ClrLink() { m_links=0; }
+ void IncLink() { m_links++; }
+ void DecLink();
+ bool IsNoLink() const { return !m_links; }
};
#endif //__KX_IACTUATOR
diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp
index 5cb62678c6b..0bd20117f31 100644
--- a/source/gameengine/GameLogic/SCA_IController.cpp
+++ b/source/gameengine/GameLogic/SCA_IController.cpp
@@ -29,6 +29,7 @@
#include "SCA_IController.h"
#include "SCA_LogicManager.h"
#include "SCA_IActuator.h"
+#include "SCA_ISensor.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -37,6 +38,7 @@
SCA_IController::SCA_IController(SCA_IObject* gameobj,
PyTypeObject* T)
:
+ m_statemask(0),
SCA_ILogicBrick(gameobj,T)
{
}
@@ -45,6 +47,7 @@ SCA_IController::SCA_IController(SCA_IObject* gameobj,
SCA_IController::~SCA_IController()
{
+ UnlinkAllActuators();
}
@@ -65,6 +68,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)
+ {
+ (*sensit)->DecLink();
+ }
+ }
m_linkedsensors.clear();
}
@@ -72,6 +83,14 @@ 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)
+ {
+ (*actit)->DecLink();
+ }
+ }
m_linkedactuators.clear();
}
@@ -95,26 +114,96 @@ void SCA_IController::Trigger(SCA_LogicManager* logicmgr)
void SCA_IController::LinkToActuator(SCA_IActuator* actua)
{
m_linkedactuators.push_back(actua);
+ if (IsActive())
+ {
+ actua->IncLink();
+ }
}
void SCA_IController::UnlinkActuator(class SCA_IActuator* actua)
{
std::vector<class SCA_IActuator*>::iterator actit;
- std::vector<class SCA_IActuator*>::iterator actfound = m_linkedactuators.end();
for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
{
if ((*actit) == actua)
- actfound = actit;
+ {
+ break;
+ }
}
- if (!(actfound==m_linkedactuators.end()))
+ if (!(actit==m_linkedactuators.end()))
{
- m_linkedactuators.erase(actfound);
+ if (IsActive())
+ {
+ (*actit)->DecLink();
+ }
+ m_linkedactuators.erase(actit);
}
-
}
void SCA_IController::LinkToSensor(SCA_ISensor* sensor)
{
m_linkedsensors.push_back(sensor);
+ if (IsActive())
+ {
+ sensor->IncLink();
+ }
+}
+
+void SCA_IController::UnlinkSensor(class SCA_ISensor* sensor)
+{
+ std::vector<class SCA_ISensor*>::iterator sensit;
+ for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
+ {
+ if ((*sensit) == sensor)
+ {
+ break;
+ }
+
+ }
+ if (!(sensit==m_linkedsensors.end()))
+ {
+ if (IsActive())
+ {
+ (*sensit)->DecLink();
+ }
+ m_linkedsensors.erase(sensit);
+ }
}
+
+void SCA_IController::ApplyState(unsigned int state)
+{
+ std::vector<class SCA_IActuator*>::iterator actit;
+ std::vector<class SCA_ISensor*>::iterator sensit;
+
+ if (m_statemask & state)
+ {
+ if (!IsActive())
+ {
+ // reactive the controller, all the links to actuator are valid again
+ for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
+ {
+ (*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);
+ }
+ } else if (IsActive())
+ {
+ for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
+ {
+ (*actit)->DecLink();
+ }
+ for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
+ {
+ (*sensit)->DecLink();
+ }
+ SetActive(false);
+ }
+}
+
diff --git a/source/gameengine/GameLogic/SCA_IController.h b/source/gameengine/GameLogic/SCA_IController.h
index 79e956dec4e..f67c0942eb4 100644
--- a/source/gameengine/GameLogic/SCA_IController.h
+++ b/source/gameengine/GameLogic/SCA_IController.h
@@ -36,6 +36,7 @@ class SCA_IController : public SCA_ILogicBrick
protected:
std::vector<class SCA_ISensor*> m_linkedsensors;
std::vector<class SCA_IActuator*> m_linkedactuators;
+ unsigned int m_statemask;
public:
SCA_IController(SCA_IObject* gameobj,PyTypeObject* T);
virtual ~SCA_IController();
@@ -47,6 +48,9 @@ public:
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);
};
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
index 8423d06dfcd..abd049e9d64 100644
--- a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
+++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
@@ -27,6 +27,7 @@
*/
#include "SCA_ILogicBrick.h"
+#include "PyObjectPlus.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -82,7 +83,10 @@ void SCA_ILogicBrick::ReParent(SCA_IObject* parent)
m_gameobj = parent;
}
-
+void SCA_ILogicBrick::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
+{
+ // nothing to do
+}
CValue* SCA_ILogicBrick::Calc(VALUE_OPERATOR op, CValue *val)
{
@@ -242,8 +246,8 @@ PyParentObject SCA_ILogicBrick::Parents[] = {
PyMethodDef SCA_ILogicBrick::Methods[] = {
- {"getOwner", (PyCFunction) SCA_ILogicBrick::sPyGetOwner, METH_VARARGS},
- {"getExecutePriority", (PyCFunction) SCA_ILogicBrick::sPySetExecutePriority, METH_VARARGS},
+ {"getOwner", (PyCFunction) SCA_ILogicBrick::sPyGetOwner, METH_NOARGS},
+ {"getExecutePriority", (PyCFunction) SCA_ILogicBrick::sPySetExecutePriority, METH_NOARGS},
{"setExecutePriority", (PyCFunction) SCA_ILogicBrick::sPySetExecutePriority, METH_VARARGS},
{NULL,NULL} //Sentinel
};
@@ -258,9 +262,7 @@ SCA_ILogicBrick::_getattr(const STR_String& attr)
-PyObject* SCA_ILogicBrick::PyGetOwner(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* SCA_ILogicBrick::PyGetOwner(PyObject* self)
{
CValue* parent = GetParent();
if (parent)
@@ -270,8 +272,7 @@ PyObject* SCA_ILogicBrick::PyGetOwner(PyObject* self,
}
printf("ERROR: Python scriptblock without owner\n");
- Py_INCREF(Py_None);
- return Py_None;//Int_FromLong(IsPositiveTrigger());
+ Py_RETURN_NONE; //Int_FromLong(IsPositiveTrigger());
}
@@ -294,9 +295,7 @@ PyObject* SCA_ILogicBrick::PySetExecutePriority(PyObject* self,
-PyObject* SCA_ILogicBrick::PyGetExecutePriority(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* SCA_ILogicBrick::PyGetExecutePriority(PyObject* self)
{
return PyInt_FromLong(m_Execute_Ueber_Priority);
}
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h
index f359ee0911b..c28711ac0f6 100644
--- a/source/gameengine/GameLogic/SCA_ILogicBrick.h
+++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h
@@ -32,6 +32,8 @@
#include "Value.h"
#include "SCA_IObject.h"
#include "BoolValue.h"
+#include "GEN_Map.h"
+#include "GEN_HashedPtr.h"
class SCA_ILogicBrick : public CValue
{
@@ -59,6 +61,7 @@ public:
SCA_IObject* GetParent();
virtual void ReParent(SCA_IObject* parent);
+ virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
// act as a BoolValue (with value IsPositiveTrigger)
virtual CValue* Calc(VALUE_OPERATOR op, CValue *val);
@@ -82,9 +85,9 @@ public:
// python methods
- KX_PYMETHOD(SCA_ILogicBrick,GetOwner);
+ KX_PYMETHOD_NOARGS(SCA_ILogicBrick,GetOwner);
KX_PYMETHOD(SCA_ILogicBrick,SetExecutePriority);
- KX_PYMETHOD(SCA_ILogicBrick,GetExecutePriority);
+ KX_PYMETHOD_NOARGS(SCA_ILogicBrick,GetExecutePriority);
enum KX_BOOL_TYPE {
KX_BOOL_NODEF = 0,
diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp
index 0d315a55f43..b0f8decee26 100644
--- a/source/gameengine/GameLogic/SCA_IObject.cpp
+++ b/source/gameengine/GameLogic/SCA_IObject.cpp
@@ -40,7 +40,7 @@
MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0);
-SCA_IObject::SCA_IObject(PyTypeObject* T): CValue(T)
+SCA_IObject::SCA_IObject(PyTypeObject* T): m_initState(0), m_state(0), CValue(T)
{
m_suspended = false;
}
@@ -52,7 +52,9 @@ SCA_IObject::~SCA_IObject()
SCA_SensorList::iterator its;
for (its = m_sensors.begin(); !(its == m_sensors.end()); ++its)
{
- ((CValue*)(*its))->Release();
+ //Use Delete for sensor to ensure proper cleaning
+ (*its)->Delete();
+ //((CValue*)(*its))->Release();
}
SCA_ControllerList::iterator itc;
for (itc = m_controllers.begin(); !(itc == m_controllers.end()); ++itc)
@@ -60,6 +62,10 @@ SCA_IObject::~SCA_IObject()
((CValue*)(*itc))->Release();
}
SCA_ActuatorList::iterator ita;
+ for (ita = m_registeredActuators.begin(); !(ita==m_registeredActuators.end()); ++ita)
+ {
+ (*ita)->UnlinkObject(this);
+ }
for (ita = m_actuators.begin(); !(ita==m_actuators.end()); ++ita)
{
((CValue*)(*ita))->Release();
@@ -96,6 +102,7 @@ SCA_ActuatorList& SCA_IObject::GetActuators()
void SCA_IObject::AddSensor(SCA_ISensor* act)
{
+ act->AddRef();
m_sensors.push_back(act);
}
@@ -103,6 +110,7 @@ void SCA_IObject::AddSensor(SCA_ISensor* act)
void SCA_IObject::AddController(SCA_IController* act)
{
+ act->AddRef();
m_controllers.push_back(act);
}
@@ -110,10 +118,28 @@ void SCA_IObject::AddController(SCA_IController* act)
void SCA_IObject::AddActuator(SCA_IActuator* act)
{
+ act->AddRef();
m_actuators.push_back(act);
}
+void SCA_IObject::RegisterActuator(SCA_IActuator* act)
+{
+ // don't increase ref count, it would create dead lock
+ m_registeredActuators.push_back(act);
+}
+void SCA_IObject::UnregisterActuator(SCA_IActuator* act)
+{
+ SCA_ActuatorList::iterator ita;
+ for (ita = m_registeredActuators.begin(); ita != m_registeredActuators.end(); ita++)
+ {
+ if ((*ita) == act) {
+ (*ita) = m_registeredActuators.back();
+ m_registeredActuators.pop_back();
+ break;
+ }
+ }
+}
void SCA_IObject::SetIgnoreActivityCulling(bool b)
{
@@ -131,15 +157,17 @@ bool SCA_IObject::GetIgnoreActivityCulling()
void SCA_IObject::ReParentLogic()
{
- SCA_SensorList& oldsensors = GetSensors();
-
- int sen = 0;
- SCA_SensorList::iterator its;
- for (its = oldsensors.begin(); !(its==oldsensors.end()); ++its)
+ SCA_ActuatorList& oldactuators = GetActuators();
+ int act = 0;
+ SCA_ActuatorList::iterator ita;
+ for (ita = oldactuators.begin(); !(ita==oldactuators.end()); ++ita)
{
- SCA_ISensor* newsensor = (SCA_ISensor*)(*its)->GetReplica();
- newsensor->ReParent(this);
- oldsensors[sen++] = newsensor;
+ SCA_IActuator* newactuator = (SCA_IActuator*) (*ita)->GetReplica();
+ newactuator->ReParent(this);
+ // actuators are initially not connected to any controller
+ newactuator->SetActive(false);
+ newactuator->ClrLink();
+ oldactuators[act++] = newactuator;
}
SCA_ControllerList& oldcontrollers = GetControllers();
@@ -149,20 +177,26 @@ void SCA_IObject::ReParentLogic()
{
SCA_IController* newcontroller = (SCA_IController*)(*itc)->GetReplica();
newcontroller->ReParent(this);
+ newcontroller->SetActive(false);
oldcontrollers[con++]=newcontroller;
}
- SCA_ActuatorList& oldactuators = GetActuators();
-
- int act = 0;
- SCA_ActuatorList::iterator ita;
- for (ita = oldactuators.begin(); !(ita==oldactuators.end()); ++ita)
+ // convert sensors last so that actuators are already available for Actuator sensor
+ SCA_SensorList& oldsensors = GetSensors();
+ int sen = 0;
+ SCA_SensorList::iterator its;
+ for (its = oldsensors.begin(); !(its==oldsensors.end()); ++its)
{
- SCA_IActuator* newactuator = (SCA_IActuator*) (*ita)->GetReplica();
- newactuator->ReParent(this);
- newactuator->SetActive(false);
- oldactuators[act++] = newactuator;
+ SCA_ISensor* newsensor = (SCA_ISensor*)(*its)->GetReplica();
+ newsensor->ReParent(this);
+ newsensor->SetActive(false);
+ // sensors are initially not connected to any controller
+ newsensor->ClrLink();
+ oldsensors[sen++] = newsensor;
}
+
+ // a new object cannot be client of any actuator
+ m_registeredActuators.clear();
}
@@ -272,7 +306,7 @@ const MT_Point3& SCA_IObject::ConvertPythonPylist(PyObject* pylist)
}
#endif
-void SCA_IObject::Suspend(void)
+void SCA_IObject::Suspend()
{
if ((!m_ignore_activity_culling)
&& (!m_suspended)) {
@@ -301,6 +335,36 @@ void SCA_IObject::Resume(void)
}
}
+void SCA_IObject::SetState(unsigned int state)
+{
+ unsigned int tmpstate;
+ SCA_ControllerList::iterator contit;
+
+ // we will update the state in two steps:
+ // 1) set the new state bits that are 1
+ // 2) clr the new state bits that are 0
+ // This to ensure continuity if a sensor is attached to two states
+ // that are switching state: no need to deactive and reactive the sensor
+
+ tmpstate = m_state | state;
+ if (tmpstate != m_state)
+ {
+ // update the status of the controllers
+ for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++)
+ {
+ (*contit)->ApplyState(tmpstate);
+ }
+ }
+ m_state = state;
+ if (m_state != tmpstate)
+ {
+ for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++)
+ {
+ (*contit)->ApplyState(m_state);
+ }
+ }
+}
+
/* ------------------------------------------------------------------------- */
diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h
index 8f3e25afa03..38a7ed29dca 100644
--- a/source/gameengine/GameLogic/SCA_IObject.h
+++ b/source/gameengine/GameLogic/SCA_IObject.h
@@ -55,6 +55,7 @@ protected:
SCA_SensorList m_sensors;
SCA_ControllerList m_controllers;
SCA_ActuatorList m_actuators;
+ SCA_ActuatorList m_registeredActuators; // actuators that use a pointer to this object
static class MT_Point3 m_sDummy;
/**
@@ -66,7 +67,17 @@ protected:
* Ignore updates?
*/
bool m_suspended;
-
+
+ /**
+ * init state of object (used when object is created)
+ */
+ unsigned int m_initState;
+
+ /**
+ * current state = bit mask of state that are active
+ */
+ unsigned int m_state;
+
public:
SCA_IObject(PyTypeObject* T=&Type);
@@ -79,6 +90,8 @@ public:
void AddSensor(SCA_ISensor* act);
void AddController(SCA_IController* act);
void AddActuator(SCA_IActuator* act);
+ void RegisterActuator(SCA_IActuator* act);
+ void UnregisterActuator(SCA_IActuator* act);
SCA_ISensor* FindSensor(const STR_String& sensorname);
SCA_IActuator* FindActuator(const STR_String& actuatorname);
@@ -108,7 +121,27 @@ public:
* Resume progress
*/
void Resume(void);
-
+
+ /**
+ * Set init state
+ */
+ void SetInitState(unsigned int initState) { m_initState = initState; }
+
+ /**
+ * initialize the state when object is created
+ */
+ void ResetState(void) { SetState(m_initState); }
+
+ /**
+ * Set the object state
+ */
+ void SetState(unsigned int state);
+
+ /**
+ * Get the object state
+ */
+ unsigned int GetState(void) { return m_state; }
+
// const class MT_Point3& ConvertPythonPylist(PyObject* pylist);
// here come the python forwarded methods
@@ -117,7 +150,7 @@ public:
virtual int GetGameObjectType() {return -1;}
typedef enum ObjectTypes {
- OBJ_ARMATURE=0
+ OBJ_ARMATURE=0,
}ObjectTypes;
};
diff --git a/source/gameengine/GameLogic/SCA_IScene.cpp b/source/gameengine/GameLogic/SCA_IScene.cpp
index 5e4e1cdcf92..9fbeb706910 100644
--- a/source/gameengine/GameLogic/SCA_IScene.cpp
+++ b/source/gameengine/GameLogic/SCA_IScene.cpp
@@ -27,25 +27,40 @@
*/
#include "SCA_IScene.h"
+#include "Value.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-SCA_IScene::SCA_IScene()
+SCA_DebugProp::SCA_DebugProp(): m_obj(NULL)
{
}
+SCA_DebugProp::~SCA_DebugProp()
+{
+ if (m_obj)
+ m_obj->Release();
+}
+SCA_IScene::SCA_IScene()
+{
+}
-SCA_IScene::~SCA_IScene()
+void SCA_IScene::RemoveAllDebugProperties()
{
- // release debugprop list
for (std::vector<SCA_DebugProp*>::iterator it = m_debugList.begin();
!(it==m_debugList.end());it++)
{
delete (*it);
}
+ m_debugList.clear();
+}
+
+
+SCA_IScene::~SCA_IScene()
+{
+ RemoveAllDebugProperties();
}
@@ -61,6 +76,7 @@ void SCA_IScene::AddDebugProperty(class CValue* debugprop,
{
SCA_DebugProp* dprop = new SCA_DebugProp();
dprop->m_obj = debugprop;
+ debugprop->AddRef();
dprop->m_name = name;
m_debugList.push_back(dprop);
}
diff --git a/source/gameengine/GameLogic/SCA_IScene.h b/source/gameengine/GameLogic/SCA_IScene.h
index 145d8a98512..d18778a37c2 100644
--- a/source/gameengine/GameLogic/SCA_IScene.h
+++ b/source/gameengine/GameLogic/SCA_IScene.h
@@ -37,6 +37,8 @@ struct SCA_DebugProp
{
class CValue* m_obj;
STR_String m_name;
+ SCA_DebugProp();
+ ~SCA_DebugProp();
};
class SCA_IScene
@@ -57,6 +59,7 @@ public:
std::vector<SCA_DebugProp*>& GetDebugProperties();
void AddDebugProperty(class CValue* debugprop,
const STR_String &name);
+ void RemoveAllDebugProperties();
};
#endif //__KX_ISCENE_H
diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp
index 9fdee0c19da..b10ac676464 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.cpp
+++ b/source/gameengine/GameLogic/SCA_ISensor.cpp
@@ -32,6 +32,8 @@
#include "SCA_ISensor.h"
#include "SCA_EventManager.h"
#include "SCA_LogicManager.h"
+// needed for IsTriggered()
+#include "SCA_PythonController.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -41,7 +43,8 @@
void SCA_ISensor::ReParent(SCA_IObject* parent)
{
SCA_ILogicBrick::ReParent(parent);
- m_eventmgr->RegisterSensor(this);
+ // will be done when the sensor is activated
+ //m_eventmgr->RegisterSensor(this);
this->SetActive(false);
}
@@ -52,8 +55,11 @@ SCA_ISensor::SCA_ISensor(SCA_IObject* gameobj,
SCA_ILogicBrick(gameobj,T),
m_triggered(false)
{
+ m_links = 0;
m_suspended = false;
m_invert = false;
+ m_level = false;
+ m_reset = false;
m_pos_ticks = 0;
m_neg_ticks = 0;
m_pos_pulsemode = false;
@@ -94,6 +100,10 @@ void SCA_ISensor::SetInvert(bool inv) {
m_invert = inv;
}
+void SCA_ISensor::SetLevel(bool lvl) {
+ m_level = lvl;
+}
+
float SCA_ISensor::GetNumber() {
return IsPositiveTrigger();
@@ -111,6 +121,24 @@ void SCA_ISensor::Resume() {
m_suspended = false;
}
+void SCA_ISensor::Init() {
+ printf("Sensor %s has no init function, please report this bug to Blender.org\n", m_name.Ptr());
+}
+
+void SCA_ISensor::DecLink() {
+ m_links--;
+ if (m_links < 0)
+ {
+ printf("Warning: sensor %s has negative m_links: %d\n", m_name.Ptr(), m_links);
+ m_links = 0;
+ }
+ if (!m_links)
+ {
+ // sensor is detached from all controllers, remove it from manager
+ UnregisterToManager();
+ }
+}
+
/* python integration */
PyTypeObject SCA_ISensor::Type = {
@@ -140,23 +168,31 @@ PyParentObject SCA_ISensor::Parents[] = {
};
PyMethodDef SCA_ISensor::Methods[] = {
{"isPositive", (PyCFunction) SCA_ISensor::sPyIsPositive,
- METH_VARARGS, IsPositive_doc},
+ METH_NOARGS, (PY_METHODCHAR)IsPositive_doc},
+ {"isTriggered", (PyCFunction) SCA_ISensor::sPyIsTriggered,
+ METH_VARARGS, (PY_METHODCHAR)IsTriggered_doc},
{"getUsePosPulseMode", (PyCFunction) SCA_ISensor::sPyGetUsePosPulseMode,
- METH_VARARGS, GetUsePosPulseMode_doc},
+ METH_NOARGS, (PY_METHODCHAR)GetUsePosPulseMode_doc},
{"setUsePosPulseMode", (PyCFunction) SCA_ISensor::sPySetUsePosPulseMode,
- METH_VARARGS, SetUsePosPulseMode_doc},
+ METH_VARARGS, (PY_METHODCHAR)SetUsePosPulseMode_doc},
{"getFrequency", (PyCFunction) SCA_ISensor::sPyGetFrequency,
- METH_VARARGS, GetFrequency_doc},
+ METH_NOARGS, (PY_METHODCHAR)GetFrequency_doc},
{"setFrequency", (PyCFunction) SCA_ISensor::sPySetFrequency,
- METH_VARARGS, SetFrequency_doc},
+ METH_VARARGS, (PY_METHODCHAR)SetFrequency_doc},
{"getUseNegPulseMode", (PyCFunction) SCA_ISensor::sPyGetUseNegPulseMode,
- METH_VARARGS, GetUseNegPulseMode_doc},
+ METH_NOARGS, (PY_METHODCHAR)GetUseNegPulseMode_doc},
{"setUseNegPulseMode", (PyCFunction) SCA_ISensor::sPySetUseNegPulseMode,
- METH_VARARGS, SetUseNegPulseMode_doc},
+ METH_VARARGS, (PY_METHODCHAR)SetUseNegPulseMode_doc},
{"getInvert", (PyCFunction) SCA_ISensor::sPyGetInvert,
- METH_VARARGS, GetInvert_doc},
+ METH_NOARGS, (PY_METHODCHAR)GetInvert_doc},
{"setInvert", (PyCFunction) SCA_ISensor::sPySetInvert,
- METH_VARARGS, SetInvert_doc},
+ METH_VARARGS, (PY_METHODCHAR)SetInvert_doc},
+ {"getLevel", (PyCFunction) SCA_ISensor::sPyGetLevel,
+ METH_NOARGS, (PY_METHODCHAR)GetLevel_doc},
+ {"setLevel", (PyCFunction) SCA_ISensor::sPySetLevel,
+ METH_VARARGS, (PY_METHODCHAR)SetLevel_doc},
+ {"reset", (PyCFunction) SCA_ISensor::sPyReset,
+ METH_NOARGS, (PY_METHODCHAR)Reset_doc},
{NULL,NULL} //Sentinel
};
@@ -170,17 +206,29 @@ SCA_ISensor::_getattr(const STR_String& attr)
void SCA_ISensor::RegisterToManager()
{
+ // sensor is just activated, initialize it
+ Init();
+ m_newControllers.erase(m_newControllers.begin(), m_newControllers.end());
m_eventmgr->RegisterSensor(this);
}
+void SCA_ISensor::UnregisterToManager()
+{
+ m_eventmgr->RemoveSensor(this);
+}
+
void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event)
{
// calculate if a __triggering__ is wanted
- if (!m_suspended) {
+ // don't evaluate a sensor that is not connected to any controller
+ if (m_links && !m_suspended) {
bool result = this->Evaluate(event);
if (result) {
logicmgr->AddActivatedSensor(this);
+ // reset these counters so that pulse are synchronized with transition
+ m_pos_ticks = 0;
+ m_neg_ticks = 0;
} else
{
/* First, the pulsing behaviour, if pulse mode is
@@ -209,26 +257,54 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event)
}
}
}
+ if (!m_newControllers.empty())
+ {
+ if (!IsActive() && 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 (std::vector<SCA_IController*>::iterator ci=m_newControllers.begin();
+ ci != m_newControllers.end(); ci++)
+ {
+ logicmgr->AddTriggeredController(*ci, 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());
+ }
}
}
/* Python functions: */
-char SCA_ISensor::IsPositive_doc[] =
+const char SCA_ISensor::IsPositive_doc[] =
"isPositive()\n"
-"\tReturns whether the sensor is registered a positive event.\n";
-PyObject* SCA_ISensor::PyIsPositive(PyObject* self, PyObject* args, PyObject* kwds)
+"\tReturns whether the sensor is in an active state.\n";
+PyObject* SCA_ISensor::PyIsPositive(PyObject* self)
{
int retval = IsPositiveTrigger();
return PyInt_FromLong(retval);
}
+const char SCA_ISensor::IsTriggered_doc[] =
+"isTriggered()\n"
+"\tReturns whether the sensor has triggered the current controller.\n";
+PyObject* SCA_ISensor::PyIsTriggered(PyObject* self)
+{
+ // check with the current controller
+ int retval = 0;
+ if (SCA_PythonController::m_sCurrentController)
+ retval = SCA_PythonController::m_sCurrentController->IsTriggered(this);
+ return PyInt_FromLong(retval);
+}
+
/**
* getUsePulseMode: getter for the pulse mode (KX_TRUE = on)
*/
-char SCA_ISensor::GetUsePosPulseMode_doc[] =
+const char SCA_ISensor::GetUsePosPulseMode_doc[] =
"getUsePosPulseMode()\n"
"\tReturns whether positive pulse mode is active.\n";
-PyObject* SCA_ISensor::PyGetUsePosPulseMode(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* SCA_ISensor::PyGetUsePosPulseMode(PyObject* self)
{
return BoolToPyArg(m_pos_pulsemode);
}
@@ -236,7 +312,7 @@ PyObject* SCA_ISensor::PyGetUsePosPulseMode(PyObject* self, PyObject* args, PyOb
/**
* setUsePulseMode: setter for the pulse mode (KX_TRUE = on)
*/
-char SCA_ISensor::SetUsePosPulseMode_doc[] =
+const char SCA_ISensor::SetUsePosPulseMode_doc[] =
"setUsePosPulseMode(pulse?)\n"
"\t - pulse? : Pulse when a positive event occurs?\n"
"\t (KX_TRUE, KX_FALSE)\n"
@@ -252,10 +328,10 @@ PyObject* SCA_ISensor::PySetUsePosPulseMode(PyObject* self, PyObject* args, PyOb
/**
* getFrequency: getter for the pulse mode interval
*/
-char SCA_ISensor::GetFrequency_doc[] =
+const char SCA_ISensor::GetFrequency_doc[] =
"getFrequency()\n"
"\tReturns the frequency of the updates in pulse mode.\n" ;
-PyObject* SCA_ISensor::PyGetFrequency(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* SCA_ISensor::PyGetFrequency(PyObject* self)
{
return PyInt_FromLong(m_pulse_frequency);
}
@@ -263,7 +339,7 @@ PyObject* SCA_ISensor::PyGetFrequency(PyObject* self, PyObject* args, PyObject*
/**
* setFrequency: setter for the pulse mode (KX_TRUE = on)
*/
-char SCA_ISensor::SetFrequency_doc[] =
+const char SCA_ISensor::SetFrequency_doc[] =
"setFrequency(pulse_frequency)\n"
"\t- pulse_frequency: The frequency of the updates in pulse mode (integer)"
"\tSet the frequency of the updates in pulse mode.\n"
@@ -287,15 +363,15 @@ PyObject* SCA_ISensor::PySetFrequency(PyObject* self, PyObject* args, PyObject*
}
-char SCA_ISensor::GetInvert_doc[] =
+const char SCA_ISensor::GetInvert_doc[] =
"getInvert()\n"
"\tReturns whether or not pulses from this sensor are inverted.\n" ;
-PyObject* SCA_ISensor::PyGetInvert(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* SCA_ISensor::PyGetInvert(PyObject* self)
{
return BoolToPyArg(m_invert);
}
-char SCA_ISensor::SetInvert_doc[] =
+const char SCA_ISensor::SetInvert_doc[] =
"setInvert(invert?)\n"
"\t- invert?: Invert the event-values? (KX_TRUE, KX_FALSE)\n"
"\tSet whether to invert pulses.\n";
@@ -307,15 +383,39 @@ PyObject* SCA_ISensor::PySetInvert(PyObject* self, PyObject* args, PyObject* kwd
Py_Return;
}
-char SCA_ISensor::GetUseNegPulseMode_doc[] =
+const char SCA_ISensor::GetLevel_doc[] =
+"getLevel()\n"
+"\tReturns whether this sensor is a level detector or a edge detector.\n"
+"\tIt makes a difference only in case of logic state transition (state actuator).\n"
+"\tA level detector will immediately generate a pulse, negative or positive\n"
+"\tdepending on the sensor condition, as soon as the state is activated.\n"
+"\tA edge detector will wait for a state change before generating a pulse.\n";
+PyObject* SCA_ISensor::PyGetLevel(PyObject* self)
+{
+ return BoolToPyArg(m_level);
+}
+
+const char SCA_ISensor::SetLevel_doc[] =
+"setLevel(level?)\n"
+"\t- level?: Detect level instead of edge? (KX_TRUE, KX_FALSE)\n"
+"\tSet whether to detect level or edge transition when entering a state.\n";
+PyObject* SCA_ISensor::PySetLevel(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int pyarg = 0;
+ if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; }
+ m_level = PyArgToBool(pyarg);
+ Py_Return;
+}
+
+const char SCA_ISensor::GetUseNegPulseMode_doc[] =
"getUseNegPulseMode()\n"
"\tReturns whether negative pulse mode is active.\n";
-PyObject* SCA_ISensor::PyGetUseNegPulseMode(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* SCA_ISensor::PyGetUseNegPulseMode(PyObject* self)
{
return BoolToPyArg(m_neg_pulsemode);
}
-char SCA_ISensor::SetUseNegPulseMode_doc[] =
+const char SCA_ISensor::SetUseNegPulseMode_doc[] =
"setUseNegPulseMode(pulse?)\n"
"\t - pulse? : Pulse when a negative event occurs?\n"
"\t (KX_TRUE, KX_FALSE)\n"
@@ -328,4 +428,15 @@ PyObject* SCA_ISensor::PySetUseNegPulseMode(PyObject* self, PyObject* args, PyOb
Py_Return;
}
+const char SCA_ISensor::Reset_doc[] =
+"reset()\n"
+"\tReset sensor internal state, effect depends on the type of sensor and settings.\n"
+"\tThe sensor is put in its initial state as if it was just activated.\n";
+PyObject* SCA_ISensor::PyReset(PyObject* self)
+{
+ Init();
+ Py_Return;
+}
+
+
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h
index 000a4951e0f..d1872009291 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.h
+++ b/source/gameengine/GameLogic/SCA_ISensor.h
@@ -34,6 +34,8 @@
#include "SCA_ILogicBrick.h"
+#include <vector>
+
/**
* Interface Class for all logic Sensors. Implements
* pulsemode,pulsefrequency */
@@ -61,12 +63,21 @@ class SCA_ISensor : public SCA_ILogicBrick
/** invert the output signal*/
bool m_invert;
+ /** detect level instead of edge*/
+ bool m_level;
+
+ /** sensor has been reset */
+ bool m_reset;
+
/** Sensor must ignore updates? */
bool m_suspended;
- /** Pass the activation on to the logic manager.*/
- void SignalActivation(class SCA_LogicManager* logicmgr);
-
+ /** 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;
+
public:
SCA_ISensor(SCA_IObject* gameobj,
class SCA_EventManager* eventmgr,
@@ -81,6 +92,7 @@ public:
void Activate(class SCA_LogicManager* logicmgr,CValue* event);
virtual bool Evaluate(CValue* event) = 0;
virtual bool IsPositiveTrigger();
+ virtual void Init();
virtual PyObject* _getattr(const STR_String& attr);
virtual CValue* GetReplica()=0;
@@ -94,10 +106,19 @@ public:
bool negmode,
int freq);
+ /** Release sensor
+ * For property sensor, it is used to release the pre-calculated expression
+ * so that self references are removed before the sensor itself is released
+ */
+ virtual void Delete() { Release(); }
/** Set inversion of pulses on or off. */
void SetInvert(bool inv);
+ /** set the level detection on or off */
+ void SetLevel(bool lvl);
+
+ virtual void RegisterToManager();
+ virtual void UnregisterToManager();
- void RegisterToManager();
virtual float GetNumber();
/** Stop sensing for a while. */
@@ -109,16 +130,30 @@ public:
/** Resume sensing. */
void Resume();
+ void AddNewController(class SCA_IController* controller)
+ { m_newControllers.push_back(controller); }
+ void ClrLink()
+ { m_links = 0; }
+ void IncLink()
+ { if (!m_links++) RegisterToManager(); }
+ void DecLink();
+ bool IsNoLink() const
+ { return !m_links; }
+
/* Python functions: */
- KX_PYMETHOD_DOC(SCA_ISensor,IsPositive);
- KX_PYMETHOD_DOC(SCA_ISensor,GetUsePosPulseMode);
+ KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,IsPositive);
+ KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,IsTriggered);
+ KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetUsePosPulseMode);
KX_PYMETHOD_DOC(SCA_ISensor,SetUsePosPulseMode);
- KX_PYMETHOD_DOC(SCA_ISensor,GetFrequency);
+ KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetFrequency);
KX_PYMETHOD_DOC(SCA_ISensor,SetFrequency);
- KX_PYMETHOD_DOC(SCA_ISensor,GetUseNegPulseMode);
+ KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetUseNegPulseMode);
KX_PYMETHOD_DOC(SCA_ISensor,SetUseNegPulseMode);
- KX_PYMETHOD_DOC(SCA_ISensor,GetInvert);
+ KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetInvert);
KX_PYMETHOD_DOC(SCA_ISensor,SetInvert);
+ KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetLevel);
+ KX_PYMETHOD_DOC(SCA_ISensor,SetLevel);
+ KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,Reset);
};
diff --git a/source/gameengine/GameLogic/SCA_JoystickManager.cpp b/source/gameengine/GameLogic/SCA_JoystickManager.cpp
index a095ad2a594..f3ce549a637 100644
--- a/source/gameengine/GameLogic/SCA_JoystickManager.cpp
+++ b/source/gameengine/GameLogic/SCA_JoystickManager.cpp
@@ -40,42 +40,49 @@ SCA_JoystickManager::SCA_JoystickManager(class SCA_LogicManager* logicmgr)
: SCA_EventManager(JOY_EVENTMGR),
m_logicmgr(logicmgr)
{
- m_joystick = new SCA_Joystick();
- m_joystick->CreateJoystickDevice();
+ int i;
+ for (i=0; i<JOYINDEX_MAX; i++) {
+ m_joystick[i] = SCA_Joystick::GetInstance( i );
+ }
}
SCA_JoystickManager::~SCA_JoystickManager()
{
- m_joystick->DestroyJoystickDevice();
- delete m_joystick;
+ int i;
+ for (i=0; i<JOYINDEX_MAX; i++) {
+ if(m_joystick[i])
+ m_joystick[i]->ReleaseInstance();
+ }
}
void SCA_JoystickManager::NextFrame(double curtime,double deltatime)
{
- for (unsigned int i = 0; i < m_sensors.size(); i++)
- {
- SCA_JoystickSensor* joysensor = (SCA_JoystickSensor*) m_sensors[i];
- if(!joysensor->IsSuspended())
+ if (m_sensors.size()==0) {
+ 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++)
{
- m_joystick->HandleEvents();
- joysensor->Activate(m_logicmgr, NULL);
+ SCA_JoystickSensor* joysensor = (SCA_JoystickSensor*)(*it);
+ if(!joysensor->IsSuspended())
+ {
+ joysensor->Activate(m_logicmgr, NULL);
+ }
}
}
}
-void SCA_JoystickManager::RegisterSensor(SCA_ISensor* sensor)
-{
- m_sensors.push_back(sensor);
-}
-
-
-SCA_Joystick *SCA_JoystickManager::GetJoystickDevice()
+SCA_Joystick *SCA_JoystickManager::GetJoystickDevice( short int joyindex)
{
/*
*Return the instance of SCA_Joystick for use
*/
- return m_joystick;
+ return m_joystick[joyindex];
}
diff --git a/source/gameengine/GameLogic/SCA_JoystickManager.h b/source/gameengine/GameLogic/SCA_JoystickManager.h
index 3c4df64677e..d3a7ac95bea 100644
--- a/source/gameengine/GameLogic/SCA_JoystickManager.h
+++ b/source/gameengine/GameLogic/SCA_JoystickManager.h
@@ -40,13 +40,12 @@ class SCA_JoystickManager : public SCA_EventManager
/**
* SDL Joystick Class Instance
*/
- SCA_Joystick *m_joystick;
+ SCA_Joystick *m_joystick[JOYINDEX_MAX];
public:
SCA_JoystickManager(class SCA_LogicManager* logicmgr);
virtual ~SCA_JoystickManager();
virtual void NextFrame(double curtime,double deltatime);
- virtual void RegisterSensor(SCA_ISensor* sensor);
- SCA_Joystick* GetJoystickDevice(void);
+ SCA_Joystick* GetJoystickDevice(short int joyindex);
};
diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
index b0e7fee130d..8b96840b149 100644
--- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
@@ -30,8 +30,11 @@
#include "SCA_EventManager.h"
#include "SCA_LogicManager.h"
+#include "PyObjectPlus.h"
+
#include <iostream>
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -39,34 +42,41 @@
SCA_JoystickSensor::SCA_JoystickSensor(class SCA_JoystickManager* eventmgr,
SCA_IObject* gameobj,
+ short int joyindex,
short int joymode,
int axis, int axisf,int prec,
- int button, int buttonf,
- int hat, int hatf,
+ int button,
+ int hat, int hatf, bool allevents,
PyTypeObject* T )
:SCA_ISensor(gameobj,eventmgr,T),
m_pJoystickMgr(eventmgr),
m_axis(axis),
m_axisf(axisf),
m_button(button),
- m_buttonf(buttonf),
m_hat(hat),
m_hatf(hatf),
m_precision(prec),
- m_joymode(joymode)
+ m_joymode(joymode),
+ m_joyindex(joyindex),
+ m_bAllEvents(allevents)
{
/*
std::cout << " axis " << m_axis << std::endl;
std::cout << " axis flag " << m_axisf << std::endl;
std::cout << " precision " << m_precision << std::endl;
std::cout << " button " << m_button << std::endl;
-std::cout << " button flag "<< m_buttonf << std::endl;
std::cout << " hat " << m_hat << std::endl;
std::cout << " hat flag " << m_hatf << std::endl;
*/
- m_istrig=0;
+ Init();
}
+void SCA_JoystickSensor::Init()
+{
+ m_istrig=(m_invert)?1:0;
+ m_istrig_prev=0;
+ m_reset = true;
+}
SCA_JoystickSensor::~SCA_JoystickSensor()
{
@@ -75,9 +85,10 @@ SCA_JoystickSensor::~SCA_JoystickSensor()
CValue* SCA_JoystickSensor::GetReplica()
{
- CValue* replica = new SCA_JoystickSensor(*this);
+ SCA_JoystickSensor* replica = new SCA_JoystickSensor(*this);
// this will copy properties and so on...
CValue::AddDataToReplica(replica);
+ replica->Init();
return replica;
}
@@ -93,9 +104,14 @@ bool SCA_JoystickSensor::IsPositiveTrigger()
bool SCA_JoystickSensor::Evaluate(CValue* event)
{
- SCA_Joystick *js = m_pJoystickMgr->GetJoystickDevice();
+ SCA_Joystick *js = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
bool result = false;
+ bool reset = m_reset && m_level;
+ if(js==NULL) /* no joystick - dont do anything */
+ return false;
+
+ m_reset = false;
switch(m_joymode)
{
case KX_JOYSENSORMODE_AXIS:
@@ -107,10 +123,25 @@ bool SCA_JoystickSensor::Evaluate(CValue* event)
m_axisf == 3 == down
numberof== m_axis -- max 2
*/
+
+ if (!js->IsTrigAxis() && !reset) /* No events from SDL? - dont bother */
+ return false;
+
js->cSetPrecision(m_precision);
- if(m_axisf == 1){
+ if (m_bAllEvents) {
+ if(js->aAnyAxisIsPositive(m_axis)){
+ m_istrig = 1;
+ result = true;
+ }else{
+ if(m_istrig){
+ m_istrig = 0;
+ result = true;
+ }
+ }
+ }
+ else if(m_axisf == 1){
if(js->aUpAxisIsPositive(m_axis)){
- m_istrig =1;
+ m_istrig = 1;
result = true;
}else{
if(m_istrig){
@@ -119,7 +150,7 @@ bool SCA_JoystickSensor::Evaluate(CValue* event)
}
}
}
- if(m_axisf == 3){
+ else if(m_axisf == 3){
if(js->aDownAxisIsPositive(m_axis)){
m_istrig = 1;
result = true;
@@ -130,7 +161,7 @@ bool SCA_JoystickSensor::Evaluate(CValue* event)
}
}
}
- if(m_axisf == 2){
+ else if(m_axisf == 2){
if(js->aLeftAxisIsPositive(m_axis)){
m_istrig = 1;
result = true;
@@ -141,7 +172,7 @@ bool SCA_JoystickSensor::Evaluate(CValue* event)
}
}
}
- if(m_axisf == 0){
+ else if(m_axisf == 0){
if(js->aRightAxisIsPositive(m_axis)){
m_istrig = 1;
result = true;
@@ -157,32 +188,20 @@ bool SCA_JoystickSensor::Evaluate(CValue* event)
case KX_JOYSENSORMODE_BUTTON:
{
/* what is what!
- pressed = m_buttonf == 0
- released = m_buttonf == 1
m_button = the actual button in question
*/
- if(m_buttonf == 0){
- if(js->aButtonPressIsPositive(m_button)){
- m_istrig = 1;
+ if (!js->IsTrigButton() && !reset) /* No events from SDL? - dont bother */
+ return false;
+
+ if(( m_bAllEvents && js->aAnyButtonPressIsPositive()) || (!m_bAllEvents && js->aButtonPressIsPositive(m_button))) {
+ m_istrig = 1;
+ result = true;
+ }else {
+ if(m_istrig){
+ m_istrig = 0;
result = true;
- }else {
- if(m_istrig){
- m_istrig = 0;
- result = true;
- }
}
}
- if(m_buttonf == 1){
- if(js->aButtonReleaseIsPositive(m_button)){
- m_istrig = 1;
- result = true;
- }else {
- if(m_istrig){
- m_istrig = 0;
- result = true;
- }
- }
- }
break;
}
case KX_JOYSENSORMODE_HAT:
@@ -191,6 +210,10 @@ bool SCA_JoystickSensor::Evaluate(CValue* event)
numberof = m_hat -- max 2
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;
@@ -213,19 +236,6 @@ bool SCA_JoystickSensor::Evaluate(CValue* event)
}
}
}
- /*
- if(m_hat == 3){
- if(js->aHatIsPositive(m_hatf)){
- m_istrig = 1;
- result = true;
- }else{
- if(m_istrig){
- m_istrig = 0;
- result = true;
- }
- }
- }
- */
break;
}
/* test for ball anyone ?*/
@@ -233,9 +243,20 @@ bool SCA_JoystickSensor::Evaluate(CValue* event)
printf("Error invalid switch statement\n");
break;
}
- if(!js->IsTrig()){
- m_istrig = 0;
+
+ /* if not all events are enabled, only send a positive pulse when
+ * the button state changes */
+ if (!m_bAllEvents) {
+ if (m_istrig_prev == m_istrig) {
+ result = false;
+ } else {
+ m_istrig_prev = m_istrig;
+ }
}
+
+ if (reset)
+ result = true;
+
return result;
}
@@ -283,18 +304,22 @@ PyParentObject SCA_JoystickSensor::Parents[] = {
PyMethodDef SCA_JoystickSensor::Methods[] = {
- {"getAxis", (PyCFunction) SCA_JoystickSensor::sPyGetAxis, METH_NOARGS, GetAxis_doc},
- {"setAxis", (PyCFunction) SCA_JoystickSensor::sPySetAxis, METH_VARARGS, SetAxis_doc},
- {"getAxisValue", (PyCFunction) SCA_JoystickSensor::sPyGetRealAxis, METH_NOARGS, GetRealAxis_doc},
- {"getThreshold", (PyCFunction) SCA_JoystickSensor::sPyGetThreshold, METH_NOARGS, GetThreshold_doc},
- {"setThreshold", (PyCFunction) SCA_JoystickSensor::sPySetThreshold, METH_VARARGS, SetThreshold_doc},
- {"getButton", (PyCFunction) SCA_JoystickSensor::sPyGetButton, METH_NOARGS, GetButton_doc},
- {"setButton", (PyCFunction) SCA_JoystickSensor::sPySetButton, METH_VARARGS, SetButton_doc},
- {"getHat", (PyCFunction) SCA_JoystickSensor::sPyGetHat, METH_NOARGS, GetHat_doc},
- {"setHat", (PyCFunction) SCA_JoystickSensor::sPySetHat, METH_VARARGS, SetHat_doc},
- {"getNumAxes", (PyCFunction) SCA_JoystickSensor::sPyNumberOfAxes, METH_NOARGS, NumberOfAxes_doc},
- {"getNumButtons",(PyCFunction) SCA_JoystickSensor::sPyNumberOfButtons,METH_NOARGS, NumberOfButtons_doc},
- {"getNumHats", (PyCFunction) SCA_JoystickSensor::sPyNumberOfHats, METH_NOARGS, NumberOfHats_doc},
+ {"getIndex", (PyCFunction) SCA_JoystickSensor::sPyGetIndex, METH_NOARGS, (PY_METHODCHAR)GetIndex_doc},
+ {"setIndex", (PyCFunction) SCA_JoystickSensor::sPySetIndex, METH_O, (PY_METHODCHAR)SetIndex_doc},
+ {"getAxis", (PyCFunction) SCA_JoystickSensor::sPyGetAxis, METH_NOARGS, (PY_METHODCHAR)GetAxis_doc},
+ {"setAxis", (PyCFunction) SCA_JoystickSensor::sPySetAxis, METH_VARARGS, (PY_METHODCHAR)SetAxis_doc},
+ {"getAxisValue", (PyCFunction) SCA_JoystickSensor::sPyGetAxisValue, METH_NOARGS, (PY_METHODCHAR)GetAxisValue_doc},
+ {"getThreshold", (PyCFunction) SCA_JoystickSensor::sPyGetThreshold, METH_NOARGS, (PY_METHODCHAR)GetThreshold_doc},
+ {"setThreshold", (PyCFunction) SCA_JoystickSensor::sPySetThreshold, METH_VARARGS, (PY_METHODCHAR)SetThreshold_doc},
+ {"getButton", (PyCFunction) SCA_JoystickSensor::sPyGetButton, METH_NOARGS, (PY_METHODCHAR)GetButton_doc},
+ {"setButton", (PyCFunction) SCA_JoystickSensor::sPySetButton, METH_O, (PY_METHODCHAR)SetButton_doc},
+ {"getButtonValue",(PyCFunction) SCA_JoystickSensor::sPyGetButtonValue, METH_NOARGS,(PY_METHODCHAR)GetButtonValue_doc},
+ {"getHat", (PyCFunction) SCA_JoystickSensor::sPyGetHat, METH_NOARGS, (PY_METHODCHAR)GetHat_doc},
+ {"setHat", (PyCFunction) SCA_JoystickSensor::sPySetHat, METH_VARARGS, (PY_METHODCHAR)SetHat_doc},
+ {"getNumAxes", (PyCFunction) SCA_JoystickSensor::sPyNumberOfAxes, METH_NOARGS, (PY_METHODCHAR)NumberOfAxes_doc},
+ {"getNumButtons",(PyCFunction) SCA_JoystickSensor::sPyNumberOfButtons,METH_NOARGS, (PY_METHODCHAR)NumberOfButtons_doc},
+ {"getNumHats", (PyCFunction) SCA_JoystickSensor::sPyNumberOfHats, METH_NOARGS, (PY_METHODCHAR)NumberOfHats_doc},
+ {"isConnected", (PyCFunction) SCA_JoystickSensor::sPyConnected, METH_NOARGS, (PY_METHODCHAR)Connected_doc},
{NULL,NULL} //Sentinel
};
@@ -304,24 +329,44 @@ PyObject* SCA_JoystickSensor::_getattr(const STR_String& attr) {
}
+/* get index ---------------------------------------------------------- */
+const char SCA_JoystickSensor::GetIndex_doc[] =
+"getIndex\n"
+"\tReturns the joystick index to use.\n";
+PyObject* SCA_JoystickSensor::PyGetIndex( PyObject* self ) {
+ return PyInt_FromLong(m_joyindex);
+}
+
+
+/* set index ---------------------------------------------------------- */
+const char SCA_JoystickSensor::SetIndex_doc[] =
+"setIndex\n"
+"\tSets the joystick index to use.\n";
+PyObject* SCA_JoystickSensor::PySetIndex( PyObject* self, PyObject* value ) {
+ int index = PyInt_AsLong( value ); /* -1 on error, will raise an error in this case */
+ if (index < 0 || index >= JOYINDEX_MAX) {
+ PyErr_SetString(PyExc_ValueError, "joystick index out of range or not an int");
+ return NULL;
+ }
+
+ m_joyindex = index;
+ Py_RETURN_NONE;
+}
+
/* get axis ---------------------------------------------------------- */
-char SCA_JoystickSensor::GetAxis_doc[] =
+const char SCA_JoystickSensor::GetAxis_doc[] =
"getAxis\n"
-"\tReturns the current state of the axis.\n";
-PyObject* SCA_JoystickSensor::PyGetAxis( PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+"\tReturns the current axis this sensor reacts to.\n";
+PyObject* SCA_JoystickSensor::PyGetAxis( PyObject* self) {
return Py_BuildValue("[ii]",m_axis, m_axisf);
}
/* set axis ---------------------------------------------------------- */
-char SCA_JoystickSensor::SetAxis_doc[] =
+const char SCA_JoystickSensor::SetAxis_doc[] =
"setAxis\n"
-"\tSets the current state of the axis.\n";
-PyObject* SCA_JoystickSensor::PySetAxis( PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+"\tSets the current axis this sensor reacts to.\n";
+PyObject* SCA_JoystickSensor::PySetAxis( PyObject* self, PyObject* args ) {
int axis,axisflag;
if(!PyArg_ParseTuple(args, "ii", &axis, &axisflag)){
@@ -329,145 +374,145 @@ PyObject* SCA_JoystickSensor::PySetAxis( PyObject* self,
}
m_axis = axis;
m_axisf = axisflag;
- Py_Return;
+ Py_RETURN_NONE;
}
/* get axis value ----------------------------------------------------- */
-char SCA_JoystickSensor::GetRealAxis_doc[] =
+const char SCA_JoystickSensor::GetAxisValue_doc[] =
"getAxisValue\n"
-"\tReturns a list of the values for each axis .\n";
-PyObject* SCA_JoystickSensor::PyGetRealAxis( PyObject* self,
- PyObject* args,
- PyObject* kwds) {
- int a,b,c,d;
- SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice();
- a = joy->GetAxis10();
- b = joy->GetAxis11();
- c = joy->GetAxis20();
- d = joy->GetAxis21();
- return Py_BuildValue("[iiii]",a,b,c,d);
+"\tReturns a list of the values for the current state of each axis.\n";
+PyObject* SCA_JoystickSensor::PyGetAxisValue( PyObject* self) {
+ SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
+ if(joy)
+ return Py_BuildValue("[iiii]", joy->GetAxis10(), joy->GetAxis11(), joy->GetAxis20(), joy->GetAxis21());
+ else
+ return Py_BuildValue("[iiii]", 0, 0, 0, 0);
}
/* get threshold ----------------------------------------------------- */
-char SCA_JoystickSensor::GetThreshold_doc[] =
+const char SCA_JoystickSensor::GetThreshold_doc[] =
"getThreshold\n"
"\tReturns the threshold of the axis.\n";
-PyObject* SCA_JoystickSensor::PyGetThreshold( PyObject* self,
- PyObject* args,
- PyObject* kwds) {
- return Py_BuildValue("i", m_precision);
+PyObject* SCA_JoystickSensor::PyGetThreshold( PyObject* self) {
+ return PyInt_FromLong(m_precision);
}
/* set threshold ----------------------------------------------------- */
-char SCA_JoystickSensor::SetThreshold_doc[] =
+const char SCA_JoystickSensor::SetThreshold_doc[] =
"setThreshold\n"
"\tSets the threshold of the axis.\n";
-PyObject* SCA_JoystickSensor::PySetThreshold( PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* SCA_JoystickSensor::PySetThreshold( PyObject* self, PyObject* args ) {
int thresh;
if(!PyArg_ParseTuple(args, "i", &thresh)){
return NULL;
}
m_precision = thresh;
- Py_Return;
+ Py_RETURN_NONE;
}
-
/* get button -------------------------------------------------------- */
-char SCA_JoystickSensor::GetButton_doc[] =
+const char SCA_JoystickSensor::GetButton_doc[] =
"getButton\n"
-"\tReturns the currently pressed button.\n";
-PyObject* SCA_JoystickSensor::PyGetButton( PyObject* self,
- PyObject* args,
- PyObject* kwds) {
- return Py_BuildValue("[ii]",m_button, m_buttonf);
+"\tReturns the current button this sensor is checking.\n";
+PyObject* SCA_JoystickSensor::PyGetButton( PyObject* self) {
+ return PyInt_FromLong(m_button);
}
-
/* set button -------------------------------------------------------- */
-char SCA_JoystickSensor::SetButton_doc[] =
+const char SCA_JoystickSensor::SetButton_doc[] =
"setButton\n"
"\tSets the button the sensor reacts to.\n";
-PyObject* SCA_JoystickSensor::PySetButton( PyObject* self,
- PyObject* args,
- PyObject* kwds) {
- int button,buttonflag;
- if(!PyArg_ParseTuple(args, "ii", &button, &buttonflag)){
+PyObject* SCA_JoystickSensor::PySetButton( PyObject* self, PyObject* value ) {
+ int button = PyInt_AsLong(value);
+ if(button==-1 && PyErr_Occurred()) {
+ PyErr_SetString(PyExc_ValueError, "expected an int");
return NULL;
}
m_button = button;
- m_buttonf = buttonflag;
- Py_Return;
+ Py_RETURN_NONE;
}
+/* get button value -------------------------------------------------- */
+const char SCA_JoystickSensor::GetButtonValue_doc[] =
+"getButtonValue\n"
+"\tReturns a list containing the indicies of the current pressed state of each button.\n";
+PyObject* SCA_JoystickSensor::PyGetButtonValue( PyObject* self) {
+ SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
+ PyObject *ls = PyList_New(0);
+ PyObject *value;
+ int i;
+
+ if(joy) {
+ for (i=0; i < joy->GetNumberOfButtons(); i++) {
+ if (joy->aButtonPressIsPositive(i)) {
+ value = PyInt_FromLong(i);
+ PyList_Append(ls, value);
+ Py_DECREF(value);
+ }
+ }
+ }
+ return ls;
+}
/* get hat ----------------------------------------------------------- */
-char SCA_JoystickSensor::GetHat_doc[] =
+const char SCA_JoystickSensor::GetHat_doc[] =
"getHat\n"
"\tReturns the current direction of the hat.\n";
-PyObject* SCA_JoystickSensor::PyGetHat( PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* SCA_JoystickSensor::PyGetHat( PyObject* self ) {
return Py_BuildValue("[ii]",m_hat, m_hatf);
}
/* set hat ----------------------------------------------------------- */
-char SCA_JoystickSensor::SetHat_doc[] =
+const char SCA_JoystickSensor::SetHat_doc[] =
"setHat\n"
"\tSets the hat the sensor reacts to.\n";
-PyObject* SCA_JoystickSensor::PySetHat( PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* SCA_JoystickSensor::PySetHat( PyObject* self, PyObject* args ) {
int hat,hatflag;
if(!PyArg_ParseTuple(args, "ii", &hat, &hatflag)){
return NULL;
}
m_hat = hat;
m_hatf = hatflag;
- Py_Return;
+ Py_RETURN_NONE;
}
/* get # of ----------------------------------------------------- */
-char SCA_JoystickSensor::NumberOfAxes_doc[] =
+const char SCA_JoystickSensor::NumberOfAxes_doc[] =
"getNumAxes\n"
"\tReturns the number of axes .\n";
-PyObject* SCA_JoystickSensor::PyNumberOfAxes( PyObject* self,
- PyObject* args,
- PyObject* kwds) {
- int num;
- SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice();
- num = joy->GetNumberOfAxes();
- return Py_BuildValue("i",num);
+PyObject* SCA_JoystickSensor::PyNumberOfAxes( PyObject* self ) {
+ SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
+ // when the joystick is null their is 0 exis still. dumb but scripters should use isConnected()
+ return PyInt_FromLong( joy ? joy->GetNumberOfAxes() : 0 );
}
-char SCA_JoystickSensor::NumberOfButtons_doc[] =
+const char SCA_JoystickSensor::NumberOfButtons_doc[] =
"getNumButtons\n"
"\tReturns the number of buttons .\n";
-PyObject* SCA_JoystickSensor::PyNumberOfButtons( PyObject* self,
- PyObject* args,
- PyObject* kwds) {
- int num;
- SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice();
- num = joy->GetNumberOfButtons();
- return Py_BuildValue("i",num);
+PyObject* SCA_JoystickSensor::PyNumberOfButtons( PyObject* self ) {
+ SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
+ return PyInt_FromLong( joy ? joy->GetNumberOfButtons() : 0 );
}
-char SCA_JoystickSensor::NumberOfHats_doc[] =
+const char SCA_JoystickSensor::NumberOfHats_doc[] =
"getNumHats\n"
"\tReturns the number of hats .\n";
-PyObject* SCA_JoystickSensor::PyNumberOfHats( PyObject* self,
- PyObject* args,
- PyObject* kwds) {
- int num;
- SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice();
- num = joy->GetNumberOfHats();
- return Py_BuildValue("i",num);
+PyObject* SCA_JoystickSensor::PyNumberOfHats( PyObject* self ) {
+ SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
+ return PyInt_FromLong( joy ? joy->GetNumberOfHats() : 0 );
+}
+
+const char SCA_JoystickSensor::Connected_doc[] =
+"getConnected\n"
+"\tReturns True if a joystick is connected at this joysticks index.\n";
+PyObject* SCA_JoystickSensor::PyConnected( PyObject* self ) {
+ SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
+ return PyBool_FromLong( joy ? joy->Connected() : 0 );
}
diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.h b/source/gameengine/GameLogic/SCA_JoystickSensor.h
index 2fbe1edf1e7..d316ad1119c 100644
--- a/source/gameengine/GameLogic/SCA_JoystickSensor.h
+++ b/source/gameengine/GameLogic/SCA_JoystickSensor.h
@@ -69,9 +69,24 @@ class SCA_JoystickSensor :public SCA_ISensor
*/
bool m_istrig;
/**
+ * Last trigger state for this sensors joystick,
+ * Otherwise it will trigger all the time
+ * this is used to see if the trigger state changes.
+ */
+ bool m_istrig_prev;
+ /**
* The mode to determine axis,button or hat
*/
short int m_joymode;
+ /**
+ * Select which joystick to use
+ */
+ short int m_joyindex;
+
+ /**
+ * Detect all events for the currently selected type
+ */
+ bool m_bAllEvents;
enum KX_JOYSENSORMODE {
KX_JOYSENSORMODE_NODEF = 0,
@@ -85,39 +100,50 @@ class SCA_JoystickSensor :public SCA_ISensor
public:
SCA_JoystickSensor(class SCA_JoystickManager* eventmgr,
SCA_IObject* gameobj,
+ short int joyindex,
short int joymode,
int axis, int axisf,int prec,
- int button, int buttonf,
- int hat, int hatf,
+ int button,
+ int hat, int hatf, bool allevents,
PyTypeObject* T=&Type );
virtual ~SCA_JoystickSensor();
virtual CValue* GetReplica();
virtual bool Evaluate(CValue* event);
virtual bool IsPositiveTrigger();
+ virtual void Init();
+ short int GetJoyIndex(void){
+ return m_joyindex;
+ }
+
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
virtual PyObject* _getattr(const STR_String& attr);
+ /* Joystick Index */
+ KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetIndex);
+ KX_PYMETHOD_DOC_O(SCA_JoystickSensor,SetIndex);
/* Axes*/
- KX_PYMETHOD_DOC(SCA_JoystickSensor,GetAxis);
- KX_PYMETHOD_DOC(SCA_JoystickSensor,SetAxis);
- KX_PYMETHOD_DOC(SCA_JoystickSensor,GetRealAxis);
- KX_PYMETHOD_DOC(SCA_JoystickSensor,GetThreshold);
- KX_PYMETHOD_DOC(SCA_JoystickSensor,SetThreshold);
+ KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetAxis);
+ KX_PYMETHOD_DOC_VARARGS(SCA_JoystickSensor,SetAxis);
+ KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetAxisValue);
+ KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetThreshold);
+ KX_PYMETHOD_DOC_VARARGS(SCA_JoystickSensor,SetThreshold);
/* Buttons */
- KX_PYMETHOD_DOC(SCA_JoystickSensor,GetButton);
- KX_PYMETHOD_DOC(SCA_JoystickSensor,SetButton);
+ KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetButton);
+ KX_PYMETHOD_DOC_O(SCA_JoystickSensor,SetButton);
+ KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetButtonValue);
/* Hats */
- KX_PYMETHOD_DOC(SCA_JoystickSensor,GetHat);
- KX_PYMETHOD_DOC(SCA_JoystickSensor,SetHat);
+ KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetHat);
+ KX_PYMETHOD_DOC_VARARGS(SCA_JoystickSensor,SetHat);
/* number of */
- KX_PYMETHOD_DOC(SCA_JoystickSensor,NumberOfAxes);
- KX_PYMETHOD_DOC(SCA_JoystickSensor,NumberOfButtons);
- KX_PYMETHOD_DOC(SCA_JoystickSensor,NumberOfHats);
+ KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,NumberOfAxes);
+ KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,NumberOfButtons);
+ KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,NumberOfHats);
+ KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,Connected);
};
diff --git a/source/gameengine/GameLogic/SCA_KeyboardManager.cpp b/source/gameengine/GameLogic/SCA_KeyboardManager.cpp
index 259b06134d7..6a96442b124 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardManager.cpp
+++ b/source/gameengine/GameLogic/SCA_KeyboardManager.cpp
@@ -62,23 +62,14 @@ void SCA_KeyboardManager::NextFrame()
{
//const SCA_InputEvent& event = GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode)=0;
// cerr << "SCA_KeyboardManager::NextFrame"<< endl;
- for (unsigned int i=0;i<m_sensors.size();i++)
+ set<SCA_ISensor*>::iterator it;
+ for (it=m_sensors.begin(); it != m_sensors.end(); it++)
{
- SCA_KeyboardSensor* keysensor = (SCA_KeyboardSensor*)m_sensors[i];
- keysensor->Activate(m_logicmanager,NULL);
+ (*it)->Activate(m_logicmanager,NULL);
}
}
-
-
-void SCA_KeyboardManager::RegisterSensor(SCA_ISensor* keysensor)
-{
- m_sensors.push_back(keysensor);
-}
-
-
-
bool SCA_KeyboardManager::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
{
return false;
diff --git a/source/gameengine/GameLogic/SCA_KeyboardManager.h b/source/gameengine/GameLogic/SCA_KeyboardManager.h
index b4a50f56025..8f3cc0ab715 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardManager.h
+++ b/source/gameengine/GameLogic/SCA_KeyboardManager.h
@@ -55,7 +55,6 @@ public:
bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode);
virtual void NextFrame();
- virtual void RegisterSensor(class SCA_ISensor* sensor);
SCA_IInputDevice* GetInputDevice();
};
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
index f7bec628991..fa39a13679f 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
@@ -62,7 +62,7 @@ SCA_KeyboardSensor::SCA_KeyboardSensor(SCA_KeyboardManager* keybdmgr,
if (hotkey == SCA_IInputDevice::KX_ESCKEY)
keybdmgr->GetInputDevice()->HookEscape();
// SetDrawColor(0xff0000ff);
- m_val=0;
+ Init();
}
@@ -71,14 +71,22 @@ SCA_KeyboardSensor::~SCA_KeyboardSensor()
{
}
-
+void SCA_KeyboardSensor::Init()
+{
+ // this function is used when the sensor is disconnected from all controllers
+ // by the state engine. It reinitializes the sensor as if it was just created.
+ // However, if the target key is pressed when the sensor is reactivated, it
+ // will not generated an event (see remark in Evaluate()).
+ m_val = (m_invert)?1:0;
+ m_reset = true;
+}
CValue* SCA_KeyboardSensor::GetReplica()
{
- CValue* replica = new SCA_KeyboardSensor(*this);
+ SCA_KeyboardSensor* replica = new SCA_KeyboardSensor(*this);
// this will copy properties and so on...
CValue::AddDataToReplica(replica);
-
+ replica->Init();
return replica;
}
@@ -113,8 +121,12 @@ bool SCA_KeyboardSensor::TriggerOnAllKeys()
bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
{
bool result = false;
- SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
+ bool reset = m_reset && m_level;
+ bool qual = true;
+ bool qual_change = false;
+ short int m_val_orig = m_val;
+ SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
// cerr << "SCA_KeyboardSensor::Eval event, sensing for "<< m_hotkey << " at device " << inputdev << "\n";
/* See if we need to do logging: togPropState exists and is
@@ -127,24 +139,29 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
LogKeystrokes();
}
-
+ m_reset = false;
/* Now see whether events must be bounced. */
if (m_bAllKeys)
{
bool justactivated = false;
bool justreleased = false;
+ bool active = false;
for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++)
{
const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
- if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
- {
+ switch (inevent.m_status)
+ {
+ case SCA_InputEvent::KX_JUSTACTIVATED:
justactivated = true;
- }
- if (inevent.m_status == SCA_InputEvent::KX_JUSTRELEASED)
- {
+ break;
+ case SCA_InputEvent::KX_JUSTRELEASED:
justreleased = true;
+ break;
+ case SCA_InputEvent::KX_ACTIVE:
+ active = true;
+ break;
}
}
@@ -156,8 +173,27 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
{
if (justreleased)
{
- m_val=0;
+ m_val=(active)?1:0;
result = true;
+ } else
+ {
+ if (active)
+ {
+ if (m_val == 0)
+ {
+ m_val = 1;
+ if (m_level) {
+ result = true;
+ }
+ }
+ } else
+ {
+ if (m_val == 1)
+ {
+ m_val = 0;
+ result = true;
+ }
+ }
}
}
@@ -170,9 +206,52 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
(SCA_IInputDevice::KX_EnumInputs) m_hotkey);
// cerr << "======= SCA_KeyboardSensor::Evaluate:: status: " << inevent.m_status << endl;
-
+
+
+ /* Check qualifier keys
+ * - see if the qualifiers we request are pressed - 'qual' true/false
+ * - see if the qualifiers we request changed their state - 'qual_change' true/false
+ */
+ if (m_qual > 0) {
+ const SCA_InputEvent & qualevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) m_qual);
+ switch(qualevent.m_status) {
+ case SCA_InputEvent::KX_NO_INPUTSTATUS:
+ qual = false;
+ break;
+ case SCA_InputEvent::KX_JUSTRELEASED:
+ qual_change = true;
+ qual = false;
+ break;
+ case SCA_InputEvent::KX_JUSTACTIVATED:
+ qual_change = true;
+ }
+ }
+ if (m_qual2 > 0 && qual==true) {
+ const SCA_InputEvent & qualevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) m_qual2);
+ /* copy of above */
+ switch(qualevent.m_status) {
+ case SCA_InputEvent::KX_NO_INPUTSTATUS:
+ qual = false;
+ break;
+ case SCA_InputEvent::KX_JUSTRELEASED:
+ qual_change = true;
+ qual = false;
+ break;
+ case SCA_InputEvent::KX_JUSTACTIVATED:
+ qual_change = true;
+ }
+ }
+ /* done reading qualifiers */
+
if (inevent.m_status == SCA_InputEvent::KX_NO_INPUTSTATUS)
{
+ if (m_val == 1)
+ {
+ // this situation may occur after a scene suspend: the keyboard release
+ // event was not captured, produce now the event off
+ m_val = 0;
+ result = true;
+ }
} else
{
if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
@@ -185,11 +264,52 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
{
m_val = 0;
result = true;
+ } else
+ {
+ if (inevent.m_status == SCA_InputEvent::KX_ACTIVE)
+ {
+ if (m_val == 0)
+ {
+ m_val = 1;
+ if (m_level)
+ {
+ result = true;
+ }
+ }
+ }
}
}
}
+
+ /* Modify the key state based on qual(s)
+ * Tested carefuly. dont touch unless your really sure.
+ * note, this will only change the results if key modifiers are set.
+ *
+ * When all modifiers and keys are positive
+ * - pulse true
+ *
+ * When ANY of the modifiers or main key become inactive,
+ * - pulse false
+ */
+ if (qual==false) { /* one of the qualifiers are not pressed */
+ if (m_val_orig && qual_change) { /* we were originally enabled, but a qualifier changed */
+ result = true;
+ } else {
+ result = false;
+ }
+ m_val = 0; /* since one of the qualifiers is not on, set the state to false */
+ } else { /* we done have any qualifiers or they are all pressed */
+ if (m_val && qual_change) { /* the main key state is true and our qualifier just changed */
+ result = true;
+ }
+ }
+ /* done with key quals */
+
}
-
+
+ if (reset)
+ // force an event
+ result = true;
return result;
}
@@ -209,6 +329,7 @@ void SCA_KeyboardSensor::AddToTargetProp(int keyIndex)
newprop.SetLength(oldlength - 1);
CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
GetParent()->SetProperty(m_targetprop, newstringprop);
+ newstringprop->Release();
}
} else {
/* append */
@@ -216,6 +337,7 @@ void SCA_KeyboardSensor::AddToTargetProp(int keyIndex)
STR_String newprop = tprop->GetText() + pchar;
CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
GetParent()->SetProperty(m_targetprop, newstringprop);
+ newstringprop->Release();
}
} else {
if (!IsDelete(keyIndex)) {
@@ -224,6 +346,7 @@ void SCA_KeyboardSensor::AddToTargetProp(int keyIndex)
STR_String newprop = pchar;
CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
GetParent()->SetProperty(m_targetprop, newstringprop);
+ newstringprop->Release();
}
}
}
@@ -448,12 +571,12 @@ PyObject* SCA_KeyboardSensor::sPySetAllMode(PyObject* self,
PyObject* kwds)
{
// printf("sPyIsPositive\n");
- return ((SCA_KeyboardSensor*) self)->PyIsPositive(self, args, kwds);
+ return ((SCA_KeyboardSensor*) self)->PyIsPositive(self);
}
/** 1. GetKey : check which key this sensor looks at */
-char SCA_KeyboardSensor::GetKey_doc[] =
+const char SCA_KeyboardSensor::GetKey_doc[] =
"getKey()\n"
"\tReturn the code of the key this sensor is listening to.\n" ;
PyObject* SCA_KeyboardSensor::PyGetKey(PyObject* self, PyObject* args, PyObject* kwds)
@@ -462,7 +585,7 @@ PyObject* SCA_KeyboardSensor::PyGetKey(PyObject* self, PyObject* args, PyObject*
}
/** 2. SetKey: change the key to look at */
-char SCA_KeyboardSensor::SetKey_doc[] =
+const char SCA_KeyboardSensor::SetKey_doc[] =
"setKey(keycode)\n"
"\t- keycode: any code from GameKeys\n"
"\tSet the key this sensor should listen to.\n" ;
@@ -482,7 +605,7 @@ PyObject* SCA_KeyboardSensor::PySetKey(PyObject* self, PyObject* args, PyObject*
}
/** 3. GetHold1 : set the first bucky bit */
-char SCA_KeyboardSensor::GetHold1_doc[] =
+const char SCA_KeyboardSensor::GetHold1_doc[] =
"getHold1()\n"
"\tReturn the code of the first key modifier to the key this \n"
"\tsensor is listening to.\n" ;
@@ -492,7 +615,7 @@ PyObject* SCA_KeyboardSensor::PyGetHold1(PyObject* self, PyObject* args, PyObjec
}
/** 4. SetHold1: change the first bucky bit */
-char SCA_KeyboardSensor::SetHold1_doc[] =
+const char SCA_KeyboardSensor::SetHold1_doc[] =
"setHold1(keycode)\n"
"\t- keycode: any code from GameKeys\n"
"\tSet the first modifier to the key this sensor should listen to.\n" ;
@@ -512,7 +635,7 @@ PyObject* SCA_KeyboardSensor::PySetHold1(PyObject* self, PyObject* args, PyObjec
}
/** 5. GetHold2 : get the second bucky bit */
-char SCA_KeyboardSensor::GetHold2_doc[] =
+const char SCA_KeyboardSensor::GetHold2_doc[] =
"getHold2()\n"
"\tReturn the code of the second key modifier to the key this \n"
"\tsensor is listening to.\n" ;
@@ -522,7 +645,7 @@ PyObject* SCA_KeyboardSensor::PyGetHold2(PyObject* self, PyObject* args, PyObjec
}
/** 6. SetHold2: change the second bucky bit */
-char SCA_KeyboardSensor::SetHold2_doc[] =
+const char SCA_KeyboardSensor::SetHold2_doc[] =
"setHold2(keycode)\n"
"\t- keycode: any code from GameKeys\n"
"\tSet the first modifier to the key this sensor should listen to.\n" ;
@@ -542,7 +665,7 @@ PyObject* SCA_KeyboardSensor::PySetHold2(PyObject* self, PyObject* args, PyObjec
}
-char SCA_KeyboardSensor::GetPressedKeys_doc[] =
+const char SCA_KeyboardSensor::GetPressedKeys_doc[] =
"getPressedKeys()\n"
"\tGet a list of pressed keys that have either been pressed, or just released this frame.\n" ;
@@ -582,7 +705,7 @@ PyObject* SCA_KeyboardSensor::PyGetPressedKeys(PyObject* self, PyObject* args, P
-char SCA_KeyboardSensor::GetCurrentlyPressedKeys_doc[] =
+const char SCA_KeyboardSensor::GetCurrentlyPressedKeys_doc[] =
"getCurrentlyPressedKeys()\n"
"\tGet a list of keys that are currently pressed.\n" ;
@@ -653,17 +776,17 @@ PyParentObject SCA_KeyboardSensor::Parents[] = {
};
PyMethodDef SCA_KeyboardSensor::Methods[] = {
- {"getKey", (PyCFunction) SCA_KeyboardSensor::sPyGetKey, METH_VARARGS, GetKey_doc},
- {"setKey", (PyCFunction) SCA_KeyboardSensor::sPySetKey, METH_VARARGS, SetKey_doc},
- {"getHold1", (PyCFunction) SCA_KeyboardSensor::sPyGetHold1, METH_VARARGS, GetHold1_doc},
- {"setHold1", (PyCFunction) SCA_KeyboardSensor::sPySetHold1, METH_VARARGS, SetHold1_doc},
- {"getHold2", (PyCFunction) SCA_KeyboardSensor::sPyGetHold2, METH_VARARGS, GetHold2_doc},
- {"setHold2", (PyCFunction) SCA_KeyboardSensor::sPySetHold2, METH_VARARGS, SetHold2_doc},
-// {"getUseAllKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetUseAllKeys, METH_VARARGS, GetUseAllKeys_doc},
-// {"setUseAllKeys", (PyCFunction) SCA_KeyboardSensor::sPySetUseAllKeys, METH_VARARGS, SetUseAllKeys_doc},
- {"getPressedKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetPressedKeys, METH_VARARGS, GetPressedKeys_doc},
- {"getCurrentlyPressedKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetCurrentlyPressedKeys, METH_VARARGS, GetCurrentlyPressedKeys_doc},
-// {"getKeyEvents", (PyCFunction) SCA_KeyboardSensor::sPyGetKeyEvents, METH_VARARGS, GetKeyEvents_doc},
+ {"getKey", (PyCFunction) SCA_KeyboardSensor::sPyGetKey, METH_VARARGS, (PY_METHODCHAR)GetKey_doc},
+ {"setKey", (PyCFunction) SCA_KeyboardSensor::sPySetKey, METH_VARARGS, (PY_METHODCHAR)SetKey_doc},
+ {"getHold1", (PyCFunction) SCA_KeyboardSensor::sPyGetHold1, METH_VARARGS, (PY_METHODCHAR)GetHold1_doc},
+ {"setHold1", (PyCFunction) SCA_KeyboardSensor::sPySetHold1, METH_VARARGS, (PY_METHODCHAR)SetHold1_doc},
+ {"getHold2", (PyCFunction) SCA_KeyboardSensor::sPyGetHold2, METH_VARARGS, (PY_METHODCHAR)GetHold2_doc},
+ {"setHold2", (PyCFunction) SCA_KeyboardSensor::sPySetHold2, METH_VARARGS, (PY_METHODCHAR)SetHold2_doc},
+// {"getUseAllKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetUseAllKeys, METH_VARARGS, (PY_METHODCHAR)GetUseAllKeys_doc},
+// {"setUseAllKeys", (PyCFunction) SCA_KeyboardSensor::sPySetUseAllKeys, METH_VARARGS, (PY_METHODCHAR)SetUseAllKeys_doc},
+ {"getPressedKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetPressedKeys, METH_VARARGS, (PY_METHODCHAR)GetPressedKeys_doc},
+ {"getCurrentlyPressedKeys", (PyCFunction) SCA_KeyboardSensor::sPyGetCurrentlyPressedKeys, METH_VARARGS, (PY_METHODCHAR)GetCurrentlyPressedKeys_doc},
+// {"getKeyEvents", (PyCFunction) SCA_KeyboardSensor::sPyGetKeyEvents, METH_VARARGS, (PY_METHODCHAR)GetKeyEvents_doc},
{NULL,NULL} //Sentinel
};
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h
index e87eddecd32..b86f6931d27 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardSensor.h
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h
@@ -114,6 +114,8 @@ public:
PyTypeObject* T=&Type );
virtual ~SCA_KeyboardSensor();
virtual CValue* GetReplica();
+ virtual void Init();
+
short int GetHotkey();
virtual bool Evaluate(CValue* event);
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp
index 9c9c7dadc52..b584b37180f 100644
--- a/source/gameengine/GameLogic/SCA_LogicManager.cpp
+++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp
@@ -33,6 +33,7 @@
#include "SCA_IController.h"
#include "SCA_IActuator.h"
#include "SCA_EventManager.h"
+#include "SCA_PythonController.h"
#include <set>
#ifdef HAVE_CONFIG_H
@@ -48,6 +49,10 @@ 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++)
{
@@ -55,8 +60,9 @@ SCA_LogicManager::~SCA_LogicManager()
assert(gameobjptr);
if (gameobjptr)
(*gameobjptr)->Release();
-
+
}
+ */
/*for (int i=0;i<m_sensorcontrollermap.size();i++)
{
vector<SCA_IController*>* controllerarray = *(m_sensorcontrollermap[i]);
@@ -69,6 +75,8 @@ SCA_LogicManager::~SCA_LogicManager()
}
m_eventmanagers.clear();
m_sensorcontrollermapje.clear();
+ m_removedActuators.clear();
+ m_activeActuators.clear();
}
@@ -120,12 +128,17 @@ void SCA_LogicManager::RegisterGameMeshName(const STR_String& gamemeshname, void
-void SCA_LogicManager::RegisterGameObj(CValue* gameobj, void* blendobj)
+void SCA_LogicManager::RegisterGameObj(void* blendobj, CValue* gameobj)
{
- m_map_gameobj_to_blendobj.insert(CHashedPtr(gameobj), blendobj);
+ m_map_blendobj_to_gameobj.insert(CHashedPtr(blendobj), gameobj);
}
-
+void SCA_LogicManager::UnregisterGameObj(void* blendobj, CValue* gameobj)
+{
+ void **obp = m_map_blendobj_to_gameobj[CHashedPtr(blendobj)];
+ if (obp && (CValue*)(*obp) == gameobj)
+ m_map_blendobj_to_gameobj.remove(CHashedPtr(blendobj));
+}
CValue* SCA_LogicManager::GetGameObjectByName(const STR_String& gameobjname)
{
@@ -139,10 +152,10 @@ CValue* SCA_LogicManager::GetGameObjectByName(const STR_String& gameobjname)
}
-void* SCA_LogicManager::FindBlendObjByGameObj(CValue* gameobject)
+CValue* SCA_LogicManager::FindGameObjByBlendObj(void* blendobj)
{
- void **obp= m_map_gameobj_to_blendobj[CHashedPtr(gameobject)];
- return obp?*obp:NULL;
+ void **obp= m_map_blendobj_to_gameobj[CHashedPtr(blendobj)];
+ return obp?(CValue*)(*obp):NULL;
}
@@ -158,15 +171,25 @@ void* SCA_LogicManager::FindBlendObjByGameMeshName(const STR_String& gamemeshnam
void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor)
{
- m_sensorcontrollermapje.erase(sensor);
-
- for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin();
- !(ie==m_eventmanagers.end());ie++)
+ controllerlist contlist = m_sensorcontrollermapje[sensor];
+ for (controllerlist::const_iterator c= contlist.begin();!(c==contlist.end());c++)
{
- (*ie)->RemoveSensor(sensor);
+ (*c)->UnlinkSensor(sensor);
}
+ m_sensorcontrollermapje.erase(sensor);
+ sensor->UnregisterToManager();
}
+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);
+ }
+}
void SCA_LogicManager::RemoveDestroyedActuator(SCA_IActuator* actuator)
@@ -210,8 +233,6 @@ void SCA_LogicManager::BeginFrame(double curtime, double fixedtime)
// for this frame, look up for activated sensors, and build the collection of triggered controllers
// int numsensors = this->m_activatedsensors.size(); /*unused*/
- set<SmartControllerPtr> triggeredControllerSet;
-
for (vector<SCA_ISensor*>::const_iterator is=m_activatedsensors.begin();
!(is==m_activatedsensors.end());is++)
{
@@ -221,19 +242,29 @@ void SCA_LogicManager::BeginFrame(double curtime, double fixedtime)
!(c==contlist.end());c++)
{
SCA_IController* contr = *c;//controllerarray->at(c);
- triggeredControllerSet.insert(SmartControllerPtr(contr,0));
+ 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);
+ }
+ }
}
//sensor->SetActive(false);
}
// int numtriggered = triggeredControllerSet.size(); /*unused*/
- for (set<SmartControllerPtr>::iterator tit=triggeredControllerSet.begin();
- !(tit==triggeredControllerSet.end());tit++)
+ for (set<SmartControllerPtr>::iterator tit=m_triggeredControllerSet.begin();
+ !(tit==m_triggeredControllerSet.end());tit++)
{
(*tit)->Trigger(this);
}
- triggeredControllerSet.clear();
+ m_triggeredControllerSet.clear();
}
@@ -248,6 +279,10 @@ void SCA_LogicManager::UpdateFrame(double curtime, bool frame)
}
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++)
{
//SCA_IActuator* actua = *ia;
@@ -258,6 +293,16 @@ void SCA_LogicManager::UpdateFrame(double curtime, bool frame)
(*ia)->SetActive(false);
//m_activeactuators.pop_back();
+ } else if ((*ia)->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.
+ CValue* event = new CBoolValue(false);
+ (*ia)->RemoveAllEvents();
+ (*ia)->AddEvent(event);
}
}
@@ -345,6 +390,17 @@ void SCA_LogicManager::AddActivatedSensor(SCA_ISensor* sensor)
}
}
+void SCA_LogicManager::AddTriggeredController(SCA_IController* controller, SCA_ISensor* sensor)
+{
+ m_triggeredControllerSet.insert(SmartControllerPtr(controller,0));
+ // so that the controller knows which sensor has activited it
+ // only needed for python controller
+ if (controller->GetType() == &SCA_PythonController::Type)
+ {
+ SCA_PythonController* pythonController = (SCA_PythonController*)controller;
+ pythonController->AddTriggeredSensor(sensor);
+ }
+}
void SCA_LogicManager::AddActiveActuator(SCA_IActuator* actua,CValue* event)
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.h b/source/gameengine/GameLogic/SCA_LogicManager.h
index 39d8b865977..50383879d8f 100644
--- a/source/gameengine/GameLogic/SCA_LogicManager.h
+++ b/source/gameengine/GameLogic/SCA_LogicManager.h
@@ -99,6 +99,7 @@ class SCA_LogicManager
vector<class SCA_ISensor*> m_activatedsensors;
set<class SmartActuatorPtr> m_activeActuators;
+ set<class SmartControllerPtr> m_triggeredControllerSet;
map<SCA_ISensor*,controllerlist > m_sensorcontrollermapje;
@@ -109,7 +110,7 @@ class SCA_LogicManager
GEN_Map<STR_HashedString,void*> m_mapStringToActions;
GEN_Map<STR_HashedString,void*> m_map_gamemeshname_to_blendobj;
- GEN_Map<CHashedPtr,void*> m_map_gameobj_to_blendobj;
+ GEN_Map<CHashedPtr,void*> m_map_blendobj_to_gameobj;
vector<SmartActuatorPtr> m_removedActuators;
public:
@@ -127,6 +128,7 @@ public:
void EndFrame();
void AddActivatedSensor(SCA_ISensor* sensor);
void AddActiveActuator(SCA_IActuator* sensor,class CValue* event);
+ void AddTriggeredController(SCA_IController* controller, SCA_ISensor* sensor);
SCA_EventManager* FindEventManager(int eventmgrtype);
void RemoveGameObject(const STR_String& gameobjname);
@@ -152,8 +154,9 @@ public:
void RegisterGameMeshName(const STR_String& gamemeshname, void* blendobj);
void* FindBlendObjByGameMeshName(const STR_String& gamemeshname);
- void RegisterGameObj(CValue* gameobj, void* blendobj);
- void* FindBlendObjByGameObj(CValue* gameobj);
+ void RegisterGameObj(void* blendobj, CValue* gameobj);
+ void UnregisterGameObj(void* blendobj, CValue* gameobj);
+ CValue* FindGameObjByBlendObj(void* blendobj);
};
#endif //__KX_LOGICMANAGER
diff --git a/source/gameengine/GameLogic/SCA_MouseManager.cpp b/source/gameengine/GameLogic/SCA_MouseManager.cpp
index b4251d8ab53..ca875dad07c 100644
--- a/source/gameengine/GameLogic/SCA_MouseManager.cpp
+++ b/source/gameengine/GameLogic/SCA_MouseManager.cpp
@@ -75,9 +75,10 @@ void SCA_MouseManager::NextFrame()
{
if (m_mousedevice)
{
- for (unsigned int i = 0; i < m_sensors.size(); i++)
+ set<SCA_ISensor*>::iterator it;
+ for (it=m_sensors.begin(); it!=m_sensors.end(); it++)
{
- SCA_MouseSensor* mousesensor = (SCA_MouseSensor*) m_sensors[i];
+ SCA_MouseSensor* mousesensor = (SCA_MouseSensor*)(*it);
// (0,0) is the Upper Left corner in our local window
// coordinates
if (!mousesensor->IsSuspended())
@@ -98,15 +99,6 @@ void SCA_MouseManager::NextFrame()
}
}
-
-
-void SCA_MouseManager::RegisterSensor(SCA_ISensor* keysensor)
-{
- m_sensors.push_back(keysensor);
-}
-
-
-
bool SCA_MouseManager::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
{
/* We should guard for non-mouse events maybe? A rather silly side */
diff --git a/source/gameengine/GameLogic/SCA_MouseManager.h b/source/gameengine/GameLogic/SCA_MouseManager.h
index bc8254486ad..efa4c639ce7 100644
--- a/source/gameengine/GameLogic/SCA_MouseManager.h
+++ b/source/gameengine/GameLogic/SCA_MouseManager.h
@@ -62,7 +62,6 @@ public:
*/
bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode);
virtual void NextFrame();
- virtual void RegisterSensor(class SCA_ISensor* sensor);
SCA_IInputDevice* GetInputDevice();
};
diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.cpp b/source/gameengine/GameLogic/SCA_MouseSensor.cpp
index a91cf3e0439..d4952ce4777 100644
--- a/source/gameengine/GameLogic/SCA_MouseSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_MouseSensor.cpp
@@ -58,7 +58,6 @@ SCA_MouseSensor::SCA_MouseSensor(SCA_MouseManager* eventmgr,
{
m_mousemode = mousemode;
m_triggermode = true;
- m_val = 0; /* stores the latest attribute */
switch (m_mousemode) {
case KX_MOUSESENSORMODE_LEFTBUTTON:
@@ -79,7 +78,13 @@ SCA_MouseSensor::SCA_MouseSensor(SCA_MouseManager* eventmgr,
default:
; /* ignore, no hotkey */
}
+ Init();
+}
+void SCA_MouseSensor::Init()
+{
+ m_val = (m_invert)?1:0; /* stores the latest attribute */
+ m_reset = true;
}
SCA_MouseSensor::~SCA_MouseSensor()
@@ -91,9 +96,10 @@ SCA_MouseSensor::~SCA_MouseSensor()
CValue* SCA_MouseSensor::GetReplica()
{
- CValue* replica = new SCA_MouseSensor(*this);
+ SCA_MouseSensor* replica = new SCA_MouseSensor(*this);
// this will copy properties and so on...
CValue::AddDataToReplica(replica);
+ replica->Init();
return replica;
}
@@ -128,6 +134,7 @@ SCA_IInputDevice::KX_EnumInputs SCA_MouseSensor::GetHotKey()
bool SCA_MouseSensor::Evaluate(CValue* event)
{
bool result = false;
+ bool reset = m_reset && m_level;
SCA_IInputDevice* mousedev = m_pMouseMgr->GetInputDevice();
@@ -139,7 +146,7 @@ bool SCA_MouseSensor::Evaluate(CValue* event)
/* both MOUSEX and MOUSEY. Treat all of these as key-presses. */
/* So, treat KX_MOUSESENSORMODE_POSITION as */
/* KX_MOUSESENSORMODE_POSITIONX || KX_MOUSESENSORMODE_POSITIONY */
-
+ m_reset = false;
switch (m_mousemode) {
case KX_MOUSESENSORMODE_LEFTBUTTON:
case KX_MOUSESENSORMODE_MIDDLEBUTTON:
@@ -158,6 +165,26 @@ bool SCA_MouseSensor::Evaluate(CValue* event)
{
m_val = 0;
result = true;
+ } else
+ {
+ if (event.m_status == SCA_InputEvent::KX_ACTIVE)
+ {
+ if (m_val == 0)
+ {
+ m_val = 1;
+ if (m_level)
+ {
+ result = true;
+ }
+ }
+ } else
+ {
+ if (m_val == 1)
+ {
+ m_val = 0;
+ result = true;
+ }
+ }
}
}
break;
@@ -183,6 +210,13 @@ bool SCA_MouseSensor::Evaluate(CValue* event)
{
m_val = 0;
result = true;
+ } else
+ {
+ if (m_val == 1)
+ {
+ m_val = 0;
+ result = true;
+ }
}
}
break;
@@ -191,6 +225,9 @@ bool SCA_MouseSensor::Evaluate(CValue* event)
; /* error */
}
+ if (reset)
+ // force an event
+ result = true;
return result;
}
@@ -246,8 +283,8 @@ PyParentObject SCA_MouseSensor::Parents[] = {
};
PyMethodDef SCA_MouseSensor::Methods[] = {
- {"getXPosition", (PyCFunction) SCA_MouseSensor::sPyGetXPosition, METH_VARARGS, GetXPosition_doc},
- {"getYPosition", (PyCFunction) SCA_MouseSensor::sPyGetYPosition, METH_VARARGS, GetYPosition_doc},
+ {"getXPosition", (PyCFunction) SCA_MouseSensor::sPyGetXPosition, METH_VARARGS, (PY_METHODCHAR)GetXPosition_doc},
+ {"getYPosition", (PyCFunction) SCA_MouseSensor::sPyGetYPosition, METH_VARARGS, (PY_METHODCHAR)GetYPosition_doc},
{NULL,NULL} //Sentinel
};
@@ -256,7 +293,7 @@ PyObject* SCA_MouseSensor::_getattr(const STR_String& attr) {
}
/* get x position ---------------------------------------------------------- */
-char SCA_MouseSensor::GetXPosition_doc[] =
+const char SCA_MouseSensor::GetXPosition_doc[] =
"getXPosition\n"
"\tReturns the x-coordinate of the mouse sensor, in frame coordinates.\n"
"\tThe lower-left corner is the origin. The coordinate is given in\n"
@@ -268,7 +305,7 @@ PyObject* SCA_MouseSensor::PyGetXPosition(PyObject* self,
}
/* get y position ---------------------------------------------------------- */
-char SCA_MouseSensor::GetYPosition_doc[] =
+const char SCA_MouseSensor::GetYPosition_doc[] =
"getYPosition\n"
"\tReturns the y-coordinate of the mouse sensor, in frame coordinates.\n"
"\tThe lower-left corner is the origin. The coordinate is given in\n"
diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.h b/source/gameengine/GameLogic/SCA_MouseSensor.h
index 86c9d96a800..26a1c5e3fd2 100644
--- a/source/gameengine/GameLogic/SCA_MouseSensor.h
+++ b/source/gameengine/GameLogic/SCA_MouseSensor.h
@@ -96,7 +96,7 @@ class SCA_MouseSensor : public SCA_ISensor
virtual ~SCA_MouseSensor();
virtual CValue* GetReplica();
virtual bool Evaluate(CValue* event);
-
+ virtual void Init();
virtual bool IsPositiveTrigger();
short int GetModeKey();
SCA_IInputDevice::KX_EnumInputs GetHotKey();
diff --git a/source/gameengine/GameLogic/SCA_NANDController.cpp b/source/gameengine/GameLogic/SCA_NANDController.cpp
new file mode 100644
index 00000000000..5b869ee8298
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_NANDController.cpp
@@ -0,0 +1,144 @@
+/**
+ * 'Nand' together all inputs
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "SCA_NANDController.h"
+#include "SCA_ISensor.h"
+#include "SCA_LogicManager.h"
+#include "BoolValue.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_NANDController::SCA_NANDController(SCA_IObject* gameobj,
+ PyTypeObject* T)
+ :
+ SCA_IController(gameobj,T)
+{
+}
+
+
+
+SCA_NANDController::~SCA_NANDController()
+{
+}
+
+
+
+void SCA_NANDController::Trigger(SCA_LogicManager* logicmgr)
+{
+
+ bool sensorresult = false;
+
+ for (vector<SCA_ISensor*>::const_iterator is=m_linkedsensors.begin();
+ !(is==m_linkedsensors.end());is++)
+ {
+ SCA_ISensor* sensor = *is;
+ if (!sensor->IsPositiveTrigger())
+ {
+ 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);
+ }
+
+ // 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();
+
+}
+
+
+
+CValue* SCA_NANDController::GetReplica()
+{
+ CValue* replica = new SCA_NANDController(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_NANDController::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_NANDController",
+ sizeof(SCA_NANDController),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_NANDController::Parents[] = {
+ &SCA_NANDController::Type,
+ &SCA_IController::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_NANDController::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_NANDController::_getattr(const STR_String& attr) {
+ _getattr_up(SCA_IController);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_NANDController.h b/source/gameengine/GameLogic/SCA_NANDController.h
new file mode 100644
index 00000000000..1193ff64f07
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_NANDController.h
@@ -0,0 +1,56 @@
+/**
+ * SCA_NANDController.h
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_NANDCONTROLLER
+#define __KX_NANDCONTROLLER
+
+#include "SCA_IController.h"
+
+class SCA_NANDController : public SCA_IController
+{
+ Py_Header;
+ //virtual void Trigger(class SCA_LogicManager* logicmgr);
+public:
+ SCA_NANDController(SCA_IObject* gameobj,PyTypeObject* T=&Type);
+ virtual ~SCA_NANDController();
+ virtual CValue* GetReplica();
+ virtual void Trigger(SCA_LogicManager* logicmgr);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(const STR_String& attr);
+
+};
+
+#endif //__KX_NANDCONTROLLER
+
diff --git a/source/gameengine/GameLogic/SCA_NORController.cpp b/source/gameengine/GameLogic/SCA_NORController.cpp
new file mode 100644
index 00000000000..2866dec0b74
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_NORController.cpp
@@ -0,0 +1,144 @@
+/**
+ * 'Nor' together all inputs
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "SCA_NORController.h"
+#include "SCA_ISensor.h"
+#include "SCA_LogicManager.h"
+#include "BoolValue.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_NORController::SCA_NORController(SCA_IObject* gameobj,
+ PyTypeObject* T)
+ :
+ SCA_IController(gameobj,T)
+{
+}
+
+
+
+SCA_NORController::~SCA_NORController()
+{
+}
+
+
+
+void SCA_NORController::Trigger(SCA_LogicManager* logicmgr)
+{
+
+ bool sensorresult = true;
+
+ 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(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);
+ }
+
+ // 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();
+
+}
+
+
+
+CValue* SCA_NORController::GetReplica()
+{
+ CValue* replica = new SCA_NORController(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_NORController::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_NORController",
+ sizeof(SCA_NORController),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_NORController::Parents[] = {
+ &SCA_NORController::Type,
+ &SCA_IController::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_NORController::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_NORController::_getattr(const STR_String& attr) {
+ _getattr_up(SCA_IController);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_NORController.h b/source/gameengine/GameLogic/SCA_NORController.h
new file mode 100644
index 00000000000..aab59e3d46c
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_NORController.h
@@ -0,0 +1,56 @@
+/**
+ * SCA_NORController.h
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_NORCONTROLLER
+#define __KX_NORCONTROLLER
+
+#include "SCA_IController.h"
+
+class SCA_NORController : public SCA_IController
+{
+ Py_Header;
+ //virtual void Trigger(class SCA_LogicManager* logicmgr);
+public:
+ SCA_NORController(SCA_IObject* gameobj,PyTypeObject* T=&Type);
+ virtual ~SCA_NORController();
+ virtual CValue* GetReplica();
+ virtual void Trigger(SCA_LogicManager* logicmgr);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(const STR_String& attr);
+
+};
+
+#endif //__KX_NORCONTROLLER
+
diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
index 1ee32e64b6c..3b541e87f02 100644
--- a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
@@ -42,17 +42,23 @@
/* Native functions */
/* ------------------------------------------------------------------------- */
-SCA_PropertyActuator::SCA_PropertyActuator(SCA_IObject* gameobj,CValue* sourceObj,const STR_String& propname,const STR_String& expr,int acttype,PyTypeObject* T )
+SCA_PropertyActuator::SCA_PropertyActuator(SCA_IObject* gameobj,SCA_IObject* sourceObj,const STR_String& propname,const STR_String& expr,int acttype,PyTypeObject* T )
: SCA_IActuator(gameobj,T),
m_type(acttype),
m_propname(propname),
m_exprtxt(expr),
m_sourceObj(sourceObj)
{
+ // protect ourselves against someone else deleting the source object
+ // don't protect against ourselves: it would create a dead lock
+ if (m_sourceObj)
+ m_sourceObj->RegisterActuator(this);
}
SCA_PropertyActuator::~SCA_PropertyActuator()
{
+ if (m_sourceObj)
+ m_sourceObj->UnregisterActuator(this);
}
bool SCA_PropertyActuator::Update()
@@ -87,12 +93,11 @@ bool SCA_PropertyActuator::Update()
if (oldprop)
{
oldprop->SetValue(newval);
- newval->Release();
} else
{
propowner->SetProperty(m_propname,newval);
}
-
+ newval->Release();
break;
}
case KX_ACT_PROP_ADD:
@@ -120,9 +125,11 @@ bool SCA_PropertyActuator::Update()
CValue* copyprop = m_sourceObj->GetProperty(m_exprtxt);
if (copyprop)
{
+ CValue *val = copyprop->GetReplica();
GetParent()->SetProperty(
m_propname,
- copyprop->GetReplica());
+ val);
+ val->Release();
}
}
@@ -173,7 +180,36 @@ GetReplica() {
};
+void SCA_PropertyActuator::ProcessReplica()
+{
+ // no need to check for self reference like in the constructor:
+ // the replica will always have a different parent
+ if (m_sourceObj)
+ m_sourceObj->RegisterActuator(this);
+ SCA_IActuator::ProcessReplica();
+}
+bool SCA_PropertyActuator::UnlinkObject(SCA_IObject* clientobj)
+{
+ if (clientobj == m_sourceObj)
+ {
+ // this object is being deleted, we cannot continue to track it.
+ m_sourceObj = NULL;
+ return true;
+ }
+ return false;
+}
+
+void SCA_PropertyActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
+{
+ void **h_obj = (*obj_map)[m_sourceObj];
+ if (h_obj) {
+ if (m_sourceObj)
+ m_sourceObj->UnregisterActuator(this);
+ m_sourceObj = (SCA_IObject*)(*h_obj);
+ m_sourceObj->RegisterActuator(this);
+ }
+}
/* ------------------------------------------------------------------------- */
@@ -209,10 +245,10 @@ PyParentObject SCA_PropertyActuator::Parents[] = {
};
PyMethodDef SCA_PropertyActuator::Methods[] = {
- {"setProperty", (PyCFunction) SCA_PropertyActuator::sPySetProperty, METH_VARARGS, SetProperty_doc},
- {"getProperty", (PyCFunction) SCA_PropertyActuator::sPyGetProperty, METH_VARARGS, GetProperty_doc},
- {"setValue", (PyCFunction) SCA_PropertyActuator::sPySetValue, METH_VARARGS, SetValue_doc},
- {"getValue", (PyCFunction) SCA_PropertyActuator::sPyGetValue, METH_VARARGS, GetValue_doc},
+ {"setProperty", (PyCFunction) SCA_PropertyActuator::sPySetProperty, METH_VARARGS, (PY_METHODCHAR)SetProperty_doc},
+ {"getProperty", (PyCFunction) SCA_PropertyActuator::sPyGetProperty, METH_VARARGS, (PY_METHODCHAR)GetProperty_doc},
+ {"setValue", (PyCFunction) SCA_PropertyActuator::sPySetValue, METH_VARARGS, (PY_METHODCHAR)SetValue_doc},
+ {"getValue", (PyCFunction) SCA_PropertyActuator::sPyGetValue, METH_VARARGS, (PY_METHODCHAR)GetValue_doc},
{NULL,NULL} //Sentinel
};
@@ -221,7 +257,7 @@ PyObject* SCA_PropertyActuator::_getattr(const STR_String& attr) {
}
/* 1. setProperty */
-char SCA_PropertyActuator::SetProperty_doc[] =
+const char SCA_PropertyActuator::SetProperty_doc[] =
"setProperty(name)\n"
"\t- name: string\n"
"\tSet the property on which to operate. If there is no property\n"
@@ -236,17 +272,18 @@ PyObject* SCA_PropertyActuator::PySetProperty(PyObject* self, PyObject* args, Py
CValue* prop = GetParent()->FindIdentifier(nameArg);
- if (prop) {
+ if (!prop->IsError()) {
m_propname = nameArg;
} else {
; /* not found ... */
}
+ prop->Release();
Py_Return;
}
/* 2. getProperty */
-char SCA_PropertyActuator::GetProperty_doc[] =
+const char SCA_PropertyActuator::GetProperty_doc[] =
"getProperty(name)\n"
"\tReturn the property on which the actuator operates.\n";
PyObject* SCA_PropertyActuator::PyGetProperty(PyObject* self, PyObject* args, PyObject* kwds)
@@ -255,7 +292,7 @@ PyObject* SCA_PropertyActuator::PyGetProperty(PyObject* self, PyObject* args, Py
}
/* 3. setValue */
-char SCA_PropertyActuator::SetValue_doc[] =
+const char SCA_PropertyActuator::SetValue_doc[] =
"setValue(value)\n"
"\t- value: string\n"
"\tSet the value with which the actuator operates. If the value\n"
@@ -274,7 +311,7 @@ PyObject* SCA_PropertyActuator::PySetValue(PyObject* self, PyObject* args, PyObj
}
/* 4. getValue */
-char SCA_PropertyActuator::GetValue_doc[] =
+const char SCA_PropertyActuator::GetValue_doc[] =
"getValue()\n"
"\tReturns the value with which the actuator operates.\n";
PyObject* SCA_PropertyActuator::PyGetValue(PyObject* self, PyObject* args, PyObject* kwds)
diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.h b/source/gameengine/GameLogic/SCA_PropertyActuator.h
index 05a7cfbc501..1e435684572 100644
--- a/source/gameengine/GameLogic/SCA_PropertyActuator.h
+++ b/source/gameengine/GameLogic/SCA_PropertyActuator.h
@@ -52,7 +52,7 @@ class SCA_PropertyActuator : public SCA_IActuator
int m_type;
STR_String m_propname;
STR_String m_exprtxt;
- CValue* m_sourceObj; // for copy property actuator
+ SCA_IObject* m_sourceObj; // for copy property actuator
public:
@@ -60,7 +60,7 @@ public:
SCA_PropertyActuator(
SCA_IObject* gameobj,
- CValue* sourceObj,
+ SCA_IObject* sourceObj,
const STR_String& propname,
const STR_String& expr,
int acttype,
@@ -74,6 +74,10 @@ public:
GetReplica(
);
+ virtual void ProcessReplica();
+ virtual bool UnlinkObject(SCA_IObject* clientobj);
+ virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
+
virtual bool
Update();
diff --git a/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp b/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
index fc56d101728..e5e3f9cced5 100644
--- a/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
@@ -47,19 +47,10 @@ SCA_PropertyEventManager::~SCA_PropertyEventManager()
}
-
-
-void SCA_PropertyEventManager::RegisterSensor(SCA_ISensor* sensor)
-{
- m_sensors.push_back(sensor);
-}
-
-
-
void SCA_PropertyEventManager::NextFrame()
{
// check for changed properties
- for (vector<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
+ for (set<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
{
(*it)->Activate(m_logicmgr,NULL);
}
diff --git a/source/gameengine/GameLogic/SCA_PropertyEventManager.h b/source/gameengine/GameLogic/SCA_PropertyEventManager.h
index aaa303a52c8..f166065b198 100644
--- a/source/gameengine/GameLogic/SCA_PropertyEventManager.h
+++ b/source/gameengine/GameLogic/SCA_PropertyEventManager.h
@@ -43,7 +43,6 @@ public:
SCA_PropertyEventManager(class SCA_LogicManager* logicmgr);
virtual ~SCA_PropertyEventManager();
virtual void NextFrame();
- virtual void RegisterSensor(SCA_ISensor* sensor);
//SCA_LogicManager* GetLogicManager() { return m_logicmgr;}
};
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
index 21ec6d39c08..64e3d49c6cb 100644
--- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
@@ -54,47 +54,65 @@ SCA_PropertySensor::SCA_PropertySensor(SCA_EventManager* eventmgr,
m_checkpropval(propval),
m_checkpropmaxval(propmaxval),
m_checkpropname(propname),
- m_lastresult(false),
m_range_expr(NULL)
{
- m_recentresult=false;
//CParser pars;
//pars.SetContext(this->AddRef());
//CValue* resultval = m_rightexpr->Calculate();
CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
- if (orgprop)
+ if (!orgprop->IsError())
{
m_previoustext = orgprop->GetText();
- orgprop->Release();
}
+ orgprop->Release();
if (m_checktype==KX_PROPSENSOR_INTERVAL)
{
PrecalculateRangeExpression();
}
+ Init();
+}
+void SCA_PropertySensor::Init()
+{
+ m_recentresult = false;
+ m_lastresult = m_invert?true:false;
+ m_reset = true;
}
void SCA_PropertySensor::PrecalculateRangeExpression()
{
CParser pars;
+ //The context is needed to retrieve the property at runtime but it creates
+ //loop of references
pars.SetContext(this->AddRef());
STR_String checkstr = "(" + m_checkpropval + " <= "
+ m_checkpropname + ") && ( "
+ m_checkpropname + " <= "
- + m_checkpropmaxval;
+ + m_checkpropmaxval + ")";
m_range_expr = pars.ProcessText(checkstr);
}
-
+// Forced deletion of precalculated range expression to break reference loop
+// Use this function when you know that you won't use the sensor anymore
+void SCA_PropertySensor::Delete()
+{
+ if (m_range_expr)
+ {
+ m_range_expr->Release();
+ m_range_expr = NULL;
+ }
+ Release();
+}
CValue* SCA_PropertySensor::GetReplica()
{
SCA_PropertySensor* replica = new SCA_PropertySensor(*this);
// m_range_expr must be recalculated on replica!
CValue::AddDataToReplica(replica);
+ replica->Init();
replica->m_range_expr = NULL;
if (replica->m_checktype==KX_PROPSENSOR_INTERVAL)
@@ -137,14 +155,15 @@ SCA_PropertySensor::~SCA_PropertySensor()
bool SCA_PropertySensor::Evaluate(CValue* event)
{
bool result = CheckPropertyCondition();
+ bool reset = m_reset && m_level;
+ m_reset = false;
if (m_lastresult!=result)
{
m_lastresult = result;
return true;
}
-
- return false;
+ return (reset) ? true : false;
}
@@ -161,7 +180,7 @@ bool SCA_PropertySensor::CheckPropertyCondition()
case KX_PROPSENSOR_EQUAL:
{
CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
- if (orgprop)
+ if (!orgprop->IsError())
{
STR_String testprop = orgprop->GetText();
// Force strings to upper case, to avoid confusion in
@@ -174,9 +193,8 @@ bool SCA_PropertySensor::CheckPropertyCondition()
} else {
result = (orgprop->GetText() == m_checkpropval);
}
- orgprop->Release();
-
}
+ orgprop->Release();
if (reverse)
result = !result;
@@ -241,15 +259,15 @@ bool SCA_PropertySensor::CheckPropertyCondition()
{
CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
- if (orgprop)
+ if (!orgprop->IsError())
{
if (m_previoustext != orgprop->GetText())
{
m_previoustext = orgprop->GetText();
result = true;
}
- orgprop->Release();
}
+ orgprop->Release();
//cout << " \nSens:Prop:changed!"; /* need implementation here!!! */
break;
@@ -315,12 +333,12 @@ PyParentObject SCA_PropertySensor::Parents[] = {
};
PyMethodDef SCA_PropertySensor::Methods[] = {
- {"getType", (PyCFunction) SCA_PropertySensor::sPyGetType, METH_VARARGS, GetType_doc},
- {"setType", (PyCFunction) SCA_PropertySensor::sPySetType, METH_VARARGS, SetType_doc},
- {"getProperty", (PyCFunction) SCA_PropertySensor::sPyGetProperty, METH_VARARGS, GetProperty_doc},
- {"setProperty", (PyCFunction) SCA_PropertySensor::sPySetProperty, METH_VARARGS, SetProperty_doc},
- {"getValue", (PyCFunction) SCA_PropertySensor::sPyGetValue, METH_VARARGS, GetValue_doc},
- {"setValue", (PyCFunction) SCA_PropertySensor::sPySetValue, METH_VARARGS, SetValue_doc},
+ {"getType", (PyCFunction) SCA_PropertySensor::sPyGetType, METH_VARARGS, (PY_METHODCHAR)GetType_doc},
+ {"setType", (PyCFunction) SCA_PropertySensor::sPySetType, METH_VARARGS, (PY_METHODCHAR)SetType_doc},
+ {"getProperty", (PyCFunction) SCA_PropertySensor::sPyGetProperty, METH_VARARGS, (PY_METHODCHAR)GetProperty_doc},
+ {"setProperty", (PyCFunction) SCA_PropertySensor::sPySetProperty, METH_VARARGS, (PY_METHODCHAR)SetProperty_doc},
+ {"getValue", (PyCFunction) SCA_PropertySensor::sPyGetValue, METH_VARARGS, (PY_METHODCHAR)GetValue_doc},
+ {"setValue", (PyCFunction) SCA_PropertySensor::sPySetValue, METH_VARARGS, (PY_METHODCHAR)SetValue_doc},
{NULL,NULL} //Sentinel
};
@@ -329,7 +347,7 @@ PyObject* SCA_PropertySensor::_getattr(const STR_String& attr) {
}
/* 1. getType */
-char SCA_PropertySensor::GetType_doc[] =
+const char SCA_PropertySensor::GetType_doc[] =
"getType()\n"
"\tReturns the type of check this sensor performs.\n";
PyObject* SCA_PropertySensor::PyGetType(PyObject* self, PyObject* args, PyObject* kwds)
@@ -338,7 +356,7 @@ PyObject* SCA_PropertySensor::PyGetType(PyObject* self, PyObject* args, PyObject
}
/* 2. setType */
-char SCA_PropertySensor::SetType_doc[] =
+const char SCA_PropertySensor::SetType_doc[] =
"setType(type)\n"
"\t- type: KX_PROPSENSOR_EQUAL, KX_PROPSENSOR_NOTEQUAL,\n"
"\t KX_PROPSENSOR_INTERVAL, KX_PROPSENSOR_CHANGED,\n"
@@ -361,7 +379,7 @@ PyObject* SCA_PropertySensor::PySetType(PyObject* self, PyObject* args, PyObject
}
/* 3. getProperty */
-char SCA_PropertySensor::GetProperty_doc[] =
+const char SCA_PropertySensor::GetProperty_doc[] =
"getProperty()\n"
"\tReturn the property with which the sensor operates.\n";
PyObject* SCA_PropertySensor::PyGetProperty(PyObject* self, PyObject* args, PyObject* kwds)
@@ -370,7 +388,7 @@ PyObject* SCA_PropertySensor::PyGetProperty(PyObject* self, PyObject* args, PyOb
}
/* 4. setProperty */
-char SCA_PropertySensor::SetProperty_doc[] =
+const char SCA_PropertySensor::SetProperty_doc[] =
"setProperty(name)\n"
"\t- name: string\n"
"\tSets the property with which to operate. If there is no property\n"
@@ -385,17 +403,18 @@ PyObject* SCA_PropertySensor::PySetProperty(PyObject* self, PyObject* args, PyOb
return NULL;
}
- if (FindIdentifier(STR_String(propNameArg))) {
+ CValue *prop = FindIdentifier(STR_String(propNameArg));
+ if (!prop->IsError()) {
m_checkpropname = propNameArg;
} else {
; /* error: bad property name */
}
-
+ prop->Release();
Py_Return;
}
/* 5. getValue */
-char SCA_PropertySensor::GetValue_doc[] =
+const char SCA_PropertySensor::GetValue_doc[] =
"getValue()\n"
"\tReturns the value with which the sensor operates.\n";
PyObject* SCA_PropertySensor::PyGetValue(PyObject* self, PyObject* args, PyObject* kwds)
@@ -404,7 +423,7 @@ PyObject* SCA_PropertySensor::PyGetValue(PyObject* self, PyObject* args, PyObjec
}
/* 6. setValue */
-char SCA_PropertySensor::SetValue_doc[] =
+const char SCA_PropertySensor::SetValue_doc[] =
"setValue(value)\n"
"\t- value: string\n"
"\tSet the value with which the sensor operates. If the value\n"
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.h b/source/gameengine/GameLogic/SCA_PropertySensor.h
index e1e27684ecc..6871cb3afdc 100644
--- a/source/gameengine/GameLogic/SCA_PropertySensor.h
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.h
@@ -74,8 +74,10 @@ public:
KX_PROPSENSOR_TYPE checktype,
PyTypeObject* T=&Type );
+ virtual void Delete();
virtual ~SCA_PropertySensor();
virtual CValue* GetReplica();
+ virtual void Init();
void PrecalculateRangeExpression();
bool CheckPropertyCondition();
diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp
index 44cdc0a7de5..c354ab39747 100644
--- a/source/gameengine/GameLogic/SCA_PythonController.cpp
+++ b/source/gameengine/GameLogic/SCA_PythonController.cpp
@@ -33,8 +33,11 @@
#include "SCA_LogicManager.h"
#include "SCA_ISensor.h"
#include "SCA_IActuator.h"
+#include "PyObjectPlus.h"
#include "compile.h"
#include "eval.h"
+#include <algorithm>
+
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -116,7 +119,7 @@ CValue* SCA_PythonController::GetReplica()
void SCA_PythonController::SetScriptText(const STR_String& text)
{
- m_scriptText = "import GameLogic\n" + text;
+ m_scriptText = text;
m_bModified = true;
}
@@ -139,28 +142,33 @@ void SCA_PythonController::SetDictionary(PyObject* pythondictionary)
m_pythondictionary = PyDict_Copy(pythondictionary); /* new reference */
}
+int SCA_PythonController::IsTriggered(class SCA_ISensor* sensor)
+{
+ if (std::find(m_triggeredSensors.begin(), m_triggeredSensors.end(), sensor) !=
+ m_triggeredSensors.end())
+ return 1;
+ return 0;
+}
+
#if 0
-static char* sPyGetCurrentController__doc__;
+static const char* sPyGetCurrentController__doc__;
#endif
-PyObject* SCA_PythonController::sPyGetCurrentController(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* SCA_PythonController::sPyGetCurrentController(PyObject* self)
{
m_sCurrentController->AddRef();
return m_sCurrentController;
}
#if 0
-static char* sPyAddActiveActuator__doc__;
+static const char* sPyAddActiveActuator__doc__;
#endif
PyObject* SCA_PythonController::sPyAddActiveActuator(
PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args)
{
PyObject* ob1;
@@ -187,14 +195,13 @@ PyObject* SCA_PythonController::sPyAddActiveActuator(
m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)act,boolval);
boolval->Release();
}
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
-char* SCA_PythonController::sPyGetCurrentController__doc__ = "getCurrentController()";
-char* SCA_PythonController::sPyAddActiveActuator__doc__= "addActiveActuator(actuator,bool)";
-char SCA_PythonController::GetActuators_doc[] = "getActuator";
+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(&PyType_Type)
@@ -222,16 +229,13 @@ PyParentObject SCA_PythonController::Parents[] = {
NULL
};
PyMethodDef SCA_PythonController::Methods[] = {
- {"getActuators", (PyCFunction) SCA_PythonController::sPyGetActuators,
- METH_VARARGS, SCA_PythonController::GetActuators_doc},
- {"getActuator", (PyCFunction) SCA_PythonController::sPyGetActuator,
- METH_VARARGS, SCA_PythonController::GetActuator_doc},
- {"getSensors", (PyCFunction) SCA_PythonController::sPyGetSensors,
- METH_VARARGS, SCA_PythonController::GetSensors_doc},
- {"getSensor", (PyCFunction) SCA_PythonController::sPyGetSensor,
- METH_VARARGS, SCA_PythonController::GetSensor_doc},
- {"getScript", (PyCFunction) SCA_PythonController::sPyGetScript, METH_VARARGS},
- {"setScript", (PyCFunction) SCA_PythonController::sPySetScript, METH_VARARGS},
+ {"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},
+ {"getScript", (PyCFunction) SCA_PythonController::sPyGetScript, METH_NOARGS},
+ {"setScript", (PyCFunction) SCA_PythonController::sPySetScript, METH_O},
+ {"getState", (PyCFunction) SCA_PythonController::sPyGetState, METH_NOARGS},
{NULL,NULL} //Sentinel
};
@@ -255,9 +259,17 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
{
// didn't compile, so instead of compile, complain
// something is wrong, tell the user what went wrong
- printf("PYTHON SCRIPT ERROR:\n");
+ printf("Python compile error from controller \"%s\": \n", 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( "last_traceback", Py_None);
+ PyErr_Clear(); /* just to be sure */
+
return;
}
m_bModified=false;
@@ -280,43 +292,36 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
* break it by hand, then DECREF (which in this case
* should always ensure excdict is cleared).
*/
-/* PyObject *excdict= myPyDict_Copy(m_pythondictionary);
- struct _object* resultobj = PyEval_EvalCode((PyCodeObject*)m_bytecode,
- excdict,
- excdict
- );
- PyDict_Clear(excdict);
- Py_DECREF(excdict);*/
-
-#if 1
PyObject *excdict= PyDict_Copy(m_pythondictionary);
PyObject* resultobj = PyEval_EvalCode((PyCodeObject*)m_bytecode,
- excdict,
- excdict
- );
- PyDict_Clear(excdict);
- Py_DECREF(excdict);
-#else
-
- PyObject* resultobj = PyEval_EvalCode((PyCodeObject*)m_bytecode,
- m_pythondictionary,
- m_pythondictionary
- );
-
-#endif
+ excdict, excdict);
if (resultobj)
{
Py_DECREF(resultobj);
- } else
+ }
+ else
{
// something is wrong, tell the user what went wrong
- printf("PYTHON SCRIPT ERROR:\n");
+ 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
+ * 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( "last_traceback", Py_None);
+ 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());
m_sCurrentController = NULL;
}
@@ -329,30 +334,26 @@ PyObject* SCA_PythonController::_getattr(const STR_String& attr)
-PyObject* SCA_PythonController::PyGetActuators(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* SCA_PythonController::PyGetActuators(PyObject* self)
{
PyObject* resultlist = PyList_New(m_linkedactuators.size());
for (unsigned int index=0;index<m_linkedactuators.size();index++)
{
- PyList_SetItem(resultlist,index,m_linkedactuators[index]->AddRef());
+ PyList_SET_ITEM(resultlist,index,m_linkedactuators[index]->AddRef());
}
return resultlist;
}
-char SCA_PythonController::GetSensor_doc[] =
+const char SCA_PythonController::GetSensor_doc[] =
"GetSensor (char sensorname) return linked sensor that is named [sensorname]\n";
PyObject*
-SCA_PythonController::PyGetSensor(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+SCA_PythonController::PyGetSensor(PyObject* self, PyObject* value)
{
- char *scriptArg;
-
- if (!PyArg_ParseTuple(args, "s", &scriptArg)) {
+ char *scriptArg = PyString_AsString(value);
+ if (scriptArg==NULL) {
+ PyErr_SetString(PyExc_TypeError, "expected a string (sensor name)");
return NULL;
}
@@ -365,24 +366,24 @@ SCA_PythonController::PyGetSensor(PyObject* self,
return sensor->AddRef();
}
}
-
- PyErr_SetString(PyExc_AttributeError, "Unable to find requested sensor");
+
+ char emsg[96];
+ PyOS_snprintf( emsg, sizeof( emsg ), "Unable to find requested sensor \"%s\"", scriptArg );
+ PyErr_SetString(PyExc_AttributeError, emsg);
return NULL;
}
-char SCA_PythonController::GetActuator_doc[] =
+const char SCA_PythonController::GetActuator_doc[] =
"GetActuator (char sensorname) return linked actuator that is named [actuatorname]\n";
PyObject*
-SCA_PythonController::PyGetActuator(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+SCA_PythonController::PyGetActuator(PyObject* self, PyObject* value)
{
- char *scriptArg;
-
- if (!PyArg_ParseTuple(args, "s", &scriptArg)) {
+ char *scriptArg = PyString_AsString(value);
+ if (scriptArg==NULL) {
+ PyErr_SetString(PyExc_TypeError, "expected a string (actuator name)");
return NULL;
}
@@ -395,42 +396,39 @@ SCA_PythonController::PyGetActuator(PyObject* self,
return actua->AddRef();
}
}
-
- PyErr_SetString(PyExc_AttributeError, "Unable to find requested actuator");
+
+ char emsg[96];
+ PyOS_snprintf( emsg, sizeof( emsg ), "Unable to find requested actuator \"%s\"", scriptArg );
+ PyErr_SetString(PyExc_AttributeError, emsg);
return NULL;
}
-char SCA_PythonController::GetSensors_doc[] = "getSensors returns a list of all attached sensors";
+const char SCA_PythonController::GetSensors_doc[] = "getSensors returns a list of all attached sensors";
PyObject*
-SCA_PythonController::PyGetSensors(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+SCA_PythonController::PyGetSensors(PyObject* self)
{
PyObject* resultlist = PyList_New(m_linkedsensors.size());
for (unsigned int index=0;index<m_linkedsensors.size();index++)
{
- PyList_SetItem(resultlist,index,m_linkedsensors[index]->AddRef());
+ PyList_SET_ITEM(resultlist,index,m_linkedsensors[index]->AddRef());
}
return resultlist;
}
/* 1. getScript */
-PyObject* SCA_PythonController::PyGetScript(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* SCA_PythonController::PyGetScript(PyObject* self)
{
return PyString_FromString(m_scriptText);
}
/* 2. setScript */
-PyObject* SCA_PythonController::PySetScript(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* SCA_PythonController::PySetScript(PyObject* self, PyObject* value)
{
- char *scriptArg;
- if (!PyArg_ParseTuple(args, "s", &scriptArg)) {
+ char *scriptArg = PyString_AsString(value);
+ if (scriptArg==NULL) {
+ PyErr_SetString(PyExc_TypeError, "expected a string (script name)");
return NULL;
}
@@ -439,7 +437,13 @@ PyObject* SCA_PythonController::PySetScript(PyObject* self,
this->SetScriptText(scriptArg);
- Py_Return;
+ Py_RETURN_NONE;
+}
+
+/* 1. getScript */
+PyObject* SCA_PythonController::PyGetState(PyObject* self)
+{
+ return PyInt_FromLong(m_statemask);
}
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h
index 63975234da9..d9b2e242bea 100644
--- a/source/gameengine/GameLogic/SCA_PythonController.h
+++ b/source/gameengine/GameLogic/SCA_PythonController.h
@@ -36,6 +36,8 @@
#include "SCA_LogicManager.h"
#include "BoolValue.h"
+#include <vector>
+
class SCA_IObject;
class SCA_PythonController : public SCA_IController
{
@@ -47,6 +49,7 @@ class SCA_PythonController : public SCA_IController
STR_String m_scriptText;
STR_String m_scriptName;
PyObject* m_pythondictionary;
+ std::vector<class SCA_ISensor*> m_triggeredSensors;
public:
static SCA_PythonController* m_sCurrentController; // protected !!!
@@ -64,23 +67,24 @@ class SCA_PythonController : public SCA_IController
void SetScriptText(const STR_String& text);
void SetScriptName(const STR_String& name);
void SetDictionary(PyObject* pythondictionary);
+ void AddTriggeredSensor(class SCA_ISensor* sensor)
+ { m_triggeredSensors.push_back(sensor); }
+ int IsTriggered(class SCA_ISensor* sensor);
- static char* sPyGetCurrentController__doc__;
- static PyObject* sPyGetCurrentController(PyObject* self,
- PyObject* args,
- PyObject* kwds);
- static char* sPyAddActiveActuator__doc__;
+ static const char* sPyGetCurrentController__doc__;
+ static PyObject* sPyGetCurrentController(PyObject* self);
+ static const char* sPyAddActiveActuator__doc__;
static PyObject* sPyAddActiveActuator(PyObject* self,
- PyObject* args,
- PyObject* kwds);
+ PyObject* args);
virtual PyObject* _getattr(const STR_String& attr);
- KX_PYMETHOD_DOC(SCA_PythonController,GetSensors);
- KX_PYMETHOD_DOC(SCA_PythonController,GetSensor);
- KX_PYMETHOD_DOC(SCA_PythonController,GetActuator);
- KX_PYMETHOD_DOC(SCA_PythonController,GetActuators);
- KX_PYMETHOD(SCA_PythonController,SetScript);
- KX_PYMETHOD(SCA_PythonController,GetScript);
+ 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);
};
diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.cpp b/source/gameengine/GameLogic/SCA_RandomActuator.cpp
index 60570f7c19c..7b50a483cd8 100644
--- a/source/gameengine/GameLogic/SCA_RandomActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomActuator.cpp
@@ -58,6 +58,7 @@ 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();
@@ -75,6 +76,7 @@ SCA_RandomActuator::~SCA_RandomActuator()
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);
@@ -337,23 +339,23 @@ PyParentObject SCA_RandomActuator::Parents[] = {
};
PyMethodDef SCA_RandomActuator::Methods[] = {
- {"setSeed", (PyCFunction) SCA_RandomActuator::sPySetSeed, METH_VARARGS, SetSeed_doc},
- {"getSeed", (PyCFunction) SCA_RandomActuator::sPyGetSeed, METH_VARARGS, GetSeed_doc},
- {"getPara1", (PyCFunction) SCA_RandomActuator::sPyGetPara1, METH_VARARGS, GetPara1_doc},
- {"getPara2", (PyCFunction) SCA_RandomActuator::sPyGetPara2, METH_VARARGS, GetPara2_doc},
- {"getDistribution", (PyCFunction) SCA_RandomActuator::sPyGetDistribution, METH_VARARGS, GetDistribution_doc},
- {"setProperty", (PyCFunction) SCA_RandomActuator::sPySetProperty, METH_VARARGS, SetProperty_doc},
- {"getProperty", (PyCFunction) SCA_RandomActuator::sPyGetProperty, METH_VARARGS, GetProperty_doc},
- {"setBoolConst", (PyCFunction) SCA_RandomActuator::sPySetBoolConst, METH_VARARGS, SetBoolConst_doc},
- {"setBoolUniform", (PyCFunction) SCA_RandomActuator::sPySetBoolUniform, METH_VARARGS, SetBoolUniform_doc},
- {"setBoolBernouilli",(PyCFunction) SCA_RandomActuator::sPySetBoolBernouilli, METH_VARARGS, SetBoolBernouilli_doc},
- {"setIntConst", (PyCFunction) SCA_RandomActuator::sPySetIntConst, METH_VARARGS, SetIntConst_doc},
- {"setIntUniform", (PyCFunction) SCA_RandomActuator::sPySetIntUniform, METH_VARARGS, SetIntUniform_doc},
- {"setIntPoisson", (PyCFunction) SCA_RandomActuator::sPySetIntPoisson, METH_VARARGS, SetIntPoisson_doc},
- {"setFloatConst", (PyCFunction) SCA_RandomActuator::sPySetFloatConst, METH_VARARGS, SetFloatConst_doc},
- {"setFloatUniform", (PyCFunction) SCA_RandomActuator::sPySetFloatUniform, METH_VARARGS, SetFloatUniform_doc},
- {"setFloatNormal", (PyCFunction) SCA_RandomActuator::sPySetFloatNormal, METH_VARARGS, SetFloatNormal_doc},
- {"setFloatNegativeExponential", (PyCFunction) SCA_RandomActuator::sPySetFloatNegativeExponential, METH_VARARGS, SetFloatNegativeExponential_doc},
+ {"setSeed", (PyCFunction) SCA_RandomActuator::sPySetSeed, METH_VARARGS, (PY_METHODCHAR)SetSeed_doc},
+ {"getSeed", (PyCFunction) SCA_RandomActuator::sPyGetSeed, METH_VARARGS, (PY_METHODCHAR)GetSeed_doc},
+ {"getPara1", (PyCFunction) SCA_RandomActuator::sPyGetPara1, METH_VARARGS, (PY_METHODCHAR)GetPara1_doc},
+ {"getPara2", (PyCFunction) SCA_RandomActuator::sPyGetPara2, METH_VARARGS, (PY_METHODCHAR)GetPara2_doc},
+ {"getDistribution", (PyCFunction) SCA_RandomActuator::sPyGetDistribution, METH_VARARGS, (PY_METHODCHAR)GetDistribution_doc},
+ {"setProperty", (PyCFunction) SCA_RandomActuator::sPySetProperty, METH_VARARGS, (PY_METHODCHAR)SetProperty_doc},
+ {"getProperty", (PyCFunction) SCA_RandomActuator::sPyGetProperty, METH_VARARGS, (PY_METHODCHAR)GetProperty_doc},
+ {"setBoolConst", (PyCFunction) SCA_RandomActuator::sPySetBoolConst, METH_VARARGS, (PY_METHODCHAR)SetBoolConst_doc},
+ {"setBoolUniform", (PyCFunction) SCA_RandomActuator::sPySetBoolUniform, METH_VARARGS, (PY_METHODCHAR)SetBoolUniform_doc},
+ {"setBoolBernouilli",(PyCFunction) SCA_RandomActuator::sPySetBoolBernouilli, METH_VARARGS, (PY_METHODCHAR)SetBoolBernouilli_doc},
+ {"setIntConst", (PyCFunction) SCA_RandomActuator::sPySetIntConst, METH_VARARGS, (PY_METHODCHAR)SetIntConst_doc},
+ {"setIntUniform", (PyCFunction) SCA_RandomActuator::sPySetIntUniform, METH_VARARGS, (PY_METHODCHAR)SetIntUniform_doc},
+ {"setIntPoisson", (PyCFunction) SCA_RandomActuator::sPySetIntPoisson, METH_VARARGS, (PY_METHODCHAR)SetIntPoisson_doc},
+ {"setFloatConst", (PyCFunction) SCA_RandomActuator::sPySetFloatConst, METH_VARARGS, (PY_METHODCHAR)SetFloatConst_doc},
+ {"setFloatUniform", (PyCFunction) SCA_RandomActuator::sPySetFloatUniform, METH_VARARGS, (PY_METHODCHAR)SetFloatUniform_doc},
+ {"setFloatNormal", (PyCFunction) SCA_RandomActuator::sPySetFloatNormal, METH_VARARGS, (PY_METHODCHAR)SetFloatNormal_doc},
+ {"setFloatNegativeExponential", (PyCFunction) SCA_RandomActuator::sPySetFloatNegativeExponential, METH_VARARGS, (PY_METHODCHAR)SetFloatNegativeExponential_doc},
{NULL,NULL} //Sentinel
};
@@ -362,7 +364,7 @@ PyObject* SCA_RandomActuator::_getattr(const STR_String& attr) {
}
/* 1. setSeed */
-char SCA_RandomActuator::SetSeed_doc[] =
+const char SCA_RandomActuator::SetSeed_doc[] =
"setSeed(seed)\n"
"\t- seed: integer\n"
"\tSet the initial seed of the generator. Equal seeds produce\n"
@@ -379,7 +381,7 @@ PyObject* SCA_RandomActuator::PySetSeed(PyObject* self, PyObject* args, PyObject
Py_Return;
}
/* 2. getSeed */
-char SCA_RandomActuator::GetSeed_doc[] =
+const char SCA_RandomActuator::GetSeed_doc[] =
"getSeed()\n"
"\tReturns the initial seed of the generator. Equal seeds produce\n"
"\tequal series.\n";
@@ -388,7 +390,7 @@ PyObject* SCA_RandomActuator::PyGetSeed(PyObject* self, PyObject* args, PyObject
}
/* 4. getPara1 */
-char SCA_RandomActuator::GetPara1_doc[] =
+const char SCA_RandomActuator::GetPara1_doc[] =
"getPara1()\n"
"\tReturns the first parameter of the active distribution. Refer\n"
"\tto the documentation of the generator types for the meaning\n"
@@ -398,7 +400,7 @@ PyObject* SCA_RandomActuator::PyGetPara1(PyObject* self, PyObject* args, PyObjec
}
/* 6. getPara2 */
-char SCA_RandomActuator::GetPara2_doc[] =
+const char SCA_RandomActuator::GetPara2_doc[] =
"getPara2()\n"
"\tReturns the first parameter of the active distribution. Refer\n"
"\tto the documentation of the generator types for the meaning\n"
@@ -408,7 +410,7 @@ PyObject* SCA_RandomActuator::PyGetPara2(PyObject* self, PyObject* args, PyObjec
}
/* 8. getDistribution */
-char SCA_RandomActuator::GetDistribution_doc[] =
+const char SCA_RandomActuator::GetDistribution_doc[] =
"getDistribution()\n"
"\tReturns the type of the active distribution.\n";
PyObject* SCA_RandomActuator::PyGetDistribution(PyObject* self, PyObject* args, PyObject* kwds) {
@@ -416,7 +418,7 @@ PyObject* SCA_RandomActuator::PyGetDistribution(PyObject* self, PyObject* args,
}
/* 9. setProperty */
-char SCA_RandomActuator::SetProperty_doc[] =
+const char SCA_RandomActuator::SetProperty_doc[] =
"setProperty(name)\n"
"\t- name: string\n"
"\tSet the property to which the random value is assigned. If the \n"
@@ -429,17 +431,17 @@ PyObject* SCA_RandomActuator::PySetProperty(PyObject* self, PyObject* args, PyOb
CValue* prop = GetParent()->FindIdentifier(nameArg);
- if (prop) {
+ if (!prop->IsError()) {
m_propname = nameArg;
- prop->Release();
} else {
; /* not found ... */
}
+ prop->Release();
Py_Return;
}
/* 10. getProperty */
-char SCA_RandomActuator::GetProperty_doc[] =
+const char SCA_RandomActuator::GetProperty_doc[] =
"getProperty(name)\n"
"\tReturn the property to which the random value is assigned. If the \n"
"\tgenerator and property types do not match, the assignment is ignored.\n";
@@ -448,7 +450,7 @@ PyObject* SCA_RandomActuator::PyGetProperty(PyObject* self, PyObject* args, PyOb
}
/* 11. setBoolConst */
-char SCA_RandomActuator::SetBoolConst_doc[] =
+const char SCA_RandomActuator::SetBoolConst_doc[] =
"setBoolConst(value)\n"
"\t- value: 0 or 1\n"
"\tSet this generator to produce a constant boolean value.\n";
@@ -468,7 +470,7 @@ PyObject* SCA_RandomActuator::PySetBoolConst(PyObject* self,
Py_Return;
}
/* 12. setBoolUniform, */
-char SCA_RandomActuator::SetBoolUniform_doc[] =
+const char SCA_RandomActuator::SetBoolUniform_doc[] =
"setBoolUniform()\n"
"\tSet this generator to produce true and false, each with 50%% chance of occuring\n";
PyObject* SCA_RandomActuator::PySetBoolUniform(PyObject* self,
@@ -480,7 +482,7 @@ PyObject* SCA_RandomActuator::PySetBoolUniform(PyObject* self,
Py_Return;
}
/* 13. setBoolBernouilli, */
-char SCA_RandomActuator::SetBoolBernouilli_doc[] =
+const char SCA_RandomActuator::SetBoolBernouilli_doc[] =
"setBoolBernouilli(value)\n"
"\t- value: a float between 0 and 1\n"
"\tReturn false value * 100%% of the time.\n";
@@ -498,7 +500,7 @@ PyObject* SCA_RandomActuator::PySetBoolBernouilli(PyObject* self,
Py_Return;
}
/* 14. setIntConst,*/
-char SCA_RandomActuator::SetIntConst_doc[] =
+const char SCA_RandomActuator::SetIntConst_doc[] =
"setIntConst(value)\n"
"\t- value: integer\n"
"\tAlways return value\n";
@@ -516,7 +518,7 @@ PyObject* SCA_RandomActuator::PySetIntConst(PyObject* self,
Py_Return;
}
/* 15. setIntUniform,*/
-char SCA_RandomActuator::SetIntUniform_doc[] =
+const char SCA_RandomActuator::SetIntUniform_doc[] =
"setIntUniform(lower_bound, upper_bound)\n"
"\t- lower_bound: integer\n"
"\t- upper_bound: integer\n"
@@ -537,7 +539,7 @@ PyObject* SCA_RandomActuator::PySetIntUniform(PyObject* self,
Py_Return;
}
/* 16. setIntPoisson, */
-char SCA_RandomActuator::SetIntPoisson_doc[] =
+const char SCA_RandomActuator::SetIntPoisson_doc[] =
"setIntPoisson(value)\n"
"\t- value: float\n"
"\tReturn a Poisson-distributed number. This performs a series\n"
@@ -557,7 +559,7 @@ PyObject* SCA_RandomActuator::PySetIntPoisson(PyObject* self,
Py_Return;
}
/* 17. setFloatConst,*/
-char SCA_RandomActuator::SetFloatConst_doc[] =
+const char SCA_RandomActuator::SetFloatConst_doc[] =
"setFloatConst(value)\n"
"\t- value: float\n"
"\tAlways return value\n";
@@ -575,7 +577,7 @@ PyObject* SCA_RandomActuator::PySetFloatConst(PyObject* self,
Py_Return;
}
/* 18. setFloatUniform, */
-char SCA_RandomActuator::SetFloatUniform_doc[] =
+const char SCA_RandomActuator::SetFloatUniform_doc[] =
"setFloatUniform(lower_bound, upper_bound)\n"
"\t- lower_bound: float\n"
"\t- upper_bound: float\n"
@@ -596,7 +598,7 @@ PyObject* SCA_RandomActuator::PySetFloatUniform(PyObject* self,
Py_Return;
}
/* 19. setFloatNormal, */
-char SCA_RandomActuator::SetFloatNormal_doc[] =
+const char SCA_RandomActuator::SetFloatNormal_doc[] =
"setFloatNormal(mean, standard_deviation)\n"
"\t- mean: float\n"
"\t- standard_deviation: float\n"
@@ -617,7 +619,7 @@ PyObject* SCA_RandomActuator::PySetFloatNormal(PyObject* self,
Py_Return;
}
/* 20. setFloatNegativeExponential, */
-char SCA_RandomActuator::SetFloatNegativeExponential_doc[] =
+const char SCA_RandomActuator::SetFloatNegativeExponential_doc[] =
"setFloatNegativeExponential(half_life)\n"
"\t- half_life: float\n"
"\tReturn negative-exponentially distributed numbers. The half-life 'time'\n"
diff --git a/source/gameengine/GameLogic/SCA_RandomEventManager.cpp b/source/gameengine/GameLogic/SCA_RandomEventManager.cpp
index 02020a52a17..156478d866d 100644
--- a/source/gameengine/GameLogic/SCA_RandomEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomEventManager.cpp
@@ -50,16 +50,9 @@ SCA_RandomEventManager::SCA_RandomEventManager(class SCA_LogicManager* logicmgr)
void SCA_RandomEventManager::NextFrame()
{
- for (vector<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
+ for (set<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
{
- SCA_ISensor *sensor = *i;
- sensor->Activate(m_logicmgr, NULL);
+ (*i)->Activate(m_logicmgr, NULL);
}
}
-
-
-void SCA_RandomEventManager::RegisterSensor(SCA_ISensor* sensor)
-{
- m_sensors.push_back(sensor);
-};
diff --git a/source/gameengine/GameLogic/SCA_RandomEventManager.h b/source/gameengine/GameLogic/SCA_RandomEventManager.h
index 8c75ef665fa..79138c23c62 100644
--- a/source/gameengine/GameLogic/SCA_RandomEventManager.h
+++ b/source/gameengine/GameLogic/SCA_RandomEventManager.h
@@ -45,7 +45,6 @@ public:
SCA_RandomEventManager(class SCA_LogicManager* logicmgr);
virtual void NextFrame();
- virtual void RegisterSensor(SCA_ISensor* sensor);
};
#endif //__KX_RANDOMEVENTMGR
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
index 540a5865537..202fd6382e6 100644
--- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
@@ -50,12 +50,9 @@ SCA_RandomSensor::SCA_RandomSensor(SCA_EventManager* eventmgr,
PyTypeObject* T)
: SCA_ISensor(gameobj,eventmgr, T)
{
- m_iteration = 0;
- m_lastdraw = false;
-
+ // m_basegenerator is never deleted => memory leak
m_basegenerator = new SCA_RandomNumberGenerator(startseed);
- m_currentDraw = m_basegenerator->Draw();
- RegisterToManager();
+ Init();
}
@@ -65,11 +62,19 @@ SCA_RandomSensor::~SCA_RandomSensor()
/* Nothing to be done here. */
}
+void SCA_RandomSensor::Init()
+{
+ m_iteration = 0;
+ m_interval = 0;
+ m_lastdraw = false;
+ m_currentDraw = m_basegenerator->Draw();
+}
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);
@@ -95,20 +100,25 @@ bool SCA_RandomSensor::Evaluate(CValue* event)
/* this is a reasonable way of generating bools. Check Knuth. */
/* Furthermore, we only draw each <delay>-eth frame. */
- bool drawResult = false;
-
- if (m_iteration > 31) {
- m_currentDraw = m_basegenerator->Draw();
- drawResult = (m_currentDraw & 0x1) == 0;
- m_iteration = 1;
- } else {
- drawResult = ((m_currentDraw >> m_iteration) & 0x1) == 0;
- m_iteration++;
+ bool evaluateResult = false;
+
+ if (++m_interval > m_pulse_frequency) {
+ bool drawResult = false;
+ m_interval = 0;
+ if (m_iteration > 31) {
+ m_currentDraw = m_basegenerator->Draw();
+ drawResult = (m_currentDraw & 0x1) == 0;
+ m_iteration = 1;
+ } else {
+ drawResult = ((m_currentDraw >> m_iteration) & 0x1) == 0;
+ m_iteration++;
+ }
+ evaluateResult = drawResult != m_lastdraw;
+ m_lastdraw = drawResult;
}
/* now pass this result to some controller */
- m_lastdraw = drawResult;
- return drawResult;
+ return evaluateResult;
}
/* ------------------------------------------------------------------------- */
@@ -144,9 +154,9 @@ PyParentObject SCA_RandomSensor::Parents[] = {
};
PyMethodDef SCA_RandomSensor::Methods[] = {
- {"setSeed", (PyCFunction) SCA_RandomSensor::sPySetSeed, METH_VARARGS, SetSeed_doc},
- {"getSeed", (PyCFunction) SCA_RandomSensor::sPyGetSeed, METH_VARARGS, GetSeed_doc},
- {"getLastDraw", (PyCFunction) SCA_RandomSensor::sPyGetLastDraw, METH_VARARGS, GetLastDraw_doc},
+ {"setSeed", (PyCFunction) SCA_RandomSensor::sPySetSeed, METH_VARARGS, (PY_METHODCHAR)SetSeed_doc},
+ {"getSeed", (PyCFunction) SCA_RandomSensor::sPyGetSeed, METH_VARARGS, (PY_METHODCHAR)GetSeed_doc},
+ {"getLastDraw", (PyCFunction) SCA_RandomSensor::sPyGetLastDraw, METH_VARARGS, (PY_METHODCHAR)GetLastDraw_doc},
{NULL,NULL} //Sentinel
};
@@ -155,7 +165,7 @@ PyObject* SCA_RandomSensor::_getattr(const STR_String& attr) {
}
/* 1. setSeed */
-char SCA_RandomSensor::SetSeed_doc[] =
+const char SCA_RandomSensor::SetSeed_doc[] =
"setSeed(seed)\n"
"\t- seed: integer\n"
"\tSet the initial seed of the generator. Equal seeds produce\n"
@@ -173,7 +183,7 @@ PyObject* SCA_RandomSensor::PySetSeed(PyObject* self, PyObject* args, PyObject*
}
/* 2. getSeed */
-char SCA_RandomSensor::GetSeed_doc[] =
+const char SCA_RandomSensor::GetSeed_doc[] =
"getSeed()\n"
"\tReturns the initial seed of the generator. Equal seeds produce\n"
"\tequal series.\n";
@@ -182,7 +192,7 @@ PyObject* SCA_RandomSensor::PyGetSeed(PyObject* self, PyObject* args, PyObject*
}
/* 3. getLastDraw */
-char SCA_RandomSensor::GetLastDraw_doc[] =
+const char SCA_RandomSensor::GetLastDraw_doc[] =
"getLastDraw()\n"
"\tReturn the last value that was drawn.\n";
PyObject* SCA_RandomSensor::PyGetLastDraw(PyObject* self, PyObject* args, PyObject* kwds) {
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h
index 729df9b2a62..d29bfb6837a 100644
--- a/source/gameengine/GameLogic/SCA_RandomSensor.h
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.h
@@ -42,6 +42,7 @@ class SCA_RandomSensor : public SCA_ISensor
unsigned int m_currentDraw;
int m_iteration;
+ int m_interval;
SCA_RandomNumberGenerator *m_basegenerator;
bool m_lastdraw;
public:
@@ -53,6 +54,7 @@ public:
virtual CValue* GetReplica();
virtual bool Evaluate(CValue* event);
virtual bool IsPositiveTrigger();
+ virtual void Init();
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
diff --git a/source/gameengine/GameLogic/SCA_TimeEventManager.cpp b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp
index 643f1247a52..b7fadd3d62c 100644
--- a/source/gameengine/GameLogic/SCA_TimeEventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp
@@ -65,6 +65,11 @@ void SCA_TimeEventManager::RegisterSensor(SCA_ISensor* sensor)
// not yet
}
+void SCA_TimeEventManager::RemoveSensor(SCA_ISensor* sensor)
+{
+ // empty
+}
+
void SCA_TimeEventManager::NextFrame(double curtime, double fixedtime)
diff --git a/source/gameengine/GameLogic/SCA_TimeEventManager.h b/source/gameengine/GameLogic/SCA_TimeEventManager.h
index 2fd39661a2d..bd57e12eb44 100644
--- a/source/gameengine/GameLogic/SCA_TimeEventManager.h
+++ b/source/gameengine/GameLogic/SCA_TimeEventManager.h
@@ -45,6 +45,7 @@ public:
virtual void NextFrame(double curtime, double fixedtime);
virtual void RegisterSensor(class SCA_ISensor* sensor);
+ virtual void RemoveSensor(class SCA_ISensor* sensor);
void AddTimeProperty(CValue* timeval);
void RemoveTimeProperty(CValue* timeval);
};
diff --git a/source/gameengine/GameLogic/SCA_XNORController.cpp b/source/gameengine/GameLogic/SCA_XNORController.cpp
new file mode 100644
index 00000000000..3ef7c07fe0a
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_XNORController.cpp
@@ -0,0 +1,148 @@
+/**
+ * 'Xnor' together all inputs
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "SCA_XNORController.h"
+#include "SCA_ISensor.h"
+#include "SCA_LogicManager.h"
+#include "BoolValue.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_XNORController::SCA_XNORController(SCA_IObject* gameobj,
+ PyTypeObject* T)
+ :
+ SCA_IController(gameobj,T)
+{
+}
+
+
+
+SCA_XNORController::~SCA_XNORController()
+{
+}
+
+
+
+void SCA_XNORController::Trigger(SCA_LogicManager* logicmgr)
+{
+
+ bool sensorresult = true;
+
+ for (vector<SCA_ISensor*>::const_iterator is=m_linkedsensors.begin();
+ !(is==m_linkedsensors.end());is++)
+ {
+ SCA_ISensor* sensor = *is;
+ if (sensor->IsPositiveTrigger())
+ {
+ if (sensorresult == false)
+ {
+ sensorresult = true;
+ break;
+ }
+ sensorresult = false;
+ }
+ }
+
+ 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);
+ }
+
+ // 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();
+
+}
+
+
+
+CValue* SCA_XNORController::GetReplica()
+{
+ CValue* replica = new SCA_XNORController(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_XNORController::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_XNORController",
+ sizeof(SCA_XNORController),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_XNORController::Parents[] = {
+ &SCA_XNORController::Type,
+ &SCA_IController::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_XNORController::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_XNORController::_getattr(const STR_String& attr) {
+ _getattr_up(SCA_IController);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_XNORController.h b/source/gameengine/GameLogic/SCA_XNORController.h
new file mode 100644
index 00000000000..4b1eaee95d8
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_XNORController.h
@@ -0,0 +1,56 @@
+/**
+ * SCA_XNORController.h
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_XNORCONTROLLER
+#define __KX_XNORCONTROLLER
+
+#include "SCA_IController.h"
+
+class SCA_XNORController : public SCA_IController
+{
+ Py_Header;
+ //virtual void Trigger(class SCA_LogicManager* logicmgr);
+public:
+ SCA_XNORController(SCA_IObject* gameobj,PyTypeObject* T=&Type);
+ virtual ~SCA_XNORController();
+ virtual CValue* GetReplica();
+ virtual void Trigger(SCA_LogicManager* logicmgr);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(const STR_String& attr);
+
+};
+
+#endif //__KX_XNORCONTROLLER
+
diff --git a/source/gameengine/GameLogic/SCA_XORController.cpp b/source/gameengine/GameLogic/SCA_XORController.cpp
new file mode 100644
index 00000000000..6499c62f5f2
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_XORController.cpp
@@ -0,0 +1,148 @@
+/**
+ * 'Xor' together all inputs
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "SCA_XORController.h"
+#include "SCA_ISensor.h"
+#include "SCA_LogicManager.h"
+#include "BoolValue.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+SCA_XORController::SCA_XORController(SCA_IObject* gameobj,
+ PyTypeObject* T)
+ :
+ SCA_IController(gameobj,T)
+{
+}
+
+
+
+SCA_XORController::~SCA_XORController()
+{
+}
+
+
+
+void SCA_XORController::Trigger(SCA_LogicManager* logicmgr)
+{
+
+ bool sensorresult = false;
+
+ for (vector<SCA_ISensor*>::const_iterator is=m_linkedsensors.begin();
+ !(is==m_linkedsensors.end());is++)
+ {
+ SCA_ISensor* sensor = *is;
+ if (sensor->IsPositiveTrigger())
+ {
+ if (sensorresult == true)
+ {
+ sensorresult = false;
+ break;
+ }
+ sensorresult = true;
+ }
+ }
+
+ 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);
+ }
+
+ // 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();
+
+}
+
+
+
+CValue* SCA_XORController::GetReplica()
+{
+ CValue* replica = new SCA_XORController(*this);
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_XORController::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_XORController",
+ sizeof(SCA_XORController),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject SCA_XORController::Parents[] = {
+ &SCA_XORController::Type,
+ &SCA_IController::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef SCA_XORController::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_XORController::_getattr(const STR_String& attr) {
+ _getattr_up(SCA_IController);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_XORController.h b/source/gameengine/GameLogic/SCA_XORController.h
new file mode 100644
index 00000000000..f50cd33c125
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_XORController.h
@@ -0,0 +1,56 @@
+/**
+ * SCA_XORController.h
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __KX_XORCONTROLLER
+#define __KX_XORCONTROLLER
+
+#include "SCA_IController.h"
+
+class SCA_XORController : public SCA_IController
+{
+ Py_Header;
+ //virtual void Trigger(class SCA_LogicManager* logicmgr);
+public:
+ SCA_XORController(SCA_IObject* gameobj,PyTypeObject* T=&Type);
+ virtual ~SCA_XORController();
+ virtual CValue* GetReplica();
+ virtual void Trigger(SCA_LogicManager* logicmgr);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(const STR_String& attr);
+
+};
+
+#endif //__KX_XORCONTROLLER
+
diff --git a/source/gameengine/GameLogic/SConscript b/source/gameengine/GameLogic/SConscript
index 38064733b73..ee0e638af60 100644
--- a/source/gameengine/GameLogic/SConscript
+++ b/source/gameengine/GameLogic/SConscript
@@ -5,8 +5,16 @@ 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 += ' ' + env['BF_PYTHON_INC']
-incs += ' ' + env['BF_SDL_INC']
-env.BlenderLib ( 'bf_logic', sources, Split(incs), [], libtype=['game','player'], priority=[30, 100] )
+
+defs = ''
+
+if env['WITH_BF_SDL']:
+ incs += ' ' + env['BF_SDL_INC']
+else:
+ defs += ' DISABLE_SDL'
+
+env.BlenderLib ( 'bf_logic', sources, Split(incs), Split(defs), libtype=['game','player'], priority=[30, 100] )