BGE performance, 4th round: logic
authorBenoit Bolsee <benoit.bolsee@online.be>
Sun, 10 May 2009 20:53:58 +0000 (20:53 +0000)
committerBenoit Bolsee <benoit.bolsee@online.be>
Sun, 10 May 2009 20:53:58 +0000 (20:53 +0000)
This commit extends the technique of dynamic linked list to the logic
system to eliminate as much as possible temporaries, map lookup or
full scan. The logic engine is now free of memory allocation, which is
an important stability factor.

The overhead of the logic system is reduced by a factor between 3 and 6
depending on the logic setup. This is the speed-up you can expect on
a logic setup using simple bricks. Heavy bricks like python controllers
and ray sensors will still take about the same time to execute so the
speed up will be less important.

The core of the logic engine has been much reworked but the functionality
is still the same except for one thing: the priority system on the
execution of controllers. The exact same remark applies to actuators but
I'll explain for controllers only:

Previously, it was possible, with the "executePriority" attribute to set
a controller to run before any other controllers in the game. Other than
that, the sequential execution of controllers, as defined in Blender was
guaranteed by default.

With the new system, the sequential execution of controllers is still
guaranteed but only within the controllers of one object. the user can
no longer set a controller to run before any other controllers in the
game. The "executePriority" attribute controls the execution of controllers
within one object. The priority is a small number starting from 0 for the
first controller and incrementing for each controller.

If this missing feature is a must, a special method can be implemented
to set a controller to run before all other controllers.

Other improvements:
- Systematic use of reference in parameter passing to avoid unnecessary data copy
- Use pre increment in iterator instead of post increment to avoid temporary allocation
- Use const char* instead of STR_String whenever possible to avoid temporary allocation
- Fix reference counting bugs (memory leak)
- Fix a crash in certain cases of state switching and object deletion
- Minor speed up in property sensor
- Removal of objects during the game is a lot faster

133 files changed:
projectfiles_vc9/gameengine/expression/EXP_expressions.vcproj
projectfiles_vc9/gameengine/gamelogic/SCA_GameLogic.vcproj
projectfiles_vc9/gameengine/ketsji/KX_ketsji.vcproj
projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj
source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
source/gameengine/Converter/BL_ActionActuator.cpp
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Converter/BL_ShapeActionActuator.cpp
source/gameengine/Converter/KX_ConvertActuators.cpp
source/gameengine/Converter/KX_ConvertActuators.h
source/gameengine/Converter/KX_ConvertControllers.cpp
source/gameengine/Converter/KX_ConvertControllers.h
source/gameengine/Converter/KX_ConvertSensors.cpp
source/gameengine/Converter/KX_ConvertSensors.h
source/gameengine/Expressions/BoolValue.cpp
source/gameengine/Expressions/BoolValue.h
source/gameengine/Expressions/CMakeLists.txt
source/gameengine/Expressions/ErrorValue.cpp
source/gameengine/Expressions/ErrorValue.h
source/gameengine/Expressions/FloatValue.cpp
source/gameengine/Expressions/FloatValue.h
source/gameengine/Expressions/IfExpr.cpp
source/gameengine/Expressions/InputParser.cpp
source/gameengine/Expressions/InputParser.h
source/gameengine/Expressions/IntValue.cpp
source/gameengine/Expressions/IntValue.h
source/gameengine/Expressions/ListValue.cpp
source/gameengine/Expressions/ListValue.h
source/gameengine/Expressions/Makefile
source/gameengine/Expressions/PyObjectPlus.cpp
source/gameengine/Expressions/PyObjectPlus.h
source/gameengine/Expressions/SConscript
source/gameengine/Expressions/StringValue.cpp
source/gameengine/Expressions/StringValue.h
source/gameengine/Expressions/Value.cpp
source/gameengine/Expressions/Value.h
source/gameengine/Expressions/VectorValue.cpp
source/gameengine/Expressions/VectorValue.h
source/gameengine/GameLogic/CMakeLists.txt
source/gameengine/GameLogic/Makefile
source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
source/gameengine/GameLogic/SCA_2DFilterActuator.h
source/gameengine/GameLogic/SCA_ANDController.cpp
source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp
source/gameengine/GameLogic/SCA_ActuatorSensor.cpp
source/gameengine/GameLogic/SCA_ActuatorSensor.h
source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
source/gameengine/GameLogic/SCA_AlwaysSensor.h
source/gameengine/GameLogic/SCA_DelaySensor.cpp
source/gameengine/GameLogic/SCA_DelaySensor.h
source/gameengine/GameLogic/SCA_EventManager.cpp
source/gameengine/GameLogic/SCA_EventManager.h
source/gameengine/GameLogic/SCA_ExpressionController.cpp
source/gameengine/GameLogic/SCA_IActuator.cpp
source/gameengine/GameLogic/SCA_IActuator.h
source/gameengine/GameLogic/SCA_IController.cpp
source/gameengine/GameLogic/SCA_IController.h
source/gameengine/GameLogic/SCA_ILogicBrick.cpp
source/gameengine/GameLogic/SCA_ILogicBrick.h
source/gameengine/GameLogic/SCA_IObject.cpp
source/gameengine/GameLogic/SCA_IObject.h
source/gameengine/GameLogic/SCA_IScene.cpp
source/gameengine/GameLogic/SCA_IScene.h
source/gameengine/GameLogic/SCA_ISensor.cpp
source/gameengine/GameLogic/SCA_ISensor.h
source/gameengine/GameLogic/SCA_JoystickManager.cpp
source/gameengine/GameLogic/SCA_JoystickSensor.cpp
source/gameengine/GameLogic/SCA_JoystickSensor.h
source/gameengine/GameLogic/SCA_KeyboardManager.cpp
source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
source/gameengine/GameLogic/SCA_KeyboardSensor.h
source/gameengine/GameLogic/SCA_LogicManager.cpp
source/gameengine/GameLogic/SCA_LogicManager.h
source/gameengine/GameLogic/SCA_MouseManager.cpp
source/gameengine/GameLogic/SCA_MouseSensor.cpp
source/gameengine/GameLogic/SCA_MouseSensor.h
source/gameengine/GameLogic/SCA_NANDController.cpp
source/gameengine/GameLogic/SCA_NORController.cpp
source/gameengine/GameLogic/SCA_ORController.cpp
source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
source/gameengine/GameLogic/SCA_PropertySensor.cpp
source/gameengine/GameLogic/SCA_PropertySensor.h
source/gameengine/GameLogic/SCA_PythonController.cpp
source/gameengine/GameLogic/SCA_RandomEventManager.cpp
source/gameengine/GameLogic/SCA_RandomSensor.cpp
source/gameengine/GameLogic/SCA_RandomSensor.h
source/gameengine/GameLogic/SCA_TimeEventManager.cpp
source/gameengine/GameLogic/SCA_XNORController.cpp
source/gameengine/GameLogic/SCA_XORController.cpp
source/gameengine/GameLogic/SConscript
source/gameengine/Ketsji/KXNetwork/CMakeLists.txt
source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp
source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
source/gameengine/Ketsji/KXNetwork/Makefile
source/gameengine/Ketsji/KXNetwork/SConscript
source/gameengine/Ketsji/KX_BlenderMaterial.cpp
source/gameengine/Ketsji/KX_CameraActuator.cpp
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_IpoActuator.cpp
source/gameengine/Ketsji/KX_MeshProxy.cpp
source/gameengine/Ketsji/KX_MeshProxy.h
source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
source/gameengine/Ketsji/KX_MouseFocusSensor.h
source/gameengine/Ketsji/KX_NearSensor.cpp
source/gameengine/Ketsji/KX_NearSensor.h
source/gameengine/Ketsji/KX_ParentActuator.cpp
source/gameengine/Ketsji/KX_PolyProxy.cpp
source/gameengine/Ketsji/KX_PolyProxy.h
source/gameengine/Ketsji/KX_PythonSeq.cpp
source/gameengine/Ketsji/KX_RayEventManager.cpp
source/gameengine/Ketsji/KX_RaySensor.cpp
source/gameengine/Ketsji/KX_RaySensor.h
source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_Scene.h
source/gameengine/Ketsji/KX_SoundActuator.cpp
source/gameengine/Ketsji/KX_SoundActuator.h
source/gameengine/Ketsji/KX_TouchEventManager.cpp
source/gameengine/Ketsji/KX_TouchSensor.cpp
source/gameengine/Ketsji/KX_TouchSensor.h
source/gameengine/Ketsji/KX_TrackToActuator.cpp
source/gameengine/Ketsji/KX_VertexProxy.cpp
source/gameengine/Ketsji/KX_VertexProxy.h
source/gameengine/Network/NG_NetworkScene.cpp
source/gameengine/Rasterizer/RAS_BucketManager.cpp
source/gameengine/Rasterizer/RAS_MeshObject.cpp
source/gameengine/Rasterizer/RAS_MeshObject.h
source/gameengine/SceneGraph/SG_DList.h
source/gameengine/SceneGraph/SG_QList.h

index 436a007..a8b94c3 100644 (file)
@@ -4,6 +4,7 @@
        Version="9,00"\r
        Name="EXP_expressions"\r
        ProjectGUID="{EADC3C5A-6C51-4F03-8038-1553E7D7F740}"\r
+       RootNamespace="EXP_expressions"\r
        TargetFrameworkVersion="131072"\r
        >\r
        <Platforms>\r
@@ -42,7 +43,7 @@
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna"\r
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\SceneGraph"\r
                                PreprocessorDefinitions="WIN32;_LIB;EXP_PYTHON_EMBEDDING;_DEBUG"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="1"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna"\r
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\SceneGraph"\r
                                PreprocessorDefinitions="WIN32,_LIB,EXP_PYTHON_EMBEDDING,_DEBUG"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="3"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna"\r
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\SceneGraph"\r
                                PreprocessorDefinitions="NDEBUG,WIN32,_LIB,EXP_PYTHON_EMBEDDING"\r
                                StringPooling="true"\r
                                RuntimeLibrary="2"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna"\r
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\SceneGraph"\r
                                PreprocessorDefinitions="NDEBUG,WIN32,_LIB,EXP_PYTHON_EMBEDDING"\r
                                StringPooling="true"\r
                                RuntimeLibrary="0"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna"\r
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\SceneGraph"\r
                                PreprocessorDefinitions="WIN32;_LIB;EXP_PYTHON_EMBEDDING;_DEBUG"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="1"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna"\r
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\SceneGraph"\r
                                PreprocessorDefinitions="NDEBUG,WIN32,_LIB,EXP_PYTHON_EMBEDDING"\r
                                StringPooling="true"\r
                                RuntimeLibrary="0"\r
index e350db5..e4d4182 100644 (file)
@@ -4,6 +4,7 @@
        Version="9,00"\r
        Name="SCA_GameLogic"\r
        ProjectGUID="{32CC75E2-EE85-45E6-8E3D-513F58464F43}"\r
+       RootNamespace="SCA_GameLogic"\r
        TargetFrameworkVersion="131072"\r
        >\r
        <Platforms>\r
@@ -42,7 +43,7 @@
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer;..\..\..\source\blender\makesdna"\r
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\Scenegraph"\r
                                PreprocessorDefinitions="WIN32;_LIB;EXP_PYTHON_EMBEDDING;_DEBUG"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="1"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer;..\..\..\source\blender\makesdna"\r
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\Scenegraph"\r
                                PreprocessorDefinitions="NDEBUG,WIN32,_LIB,EXP_PYTHON_EMBEDDING"\r
                                StringPooling="true"\r
                                RuntimeLibrary="0"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer;..\..\..\source\blender\makesdna"\r
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\Scenegraph"\r
                                PreprocessorDefinitions="NDEBUG,WIN32,_LIB,EXP_PYTHON_EMBEDDING"\r
                                StringPooling="true"\r
                                RuntimeLibrary="2"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer;..\..\..\source\blender\makesdna"\r
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\Scenegraph"\r
                                PreprocessorDefinitions="WIN32,_LIB,EXP_PYTHON_EMBEDDING,_DEBUG"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="3"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer;..\..\..\source\blender\makesdna"\r
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\Scenegraph"\r
                                PreprocessorDefinitions="WIN32;_LIB;EXP_PYTHON_EMBEDDING;_DEBUG"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="1"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer;..\..\..\source\blender\makesdna"\r
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer;..\..\..\source\blender\makesdna;..\..\..\source\gameengine\Scenegraph"\r
                                PreprocessorDefinitions="NDEBUG,WIN32,_LIB,EXP_PYTHON_EMBEDDING"\r
                                StringPooling="true"\r
                                RuntimeLibrary="0"\r
index 80c34be..fb812c0 100644 (file)
                                RelativePath="..\..\..\source\gameengine\Ketsji\KX_PythonInitTypes.cpp"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\..\source\gameengine\Ketsji\KX_PythonSeq.cpp"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\..\source\gameengine\Ketsji\KX_RayCast.cpp"\r
                                >\r
                                RelativePath="..\..\..\source\gameengine\Ketsji\KX_PythonInitTypes.h"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\..\source\gameengine\Ketsji\KX_PythonSeq.h"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\..\source\gameengine\Ketsji\KX_RayCast.h"\r
                                >\r
index a3f43b0..b6d3aa5 100644 (file)
@@ -4,6 +4,7 @@
        Version="9,00"\r
        Name="KX_network"\r
        ProjectGUID="{6E24BF09-9653-4166-A871-F65CC9E98A9B}"\r
+       RootNamespace="KX_network"\r
        TargetFrameworkVersion="131072"\r
        >\r
        <Platforms>\r
@@ -42,7 +43,7 @@
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\ketsji;..\..\..\..\source\gameengine\Network;..\..\..\..\source\gameengine\expressions;..\..\..\..\source\gameengine\GameLogic"\r
+                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\ketsji;..\..\..\..\source\gameengine\Network;..\..\..\..\source\gameengine\expressions;..\..\..\..\source\gameengine\GameLogic;..\..\..\..\source\gameengine\Scenegraph"\r
                                PreprocessorDefinitions="NDEBUG,WIN32,_LIB"\r
                                StringPooling="true"\r
                                RuntimeLibrary="0"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\ketsji;..\..\..\..\source\gameengine\Network;..\..\..\..\source\gameengine\expressions;..\..\..\..\source\gameengine\GameLogic"\r
+                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\ketsji;..\..\..\..\source\gameengine\Network;..\..\..\..\source\gameengine\expressions;..\..\..\..\source\gameengine\GameLogic;..\..\..\..\source\gameengine\Scenegraph"\r
                                PreprocessorDefinitions="WIN32,_LIB,_DEBUG"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="1"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\ketsji;..\..\..\..\source\gameengine\Network;..\..\..\..\source\gameengine\expressions;..\..\..\..\source\gameengine\GameLogic"\r
+                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\ketsji;..\..\..\..\source\gameengine\Network;..\..\..\..\source\gameengine\expressions;..\..\..\..\source\gameengine\GameLogic;..\..\..\..\source\gameengine\Scenegraph"\r
                                PreprocessorDefinitions="NDEBUG,WIN32,_LIB"\r
                                StringPooling="true"\r
                                RuntimeLibrary="2"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\ketsji;..\..\..\..\source\gameengine\Network;..\..\..\..\source\gameengine\expressions;..\..\..\..\source\gameengine\GameLogic"\r
+                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\ketsji;..\..\..\..\source\gameengine\Network;..\..\..\..\source\gameengine\expressions;..\..\..\..\source\gameengine\GameLogic;..\..\..\..\source\gameengine\Scenegraph"\r
                                PreprocessorDefinitions="WIN32,_LIB,_DEBUG"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="3"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\ketsji;..\..\..\..\source\gameengine\Network;..\..\..\..\source\gameengine\expressions;..\..\..\..\source\gameengine\GameLogic"\r
+                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\ketsji;..\..\..\..\source\gameengine\Network;..\..\..\..\source\gameengine\expressions;..\..\..\..\source\gameengine\GameLogic;..\..\..\..\source\gameengine\Scenegraph"\r
                                PreprocessorDefinitions="WIN32,_LIB,_DEBUG"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="1"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\ketsji;..\..\..\..\source\gameengine\Network;..\..\..\..\source\gameengine\expressions;..\..\..\..\source\gameengine\GameLogic"\r
+                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\ketsji;..\..\..\..\source\gameengine\Network;..\..\..\..\source\gameengine\expressions;..\..\..\..\source\gameengine\GameLogic;..\..\..\..\source\gameengine\Scenegraph"\r
                                PreprocessorDefinitions="NDEBUG,WIN32,_LIB"\r
                                StringPooling="true"\r
                                RuntimeLibrary="0"\r
index e393b6d..17d1bf6 100644 (file)
@@ -295,7 +295,7 @@ void KX_BlenderRenderTools::RenderText(
        RAS_IPolyMaterial* polymat,
        float v1[3], float v2[3], float v3[3], float v4[3], int glattrib)
 {
-       STR_String mytext = ((CValue*)m_clientobject)->GetPropertyText("Text");
+       const STR_String& mytext = ((CValue*)m_clientobject)->GetPropertyText("Text");
        
        const unsigned int flag = polymat->GetFlag();
        struct MTFace* tface = 0;
index 646a65d..145cb1f 100644 (file)
@@ -156,16 +156,9 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
        // maybe there are events for us in the queue !
        if (frame)
        {
-               for (vector<CValue*>::iterator i=m_events.begin(); !(i==m_events.end());i++)
-               {
-                       if ((*i)->GetNumber() == 0.0f)
-                               bNegativeEvent = true;
-                       else
-                               bPositiveEvent= true;
-                       (*i)->Release();
-               
-               }
-               m_events.clear();
+               bNegativeEvent = m_negevent;
+               bPositiveEvent = m_posevent;
+               RemoveAllEvents();
                
                if (bPositiveEvent)
                        m_flag |= ACT_FLAG_ACTIVE;
index 1d2b275..7d0bbbe 100644 (file)
@@ -2610,8 +2610,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
        templist->Release();
        sumolist->Release();    
 
-       int executePriority=0; /* incremented by converter routines */
-       
        // convert global sound stuff
 
        /* XXX, glob is the very very wrong place for this
@@ -2642,7 +2640,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
                struct Object* blenderobj = converter->FindBlenderObject(gameobj);
                int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
                bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
-               BL_ConvertActuators(maggie->name, blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,executePriority, layerMask,isInActiveLayer,rendertools,converter);
+               BL_ConvertActuators(maggie->name, blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,layerMask,isInActiveLayer,rendertools,converter);
        }
        for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
        {
@@ -2650,7 +2648,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
                struct Object* blenderobj = converter->FindBlenderObject(gameobj);
                int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
                bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
-               BL_ConvertControllers(blenderobj,gameobj,logicmgr,pythondictionary,executePriority,layerMask,isInActiveLayer,converter);
+               BL_ConvertControllers(blenderobj,gameobj,logicmgr,pythondictionary,layerMask,isInActiveLayer,converter);
        }
        for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
        {
@@ -2658,7 +2656,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
                struct Object* blenderobj = converter->FindBlenderObject(gameobj);
                int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
                bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
-               BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,keydev,executePriority,layerMask,isInActiveLayer,canvas,converter);
+               BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,keydev,layerMask,isInActiveLayer,canvas,converter);
                // set the init state to all objects
                gameobj->SetInitState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state);
        }
index 5fea568..29bbe9b 100644 (file)
@@ -160,16 +160,9 @@ bool BL_ShapeActionActuator::Update(double curtime, bool frame)
        // maybe there are events for us in the queue !
        if (frame)
        {
-               for (vector<CValue*>::iterator i=m_events.begin(); !(i==m_events.end());i++)
-               {
-                       if ((*i)->GetNumber() == 0.0f)
-                               bNegativeEvent = true;
-                       else
-                               bPositiveEvent= true;
-                       (*i)->Release();
-               
-               }
-               m_events.clear();
+               bNegativeEvent = m_negevent;
+               bPositiveEvent = m_posevent;
+               RemoveAllEvents();
                
                if (bPositiveEvent)
                        m_flag |= ACT_FLAG_ACTIVE;
index 73d35a7..76b8540 100644 (file)
@@ -105,7 +105,6 @@ void BL_ConvertActuators(char* maggiename,
                                                 SCA_LogicManager* logicmgr,
                                                 KX_Scene* scene,
                                                 KX_KetsjiEngine* ketsjiEngine,
-                                                int & executePriority, 
                                                 int activeLayerBitInfo,
                                                 bool isInActiveLayer,
                                                 RAS_IRenderTools* rendertools,
@@ -114,11 +113,20 @@ void BL_ConvertActuators(char* maggiename,
 {
        
        int uniqueint = 0;
+       int actcount = 0;
+       int executePriority = 0;
        bActuator* bact = (bActuator*) blenderobject->actuators.first;
+       while (bact)
+       {
+               actcount++;
+               bact = bact->next;
+       }
+       gameobj->ReserveActuator(actcount);
+       bact = (bActuator*) blenderobject->actuators.first;
        while(bact)
        {
                STR_String uniquename = bact->name;
-               STR_String objectname = gameobj->GetName();
+               STR_String& objectname = gameobj->GetName();
                
                SCA_IActuator* baseact = NULL;
                switch (bact->type)
@@ -1144,7 +1152,7 @@ void BL_ConvertActuators(char* maggiename,
                        CIntValue* uniqueval = new CIntValue(uniqueint);
                        uniquename += uniqueval->GetText();
                        uniqueval->Release();
-                       baseact->SetName(STR_String(bact->name));
+                       baseact->SetName(bact->name);
                        //gameobj->SetProperty(uniquename,baseact);
                        gameobj->AddActuator(baseact);
                        
index 03ea0db..e38a9c7 100644 (file)
@@ -35,7 +35,6 @@ void BL_ConvertActuators(char* maggiename,
         class SCA_LogicManager* logicmgr,
         class KX_Scene* scene,
         class KX_KetsjiEngine* ketsjiEngine,
-        int & executePriority,
         int activeLayerBitInfo,
         bool isInActiveLayer,
         class RAS_IRenderTools* rendertools, 
index 856f3f7..9b0e27b 100644 (file)
@@ -76,6 +76,7 @@ LinkControllerToActuators(
        // Iterate through the actuators of the game blender
        // controller and find the corresponding ketsji actuator.
 
+       game_controller->ReserveActuator(bcontr->totlinks);
        for (int i=0;i<bcontr->totlinks;i++)
        {
                bActuator* bact = (bActuator*) bcontr->links[i];
@@ -92,14 +93,22 @@ void BL_ConvertControllers(
        class KX_GameObject* gameobj,
        SCA_LogicManager* logicmgr, 
        PyObject* pythondictionary,
-       int &executePriority,
        int activeLayerBitInfo,
        bool isInActiveLayer,
        KX_BlenderSceneConverter* converter
 ) {
        int uniqueint=0;
+       int count = 0;
+       int executePriority=0;
        bController* bcontr = (bController*)blenderobject->controllers.first;
        while (bcontr)
+       {
+               bcontr = bcontr->next;
+               count++;
+       }
+       gameobj->ReserveController(count);
+       bcontr = (bController*)blenderobject->controllers.first;
+       while (bcontr)
        {
                SCA_IController* gamecontroller = NULL;
                switch(bcontr->type)
@@ -107,37 +116,31 @@ void BL_ConvertControllers(
                        case CONT_LOGIC_AND:
                        {
                                gamecontroller = new SCA_ANDController(gameobj);
-                               LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
                                break;
                        }
                        case CONT_LOGIC_OR:
                        {
                                gamecontroller = new SCA_ORController(gameobj);
-                               LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
                                break;
                        }
                        case CONT_LOGIC_NAND:
                        {
                                gamecontroller = new SCA_NANDController(gameobj);
-                               LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
                                break;
                        }
                        case CONT_LOGIC_NOR:
                        {
                                gamecontroller = new SCA_NORController(gameobj);
-                               LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
                                break;
                        }
                        case CONT_LOGIC_XOR:
                        {
                                gamecontroller = new SCA_XORController(gameobj);
-                               LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
                                break;
                        }
                        case CONT_LOGIC_XNOR:
                        {
                                gamecontroller = new SCA_XNORController(gameobj);
-                               LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
                                break;
                        }
                        case CONT_EXPRESSION:
@@ -147,8 +150,6 @@ void BL_ConvertControllers(
                                if (expressiontext.Length() > 0)
                                {
                                        gamecontroller = new SCA_ExpressionController(gameobj,expressiontext);
-                                       LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
-
                                }
                                break;
                        }
@@ -186,7 +187,6 @@ void BL_ConvertControllers(
                                        pyctrl->SetDebug(true);
                                }
                                
-                               LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
                                break;
                        }
                        default:
@@ -197,6 +197,7 @@ void BL_ConvertControllers(
 
                if (gamecontroller)
                {
+                       LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
                        gamecontroller->SetExecutePriority(executePriority++);
                        gamecontroller->SetState(bcontr->state_mask);
                        STR_String uniquename = bcontr->name;
index 3e8a87f..d340778 100644 (file)
@@ -36,7 +36,6 @@ void BL_ConvertControllers(
        class KX_GameObject* gameobj,
        class SCA_LogicManager* logicmgr, 
        PyObject* pythondictionary,
-       int & executePriority,
        int activeLayerBitInfo,
        bool isInActiveLayer, 
        class KX_BlenderSceneConverter* converter
index af57094..07b0aba 100644 (file)
@@ -94,161 +94,166 @@ void BL_ConvertSensors(struct Object* blenderobject,
                                           KX_Scene* kxscene,
                                           KX_KetsjiEngine* kxengine,
                                           SCA_IInputDevice* keydev,
-                                          int & executePriority,
                                           int activeLayerBitInfo,
                                           bool isInActiveLayer,
                                           RAS_ICanvas* canvas,
                                           KX_BlenderSceneConverter* converter
                                           )
 {
+       static bool reverseTableConverted = false;      
        
-       
-       
-       /* The reverse table. In order to not confuse ourselves, we      */
-       /* immediately convert all events that come in to KX codes.      */
-       gReverseKeyTranslateTable[LEFTMOUSE                     ] =     SCA_IInputDevice::KX_LEFTMOUSE;
-       gReverseKeyTranslateTable[MIDDLEMOUSE           ] =     SCA_IInputDevice::KX_MIDDLEMOUSE;
-       gReverseKeyTranslateTable[RIGHTMOUSE            ] =     SCA_IInputDevice::KX_RIGHTMOUSE;
-       gReverseKeyTranslateTable[WHEELUPMOUSE          ] =     SCA_IInputDevice::KX_WHEELUPMOUSE;
-       gReverseKeyTranslateTable[WHEELDOWNMOUSE        ] =     SCA_IInputDevice::KX_WHEELDOWNMOUSE;
-       gReverseKeyTranslateTable[MOUSEX                        ] = SCA_IInputDevice::KX_MOUSEX;
-       gReverseKeyTranslateTable[MOUSEY                        ] =     SCA_IInputDevice::KX_MOUSEY;
-       
-       // TIMERS                                                                                                  
-       
-       gReverseKeyTranslateTable[TIMER0                        ] = SCA_IInputDevice::KX_TIMER0;                  
-       gReverseKeyTranslateTable[TIMER1                        ] = SCA_IInputDevice::KX_TIMER1;                  
-       gReverseKeyTranslateTable[TIMER2                        ] = SCA_IInputDevice::KX_TIMER2;                  
-       gReverseKeyTranslateTable[TIMER3                        ] = SCA_IInputDevice::KX_TIMER3;                  
-       
-       // SYSTEM                                                                                                  
-       
-       gReverseKeyTranslateTable[KEYBD                         ] = SCA_IInputDevice::KX_KEYBD;                  
-       gReverseKeyTranslateTable[RAWKEYBD                      ] = SCA_IInputDevice::KX_RAWKEYBD;                  
-       gReverseKeyTranslateTable[REDRAW                        ] = SCA_IInputDevice::KX_REDRAW;                  
-       gReverseKeyTranslateTable[INPUTCHANGE           ] = SCA_IInputDevice::KX_INPUTCHANGE;                  
-       gReverseKeyTranslateTable[QFULL                         ] = SCA_IInputDevice::KX_QFULL;                  
-       gReverseKeyTranslateTable[WINFREEZE                     ] = SCA_IInputDevice::KX_WINFREEZE;                  
-       gReverseKeyTranslateTable[WINTHAW                       ] = SCA_IInputDevice::KX_WINTHAW;                  
-       gReverseKeyTranslateTable[WINCLOSE                      ] = SCA_IInputDevice::KX_WINCLOSE;                  
-       gReverseKeyTranslateTable[WINQUIT                       ] = SCA_IInputDevice::KX_WINQUIT;                  
-       gReverseKeyTranslateTable[Q_FIRSTTIME           ] = SCA_IInputDevice::KX_Q_FIRSTTIME;                  
-       
-       // standard keyboard                                                                                       
-       
-       gReverseKeyTranslateTable[AKEY                          ] = SCA_IInputDevice::KX_AKEY;                  
-       gReverseKeyTranslateTable[BKEY                          ] = SCA_IInputDevice::KX_BKEY;                  
-       gReverseKeyTranslateTable[CKEY                          ] = SCA_IInputDevice::KX_CKEY;                  
-       gReverseKeyTranslateTable[DKEY                          ] = SCA_IInputDevice::KX_DKEY;                  
-       gReverseKeyTranslateTable[EKEY                          ] = SCA_IInputDevice::KX_EKEY;                  
-       gReverseKeyTranslateTable[FKEY                          ] = SCA_IInputDevice::KX_FKEY;                  
-       gReverseKeyTranslateTable[GKEY                          ] = SCA_IInputDevice::KX_GKEY;                  
-       gReverseKeyTranslateTable[HKEY                          ] = SCA_IInputDevice::KX_HKEY;                  
-       gReverseKeyTranslateTable[IKEY                          ] = SCA_IInputDevice::KX_IKEY;                  
-       gReverseKeyTranslateTable[JKEY                          ] = SCA_IInputDevice::KX_JKEY;                  
-       gReverseKeyTranslateTable[KKEY                          ] = SCA_IInputDevice::KX_KKEY;                  
-       gReverseKeyTranslateTable[LKEY                          ] = SCA_IInputDevice::KX_LKEY;                  
-       gReverseKeyTranslateTable[MKEY                          ] = SCA_IInputDevice::KX_MKEY;                  
-       gReverseKeyTranslateTable[NKEY                          ] = SCA_IInputDevice::KX_NKEY;                  
-       gReverseKeyTranslateTable[OKEY                          ] = SCA_IInputDevice::KX_OKEY;                  
-       gReverseKeyTranslateTable[PKEY                          ] = SCA_IInputDevice::KX_PKEY;                  
-       gReverseKeyTranslateTable[QKEY                          ] = SCA_IInputDevice::KX_QKEY;                  
-       gReverseKeyTranslateTable[RKEY                          ] = SCA_IInputDevice::KX_RKEY;                  
-       gReverseKeyTranslateTable[SKEY                          ] = SCA_IInputDevice::KX_SKEY;                  
-       gReverseKeyTranslateTable[TKEY                          ] = SCA_IInputDevice::KX_TKEY;                  
-       gReverseKeyTranslateTable[UKEY                          ] = SCA_IInputDevice::KX_UKEY;                  
-       gReverseKeyTranslateTable[VKEY                          ] = SCA_IInputDevice::KX_VKEY;                  
-       gReverseKeyTranslateTable[WKEY                          ] = SCA_IInputDevice::KX_WKEY;                  
-       gReverseKeyTranslateTable[XKEY                          ] = SCA_IInputDevice::KX_XKEY;                  
-       gReverseKeyTranslateTable[YKEY                          ] = SCA_IInputDevice::KX_YKEY;                  
-       gReverseKeyTranslateTable[ZKEY                          ] = SCA_IInputDevice::KX_ZKEY;                  
-       
-       gReverseKeyTranslateTable[ZEROKEY                       ] = SCA_IInputDevice::KX_ZEROKEY;                  
-       gReverseKeyTranslateTable[ONEKEY                        ] = SCA_IInputDevice::KX_ONEKEY;                  
-       gReverseKeyTranslateTable[TWOKEY                        ] = SCA_IInputDevice::KX_TWOKEY;                  
-       gReverseKeyTranslateTable[THREEKEY                      ] = SCA_IInputDevice::KX_THREEKEY;                  
-       gReverseKeyTranslateTable[FOURKEY                       ] = SCA_IInputDevice::KX_FOURKEY;                  
-       gReverseKeyTranslateTable[FIVEKEY                       ] = SCA_IInputDevice::KX_FIVEKEY;                  
-       gReverseKeyTranslateTable[SIXKEY                        ] = SCA_IInputDevice::KX_SIXKEY;                  
-       gReverseKeyTranslateTable[SEVENKEY                      ] = SCA_IInputDevice::KX_SEVENKEY;                  
-       gReverseKeyTranslateTable[EIGHTKEY                      ] = SCA_IInputDevice::KX_EIGHTKEY;                  
-       gReverseKeyTranslateTable[NINEKEY                       ] = SCA_IInputDevice::KX_NINEKEY;                  
-       
-       gReverseKeyTranslateTable[CAPSLOCKKEY           ] = SCA_IInputDevice::KX_CAPSLOCKKEY;                  
-       
-       gReverseKeyTranslateTable[LEFTCTRLKEY           ] = SCA_IInputDevice::KX_LEFTCTRLKEY;                  
-       gReverseKeyTranslateTable[LEFTALTKEY            ] = SCA_IInputDevice::KX_LEFTALTKEY;                  
-       gReverseKeyTranslateTable[RIGHTALTKEY           ] = SCA_IInputDevice::KX_RIGHTALTKEY;                  
-       gReverseKeyTranslateTable[RIGHTCTRLKEY          ] = SCA_IInputDevice::KX_RIGHTCTRLKEY;                  
-       gReverseKeyTranslateTable[RIGHTSHIFTKEY         ] = SCA_IInputDevice::KX_RIGHTSHIFTKEY;                  
-       gReverseKeyTranslateTable[LEFTSHIFTKEY          ] = SCA_IInputDevice::KX_LEFTSHIFTKEY;                  
-       
-       gReverseKeyTranslateTable[ESCKEY                        ] = SCA_IInputDevice::KX_ESCKEY;                  
-       gReverseKeyTranslateTable[TABKEY                        ] = SCA_IInputDevice::KX_TABKEY;                  
-       gReverseKeyTranslateTable[RETKEY                        ] = SCA_IInputDevice::KX_RETKEY;                  
-       gReverseKeyTranslateTable[SPACEKEY                      ] = SCA_IInputDevice::KX_SPACEKEY;                  
-       gReverseKeyTranslateTable[LINEFEEDKEY           ] = SCA_IInputDevice::KX_LINEFEEDKEY;                  
-       gReverseKeyTranslateTable[BACKSPACEKEY          ] = SCA_IInputDevice::KX_BACKSPACEKEY;                  
-       gReverseKeyTranslateTable[DELKEY                        ] = SCA_IInputDevice::KX_DELKEY;                  
-       gReverseKeyTranslateTable[SEMICOLONKEY          ] = SCA_IInputDevice::KX_SEMICOLONKEY;                  
-       gReverseKeyTranslateTable[PERIODKEY                     ] = SCA_IInputDevice::KX_PERIODKEY;                  
-       gReverseKeyTranslateTable[COMMAKEY                      ] = SCA_IInputDevice::KX_COMMAKEY;                  
-       gReverseKeyTranslateTable[QUOTEKEY                      ] = SCA_IInputDevice::KX_QUOTEKEY;                  
-       gReverseKeyTranslateTable[ACCENTGRAVEKEY        ] = SCA_IInputDevice::KX_ACCENTGRAVEKEY;                  
-       gReverseKeyTranslateTable[MINUSKEY                      ] = SCA_IInputDevice::KX_MINUSKEY;                  
-       gReverseKeyTranslateTable[SLASHKEY                      ] = SCA_IInputDevice::KX_SLASHKEY;                  
-       gReverseKeyTranslateTable[BACKSLASHKEY          ] = SCA_IInputDevice::KX_BACKSLASHKEY;                  
-       gReverseKeyTranslateTable[EQUALKEY                      ] = SCA_IInputDevice::KX_EQUALKEY;                  
-       gReverseKeyTranslateTable[LEFTBRACKETKEY        ] = SCA_IInputDevice::KX_LEFTBRACKETKEY;                  
-       gReverseKeyTranslateTable[RIGHTBRACKETKEY       ] = SCA_IInputDevice::KX_RIGHTBRACKETKEY;                  
-       
-       gReverseKeyTranslateTable[LEFTARROWKEY          ] = SCA_IInputDevice::KX_LEFTARROWKEY;                  
-       gReverseKeyTranslateTable[DOWNARROWKEY          ] = SCA_IInputDevice::KX_DOWNARROWKEY;                  
-       gReverseKeyTranslateTable[RIGHTARROWKEY         ] = SCA_IInputDevice::KX_RIGHTARROWKEY;                  
-       gReverseKeyTranslateTable[UPARROWKEY            ] = SCA_IInputDevice::KX_UPARROWKEY;                  
-       
-       gReverseKeyTranslateTable[PAD2                          ] = SCA_IInputDevice::KX_PAD2;                  
-       gReverseKeyTranslateTable[PAD4                          ] = SCA_IInputDevice::KX_PAD4;                  
-       gReverseKeyTranslateTable[PAD6                          ] = SCA_IInputDevice::KX_PAD6;                  
-       gReverseKeyTranslateTable[PAD8                          ] = SCA_IInputDevice::KX_PAD8;                  
-       
-       gReverseKeyTranslateTable[PAD1                          ] = SCA_IInputDevice::KX_PAD1;                  
-       gReverseKeyTranslateTable[PAD3                          ] = SCA_IInputDevice::KX_PAD3;                  
-       gReverseKeyTranslateTable[PAD5                          ] = SCA_IInputDevice::KX_PAD5;                  
-       gReverseKeyTranslateTable[PAD7                          ] = SCA_IInputDevice::KX_PAD7;                  
-       gReverseKeyTranslateTable[PAD9                          ] = SCA_IInputDevice::KX_PAD9;                  
-       
-       gReverseKeyTranslateTable[PADPERIOD                     ] = SCA_IInputDevice::KX_PADPERIOD;                  
-       gReverseKeyTranslateTable[PADSLASHKEY           ] = SCA_IInputDevice::KX_PADSLASHKEY;                  
-       gReverseKeyTranslateTable[PADASTERKEY           ] = SCA_IInputDevice::KX_PADASTERKEY;                  
-       
-       gReverseKeyTranslateTable[PAD0                          ] = SCA_IInputDevice::KX_PAD0;                  
-       gReverseKeyTranslateTable[PADMINUS                      ] = SCA_IInputDevice::KX_PADMINUS;                  
-       gReverseKeyTranslateTable[PADENTER                      ] = SCA_IInputDevice::KX_PADENTER;                  
-       gReverseKeyTranslateTable[PADPLUSKEY            ] = SCA_IInputDevice::KX_PADPLUSKEY;                  
-       
-       
-       gReverseKeyTranslateTable[F1KEY                         ] = SCA_IInputDevice::KX_F1KEY;                  
-       gReverseKeyTranslateTable[F2KEY                         ] = SCA_IInputDevice::KX_F2KEY;                  
-       gReverseKeyTranslateTable[F3KEY                         ] = SCA_IInputDevice::KX_F3KEY;                  
-       gReverseKeyTranslateTable[F4KEY                         ] = SCA_IInputDevice::KX_F4KEY;                  
-       gReverseKeyTranslateTable[F5KEY                         ] = SCA_IInputDevice::KX_F5KEY;                  
-       gReverseKeyTranslateTable[F6KEY                         ] = SCA_IInputDevice::KX_F6KEY;                  
-       gReverseKeyTranslateTable[F7KEY                         ] = SCA_IInputDevice::KX_F7KEY;                  
-       gReverseKeyTranslateTable[F8KEY                         ] = SCA_IInputDevice::KX_F8KEY;                  
-       gReverseKeyTranslateTable[F9KEY                         ] = SCA_IInputDevice::KX_F9KEY;                  
-       gReverseKeyTranslateTable[F10KEY                        ] = SCA_IInputDevice::KX_F10KEY;                  
-       gReverseKeyTranslateTable[F11KEY                        ] = SCA_IInputDevice::KX_F11KEY;                  
-       gReverseKeyTranslateTable[F12KEY                        ] = SCA_IInputDevice::KX_F12KEY;                  
-       
-       gReverseKeyTranslateTable[PAUSEKEY                      ] = SCA_IInputDevice::KX_PAUSEKEY;                  
-       gReverseKeyTranslateTable[INSERTKEY                     ] = SCA_IInputDevice::KX_INSERTKEY;                  
-       gReverseKeyTranslateTable[HOMEKEY                       ] = SCA_IInputDevice::KX_HOMEKEY;                  
-       gReverseKeyTranslateTable[PAGEUPKEY                     ] = SCA_IInputDevice::KX_PAGEUPKEY;                  
-       gReverseKeyTranslateTable[PAGEDOWNKEY           ] = SCA_IInputDevice::KX_PAGEDOWNKEY;                  
-       gReverseKeyTranslateTable[ENDKEY                        ] = SCA_IInputDevice::KX_ENDKEY;
-       
+       if (!reverseTableConverted)
+       {
+               reverseTableConverted = true;
+               
+               /* The reverse table. In order to not confuse ourselves, we      */
+               /* immediately convert all events that come in to KX codes.      */
+               gReverseKeyTranslateTable[LEFTMOUSE                     ] =     SCA_IInputDevice::KX_LEFTMOUSE;
+               gReverseKeyTranslateTable[MIDDLEMOUSE           ] =     SCA_IInputDevice::KX_MIDDLEMOUSE;
+               gReverseKeyTranslateTable[RIGHTMOUSE            ] =     SCA_IInputDevice::KX_RIGHTMOUSE;
+               gReverseKeyTranslateTable[WHEELUPMOUSE          ] =     SCA_IInputDevice::KX_WHEELUPMOUSE;
+               gReverseKeyTranslateTable[WHEELDOWNMOUSE        ] =     SCA_IInputDevice::KX_WHEELDOWNMOUSE;
+               gReverseKeyTranslateTable[MOUSEX                        ] = SCA_IInputDevice::KX_MOUSEX;
+               gReverseKeyTranslateTable[MOUSEY                        ] =     SCA_IInputDevice::KX_MOUSEY;
+               
+               // TIMERS                                                                                                  
+               
+               gReverseKeyTranslateTable[TIMER0                        ] = SCA_IInputDevice::KX_TIMER0;                  
+               gReverseKeyTranslateTable[TIMER1                        ] = SCA_IInputDevice::KX_TIMER1;                  
+               gReverseKeyTranslateTable[TIMER2                        ] = SCA_IInputDevice::KX_TIMER2;                  
+               gReverseKeyTranslateTable[TIMER3                        ] = SCA_IInputDevice::KX_TIMER3;                  
+               
+               // SYSTEM                                                                                                  
+               
+               gReverseKeyTranslateTable[KEYBD                         ] = SCA_IInputDevice::KX_KEYBD;                  
+               gReverseKeyTranslateTable[RAWKEYBD                      ] = SCA_IInputDevice::KX_RAWKEYBD;                  
+               gReverseKeyTranslateTable[REDRAW                        ] = SCA_IInputDevice::KX_REDRAW;                  
+               gReverseKeyTranslateTable[INPUTCHANGE           ] = SCA_IInputDevice::KX_INPUTCHANGE;                  
+               gReverseKeyTranslateTable[QFULL                         ] = SCA_IInputDevice::KX_QFULL;                  
+               gReverseKeyTranslateTable[WINFREEZE                     ] = SCA_IInputDevice::KX_WINFREEZE;                  
+               gReverseKeyTranslateTable[WINTHAW                       ] = SCA_IInputDevice::KX_WINTHAW;                  
+               gReverseKeyTranslateTable[WINCLOSE                      ] = SCA_IInputDevice::KX_WINCLOSE;                  
+               gReverseKeyTranslateTable[WINQUIT                       ] = SCA_IInputDevice::KX_WINQUIT;                  
+               gReverseKeyTranslateTable[Q_FIRSTTIME           ] = SCA_IInputDevice::KX_Q_FIRSTTIME;                  
+               
+               // standard keyboard                                                                                       
+               
+               gReverseKeyTranslateTable[AKEY                          ] = SCA_IInputDevice::KX_AKEY;                  
+               gReverseKeyTranslateTable[BKEY                          ] = SCA_IInputDevice::KX_BKEY;                  
+               gReverseKeyTranslateTable[CKEY                          ] = SCA_IInputDevice::KX_CKEY;                  
+               gReverseKeyTranslateTable[DKEY                          ] = SCA_IInputDevice::KX_DKEY;                  
+               gReverseKeyTranslateTable[EKEY                          ] = SCA_IInputDevice::KX_EKEY;                  
+               gReverseKeyTranslateTable[FKEY                          ] = SCA_IInputDevice::KX_FKEY;                  
+               gReverseKeyTranslateTable[GKEY                          ] = SCA_IInputDevice::KX_GKEY;                  
+               gReverseKeyTranslateTable[HKEY                          ] = SCA_IInputDevice::KX_HKEY;                  
+               gReverseKeyTranslateTable[IKEY                          ] = SCA_IInputDevice::KX_IKEY;                  
+               gReverseKeyTranslateTable[JKEY                          ] = SCA_IInputDevice::KX_JKEY;                  
+               gReverseKeyTranslateTable[KKEY                          ] = SCA_IInputDevice::KX_KKEY;                  
+               gReverseKeyTranslateTable[LKEY                          ] = SCA_IInputDevice::KX_LKEY;                  
+               gReverseKeyTranslateTable[MKEY                          ] = SCA_IInputDevice::KX_MKEY;                  
+               gReverseKeyTranslateTable[NKEY                          ] = SCA_IInputDevice::KX_NKEY;                  
+               gReverseKeyTranslateTable[OKEY                          ] = SCA_IInputDevice::KX_OKEY;                  
+               gReverseKeyTranslateTable[PKEY                          ] = SCA_IInputDevice::KX_PKEY;                  
+               gReverseKeyTranslateTable[QKEY                          ] = SCA_IInputDevice::KX_QKEY;                  
+               gReverseKeyTranslateTable[RKEY                          ] = SCA_IInputDevice::KX_RKEY;                  
+               gReverseKeyTranslateTable[SKEY                          ] = SCA_IInputDevice::KX_SKEY;                  
+               gReverseKeyTranslateTable[TKEY                          ] = SCA_IInputDevice::KX_TKEY;                  
+               gReverseKeyTranslateTable[UKEY                          ] = SCA_IInputDevice::KX_UKEY;                  
+               gReverseKeyTranslateTable[VKEY                          ] = SCA_IInputDevice::KX_VKEY;                  
+               gReverseKeyTranslateTable[WKEY                          ] = SCA_IInputDevice::KX_WKEY;                  
+               gReverseKeyTranslateTable[XKEY                          ] = SCA_IInputDevice::KX_XKEY;                  
+               gReverseKeyTranslateTable[YKEY                          ] = SCA_IInputDevice::KX_YKEY;                  
+               gReverseKeyTranslateTable[ZKEY                          ] = SCA_IInputDevice::KX_ZKEY;                  
+               
+               gReverseKeyTranslateTable[ZEROKEY                       ] = SCA_IInputDevice::KX_ZEROKEY;                  
+               gReverseKeyTranslateTable[ONEKEY                        ] = SCA_IInputDevice::KX_ONEKEY;                  
+               gReverseKeyTranslateTable[TWOKEY                        ] = SCA_IInputDevice::KX_TWOKEY;                  
+               gReverseKeyTranslateTable[THREEKEY                      ] = SCA_IInputDevice::KX_THREEKEY;                  
+               gReverseKeyTranslateTable[FOURKEY                       ] = SCA_IInputDevice::KX_FOURKEY;                  
+               gReverseKeyTranslateTable[FIVEKEY                       ] = SCA_IInputDevice::KX_FIVEKEY;                  
+               gReverseKeyTranslateTable[SIXKEY                        ] = SCA_IInputDevice::KX_SIXKEY;                  
+               gReverseKeyTranslateTable[SEVENKEY                      ] = SCA_IInputDevice::KX_SEVENKEY;                  
+               gReverseKeyTranslateTable[EIGHTKEY                      ] = SCA_IInputDevice::KX_EIGHTKEY;                  
+               gReverseKeyTranslateTable[NINEKEY                       ] = SCA_IInputDevice::KX_NINEKEY;                  
+               
+               gReverseKeyTranslateTable[CAPSLOCKKEY           ] = SCA_IInputDevice::KX_CAPSLOCKKEY;                  
+               
+               gReverseKeyTranslateTable[LEFTCTRLKEY           ] = SCA_IInputDevice::KX_LEFTCTRLKEY;                  
+               gReverseKeyTranslateTable[LEFTALTKEY            ] = SCA_IInputDevice::KX_LEFTALTKEY;                  
+               gReverseKeyTranslateTable[RIGHTALTKEY           ] = SCA_IInputDevice::KX_RIGHTALTKEY;                  
+               gReverseKeyTranslateTable[RIGHTCTRLKEY          ] = SCA_IInputDevice::KX_RIGHTCTRLKEY;                  
+               gReverseKeyTranslateTable[RIGHTSHIFTKEY         ] = SCA_IInputDevice::KX_RIGHTSHIFTKEY;                  
+               gReverseKeyTranslateTable[LEFTSHIFTKEY          ] = SCA_IInputDevice::KX_LEFTSHIFTKEY;                  
+               
+               gReverseKeyTranslateTable[ESCKEY                        ] = SCA_IInputDevice::KX_ESCKEY;                  
+               gReverseKeyTranslateTable[TABKEY                        ] = SCA_IInputDevice::KX_TABKEY;                  
+               gReverseKeyTranslateTable[RETKEY                        ] = SCA_IInputDevice::KX_RETKEY;                  
+               gReverseKeyTranslateTable[SPACEKEY                      ] = SCA_IInputDevice::KX_SPACEKEY;                  
+               gReverseKeyTranslateTable[LINEFEEDKEY           ] = SCA_IInputDevice::KX_LINEFEEDKEY;                  
+               gReverseKeyTranslateTable[BACKSPACEKEY          ] = SCA_IInputDevice::KX_BACKSPACEKEY;                  
+               gReverseKeyTranslateTable[DELKEY                        ] = SCA_IInputDevice::KX_DELKEY;                  
+               gReverseKeyTranslateTable[SEMICOLONKEY          ] = SCA_IInputDevice::KX_SEMICOLONKEY;                  
+               gReverseKeyTranslateTable[PERIODKEY                     ] = SCA_IInputDevice::KX_PERIODKEY;                  
+               gReverseKeyTranslateTable[COMMAKEY                      ] = SCA_IInputDevice::KX_COMMAKEY;                  
+               gReverseKeyTranslateTable[QUOTEKEY                      ] = SCA_IInputDevice::KX_QUOTEKEY;                  
+               gReverseKeyTranslateTable[ACCENTGRAVEKEY        ] = SCA_IInputDevice::KX_ACCENTGRAVEKEY;                  
+               gReverseKeyTranslateTable[MINUSKEY                      ] = SCA_IInputDevice::KX_MINUSKEY;                  
+               gReverseKeyTranslateTable[SLASHKEY                      ] = SCA_IInputDevice::KX_SLASHKEY;                  
+               gReverseKeyTranslateTable[BACKSLASHKEY          ] = SCA_IInputDevice::KX_BACKSLASHKEY;                  
+               gReverseKeyTranslateTable[EQUALKEY                      ] = SCA_IInputDevice::KX_EQUALKEY;                  
+               gReverseKeyTranslateTable[LEFTBRACKETKEY        ] = SCA_IInputDevice::KX_LEFTBRACKETKEY;                  
+               gReverseKeyTranslateTable[RIGHTBRACKETKEY       ] = SCA_IInputDevice::KX_RIGHTBRACKETKEY;                  
+               
+               gReverseKeyTranslateTable[LEFTARROWKEY          ] = SCA_IInputDevice::KX_LEFTARROWKEY;                  
+               gReverseKeyTranslateTable[DOWNARROWKEY          ] = SCA_IInputDevice::KX_DOWNARROWKEY;                  
+               gReverseKeyTranslateTable[RIGHTARROWKEY         ] = SCA_IInputDevice::KX_RIGHTARROWKEY;                  
+               gReverseKeyTranslateTable[UPARROWKEY            ] = SCA_IInputDevice::KX_UPARROWKEY;                  
+               
+               gReverseKeyTranslateTable[PAD2                          ] = SCA_IInputDevice::KX_PAD2;                  
+               gReverseKeyTranslateTable[PAD4                          ] = SCA_IInputDevice::KX_PAD4;                  
+               gReverseKeyTranslateTable[PAD6                          ] = SCA_IInputDevice::KX_PAD6;                  
+               gReverseKeyTranslateTable[PAD8                          ] = SCA_IInputDevice::KX_PAD8;                  
+               
+               gReverseKeyTranslateTable[PAD1                          ] = SCA_IInputDevice::KX_PAD1;                  
+               gReverseKeyTranslateTable[PAD3                          ] = SCA_IInputDevice::KX_PAD3;                  
+               gReverseKeyTranslateTable[PAD5                          ] = SCA_IInputDevice::KX_PAD5;                  
+               gReverseKeyTranslateTable[PAD7                          ] = SCA_IInputDevice::KX_PAD7;                  
+               gReverseKeyTranslateTable[PAD9                          ] = SCA_IInputDevice::KX_PAD9;                  
+               
+               gReverseKeyTranslateTable[PADPERIOD                     ] = SCA_IInputDevice::KX_PADPERIOD;                  
+               gReverseKeyTranslateTable[PADSLASHKEY           ] = SCA_IInputDevice::KX_PADSLASHKEY;                  
+               gReverseKeyTranslateTable[PADASTERKEY           ] = SCA_IInputDevice::KX_PADASTERKEY;                  
+               
+               gReverseKeyTranslateTable[PAD0                          ] = SCA_IInputDevice::KX_PAD0;                  
+               gReverseKeyTranslateTable[PADMINUS                      ] = SCA_IInputDevice::KX_PADMINUS;                  
+               gReverseKeyTranslateTable[PADENTER                      ] = SCA_IInputDevice::KX_PADENTER;                  
+               gReverseKeyTranslateTable[PADPLUSKEY            ] = SCA_IInputDevice::KX_PADPLUSKEY;                  
+               
+               
+               gReverseKeyTranslateTable[F1KEY                         ] = SCA_IInputDevice::KX_F1KEY;                  
+               gReverseKeyTranslateTable[F2KEY                         ] = SCA_IInputDevice::KX_F2KEY;                  
+               gReverseKeyTranslateTable[F3KEY                         ] = SCA_IInputDevice::KX_F3KEY;                  
+               gReverseKeyTranslateTable[F4KEY                         ] = SCA_IInputDevice::KX_F4KEY;                  
+               gReverseKeyTranslateTable[F5KEY                         ] = SCA_IInputDevice::KX_F5KEY;                  
+               gReverseKeyTranslateTable[F6KEY                         ] = SCA_IInputDevice::KX_F6KEY;                  
+               gReverseKeyTranslateTable[F7KEY                         ] = SCA_IInputDevice::KX_F7KEY;                  
+               gReverseKeyTranslateTable[F8KEY                         ] = SCA_IInputDevice::KX_F8KEY;                  
+               gReverseKeyTranslateTable[F9KEY                         ] = SCA_IInputDevice::KX_F9KEY;                  
+               gReverseKeyTranslateTable[F10KEY                        ] = SCA_IInputDevice::KX_F10KEY;                  
+               gReverseKeyTranslateTable[F11KEY                        ] = SCA_IInputDevice::KX_F11KEY;                  
+               gReverseKeyTranslateTable[F12KEY                        ] = SCA_IInputDevice::KX_F12KEY;                  
+               
+               gReverseKeyTranslateTable[PAUSEKEY                      ] = SCA_IInputDevice::KX_PAUSEKEY;                  
+               gReverseKeyTranslateTable[INSERTKEY                     ] = SCA_IInputDevice::KX_INSERTKEY;                  
+               gReverseKeyTranslateTable[HOMEKEY                       ] = SCA_IInputDevice::KX_HOMEKEY;                  
+               gReverseKeyTranslateTable[PAGEUPKEY                     ] = SCA_IInputDevice::KX_PAGEUPKEY;                  
+               gReverseKeyTranslateTable[PAGEDOWNKEY           ] = SCA_IInputDevice::KX_PAGEDOWNKEY;                  
+               gReverseKeyTranslateTable[ENDKEY                        ] = SCA_IInputDevice::KX_ENDKEY;
+       }
+
+    int executePriority = 0;
        int uniqueint = 0;
+       int count = 0;
        bSensor* sens = (bSensor*)blenderobject->sensors.first;
        bool pos_pulsemode = false;
        bool neg_pulsemode = false;
@@ -257,6 +262,13 @@ void BL_ConvertSensors(struct Object* blenderobject,
        bool level = false;
        bool tap = false;
        
+       while (sens)
+       {
+               sens = sens->next;
+               count++;
+       }
+       gameobj->ReserveSensor(count);
+       sens = (bSensor*)blenderobject->sensors.first;
        while(sens)
        {
                SCA_ISensor* gamesensor=NULL;
@@ -758,7 +770,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
                        gamesensor->SetInvert(invert);
                        gamesensor->SetLevel(level);
                        gamesensor->SetTap(tap);
-                       gamesensor->SetName(STR_String(sens->name));                    
+                       gamesensor->SetName(sens->name);                        
                        
                        gameobj->AddSensor(gamesensor);
                        
@@ -767,7 +779,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
                        //if (isInActiveLayer)
                        //      gamesensor->RegisterToManager();
                        
-                       
+                       gamesensor->ReserveController(sens->totlinks);
                        for (int i=0;i<sens->totlinks;i++)
                        {
                                bController* linkedcont = (bController*) sens->links[i];
index b18ffc1..9162a86 100644 (file)
@@ -35,7 +35,6 @@ void BL_ConvertSensors(struct Object* blenderobject,
           class KX_Scene* kxscene,
           class KX_KetsjiEngine* kxengine,
           class SCA_IInputDevice* keydev,
-          int & executePriority ,
           int activeLayerBitInfo,
           bool isInActiveLayer,
           class RAS_ICanvas* canvas, 
index 4e0a71e..d90da8b 100644 (file)
@@ -26,6 +26,9 @@
 // Construction/Destruction
 //////////////////////////////////////////////////////////////////////
 
+const STR_String CBoolValue::sTrueString  = "TRUE";
+const STR_String CBoolValue::sFalseString = "FALSE";
+
 
 CBoolValue::CBoolValue()
 /*
@@ -45,7 +48,7 @@ CBoolValue::CBoolValue(bool inBool)
 
 
 
-CBoolValue::CBoolValue(bool innie,STR_String name,AllocationTYPE alloctype)
+CBoolValue::CBoolValue(bool innie,const char *name,AllocationTYPE alloctype)
 {
        m_bool = innie;
        SetName(name);
@@ -190,9 +193,6 @@ double CBoolValue::GetNumber()
 
 const STR_String& CBoolValue::GetText()
 {
-       static STR_String sTrueString  = STR_String("TRUE");
-       static STR_String sFalseString = STR_String("FALSE");
-       
        return m_bool ? sTrueString : sFalseString;
 }
 
index 9352b9d..726619e 100644 (file)
@@ -28,9 +28,12 @@ class CBoolValue : public CPropValue
        //PLUGIN_DECLARE_SERIAL(CBoolValue,CValue)      
 
 public:
+       static const STR_String sTrueString;
+       static const STR_String sFalseString;
+
        CBoolValue();
        CBoolValue(bool inBool);
-       CBoolValue(bool innie, STR_String name, AllocationTYPE alloctype = CValue::HEAPVALUE);
+       CBoolValue(bool innie, const char *name, AllocationTYPE alloctype = CValue::HEAPVALUE);
 
        virtual const STR_String& GetText();
        virtual double          GetNumber();
index 6b2a835..eb87fdc 100644 (file)
@@ -31,6 +31,7 @@ SET(INC
   ../../../source/kernel/gen_system
   ../../../intern/string
   ../../../intern/moto/include
+  ../../../source/gameengine/Scenegraph
   ${PYTHON_INC}
 )
 
index 651a772..a44abf8 100644 (file)
@@ -34,13 +34,15 @@ effect: constructs a new CErrorValue containing errormessage "Error"
 
 
 
-CErrorValue::CErrorValue(STR_String errmsg)
+CErrorValue::CErrorValue(const char *errmsg)
 /*
 pre:
 effect: constructs a new CErrorValue containing errormessage errmsg
 */
 {
-  m_strErrorText = "[" + errmsg + "]";
+  m_strErrorText = "[";
+  m_strErrorText += errmsg;
+  m_strErrorText += "]";
   SetError(true);
 }
 
index 5b57951..b4b758f 100644 (file)
@@ -25,7 +25,7 @@ public:
        virtual const STR_String & GetText();
        virtual double GetNumber();
        CErrorValue();
-       CErrorValue(STR_String errmsg);
+       CErrorValue(const char *errmsg);
        virtual ~CErrorValue();
        virtual CValue* Calc(VALUE_OPERATOR op, CValue* val);
        virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
index a31d3b9..4de685a 100644 (file)
@@ -50,7 +50,7 @@ effect: constructs a new CFloatValue containing value fl
 
 
 
-CFloatValue::CFloatValue(float fl,STR_String name,AllocationTYPE alloctype)
+CFloatValue::CFloatValue(float fl,const char *name,AllocationTYPE alloctype)
 /*
 pre:
 effect: constructs a new CFloatValue containing value fl
index 41f70b5..fb75b7c 100644 (file)
@@ -23,7 +23,7 @@ class CFloatValue : public CPropValue
 public:
        CFloatValue();
        CFloatValue(float fl);
-       CFloatValue(float fl,STR_String name,AllocationTYPE alloctype=CValue::HEAPVALUE);
+       CFloatValue(float fl,const char *name,AllocationTYPE alloctype=CValue::HEAPVALUE);
 
        virtual const STR_String & GetText();
 
index 5d3eb36..fcb37bf 100644 (file)
@@ -15,6 +15,7 @@
 #include "IfExpr.h"
 #include "EmptyValue.h"
 #include "ErrorValue.h"
+#include "BoolValue.h"
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -72,14 +73,14 @@ ret: a new object containing the value of m_e1 if m_guard is a boolean TRUE
 {
        CValue *guardval;
        guardval = m_guard->Calculate();
-       STR_String text = guardval->GetText();
+       const STR_String& text = guardval->GetText();
        guardval->Release();
 
-       if (text == STR_String("TRUE"))
+       if (&text == &CBoolValue::sTrueString)
        {
                return m_e1->Calculate();
        }
-       else if (text == STR_String("FALSE"))
+       else if (&text == &CBoolValue::sFalseString)
        {
                return m_e2->Calculate();
        }
index 91a14f9..b15b206 100644 (file)
@@ -66,7 +66,7 @@ CParser::~CParser()
 
 
 
-void CParser::ScanError(STR_String str)
+void CParser::ScanError(const char *str)
 {
        // sets the global variable errmsg to an errormessage with
        // contents str, appending if it already exists
@@ -81,7 +81,7 @@ void CParser::ScanError(STR_String str)
 
 
 
-CExpression* CParser::Error(STR_String str)
+CExpression* CParser::Error(const char *str)
 {
        // makes and returns a new CConstExpr filled with an CErrorValue
        // with string str
@@ -537,7 +537,7 @@ CExpression *CParser::Expr() {
 }
 
 CExpression* CParser::ProcessText
-(STR_String intext) {
+(const char *intext) {
        
        // and parses the string in intext and returns it.
        
@@ -574,7 +574,7 @@ CExpression* CParser::ProcessText
 
 
 
-float CParser::GetFloat(STR_String txt)
+float CParser::GetFloat(STR_String& txt)
 {
        // returns parsed text into a float
        // empty string returns -1
@@ -599,7 +599,7 @@ float CParser::GetFloat(STR_String txt)
        return result;
 }
 
-CValue* CParser::GetValue(STR_String txt, bool bFallbackToText)
+CValue* CParser::GetValue(STR_String& txt, bool bFallbackToText)
 {
        // returns parsed text into a value, 
        // empty string returns NULL value !
index 3d51722..810bdc2 100644 (file)
@@ -27,9 +27,9 @@ public:
        CParser();
        virtual                         ~CParser();
 
-       float                           GetFloat(STR_String txt);
-       CValue*                         GetValue(STR_String txt, bool bFallbackToText=false);
-       CExpression*            ProcessText(STR_String intext);
+       float                           GetFloat(STR_String& txt);
+       CValue*                         GetValue(STR_String& txt, bool bFallbackToText=false);
+       CExpression*            ProcessText(const char *intext);
        void                            SetContext(CValue* context);
 
 private:
@@ -86,8 +86,8 @@ private:
        CValue* m_identifierContext;// context in which identifiers are looked up
        
        
-       void ScanError(STR_String str);
-       CExpression* Error(STR_String str);
+       void ScanError(const char *str);
+       CExpression* Error(const char *str);
        void NextCh();
        void TermChar(char c);
        void DigRep();
index 74ec986..227518e 100644 (file)
@@ -54,7 +54,7 @@ effect: constructs a new CIntValue containing cInt innie
 
 
 
-CIntValue::CIntValue(cInt innie,STR_String name,AllocationTYPE alloctype)
+CIntValue::CIntValue(cInt innie,const char *name,AllocationTYPE alloctype)
 {
        m_int = innie;
        SetName(name);
index 0f3a38b..06bf175 100644 (file)
@@ -32,7 +32,7 @@ public:
        CIntValue();
        CIntValue(cInt innie);
        CIntValue(cInt innie,
-                         STR_String name,
+                         const char *name,
                          AllocationTYPE alloctype=CValue::HEAPVALUE);
        
        virtual CValue* Calc(VALUE_OPERATOR op,
index f4a801a..75ae2cb 100644 (file)
@@ -18,6 +18,7 @@
 #include "StringValue.h"
 #include "VoidValue.h"
 #include <algorithm>
+#include "BoolValue.h"
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -75,7 +76,7 @@ PyObject* listvalue_mapping_subscript(PyObject* self, PyObject* pyindex)
        
        if (PyString_Check(pyindex))
        {
-               STR_String  index(PyString_AsString(pyindex));
+               const char *index = PyString_AsString(pyindex);
                CValue *item = ((CListValue*) list)->FindValue(index);
                if (item)
                {
@@ -394,7 +395,7 @@ void CListValue::ReleaseAndRemoveAll()
 
 
 
-CValue* CListValue::FindValue(const STR_String & name)
+CValue* CListValue::FindValue(const char * name)
 {
        CValue* resultval = NULL;
        int i=0;
@@ -497,13 +498,12 @@ bool CListValue::CheckEqual(CValue* first,CValue* second)
        
        if (eqval==NULL)
                return false;
-               
-       STR_String txt = eqval->GetText();
-       eqval->Release();
-       if (txt=="TRUE")
+       const STR_String& text = eqval->GetText();
+       if (&text==&CBoolValue::sTrueString)
        {
                result = true;
        }
+       eqval->Release();
        return result;
 
 }
index 3d88b5a..ad918cb 100644 (file)
@@ -45,7 +45,7 @@ public:
        void SetReleaseOnDestruct(bool bReleaseContents);
        bool SearchValue(CValue* val);
        
-       CValue* FindValue(const STR_String & name);
+       CValue* FindValue(const char *name);
 
        void ReleaseAndRemoveAll();
        virtual void SetModified(bool bModified);
index 6736149..a1400c4 100644 (file)
@@ -41,4 +41,5 @@ CPPFLAGS += -I../../blender/makesdna
 CPPFLAGS += -I$(NAN_STRING)/include
 CPPFLAGS += -I$(NAN_MOTO)/include
 CPPFLAGS += -I../../kernel/gen_system
+CPPFLAGS += -I../../gameengine/Scenegraph
 
index 7026db5..83c0b25 100644 (file)
@@ -104,7 +104,7 @@ void PyObjectPlus::py_base_dealloc(PyObject *self)                          // python wrapper
        PyObject_DEL( self );
 };
 
-PyObjectPlus::PyObjectPlus(PyTypeObject *T)                            // constructor
+PyObjectPlus::PyObjectPlus(PyTypeObject *T) : SG_QList()                               // constructor
 {
        MT_assert(T != NULL);
        m_proxy= NULL;
index b7f2240..b69697f 100644 (file)
@@ -38,6 +38,7 @@
 
 #include "KX_Python.h"
 #include "STR_String.h"
+#include "SG_QList.h"
 
 /*------------------------------
  * Python defines
@@ -462,7 +463,18 @@ typedef struct KX_PYATTRIBUTE_DEF {
 ------------------------------*/
 typedef PyTypeObject * PyParentObject;                         // Define the PyParent Object
 
-class PyObjectPlus 
+// By making SG_QList the ultimate parent for PyObjectPlus objects, it
+// allows to put them in 2 different dynamic lists at the same time
+// The use of these links is interesting because they free of memory allocation
+// but it's very important not to mess up with them. If you decide that 
+// the SG_QList or SG_DList component is used for something for a certain class,
+// they cannot can be used for anything else at a parent level!
+// What these lists are and what they are used for must be carefully documented
+// at the level where they are used.
+// DON'T MAKE ANY USE OF THESE LIST AT THIS LEVEL, they are already used
+// at SCA_IActuator, SCA_ISensor, SCA_IController level which rules out the
+// possibility to use them at SCA_ILogicBrick, CValue and PyObjectPlus level.
+class PyObjectPlus : public SG_QList
 {                              // The PyObjectPlus abstract class
        Py_Header;                                                      // Always start with Py_Header
        
index 3d855d4..9d6823e 100644 (file)
@@ -3,7 +3,7 @@ Import ('env')
 
 sources = env.Glob('*.cpp')
 
-incs ='. #source/kernel/gen_system #intern/string #intern/moto/include'
+incs ='. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/Scenegraph'
 incs += ' ' + env['BF_PYTHON_INC']
 
 cxxflags = []
index 857aa97..a7033fc 100644 (file)
@@ -34,7 +34,7 @@ effect: constructs a new CStringValue
        m_strString = "[Illegal String constructor call]";
 }
 
-CStringValue::CStringValue(STR_String txt,STR_String name,AllocationTYPE alloctype)
+CStringValue::CStringValue(const char *txt,const char *name,AllocationTYPE alloctype)
 /*
 pre:
 effect: constructs a new CStringValue containing text txt
index 16575ed..52f8a58 100644 (file)
@@ -26,7 +26,7 @@ class CStringValue : public CPropValue
 public:
        /// Construction / destruction
        CStringValue();
-       CStringValue (STR_String txt, STR_String name , AllocationTYPE alloctype = CValue::HEAPVALUE);
+       CStringValue (const char *txt, const char *name , AllocationTYPE alloctype = CValue::HEAPVALUE);
 
        virtual ~CStringValue() {
        };
index a811b39..83deeef 100644 (file)
@@ -291,13 +291,17 @@ CValue* CValue::GetProperty(const char *inName)
 //
 // Get text description of property with name <inName>, returns an empty string if there is no property named <inName>
 //
-STR_String CValue::GetPropertyText(const STR_String & inName,const STR_String& deftext)
+const STR_String& CValue::GetPropertyText(const STR_String & inName,const char *deftext)
 {
+       const static STR_String sEmpty("");
+
        CValue *property = GetProperty(inName);
        if (property)
                return property->GetText();
+       else if (deftext)
+               return STR_String(deftext);
        else
-               return deftext;//String::sEmpty;
+               return sEmpty;
 }
 
 float CValue::GetPropertyNumber(const STR_String& inName,float defnumber)
@@ -647,7 +651,7 @@ CValue* CValue::ConvertPythonToValue(PyObject* pyobj, const char *error_prefix)
 int    CValue::py_delattro(PyObject *attr)
 {
        char *attr_str= PyString_AsString(attr);
-       if (RemoveProperty(STR_String(attr_str)))
+       if (RemoveProperty(attr_str))
                return 0;
        
        PyErr_Format(PyExc_AttributeError, "attribute \"%s\" dosnt exist", attr_str);
index c5c8229..e5c95df 100644 (file)
@@ -308,7 +308,7 @@ public:
        virtual void            SetProperty(const char* name,CValue* ioProperty);
        virtual CValue*         GetProperty(const char* inName);                                                        // Get pointer to a property with name <inName>, returns NULL if there is no property named <inName>
        virtual CValue*         GetProperty(const STR_String & inName);
-       STR_String                      GetPropertyText(const STR_String & inName,const STR_String& deftext="");                                                // Get text description of property with name <inName>, returns an empty string if there is no property named <inName>
+       const STR_String&       GetPropertyText(const STR_String & inName,const char *deftext=NULL);                                            // Get text description of property with name <inName>, returns an empty string if there is no property named <inName>
        float                           GetPropertyNumber(const STR_String& inName,float defnumber);
        virtual bool            RemoveProperty(const char *inName);                                             // Remove the property named <inName>, returns true if the property was succesfully removed, false if property was not found or could not be removed
        virtual vector<STR_String>      GetPropertyNames();
@@ -331,8 +331,8 @@ public:
        double*                         ZeroVector() { return m_sZeroVec; };
        virtual double*         GetVector3(bool bGetTransformedVec = false);
 
-       virtual STR_String      GetName() = 0;                                                                                  // Retrieve the name of the value
-       virtual void            SetName(STR_String name) = 0;                                                           // Set the name of the value
+       virtual STR_String&     GetName() = 0;                                                                                  // Retrieve the name of the value
+       virtual void            SetName(const char *name) = 0;                                                          // Set the name of the value
        /** Sets the value to this cvalue.
         * @attention this particular function should never be called. Why not abstract? */
        virtual void            SetValue(CValue* newval);
@@ -420,49 +420,28 @@ public:
 #else
        CPropValue() :
 #endif //NO_EXP_PYTHON_EMBEDDING
-               m_pstrNewName(NULL)
+               m_strNewName()
 
        {
        }
        
        virtual ~CPropValue()
        {
-               if (m_pstrNewName)
-               {
-                       delete m_pstrNewName;
-                       m_pstrNewName = NULL;
-               }
        }
        
-       virtual void                    SetName(STR_String name) {
-               if (m_pstrNewName)
-               {
-                       delete m_pstrNewName;
-                       m_pstrNewName = NULL;   
-               }
-               if (name.Length())
-                       m_pstrNewName = new STR_String(name);
-       }
-       virtual void                    ProcessReplica() {
-               CValue::ProcessReplica();
-               if (m_pstrNewName)
-                       m_pstrNewName = new STR_String(*m_pstrNewName);
+       virtual void                    SetName(const char *name) {
+               m_strNewName = name;
        }
        
-       virtual STR_String                      GetName() {
+       virtual STR_String&                     GetName() {
                //STR_String namefromprop = GetPropertyText("Name");
                //if (namefromprop.Length() > 0)
                //      return namefromprop;
-               
-               if (m_pstrNewName)
-               {
-                       return *m_pstrNewName;
-               }
-               return STR_String("");
+               return m_strNewName;
        };                                              // name of Value
        
 protected:
-       STR_String*                                     m_pstrNewName;                              // Identification
+       STR_String                                      m_strNewName;                               // Identification
 };
 
 #endif // !defined _VALUEBASECLASS_H
index e8e1d45..c58c78e 100644 (file)
@@ -48,7 +48,7 @@ CVectorValue::CVectorValue(float x,float y,float z, AllocationTYPE alloctype)
        m_vec[KX_Z] = m_transformedvec[KX_Z] = z;
        
 }
-CVectorValue::CVectorValue(double vec[],STR_String name,AllocationTYPE alloctype) {
+CVectorValue::CVectorValue(double vec[],const char *name,AllocationTYPE alloctype) {
        
        SetCustomFlag1(false);//FancyOutput=false;
        
index 99bf0ab..19c7dd3 100644 (file)
@@ -41,7 +41,7 @@ public:
        CValue*         CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
        
        
-       CVectorValue(double vec[],STR_String name,AllocationTYPE alloctype=CValue::HEAPVALUE);
+       CVectorValue(double vec[],const char *name,AllocationTYPE alloctype=CValue::HEAPVALUE);
        CVectorValue() {};
 
        CVectorValue(double vec[],AllocationTYPE alloctype=CValue::HEAPVALUE);
index a751919..449aae3 100644 (file)
@@ -31,6 +31,7 @@ SET(INC
   ../../../source/kernel/gen_system 
   ../../../intern/string
   ../../../source/gameengine/Expressions 
+  ../../../source/gameengine/Scenegraph
   ../../../intern/moto/include
   ../../../source/gameengine/Rasterizer
   ${PYTHON_INC}
index 355ece6..6e9af67 100644 (file)
@@ -39,6 +39,7 @@ include nan_compile.mk
 CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
 
 CPPFLAGS += -I../Expressions 
+CPPFLAGS += -I../Scenegraph
 CPPFLAGS += -I../Rasterizer
 CPPFLAGS += -I$(NAN_STRING)/include    
 CPPFLAGS += -I$(NAN_MOTO)/include
index fb72eef..1aaa59e 100644 (file)
@@ -95,7 +95,7 @@ bool SCA_2DFilterActuator::Update()
 }
 
 
-void SCA_2DFilterActuator::SetShaderText(STR_String text)
+void SCA_2DFilterActuator::SetShaderText(STR_String& text)
 {
        m_shaderText = text;
 }
index b43dc09..aea3a35 100644 (file)
@@ -60,7 +60,7 @@ public:
         PyTypeObject* T=&Type
         );
 
-       void    SetShaderText(STR_String text);
+       void    SetShaderText(STR_String& text);
     virtual ~SCA_2DFilterActuator();
     virtual bool Update();
 
index 7991e82..87f7c61 100644 (file)
@@ -73,19 +73,12 @@ void SCA_ANDController::Trigger(SCA_LogicManager* logicmgr)
                }
        }
        
-       CValue* newevent = new CBoolValue(sensorresult);
-
        for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
        !(i==m_linkedactuators.end());i++)
        {
-               SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
-               logicmgr->AddActiveActuator(actua,newevent);
+               SCA_IActuator* actua = *i;
+               logicmgr->AddActiveActuator(actua,sensorresult);
        }
-
-       // every actuator that needs the event, has a it's own reference to it now so
-       // release it (so to be clear: if there is no actuator, it's deleted right now)
-       newevent->Release();
-
 }
 
 
index 768a3a4..a80b2af 100644 (file)
@@ -51,17 +51,19 @@ SCA_ActuatorEventManager::~SCA_ActuatorEventManager()
 void SCA_ActuatorEventManager::NextFrame()
 {
        // check for changed actuator
-       for (set<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
+       SG_DList::iterator<SCA_ISensor> it(m_sensors);
+       for (it.begin();!it.end();++it)
        {
-               (*it)->Activate(m_logicmgr,NULL);
+               (*it)->Activate(m_logicmgr);
        }
 }
 
 void SCA_ActuatorEventManager::UpdateFrame()
 {
        // update the state of actuator before executing them
-       for (set<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
+       SG_DList::iterator<SCA_ActuatorSensor> it(m_sensors);
+       for (it.begin();!it.end();++it)
        {
-               ((SCA_ActuatorSensor*)(*it))->Update();
+               (*it)->Update();
        }
 }
\ No newline at end of file
index 464797f..4dad65c 100644 (file)
@@ -89,7 +89,7 @@ SCA_ActuatorSensor::~SCA_ActuatorSensor()
 
 
 
-bool SCA_ActuatorSensor::Evaluate(CValue* event)
+bool SCA_ActuatorSensor::Evaluate()
 {
        if (m_actuator)
        {
index 974b2e4..6655e08 100644 (file)
@@ -52,7 +52,7 @@ public:
        virtual ~SCA_ActuatorSensor();
        virtual CValue* GetReplica();
        virtual void Init();
-       virtual bool Evaluate(CValue* event);
+       virtual bool Evaluate();
        virtual bool    IsPositiveTrigger();
        virtual void    ReParent(SCA_IObject* parent);
        void Update();
index 4cd2dfb..dd3b55a 100644 (file)
@@ -51,9 +51,10 @@ SCA_AlwaysEventManager::SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr)
 
 void SCA_AlwaysEventManager::NextFrame()
 {
-       for (set<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
+       SG_DList::iterator<SCA_ISensor> it(m_sensors);
+       for (it.begin();!it.end();++it)
        {
-               (*i)->Activate(m_logicmgr, NULL);
+               (*it)->Activate(m_logicmgr);
        }
 }
 
index 19d19b6..ff02680 100644 (file)
@@ -86,7 +86,7 @@ bool SCA_AlwaysSensor::IsPositiveTrigger()
 
 
 
-bool SCA_AlwaysSensor::Evaluate(CValue* event)
+bool SCA_AlwaysSensor::Evaluate()
 {
        /* Nice! :) */
                //return true;
index 769e1e8..0f85a64 100644 (file)
@@ -43,7 +43,7 @@ public:
                                        PyTypeObject* T =&Type);
        virtual ~SCA_AlwaysSensor();
        virtual CValue* GetReplica();
-       virtual bool Evaluate(CValue* event);
+       virtual bool Evaluate();
        virtual bool IsPositiveTrigger();
        virtual void Init();
 
index 4752d0e..dcdae0b 100644 (file)
@@ -89,7 +89,7 @@ bool SCA_DelaySensor::IsPositiveTrigger()
        return (m_invert ? !m_lastResult : m_lastResult);
 }
 
-bool SCA_DelaySensor::Evaluate(CValue* event)
+bool SCA_DelaySensor::Evaluate()
 {
        bool trigger = false;
        bool result;
index 31394fd..5ccb33f 100644 (file)
@@ -51,7 +51,7 @@ public:
                                        PyTypeObject* T =&Type);
        virtual ~SCA_DelaySensor();
        virtual CValue* GetReplica();
-       virtual bool Evaluate(CValue* event);
+       virtual bool Evaluate();
        virtual bool IsPositiveTrigger();
        virtual void Init();
 
index e4fd037..d130154 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <assert.h>
 #include "SCA_EventManager.h"
+#include "SCA_ISensor.h"
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -43,16 +44,18 @@ SCA_EventManager::SCA_EventManager(EVENT_MANAGER_TYPE mgrtype)
 
 SCA_EventManager::~SCA_EventManager()
 {
+       // all sensors should be removed
+       assert(m_sensors.Empty());
 }
 
 void SCA_EventManager::RegisterSensor(class SCA_ISensor* sensor)
 {
-       m_sensors.insert(sensor);
+       m_sensors.AddBack(sensor);
 }
 
 void SCA_EventManager::RemoveSensor(class SCA_ISensor* sensor)
 {
-       m_sensors.erase(sensor);
+       sensor->Delink();
 }
 
 void SCA_EventManager::NextFrame(double curtime, double fixedtime)
index 9dbb5a6..5ff5584 100644 (file)
 #include <set>
 #include <algorithm>
 
+#include "SG_DList.h"
+
 class SCA_EventManager
 {
 protected:
        // use a set to speed-up insertion/removal
-       std::set <class SCA_ISensor*>                           m_sensors;
+       //std::set <class SCA_ISensor*>                         m_sensors;
+       SG_DList                m_sensors;
 
 public:
        enum EVENT_MANAGER_TYPE {
index a4e898a..8e044b8 100644 (file)
@@ -115,37 +115,14 @@ void SCA_ExpressionController::Trigger(SCA_LogicManager* logicmgr)
                        value->Release();
 
                }
-               //m_exprCache->Release();
-               //m_exprCache = NULL;
        }
 
-       /*
-
-       for (vector<SCA_ISensor*>::const_iterator is=m_linkedsensors.begin();
-       !(is==m_linkedsensors.end());is++)
-       {
-               SCA_ISensor* sensor = *is;
-               if (!sensor->IsPositiveTrigger())
-               {
-                       sensorresult = false;
-                       break;
-               }
-       }
-       
-         */
-       
-       CValue* newevent = new CBoolValue(expressionresult);
-
        for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
        !(i==m_linkedactuators.end());i++)
        {
                SCA_IActuator* actua = *i;
-               logicmgr->AddActiveActuator(actua,newevent);
+               logicmgr->AddActiveActuator(actua,expressionresult);
        }
-       //printf("expr %d.",expressionresult);
-       // every actuator that needs the event, has a it's own reference to it now so
-       // release it (so to be clear: if there is no actuator, it's deleted right now)
-       newevent->Release();
 }
 
 
index 214c7dd..5f71bb3 100644 (file)
@@ -37,46 +37,13 @@ using namespace std;
 SCA_IActuator::SCA_IActuator(SCA_IObject* gameobj,
                                                         PyTypeObject* T) :
        SCA_ILogicBrick(gameobj,T),
-       m_links(0)
+       m_links(0),
+       m_posevent(false),
+       m_negevent(false)
 {
        // nothing to do
 }
 
-
-
-void SCA_IActuator::RemoveAllEvents()
-{      // remove event queue!
-       for (vector<CValue*>::iterator i=m_events.begin(); !(i==m_events.end());i++)
-       {
-               (*i)->Release();
-       }
-       m_events.clear();
-}
-
-
-
-
-
-bool SCA_IActuator::IsNegativeEvent() const
-{
-       bool bPositiveEvent(false);
-       bool bNegativeEvent(false);
-
-       for (vector<CValue*>::const_iterator i=m_events.begin(); i!=m_events.end();++i)
-       {
-               if ((*i)->GetNumber() == 0.0f)
-               {
-                       bNegativeEvent = true;
-               } else {
-                       bPositiveEvent = true;
-               }
-       }
-
-       // if at least 1 positive event, return false
-       
-       return !bPositiveEvent && bNegativeEvent;
-}
-
 bool SCA_IActuator::Update(double curtime, bool frame)
 {
        if (frame)
@@ -94,7 +61,8 @@ bool SCA_IActuator::Update()
 void SCA_IActuator::ProcessReplica()
 {
        SCA_ILogicBrick::ProcessReplica();
-       m_events.clear();
+       RemoveAllEvents();
+       m_linkedcontrollers.clear();
 }
 
 
@@ -113,3 +81,36 @@ void SCA_IActuator::DecLink()
                m_links = 0;
        }
 }
+
+void SCA_IActuator::LinkToController(SCA_IController* controller)
+{
+       m_linkedcontrollers.push_back(controller);
+}
+
+void SCA_IActuator::UnlinkController(SCA_IController* controller)
+{
+       std::vector<class SCA_IController*>::iterator contit;
+       for (contit = m_linkedcontrollers.begin();!(contit==m_linkedcontrollers.end());++contit)
+       {
+               if ((*contit) == controller)
+               {
+                       *contit = m_linkedcontrollers.back();
+                       m_linkedcontrollers.pop_back();
+                       return;
+               }
+       }
+       printf("Missing link from actuator %s:%s to controller %s:%s\n", 
+               m_gameobj->GetName().ReadPtr(), GetName().ReadPtr(), 
+               controller->GetParent()->GetName().ReadPtr(), controller->GetName().ReadPtr());
+}
+
+void SCA_IActuator::UnlinkAllControllers()
+{
+       std::vector<class SCA_IController*>::iterator contit;
+       for (contit = m_linkedcontrollers.begin();!(contit==m_linkedcontrollers.end());++contit)
+       {
+               (*contit)->UnlinkActuator(this);
+       }
+       m_linkedcontrollers.clear();
+}
+
index e5f0a2c..3055e1d 100644 (file)
 #ifndef __KX_IACTUATOR
 #define __KX_IACTUATOR
 
-#include "SCA_ILogicBrick.h"
+#include "SCA_IController.h"
 #include <vector>
 
+/*
+ * Use of SG_DList : element of actuator being deactivated
+ *                   Head: SCA_LogicManager::m_removedActuators
+ * Use of SG_QList : element of activated actuator list of their owner
+ *                   Head: SCA_IObject::m_activeActuators
+ */
 class SCA_IActuator : public SCA_ILogicBrick
 {
        friend class SCA_LogicManager;
 protected:
        int                                      m_links;       // number of active links to controllers
                                                                        // when 0, the actuator is automatically stopped
-       std::vector<CValue*> m_events;
-       void RemoveAllEvents();
+       //std::vector<CValue*> m_events;
+       bool                         m_posevent;
+       bool                         m_negevent;
+
+       std::vector<class SCA_IController*>             m_linkedcontrollers;
+
+       void RemoveAllEvents()
+       {
+               m_posevent = false;
+               m_negevent = false;
+       }
+
 
 public:
        /**
@@ -75,9 +91,13 @@ public:
        /** 
         * Add an event to an actuator.
         */ 
-       void AddEvent(CValue* event)
+       //void AddEvent(CValue* event)
+       void AddEvent(bool event)
        {
-               m_events.push_back(event);
+               if (event)
+                       m_posevent = true;
+               else
+                       m_negevent = true;
        }
 
        virtual void ProcessReplica();
@@ -88,9 +108,38 @@ public:
         * not immediately clear. But usually refers to key-up events
         * or events where no action is required.
         */
-       bool IsNegativeEvent() const;
+       bool IsNegativeEvent() const
+       {
+               return !m_posevent && m_negevent;
+       }
+
        virtual ~SCA_IActuator();
 
+       /**
+        * remove this actuator from the list of active actuators
+        */
+       void Deactivate()
+       {
+               if (QDelink())
+                       // the actuator was in the active list
+                       if (m_gameobj->m_activeActuators.QEmpty())
+                               // the owner object has no more active actuators, remove it from the global list
+                               m_gameobj->m_activeActuators.Delink();
+       }
+
+       void Activate(SG_DList& head)
+       {
+               if (QEmpty())
+               {
+                       InsertActiveQList(m_gameobj->m_activeActuators);
+                       head.AddBack(&m_gameobj->m_activeActuators);
+               }
+       }
+
+       void    LinkToController(SCA_IController* controller);
+       void    UnlinkController(class SCA_IController* cont);
+       void    UnlinkAllControllers();
+
        void ClrLink() { m_links=0; }
        void IncLink() { m_links++; }
        void DecLink();
index 24509f6..f8b081e 100644 (file)
@@ -41,7 +41,8 @@ SCA_IController::SCA_IController(SCA_IObject* gameobj,
                                                                 PyTypeObject* T)
        :
        SCA_ILogicBrick(gameobj,T),
-       m_statemask(0)
+       m_statemask(0),
+       m_justActivated(false)
 {
 }
        
@@ -49,19 +50,19 @@ SCA_IController::SCA_IController(SCA_IObject* gameobj,
        
 SCA_IController::~SCA_IController()
 {
-       UnlinkAllActuators();
+       //UnlinkAllActuators();
 }
 
 
 
-const std::vector<class SCA_ISensor*>& SCA_IController::GetLinkedSensors()
+std::vector<class SCA_ISensor*>& SCA_IController::GetLinkedSensors()
 {
        return m_linkedsensors;
 }
 
 
 
-const std::vector<class SCA_IActuator*>& SCA_IController::GetLinkedActuators()
+std::vector<class SCA_IActuator*>& SCA_IController::GetLinkedActuators()
 {
        return m_linkedactuators;
 }
@@ -70,13 +71,14 @@ const std::vector<class SCA_IActuator*>& SCA_IController::GetLinkedActuators()
 
 void SCA_IController::UnlinkAllSensors()
 {
-       if (IsActive()) 
+       std::vector<class SCA_ISensor*>::iterator sensit;
+       for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
        {
-               std::vector<class SCA_ISensor*>::iterator sensit;
-               for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
+               if (IsActive()) 
                {
                        (*sensit)->DecLink();
                }
+               (*sensit)->UnlinkController(this);
        }
        m_linkedsensors.clear();
 }
@@ -85,34 +87,18 @@ void SCA_IController::UnlinkAllSensors()
 
 void SCA_IController::UnlinkAllActuators()
 {
-       if (IsActive()) 
+       std::vector<class SCA_IActuator*>::iterator actit;
+       for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
        {
-               std::vector<class SCA_IActuator*>::iterator actit;
-               for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
+               if (IsActive()) 
                {
                        (*actit)->DecLink();
                }
+               (*actit)->UnlinkController(this);
        }
        m_linkedactuators.clear();
 }
 
-
-
-/*
-void SCA_IController::Trigger(SCA_LogicManager* logicmgr)
-{
-       //for (int i=0;i<m_linkedactuators.size();i++)
-       for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
-       !(i==m_linkedactuators.end());i++)
-       {
-               SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
-               
-               logicmgr->AddActiveActuator(actua);
-       }
-
-}
-*/
-
 void SCA_IController::LinkToActuator(SCA_IActuator* actua)
 {
        m_linkedactuators.push_back(actua);
@@ -129,18 +115,18 @@ void      SCA_IController::UnlinkActuator(class SCA_IActuator* actua)
        {
                if ((*actit) == actua)
                {
-                       break;
-               }
-               
-       }
-       if (!(actit==m_linkedactuators.end()))
-       {
-               if (IsActive())
-               {
-                       (*actit)->DecLink();
+                       if (IsActive())
+                       {
+                               (*actit)->DecLink();
+                       }
+                       *actit = m_linkedactuators.back();
+                       m_linkedactuators.pop_back();
+                       return;
                }
-               m_linkedactuators.erase(actit);
        }
+       printf("Missing link from controller %s:%s to actuator %s:%s\n", 
+               m_gameobj->GetName().ReadPtr(), GetName().ReadPtr(), 
+               actua->GetParent()->GetName().ReadPtr(), actua->GetName().ReadPtr());
 }
 
 void SCA_IController::LinkToSensor(SCA_ISensor* sensor)
@@ -159,20 +145,21 @@ void SCA_IController::UnlinkSensor(class SCA_ISensor* sensor)
        {
                if ((*sensit) == sensor)
                {
-                       break;
-               }
-               
-       }
-       if (!(sensit==m_linkedsensors.end()))
-       {
-               if (IsActive())
-               {
-                       (*sensit)->DecLink();
+                       if (IsActive())
+                       {
+                               sensor->DecLink();
+                       }
+                       *sensit = m_linkedsensors.back();
+                       m_linkedsensors.pop_back();
+                       return;
                }
-               m_linkedsensors.erase(sensit);
        }
+       printf("Missing link from controller %s:%s to sensor %s:%s\n", 
+               m_gameobj->GetName().ReadPtr(), GetName().ReadPtr(), 
+               sensor->GetParent()->GetName().ReadPtr(), sensor->GetName().ReadPtr());
 }
 
+
 void SCA_IController::ApplyState(unsigned int state)
 {
        std::vector<class SCA_IActuator*>::iterator actit;
@@ -187,13 +174,13 @@ void SCA_IController::ApplyState(unsigned int state)
                        {
                                (*actit)->IncLink();
                        }
+
                        for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
                        {
                                (*sensit)->IncLink();
-                               // remember that this controller just activated that sensor
-                               (*sensit)->AddNewController(this);
                        }
                        SetActive(true);
+                       m_justActivated = true;
                }
        } else if (IsActive())
        {
@@ -206,6 +193,7 @@ void SCA_IController::ApplyState(unsigned int state)
                        (*sensit)->DecLink();
                }
                SetActive(false);
+               m_justActivated = false;
        }
 }
 
@@ -301,7 +289,7 @@ PyObject* SCA_IController::PyGetSensor(PyObject* value)
        for (unsigned int index=0;index<m_linkedsensors.size();index++)
        {
                SCA_ISensor* sensor = m_linkedsensors[index];
-               STR_String realname = sensor->GetName();
+               STR_String& realname = sensor->GetName();
                if (realname == scriptArg)
                {
                        return sensor->GetProxy();
index 7ed83bc..1b9d8fb 100644 (file)
 #include "SCA_ILogicBrick.h"
 #include "PyObjectPlus.h"
 
+/*
+ * Use of SG_DList element: none
+ * Use of SG_QList element: build ordered list of activated controller on the owner object
+ *                          Head: SCA_IObject::m_activeControllers
+ */
 class SCA_IController : public SCA_ILogicBrick
 {
        Py_Header;
@@ -39,21 +44,48 @@ protected:
        std::vector<class SCA_ISensor*>         m_linkedsensors;
        std::vector<class SCA_IActuator*>       m_linkedactuators;
        unsigned int                                            m_statemask;
+       bool                                                            m_justActivated;
 public:
        SCA_IController(SCA_IObject* gameobj,PyTypeObject* T);
        virtual ~SCA_IController();
        virtual void Trigger(class SCA_LogicManager* logicmgr)=0;
        void    LinkToSensor(SCA_ISensor* sensor);
        void    LinkToActuator(SCA_IActuator*);
-       const std::vector<class SCA_ISensor*>&          GetLinkedSensors();
-       const std::vector<class SCA_IActuator*>&        GetLinkedActuators();
+       std::vector<class SCA_ISensor*>&        GetLinkedSensors();
+       std::vector<class SCA_IActuator*>&      GetLinkedActuators();
+       void    ReserveActuator(int num)
+       {
+               m_linkedactuators.reserve(num);
+       }
        void    UnlinkAllSensors();
        void    UnlinkAllActuators();
        void    UnlinkActuator(class SCA_IActuator* actua);
        void    UnlinkSensor(class SCA_ISensor* sensor);
        void    SetState(unsigned int state) { m_statemask = state; }
        void    ApplyState(unsigned int state);
-       
+       void    Deactivate()
+       {
+               // the controller can only be part of a sensor m_newControllers list
+               Delink();
+       }
+       bool IsJustActivated()
+       {
+               return m_justActivated;
+       }
+       void ClrJustActivated()
+       {
+               m_justActivated = false;
+       }
+
+       void Activate(SG_DList& head)
+       {
+               if (QEmpty())
+               {
+                       InsertActiveQList(m_gameobj->m_activeControllers);
+                       head.AddBack(&m_gameobj->m_activeControllers);
+               }
+       }
+
        virtual PyObject* py_getattro(PyObject *attr);
        virtual PyObject* py_getattro_dict();
        virtual int py_setattro(PyObject *attr, PyObject *value);
index 6de9986..2dc80f5 100644 (file)
@@ -123,14 +123,14 @@ double SCA_ILogicBrick::GetNumber()
 
 
 
-STR_String SCA_ILogicBrick::GetName()
+STR_String& SCA_ILogicBrick::GetName()
 {
        return m_name;
 }
 
 
 
-void SCA_ILogicBrick::SetName(STR_String name)
+void SCA_ILogicBrick::SetName(const char *name)
 {
        m_name = name;
 }
@@ -222,7 +222,7 @@ PyMethodDef SCA_ILogicBrick::Methods[] = {
 
 PyAttributeDef SCA_ILogicBrick::Attributes[] = {
        KX_PYATTRIBUTE_RO_FUNCTION("owner",     SCA_ILogicBrick, pyattr_get_owner),
-       KX_PYATTRIBUTE_INT_RW("executePriority",0,100000,false,SCA_ILogicBrick,m_Execute_Ueber_Priority),
+       KX_PYATTRIBUTE_INT_RW("executePriority",0,100000,false,SCA_ILogicBrick,m_Execute_Priority),
        KX_PYATTRIBUTE_STRING_RO("name", SCA_ILogicBrick, m_name),
        {NULL} //Sentinel
 };
@@ -286,7 +286,7 @@ PyObject* SCA_ILogicBrick::PySetExecutePriority(PyObject* args)
                return NULL;
     }
        
-       m_Execute_Ueber_Priority = priority;
+       m_Execute_Priority = priority;
 
        Py_RETURN_NONE;
 }
@@ -296,7 +296,7 @@ PyObject* SCA_ILogicBrick::PySetExecutePriority(PyObject* args)
 PyObject* SCA_ILogicBrick::PyGetExecutePriority()
 {
        ShowDeprecationWarning("getExecutePriority()", "the executePriority property");
-       return PyInt_FromLong(m_Execute_Ueber_Priority);
+       return PyInt_FromLong(m_Execute_Priority);
 }
 
 
index b1384e8..90881c0 100644 (file)
@@ -71,8 +71,8 @@ public:
 
        virtual const STR_String &      GetText();
        virtual double          GetNumber();
-       virtual STR_String      GetName();
-       virtual void            SetName(STR_String name);
+       virtual STR_String&     GetName();
+       virtual void            SetName(const char *);
                
        bool                            IsActive()
        {
@@ -84,6 +84,13 @@ public:
                m_bActive=active;
        }
 
+       // insert in a QList at position corresponding to m_Execute_Priority
+       void                        InsertActiveQList(SG_QList& head)
+       {
+               SG_QList::iterator<SCA_ILogicBrick> it(head);
+               for(it.begin(); !it.end() && m_Execute_Priority > (*it)->m_Execute_Priority; ++it);
+               it.add_back(this);
+       }
 
        virtual bool            LessComparedTo(SCA_ILogicBrick* other);
        
index 7eaa5c6..8962c8e 100644 (file)
@@ -70,7 +70,7 @@ SCA_IObject::~SCA_IObject()
        }
        for (ita = m_actuators.begin(); !(ita==m_actuators.end()); ++ita)
        {
-               ((CValue*)(*ita))->Release();
+               (*ita)->Delete();
        }
 
        //T_InterpolatorList::iterator i;
@@ -110,7 +110,7 @@ void SCA_IObject::RegisterActuator(SCA_IActuator* act)
 void SCA_IObject::UnregisterActuator(SCA_IActuator* act)
 {
        SCA_ActuatorList::iterator ita;
-       for (ita = m_registeredActuators.begin(); ita != m_registeredActuators.end(); ita++)
+       for (ita = m_registeredActuators.begin(); ita != m_registeredActuators.end(); ++ita)
        {
                if ((*ita) == act) {
                        (*ita) = m_registeredActuators.back();
@@ -171,7 +171,7 @@ SCA_ISensor* SCA_IObject::FindSensor(const STR_String& sensorname)
 {
        SCA_ISensor* foundsensor = NULL;
 
-       for (SCA_SensorList::iterator its = m_sensors.begin();!(its==m_sensors.end());its++)
+       for (SCA_SensorList::iterator its = m_sensors.begin();!(its==m_sensors.end());++its)
        {
                if ((*its)->GetName() == sensorname)
                {
@@ -188,7 +188,7 @@ SCA_IController* SCA_IObject::FindController(const STR_String& controllername)
 {
        SCA_IController* foundcontroller = NULL;
 
-       for (SCA_ControllerList::iterator itc = m_controllers.begin();!(itc==m_controllers.end());itc++)
+       for (SCA_ControllerList::iterator itc = m_controllers.begin();!(itc==m_controllers.end());++itc)
        {
                if ((*itc)->GetName() == controllername)
                {
@@ -205,7 +205,7 @@ SCA_IActuator* SCA_IObject::FindActuator(const STR_String& actuatorname)
 {
        SCA_IActuator* foundactuator = NULL;
 
-       for (SCA_ActuatorList::iterator ita = m_actuators.begin();!(ita==m_actuators.end());ita++)
+       for (SCA_ActuatorList::iterator ita = m_actuators.begin();!(ita==m_actuators.end());++ita)
        {
                if ((*ita)->GetName() == actuatorname)
                {
@@ -272,7 +272,7 @@ void SCA_IObject::Suspend()
                SCA_SensorList::iterator i = m_sensors.begin();
                while (i != m_sensors.end()) {
                        (*i)->Suspend();
-                       i++;
+                       ++i;
                }
        }
 }
@@ -287,7 +287,7 @@ void SCA_IObject::Resume(void)
                SCA_SensorList::iterator i = m_sensors.begin();
                while (i != m_sensors.end()) {
                        (*i)->Resume();
-                       i++;
+                       ++i;
                }
        }
 }
@@ -307,7 +307,7 @@ void SCA_IObject::SetState(unsigned int state)
        if (tmpstate != m_state)
        {
                // update the status of the controllers
-               for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++)
+               for (contit = m_controllers.begin(); contit != m_controllers.end(); ++contit)
                {
                        (*contit)->ApplyState(tmpstate);
                }
@@ -315,7 +315,7 @@ void SCA_IObject::SetState(unsigned int state)
        m_state = state;
        if (m_state != tmpstate)
        {
-               for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++)
+               for (contit = m_controllers.begin(); contit != m_controllers.end(); ++contit)
                {
                        (*contit)->ApplyState(m_state);
                }
index 10cf551..281c72e 100644 (file)
@@ -52,10 +52,24 @@ class SCA_IObject : public CValue
        Py_Header;
        
 protected:
+       friend class SCA_IActuator;
+       friend class SCA_IController;
        SCA_SensorList         m_sensors;
        SCA_ControllerList     m_controllers;
        SCA_ActuatorList       m_actuators;
        SCA_ActuatorList       m_registeredActuators;   // actuators that use a pointer to this object
+
+       // SG_Dlist: element of objects with active actuators
+       //           Head: SCA_LogicManager::m_activeActuators
+       // SG_QList: Head of active actuators list on this object
+       //           Elements: SCA_IActuator
+       SG_QList                           m_activeActuators;
+       // SG_Dlist: element of objects with active controllers
+       //           Head: SCA_LogicManager::m_activeControllers
+       // SG_QList: Head of active controller list on this object
+       //           Elements: SCA_IController
+       SG_QList                           m_activeControllers;
+
        static class MT_Point3 m_sDummy;
 
        /**
@@ -95,10 +109,26 @@ public:
        {
                return m_actuators;
        }
+       SG_QList& GetActiveActuators()
+       {
+               return m_activeActuators;
+       }
 
        void AddSensor(SCA_ISensor* act);
+       void ReserveSensor(int num)
+       {
+               m_sensors.reserve(num);
+       }
        void AddController(SCA_IController* act);
+       void ReserveController(int num)
+       {
+               m_controllers.reserve(num);
+       }
        void AddActuator(SCA_IActuator* act);
+       void ReserveActuator(int num)
+       {
+               m_actuators.reserve(num);
+       }
        void RegisterActuator(SCA_IActuator* act);
        void UnregisterActuator(SCA_IActuator* act);
        
index 9fbeb70..86b176a 100644 (file)
@@ -50,7 +50,7 @@ SCA_IScene::SCA_IScene()
 void SCA_IScene::RemoveAllDebugProperties()
 {
        for (std::vector<SCA_DebugProp*>::iterator it = m_debugList.begin();
-               !(it==m_debugList.end());it++)
+               !(it==m_debugList.end());++it)
        {
                delete (*it);
        }
index d18778a..b641efc 100644 (file)
@@ -52,7 +52,7 @@ public:
                                                                                                int lifespan=0)=0;
        virtual void    RemoveObject(class CValue* gameobj)=0;
        virtual void    DelayedRemoveObject(class CValue* gameobj)=0;
-       virtual void    DelayedReleaseObject(class CValue* gameobj)=0;
+       //virtual void  DelayedReleaseObject(class CValue* gameobj)=0;
        
        virtual void    ReplaceMesh(class CValue* gameobj,
                                                                void* meshobj)=0;
index 1e9a452..2783bf1 100644 (file)
@@ -45,7 +45,7 @@ void  SCA_ISensor::ReParent(SCA_IObject* parent)
        SCA_ILogicBrick::ReParent(parent);
        // will be done when the sensor is activated
        //m_eventmgr->RegisterSensor(this);
-       this->SetActive(false);
+       //this->SetActive(false);
 }
 
 
@@ -77,6 +77,12 @@ SCA_ISensor::~SCA_ISensor()
        // intentionally empty
 }
 
+void SCA_ISensor::ProcessReplica()
+{
+       SCA_ILogicBrick::ProcessReplica();
+       m_linkedcontrollers.clear();
+}
+
 bool SCA_ISensor::IsPositiveTrigger() { 
        bool result = false;
        
@@ -150,29 +156,72 @@ void SCA_ISensor::RegisterToManager()
        // sensor is just activated, initialize it
        Init();
        m_state = false;
-       m_newControllers.erase(m_newControllers.begin(), m_newControllers.end());
        m_eventmgr->RegisterSensor(this);
 }
 
+void SCA_ISensor::LinkToController(SCA_IController* controller)
+{
+       m_linkedcontrollers.push_back(controller);
+}
+
+void SCA_ISensor::UnlinkController(SCA_IController* controller)
+{
+       std::vector<class SCA_IController*>::iterator contit;
+       for (contit = m_linkedcontrollers.begin();!(contit==m_linkedcontrollers.end());++contit)
+       {
+               if ((*contit) == controller)
+               {
+                       *contit = m_linkedcontrollers.back();
+                       m_linkedcontrollers.pop_back();
+                       return;
+               }
+       }
+       printf("Missing link from sensor %s:%s to controller %s:%s\n", 
+               m_gameobj->GetName().ReadPtr(), GetName().ReadPtr(), 
+               controller->GetParent()->GetName().ReadPtr(), controller->GetName().ReadPtr());
+}
+
+void SCA_ISensor::UnlinkAllControllers()
+{
+       std::vector<class SCA_IController*>::iterator contit;
+       for (contit = m_linkedcontrollers.begin();!(contit==m_linkedcontrollers.end());++contit)
+       {
+               (*contit)->UnlinkSensor(this);
+       }
+       m_linkedcontrollers.clear();
+}
+
 void SCA_ISensor::UnregisterToManager()
 {
        m_eventmgr->RemoveSensor(this);
+       m_links = 0;
 }
 
-void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr,     CValue* event)
+void SCA_ISensor::ActivateControllers(class SCA_LogicManager* logicmgr)
+{
+    for(vector<SCA_IController*>::const_iterator c= m_linkedcontrollers.begin();
+               c!=m_linkedcontrollers.end();++c)
+       {
+               SCA_IController* contr = *c;
+               if (contr->IsActive())
+                       logicmgr->AddTriggeredController(contr, this);
+       }
+}
+
+void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr)
 {
        
        // calculate if a __triggering__ is wanted
        // don't evaluate a sensor that is not connected to any controller
        if (m_links && !m_suspended) {
-               bool result = this->Evaluate(event);
+               bool result = this->Evaluate();
                // store the state for the rest of the logic system
                m_prev_state = m_state;
                m_state = this->IsPositiveTrigger();
                if (result) {
                        // the sensor triggered this frame
                        if (m_state || !m_tap) {
-                               logicmgr->AddActivatedSensor(this);     
+                               ActivateControllers(logicmgr);  
                                // reset these counters so that pulse are synchronized with transition
                                m_pos_ticks = 0;
                                m_neg_ticks = 0;
@@ -190,7 +239,7 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr,          CValue* event)
                                if (m_pos_ticks > m_pulse_frequency) {
                                        if ( m_state )
                                        {
-                                               logicmgr->AddActivatedSensor(this);
+                                               ActivateControllers(logicmgr);
                                                result = true;
                                        }
                                        m_pos_ticks = 0;
@@ -203,7 +252,8 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr,          CValue* event)
                                if (m_neg_ticks > m_pulse_frequency) {
                                        if (!m_state )
                                        {
-                                               logicmgr->AddActivatedSensor(this);
+                                               ActivateControllers(logicmgr);
+                                               result = true;
                                        }
                                        m_neg_ticks = 0;
                                }
@@ -218,27 +268,24 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr,        CValue* event)
                                if (m_prev_state)
                                {
                                        // but it triggered on previous frame => send a negative pulse
-                                       logicmgr->AddActivatedSensor(this);     
+                                       ActivateControllers(logicmgr);
+                                       result = true;
                                }
                                // in any case, absence of trigger means sensor off
                                m_state = false;
                        }
                }
-               if (!m_newControllers.empty())
+               if (!result && m_level)
                {
-                       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(vector<SCA_IController*>::const_iterator c= m_linkedcontrollers.begin();
+                               c!=m_linkedcontrollers.end();++c)
                        {
-                               // 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);
-                               }
+                               SCA_IController* contr = *c;
+                               if (contr->IsJustActivated())
+                                       logicmgr->AddTriggeredController(contr, this);
                        }
-                       // clear the list. Instead of using clear, which also release the memory,
-                       // use erase, which keeps the memory available for next time.
-                       m_newControllers.erase(m_newControllers.begin(), m_newControllers.end());
                }
        } 
 }
index 7bbef5f..9aeda72 100644 (file)
 #ifndef __SCA_ISENSOR
 #define __SCA_ISENSOR
 
-#include "SCA_ILogicBrick.h"
+#include "SCA_IController.h"
 
 #include <vector>
 
 /**
  * Interface Class for all logic Sensors. Implements
- * pulsemode,pulsefrequency */
+ * pulsemode,pulsefrequency 
+ * Use of SG_DList element: link sensors to their respective event manager
+ *                          Head: SCA_EventManager::m_sensors
+ * Use of SG_QList element: not used
+ */
 class SCA_ISensor : public SCA_ILogicBrick
 {
        Py_Header;
+protected:
        class SCA_EventManager* m_eventmgr;
 
        /** Pulse positive  pulses? */
@@ -83,8 +88,7 @@ class SCA_ISensor : public SCA_ILogicBrick
        /** previous state (for tap option) */
        bool m_prev_state;
 
-       /** list of controllers that have just activated this sensor because of a state change */
-       std::vector<class SCA_IController*> m_newControllers;
+       std::vector<class SCA_IController*>             m_linkedcontrollers;
 
 public:
        SCA_ISensor(SCA_IObject* gameobj,
@@ -97,8 +101,8 @@ public:
        /* an implementation on this level. It requires an evaluate on the lower */
        /* level of individual sensors. Mapping the old activate()s is easy.     */
        /* The IsPosTrig() also has to change, to keep things consistent.        */
-       void Activate(class SCA_LogicManager* logicmgr,CValue* event);
-       virtual bool Evaluate(CValue* event) = 0;
+       void Activate(class SCA_LogicManager* logicmgr);
+       virtual bool Evaluate() = 0;
        virtual bool IsPositiveTrigger();
        virtual void Init();
 
@@ -121,6 +125,16 @@ public:
 
        virtual void RegisterToManager();
        virtual void UnregisterToManager();
+       void ReserveController(int num)
+       {
+               m_linkedcontrollers.reserve(num);
+       }
+       void LinkToController(SCA_IController* controller);
+       void UnlinkController(SCA_IController* controller);
+       void UnlinkAllControllers();
+       void ActivateControllers(class SCA_LogicManager* logicmgr);
+
+       virtual void ProcessReplica();
 
        virtual double GetNumber();
 
@@ -139,8 +153,6 @@ public:
        /** Resume sensing. */
        void Resume();
 
-       void AddNewController(class SCA_IController* controller)
-               { m_newControllers.push_back(controller); }
        void ClrLink()
                { m_links = 0; }
        void IncLink()
index f3ce549..ff8f3b1 100644 (file)
@@ -59,20 +59,21 @@ SCA_JoystickManager::~SCA_JoystickManager()
 
 void SCA_JoystickManager::NextFrame(double curtime,double deltatime)
 {
-       if (m_sensors.size()==0) {
+       if (m_sensors.Empty()) {
                return;
        }
        else {
-               set<SCA_ISensor*>::iterator it;
+               ;
 #ifndef        DISABLE_SDL
                SCA_Joystick::HandleEvents(); /* Handle all SDL Joystick events */
 #endif
-               for (it = m_sensors.begin(); it != m_sensors.end(); it++)
+               SG_DList::iterator<SCA_JoystickSensor> it(m_sensors);
+               for (it.begin();!it.end();++it)
                {
-                       SCA_JoystickSensor* joysensor = (SCA_JoystickSensor*)(*it);
+                       SCA_JoystickSensor* joysensor = *it;
                        if(!joysensor->IsSuspended())
                        {
-                               joysensor->Activate(m_logicmgr, NULL);
+                               joysensor->Activate(m_logicmgr);
                        }
                }
        }
index 34d63a4..906d454 100644 (file)
@@ -102,7 +102,7 @@ bool SCA_JoystickSensor::IsPositiveTrigger()
 }
 
 
-bool SCA_JoystickSensor::Evaluate(CValue* event)
+bool SCA_JoystickSensor::Evaluate()
 {
        SCA_Joystick *js = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
        bool result = false;
index 20fff66..e8185d1 100644 (file)
@@ -110,7 +110,7 @@ public:
        virtual ~SCA_JoystickSensor();
        virtual CValue* GetReplica();
        
-       virtual bool Evaluate(CValue* event);
+       virtual bool Evaluate();
        virtual bool IsPositiveTrigger();
        virtual void Init();
        
index 6a96442..279adab 100644 (file)
@@ -62,12 +62,11 @@ void SCA_KeyboardManager::NextFrame()
 {
        //const SCA_InputEvent& event = GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode)=0;
   //   cerr << "SCA_KeyboardManager::NextFrame"<< endl;
-       set<SCA_ISensor*>::iterator it;
-       for (it=m_sensors.begin(); it != m_sensors.end(); it++)
+       SG_DList::iterator<SCA_ISensor> it(m_sensors);
+       for (it.begin();!it.end();++it)
        {
-               (*it)->Activate(m_logicmanager,NULL);
+               (*it)->Activate(m_logicmanager);
        }
-
 }
 
 bool SCA_KeyboardManager::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
index a9ea427..f8ee8ed 100644 (file)
@@ -118,7 +118,7 @@ bool SCA_KeyboardSensor::TriggerOnAllKeys()
 
 
 
-bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
+bool SCA_KeyboardSensor::Evaluate()
 {
        bool result    = false;
        bool reset     = m_reset && m_level;
index 1dd6ea2..033225c 100644 (file)
@@ -102,7 +102,7 @@ public:
 
 
        short int GetHotkey();
-       virtual bool Evaluate(CValue* event);
+       virtual bool Evaluate();
        virtual bool IsPositiveTrigger();
        bool    TriggerOnAllKeys();
 
index c43875a..74370f8 100644 (file)
@@ -49,42 +49,12 @@ SCA_LogicManager::SCA_LogicManager()
 
 SCA_LogicManager::~SCA_LogicManager()
 {
-       /* AddRef() is not used when the objects are added to m_mapStringToGameObjects
-          so Release() should not be used either. The memory leak big is fixed
-          in BL_ConvertBlenderObjects()
-
-       int numgameobj = m_mapStringToGameObjects.size();
-       for (int i = 0; i < numgameobj; i++)
-       {
-               CValue** gameobjptr = m_mapStringToGameObjects.at(i);
-               assert(gameobjptr);
-               if (gameobjptr)
-                       (*gameobjptr)->Release();
-    
-       }
-       */
-       /*for (int i=0;i<m_sensorcontrollermap.size();i++)
-       {
-               vector<SCA_IController*>* controllerarray = *(m_sensorcontrollermap[i]);
-               delete controllerarray;
-       }
-       */
-       for (vector<SCA_EventManager*>::iterator it = m_eventmanagers.begin();!(it==m_eventmanagers.end());it++)
+       for (vector<SCA_EventManager*>::iterator it = m_eventmanagers.begin();!(it==m_eventmanagers.end());++it)
        {
                delete (*it);
        }
        m_eventmanagers.clear();
-       m_sensorcontrollermapje.clear();
-       m_removedActuators.clear();
-       m_activeActuators.clear();
-}
-
-// this function is a performance helper when the scene is destoyed
-// without it, the map updated for each object... a massive slow down when there are
-// large number of objects. By clearing the map upfront we avoid the waster of time.
-void SCA_LogicManager::RemoveSensorMap()
-{
-       m_sensorcontrollermapje.clear();
+       assert(m_activeActuators.Empty());
 }
 
 /*
@@ -178,62 +148,30 @@ void* SCA_LogicManager::FindBlendObjByGameMeshName(const STR_String& gamemeshnam
 
 void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor)
 {
-       sensormap_t::const_iterator mit = m_sensorcontrollermapje.find(sensor);
-       if (mit != m_sensorcontrollermapje.end())
-       {
-               const controllerlist& contlist = mit->second;
-               for (controllerlist::const_iterator c= contlist.begin();!(c==contlist.end());c++)
-               {
-                       (*c)->UnlinkSensor(sensor);
-               }
-               m_sensorcontrollermapje.erase(sensor);
-       }
+       sensor->UnlinkAllControllers();
        sensor->UnregisterToManager();
 }
 
 void SCA_LogicManager::RemoveController(SCA_IController* controller)
 {
-       sensormap_t::iterator sit;
-       sit = m_sensorcontrollermapje.begin();
-       if (sit==m_sensorcontrollermapje.end())
-       {
-               //TRICK: either there is no sensor at all, or the scene is being deleted 
-               //(see KX_Scene::~KX_Scene()). In the first case, this is harmless. 
-               //In the second case, we cannot rely on the sensor being still available, 
-               //make the controller inactive to avoid link count. 
-               //Need a better solution, maybe something similar to m_removedActuators.
-               controller->SetActive(false);
-       }
        controller->UnlinkAllSensors();
        controller->UnlinkAllActuators();
-       for (;!(sit==m_sensorcontrollermapje.end());++sit)
-       {
-               (*sit).second.remove(controller);
-       }
+       controller->Deactivate();
 }
 
 
-void SCA_LogicManager::RemoveDestroyedActuator(SCA_IActuator* actuator)
+void SCA_LogicManager::RemoveActuator(SCA_IActuator* actuator)
 {
-       m_removedActuators.push_back(SmartActuatorPtr(actuator,0));
-       // take care that no controller can use this actuator again !
-
-       sensormap_t::const_iterator sit;
-       for (sit = m_sensorcontrollermapje.begin();!(sit==m_sensorcontrollermapje.end());++sit)
-       {
-               const controllerlist& contlist = sit->second;
-               for (list<SCA_IController*>::const_iterator c= contlist.begin();!(c==contlist.end());c++)
-               {
-                       (*c)->UnlinkActuator(actuator);
-               }
-       }
+       actuator->UnlinkAllControllers();
+       actuator->Deactivate();
+       actuator->SetActive(false);
 }
 
 
 
 void SCA_LogicManager::RegisterToSensor(SCA_IController* controller,SCA_ISensor* sensor)
 {
-    m_sensorcontrollermapje[sensor].push_back(controller);
+       sensor->LinkToController(controller);
        controller->LinkToSensor(sensor);
 }
 
@@ -241,6 +179,7 @@ void SCA_LogicManager::RegisterToSensor(SCA_IController* controller,SCA_ISensor*
 
 void SCA_LogicManager::RegisterToActuator(SCA_IController* controller,SCA_IActuator* actua)
 {
+       actua->LinkToController(controller);
        controller->LinkToActuator(actua);
 }
 
@@ -251,88 +190,60 @@ void SCA_LogicManager::BeginFrame(double curtime, double fixedtime)
        for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin(); !(ie==m_eventmanagers.end()); ie++)
                (*ie)->NextFrame(curtime, fixedtime);
 
-       // for this frame, look up for activated sensors, and build the collection of triggered controllers
-       // int numsensors = this->m_activatedsensors.size(); /*unused*/
-
-       for (vector<SCA_ISensor*>::const_iterator is=m_activatedsensors.begin();
-       !(is==m_activatedsensors.end());is++)
+       for(SG_QList* obj = (SG_QList*)m_triggeredControllerSet.Remove();
+               obj != NULL;
+               obj = (SG_QList*)m_triggeredControllerSet.Remove())
        {
-               SCA_ISensor* sensor = *is;
-        const controllerlist& contlist = m_sensorcontrollermapje[sensor];
-        for (list<SCA_IController*>::const_iterator c= contlist.begin();
-                       !(c==contlist.end());c++)
+               for(SCA_IController* contr = (SCA_IController*)obj->QRemove();
+                       contr != NULL;
+                       contr = (SCA_IController*)obj->QRemove())
                {
-                               SCA_IController* contr = *c;//controllerarray->at(c);
-                               if (contr->IsActive())
-                               {
-                                       m_triggeredControllerSet.insert(SmartControllerPtr(contr,0));
-                                       // So that the controller knows which sensor has activited it.
-                                       // Only needed for the python controller though.
-                                       if (contr->GetType() == &SCA_PythonController::Type)
-                                       {
-                                               SCA_PythonController* pythonController = (SCA_PythonController*)contr;
-                                               pythonController->AddTriggeredSensor(sensor);
-                                       }
-                               }
+                       contr->Trigger(this);
+                       contr->ClrJustActivated();
                }
-               //sensor->SetActive(false);
-       }
-
-       
-       // int numtriggered = triggeredControllerSet.size(); /*unused*/
-       for (set<SmartControllerPtr>::iterator tit=m_triggeredControllerSet.begin();
-       !(tit==m_triggeredControllerSet.end());tit++)
-       {
-               (*tit)->Trigger(this);
        }
-       m_triggeredControllerSet.clear();
 }
 
 
 
 void SCA_LogicManager::UpdateFrame(double curtime, bool frame)
 {
-       vector<SmartActuatorPtr>::iterator ra;
-       for (ra = m_removedActuators.begin(); !(ra == m_removedActuators.end()); ra++)
-       {
-               m_activeActuators.erase(*ra);
-               (*ra)->SetActive(false);
-       }
-       m_removedActuators.clear();
-       
-       // About to run actuators, but before update the sensors for those which depends on actuators
        for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin(); !(ie==m_eventmanagers.end()); ie++)
                (*ie)->UpdateFrame();
 
-       for (set<SmartActuatorPtr>::iterator ia = m_activeActuators.begin();!(ia==m_activeActuators.end());ia++)
+       SG_DList::iterator<SG_QList> io(m_activeActuators);
+       for (io.begin(); !io.end(); ++io)
        {
-               //SCA_IActuator* actua = *ia;
-               if (!(*ia)->Update(curtime, frame))
-               {
-                       //*ia = m_activeactuators.back();
-                       m_removedActuators.push_back(*ia);
-                       
-                       (*ia)->SetActive(false);
-                       //m_activeactuators.pop_back();
-               } else if ((*ia)->IsNoLink())
+               SG_QList::iterator<SCA_IActuator> ia(*(*io));
+               for (ia.begin(); !ia.end(); ++ia)
                {
-                       // 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);
+                       SCA_IActuator* actua = *ia;
+                       if (!actua->Update(curtime, frame))
+                       {
+                               // cannot deactive the actuator now as it will disturb the list
+                               m_removedActuators.AddBack(actua);
+                               actua->SetActive(false);
+                       } else if (actua->IsNoLink())
+                       {
+                               // This actuator has no more links but it still active
+                               // make sure it will get a negative event on next frame to stop it
+                               // Do this check after Update() rather than before to make sure
+                               // that all the actuators that are activated at same time than a state
+                               // actuator have a chance to execute. 
+                               bool event = false;
+                               actua->RemoveAllEvents();
+                               actua->AddEvent(event);
+                       }
                }
        }
-       
-       for ( ra = m_removedActuators.begin(); !(ra == m_removedActuators.end()); ra++)
+
+       for (SCA_IActuator* act = (SCA_IActuator*)m_removedActuators.Remove();
+               act != NULL;
+               act = (SCA_IActuator*)m_removedActuators.Remove())
        {
-               m_activeActuators.erase(*ra);
-               (*ra)->SetActive(false);
+               act->Deactivate();
+               act->SetActive(false);
        }
-       m_removedActuators.clear();
 }
 
 
@@ -381,39 +292,17 @@ void SCA_LogicManager::RegisterActionName(const STR_String& actname,void* action
 
 void SCA_LogicManager::EndFrame()
 {
-       for (vector<SCA_ISensor*>::const_iterator is=m_activatedsensors.begin();
-       !(is==m_activatedsensors.end());is++)
-       {
-               SCA_ISensor* sensor = *is;
-               sensor->SetActive(false);
-       }
-       m_activatedsensors.clear();
-
        for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin();
        !(ie==m_eventmanagers.end());ie++)
        {
                (*ie)->EndFrame();
        }
-
-
 }
 
 
-
-void SCA_LogicManager::AddActivatedSensor(SCA_ISensor* sensor)
-{
-       // each frame, only add sensor once, and to avoid a seek, or bloated container
-       // hold a flag in each sensor, with the 'framenr'
-       if (!sensor->IsActive())
-       {
-               sensor->SetActive(true);
-               m_activatedsensors.push_back(sensor);
-       }
-}
-
 void SCA_LogicManager::AddTriggeredController(SCA_IController* controller, SCA_ISensor* sensor)
 {
-       m_triggeredControllerSet.insert(SmartControllerPtr(controller,0));
+       controller->Activate(m_triggeredControllerSet);
        // so that the controller knows which sensor has activited it
        // only needed for python controller
        if (controller->GetType() == &SCA_PythonController::Type)
@@ -424,14 +313,11 @@ void SCA_LogicManager::AddTriggeredController(SCA_IController* controller, SCA_I
 }
 
 
-void SCA_LogicManager::AddActiveActuator(SCA_IActuator* actua,CValue* event)
+void SCA_LogicManager::AddActiveActuator(SCA_IActuator* actua,bool event)
 {
-       if (!actua->IsActive())
-       {
-               actua->SetActive(true);
-               m_activeActuators.insert(SmartActuatorPtr(actua,0));
-       }
-       actua->AddEvent(event->AddRef());
+       actua->SetActive(true);
+       actua->Activate(m_activeActuators);
+       actua->AddEvent(event);
 }
 
 
@@ -453,109 +339,3 @@ SCA_EventManager* SCA_LogicManager::FindEventManager(int eventmgrtype)
        }
        return eventmgr;
 }
-
-
-
-SmartActuatorPtr::SmartActuatorPtr(const SmartActuatorPtr& other)
-{
-       this->m_actuator = other.m_actuator;
-       this->m_actuator->AddRef();
-}
-
-
-
-SmartActuatorPtr::SmartActuatorPtr(SCA_IActuator* actua,int dummy)
-: m_actuator(actua)
-{
-       actua->AddRef();
-}
-
-
-
-SmartActuatorPtr::~SmartActuatorPtr()
-{
-       m_actuator->Release();
-}
-
-
-
-bool SmartActuatorPtr::operator <(const SmartActuatorPtr& other) const
-{
-       
-       return m_actuator->LessComparedTo(*other);
-}
-
-
-
-bool SmartActuatorPtr::operator ==(const SmartActuatorPtr& other) const
-{
-       bool result2 = other->LessComparedTo(m_actuator);
-       return (m_actuator->LessComparedTo(*other) && result2);
-}
-
-
-
-SCA_IActuator* SmartActuatorPtr::operator->() const
-{
-       return m_actuator;
-}
-
-
-
-SCA_IActuator*  SmartActuatorPtr::operator*() const
-{
-       return m_actuator;
-}
-
-
-
-SmartControllerPtr::SmartControllerPtr(const SmartControllerPtr& copy)
-{
-       this->m_controller = copy.m_controller;
-       this->m_controller->AddRef();
-}
-
-
-
-SmartControllerPtr::SmartControllerPtr(SCA_IController* contr,int dummy)
-: m_controller(contr)
-{
-       m_controller->AddRef();
-}
-
-
-
-SmartControllerPtr::~SmartControllerPtr()
-{
-       m_controller->Release();
-}
-
-
-
-bool   SmartControllerPtr::operator <(const SmartControllerPtr& other) const
-{
-       return m_controller->LessComparedTo(*other);
-}
-
-
-
-bool   SmartControllerPtr::operator ==(const SmartControllerPtr& other) const
-{
-       return (m_controller->LessComparedTo(*other) && other->LessComparedTo(m_controller));
-}
-
-
-
-SCA_IController*       SmartControllerPtr::operator->() const
-{
-       return m_controller;
-}
-
-
-
-SCA_IController*       SmartControllerPtr::operator*() const
-{
-       return m_controller;
-}
-
-
index 17971c2..0d610c9 100644 (file)
@@ -43,6 +43,7 @@
 #include "GEN_Map.h"
 #include "STR_HashedString.h"
 #include "Value.h"
+#include "SG_QList.h"
 
 #include "KX_HashedPtr.h"
 
@@ -65,44 +66,17 @@ typedef std::map<class SCA_ISensor*,controllerlist > sensormap_t;
 
 #include "SCA_ILogicBrick.h"
 
-// todo: make this into a template, but first I want to think about what exactly to put in
-class  SmartActuatorPtr
-{
-       SCA_IActuator*  m_actuator;
-public:
-       SmartActuatorPtr(SCA_IActuator* actua,int dummy);
-       SmartActuatorPtr(const SmartActuatorPtr& other);
-       virtual ~SmartActuatorPtr();
-       bool operator <(const SmartActuatorPtr& other) const;
-       bool operator ==(const SmartActuatorPtr& other) const;
-       SCA_IActuator*  operator->() const;
-       SCA_IActuator* operator*() const;
-
-};
-
-class  SmartControllerPtr
-{
-       SCA_IController*        m_controller;
-public:
-       SmartControllerPtr(const SmartControllerPtr& copy);
-       SmartControllerPtr(SCA_IController* contr,int dummy);
-       virtual ~SmartControllerPtr();
-       bool    operator <(const SmartControllerPtr& other) const;
-       bool    operator ==(const SmartControllerPtr& other) const;
-       SCA_IController*        operator->() const;
-       SCA_IController*        operator*() const; 
-
-};
 
 class SCA_LogicManager
 {
        vector<class SCA_EventManager*>         m_eventmanagers;
        
-       vector<class SCA_ISensor*>                      m_activatedsensors;
-       set<class SmartActuatorPtr>                     m_activeActuators;
-       set<class SmartControllerPtr>           m_triggeredControllerSet;
-
-       sensormap_t                                                     m_sensorcontrollermapje;
+       // SG_DList: Head of objects having activated actuators
+       //           element: SCA_IObject::m_activeActuators
+       SG_DList                                                        m_activeActuators;
+       // SG_DList: Head of objects having activated controllers
+       //           element: SCA_IObject::m_activeControllers
+       SG_DList                                                        m_triggeredControllerSet;
 
        // need to find better way for this
        // also known as FactoryManager...
@@ -113,12 +87,11 @@ class SCA_LogicManager
        GEN_Map<STR_HashedString,void*>         m_map_gamemeshname_to_blendobj;
        GEN_Map<CHashedPtr,void*>                       m_map_blendobj_to_gameobj;
 
-       vector<SmartActuatorPtr>                        m_removedActuators;
+       // head of actuators being deactivated during the logic update
+       SG_DList                                                        m_removedActuators;
 public:
        SCA_LogicManager();
        virtual ~SCA_LogicManager();
-       // can ONLY be used during scene destruction, avoid massive slow down when scene has many many objects
-       void RemoveSensorMap();         
 
        //void  SetKeyboardManager(SCA_KeyboardManager* keyboardmgr) { m_keyboardmgr=keyboardmgr;}
        void    RegisterEventManager(SCA_EventManager* eventmgr);
@@ -130,8 +103,7 @@ public:
        void    BeginFrame(double curtime, double fixedtime);
        void    UpdateFrame(double curtime, bool frame);
        void    EndFrame();
-       void    AddActivatedSensor(SCA_ISensor* sensor);
-       void    AddActiveActuator(SCA_IActuator* sensor,class CValue* event);
+       void    AddActiveActuator(SCA_IActuator* sensor,bool event);
        void    AddTriggeredController(SCA_IController* controller, SCA_ISensor* sensor);
        SCA_EventManager*       FindEventManager(int eventmgrtype);
        
@@ -142,7 +114,7 @@ public:
        */
        void    RemoveSensor(SCA_ISensor* sensor);
        void    RemoveController(SCA_IController* controller);
-       void    RemoveDestroyedActuator(SCA_IActuator* actuator);
+       void    RemoveActuator(SCA_IActuator* actuator);
        
 
        // for the scripting... needs a FactoryManager later (if we would have time... ;)
index ca875da..d407647 100644 (file)
@@ -75,8 +75,8 @@ void SCA_MouseManager::NextFrame()
 {
        if (m_mousedevice)
        {
-               set<SCA_ISensor*>::iterator it;
-               for (it=m_sensors.begin(); it!=m_sensors.end(); it++)
+               SG_DList::iterator<SCA_ISensor> it(m_sensors);
+               for (it.begin();!it.end();++it)
                {
                        SCA_MouseSensor* mousesensor = (SCA_MouseSensor*)(*it);
                        // (0,0) is the Upper Left corner in our local window
@@ -93,7 +93,7 @@ void SCA_MouseManager::NextFrame()
                                mousesensor->setX(mx);
                                mousesensor->setY(my);
                                
-                               mousesensor->Activate(m_logicmanager,NULL);
+                               mousesensor->Activate(m_logicmanager);
                        }
                }
        }
index 46be6ad..c5e1c3c 100644 (file)
@@ -144,7 +144,7 @@ SCA_IInputDevice::KX_EnumInputs SCA_MouseSensor::GetHotKey()
 
 
 
-bool SCA_MouseSensor::Evaluate(CValue* event)
+bool SCA_MouseSensor::Evaluate()
 {
        bool result = false;
        bool reset = m_reset && m_level;
index 5282374..6d6302b 100644 (file)
@@ -97,7 +97,7 @@ class SCA_MouseSensor : public SCA_ISensor
 
        virtual ~SCA_MouseSensor();
        virtual CValue* GetReplica();
-       virtual bool Evaluate(CValue* event);
+       virtual bool Evaluate();
        virtual void Init();
        virtual bool IsPositiveTrigger();
        short int GetModeKey();
index df62f91..d27aea5 100644 (file)
@@ -73,19 +73,12 @@ void SCA_NANDController::Trigger(SCA_LogicManager* logicmgr)
                }
        }
        
-       CValue* newevent = new CBoolValue(sensorresult);
-
        for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
        !(i==m_linkedactuators.end());i++)
        {
-               SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
-               logicmgr->AddActiveActuator(actua,newevent);
+               SCA_IActuator* actua = *i;
+               logicmgr->AddActiveActuator(actua,sensorresult);
        }
-
-       // every actuator that needs the event, has a it's own reference to it now so
-       // release it (so to be clear: if there is no actuator, it's deleted right now)
-       newevent->Release();
-
 }
 
 
index b87af96..6c91416 100644 (file)
@@ -73,19 +73,12 @@ void SCA_NORController::Trigger(SCA_LogicManager* logicmgr)
                }
        }
        
-       CValue* newevent = new CBoolValue(sensorresult);
-
        for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
        !(i==m_linkedactuators.end());i++)
        {
-               SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
-               logicmgr->AddActiveActuator(actua,newevent);
+               SCA_IActuator* actua = *i;
+               logicmgr->AddActiveActuator(actua,sensorresult);
        }
-
-       // every actuator that needs the event, has a it's own reference to it now so
-       // release it (so to be clear: if there is no actuator, it's deleted right now)
-       newevent->Release();
-
 }
 
 
index 7aa58b6..42c0a67 100644 (file)
@@ -80,17 +80,12 @@ void SCA_ORController::Trigger(SCA_LogicManager* logicmgr)
                is++;
        }
        
-       CValue* newevent = new CBoolValue(sensorresult);
-
        for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
        !(i==m_linkedactuators.end());i++)
        {
-               SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
-               logicmgr->AddActiveActuator(actua,newevent);
+               SCA_IActuator* actua = *i;
+               logicmgr->AddActiveActuator(actua,sensorresult);
        }
-
-
-       newevent->Release();
 }
 
 /* ------------------------------------------------------------------------- */
index e5e3f9c..7644653 100644 (file)
@@ -50,8 +50,9 @@ SCA_PropertyEventManager::~SCA_PropertyEventManager()
 void SCA_PropertyEventManager::NextFrame()
 {
        // check for changed properties
-       for (set<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
+       SG_DList::iterator<SCA_ISensor> it(m_sensors);
+       for (it.begin();!it.end();++it)
        {
-               (*it)->Activate(m_logicmgr,NULL);
+               (*it)->Activate(m_logicmgr);
        }
 }
index e8a291b..2632cbd 100644 (file)
@@ -37,6 +37,7 @@
 #include "StringValue.h"
 #include "SCA_EventManager.h"
 #include "SCA_LogicManager.h"
+#include "BoolValue.h"
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -152,7 +153,7 @@ SCA_PropertySensor::~SCA_PropertySensor()
 
 
 
-bool SCA_PropertySensor::Evaluate(CValue* event)
+bool SCA_PropertySensor::Evaluate()
 {
        bool result = CheckPropertyCondition();
        bool reset = m_reset && m_level;
@@ -182,17 +183,14 @@ bool      SCA_PropertySensor::CheckPropertyCondition()
                        CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
                        if (!orgprop->IsError())
                        {
-                               STR_String testprop = orgprop->GetText();
+                               const STR_String& testprop = orgprop->GetText();
                                // Force strings to upper case, to avoid confusion in
                                // bool tests. It's stupid the prop's identity is lost
                                // on the way here...
-                               if ((testprop == "TRUE") || (testprop == "FALSE")) {
-                                       STR_String checkprop = m_checkpropval;
-                                       checkprop.Upper();
-                                       result = (testprop == checkprop);
-                               } else {
-                                       result = (orgprop->GetText() == m_checkpropval);
+                               if ((&testprop == &CBoolValue::sTrueString) || (&testprop == &CBoolValue::sFalseString)) {
+                                       m_checkpropval.Upper();
                                }
+                               result = (testprop == m_checkpropval);
                        }
                        orgprop->Release();
 
@@ -232,8 +230,8 @@ bool        SCA_PropertySensor::CheckPropertyCondition()
                                        CValue* vallie = m_range_expr->Calculate();
                                        if (vallie)
                                        {
-                                               STR_String errtext = vallie->GetText();
-                                               if (errtext == "TRUE")
+                                               const STR_String& errtext = vallie->GetText();
+                                               if (&errtext == &CBoolValue::sTrueString)
                                                {
                                                        result = true;
                                                } else
index 7abf4d4..538ecd6 100644 (file)
@@ -81,7 +81,7 @@ public:
        void    PrecalculateRangeExpression();
        bool    CheckPropertyCondition();
 
-       virtual bool Evaluate(CValue* event);
+       virtual bool Evaluate();
        virtual bool    IsPositiveTrigger();
        virtual CValue*         FindIdentifier(const STR_String& identifiername);
 
index 063a7b4..212366e 100644 (file)
@@ -178,7 +178,7 @@ SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value)
        if (PyString_Check(value)) {
                /* get the actuator from the name */
                char *name= PyString_AsString(value);
-               for(it = lacts.begin(); it!= lacts.end(); it++) {
+               for(it = lacts.begin(); it!= lacts.end(); ++it) {
                        if( name == (*it)->GetName() ) {
                                return *it;
                        }
@@ -186,7 +186,7 @@ SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value)
        }
        else if (BGE_PROXY_CHECK_TYPE(value)) {
                PyObjectPlus *value_plus= BGE_PROXY_REF(value);
-               for(it = lacts.begin(); it!= lacts.end(); it++) {
+               for(it = lacts.begin(); it!= lacts.end(); ++it) {
                        if( static_cast<SCA_IActuator*>(value_plus) == (*it) ) {
                                return *it;
                        }
@@ -215,9 +215,8 @@ PyObject* SCA_PythonController::sPyAddActiveActuator(PyObject* self, PyObject* a
        if(actu==NULL)
                return NULL;
        
-       CValue* boolval = new CBoolValue(activate!=0);
+       bool boolval = (activate!=0);
        m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu,boolval);
-       boolval->Release();
        Py_RETURN_NONE;
 }
 
@@ -473,7 +472,7 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
                Py_DECREF(excdict);
        }       
        
-       m_triggeredSensors.erase(m_triggeredSensors.begin(), m_triggeredSensors.end());
+       m_triggeredSensors.clear();
        m_sCurrentController = NULL;
 }
 
@@ -499,9 +498,7 @@ PyObject* SCA_PythonController::PyActivate(PyObject *value)
        if(actu==NULL)
                return NULL;
        
-       CValue* boolval = new CBoolValue(true);
-       m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, boolval);
-       boolval->Release();
+       m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, true);
        Py_RETURN_NONE;
 }
 
@@ -511,9 +508,7 @@ PyObject* SCA_PythonController::PyDeActivate(PyObject *value)
        if(actu==NULL)
                return NULL;
        
-       CValue* boolval = new CBoolValue(false);
-       m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, boolval);
-       boolval->Release();
+       m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, false);
        Py_RETURN_NONE;
 }
 
index 156478d..976597a 100644 (file)
@@ -50,9 +50,10 @@ SCA_RandomEventManager::SCA_RandomEventManager(class SCA_LogicManager* logicmgr)
 
 void SCA_RandomEventManager::NextFrame()
 {
-       for (set<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
+       SG_DList::iterator<SCA_ISensor> it(m_sensors);
+       for (it.begin();!it.end();++it)
        {
-               (*i)->Activate(m_logicmgr, NULL);
+               (*it)->Activate(m_logicmgr);
        }
 }
 
index 5c109ba..1581a29 100644 (file)
@@ -89,7 +89,7 @@ bool SCA_RandomSensor::IsPositiveTrigger()
 }
 
 
-bool SCA_RandomSensor::Evaluate(CValue* event)
+bool SCA_RandomSensor::Evaluate()
 {
     /* Random generator is the generator from Line 25 of Table 1 in          */
     /* [KNUTH 1981, The Art of Computer Programming Vol. 2                   */
index 63a96dd..27b4184 100644 (file)
@@ -52,7 +52,7 @@ public:
                                        PyTypeObject* T=&Type);
        virtual ~SCA_RandomSensor();
        virtual CValue* GetReplica();
-       virtual bool Evaluate(CValue* event);
+       virtual bool Evaluate();
        virtual bool IsPositiveTrigger();
        virtual void Init();
 
index b7fadd3..911ea77 100644 (file)
@@ -52,7 +52,7 @@ SCA_TimeEventManager::SCA_TimeEventManager(SCA_LogicManager* logicmgr)
 SCA_TimeEventManager::~SCA_TimeEventManager()
 {
        for (vector<CValue*>::iterator it = m_timevalues.begin();
-                       !(it == m_timevalues.end()); it++)
+                       !(it == m_timevalues.end()); ++it)
        {
                (*it)->Release();
        }       
@@ -80,7 +80,7 @@ void SCA_TimeEventManager::NextFrame(double curtime, double fixedtime)
                
                // update sensors, but ... need deltatime !
                for (vector<CValue*>::iterator it = m_timevalues.begin();
-               !(it == m_timevalues.end()); it++)
+               !(it == m_timevalues.end()); ++it)
                {
                        float newtime = (*it)->GetNumber() + fixedtime;
                        floatval->SetFloat(newtime);
@@ -104,7 +104,7 @@ void SCA_TimeEventManager::AddTimeProperty(CValue* timeval)
 void SCA_TimeEventManager::RemoveTimeProperty(CValue* timeval)
 {
        for (vector<CValue*>::iterator it = m_timevalues.begin();
-                       !(it == m_timevalues.end()); it++)
+                       !(it == m_timevalues.end()); ++it)
        {
                if ((*it) == timeval)
                {
index 9b0fe51..aee8e26 100644 (file)
@@ -77,19 +77,12 @@ void SCA_XNORController::Trigger(SCA_LogicManager* logicmgr)
                }
        }
 
-       CValue* newevent = new CBoolValue(sensorresult);
-
        for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
        !(i==m_linkedactuators.end());i++)
        {
-               SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
-               logicmgr->AddActiveActuator(actua,newevent);
+               SCA_IActuator* actua = *i;
+               logicmgr->AddActiveActuator(actua,sensorresult);
        }
-
-       // every actuator that needs the event, has a it's own reference to it now so
-       // release it (so to be clear: if there is no actuator, it's deleted right now)
-       newevent->Release();
-
 }
 
 
index 9232120..5afb3a7 100644 (file)
@@ -77,19 +77,12 @@ void SCA_XORController::Trigger(SCA_LogicManager* logicmgr)
                }
        }
        
-       CValue* newevent = new CBoolValue(sensorresult);
-
        for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
        !(i==m_linkedactuators.end());i++)
        {
-               SCA_IActuator* actua = *i;//m_linkedactuators.at(i);
-               logicmgr->AddActiveActuator(actua,newevent);
+               SCA_IActuator* actua = *i;
+               logicmgr->AddActiveActuator(actua,sensorresult);
        }
-
-       // every actuator that needs the event, has a it's own reference to it now so
-       // release it (so to be clear: if there is no actuator, it's deleted right now)
-       newevent->Release();
-
 }
 
 
index ebf225f..189c39e 100644 (file)
@@ -5,7 +5,7 @@ sources = env.Glob('*.cpp') + env.Glob('Joystick/*.cpp')
 
 incs = '. #/source/kernel/gen_system #/intern/string'
 incs += ' #/source/gameengine/Expressions #/intern/moto/include'
-incs += ' #/source/gameengine/Rasterizer'
+incs += ' #/source/gameengine/Rasterizer #/source/gameengine/Scenegraph'
 
 incs += ' ' + env['BF_PYTHON_INC']
 
index fa0ca37..eb1d5fc 100644 (file)
@@ -33,6 +33,7 @@ SET(INC
   ../../../../source/gameengine/Ketsji
   ../../../../source/gameengine/GameLogic
   ../../../../source/gameengine/Expressions
+  ../../../../source/gameengine/Scenegraph
   ../../../../source/gameengine/Network
   ${PYTHON_INC}
 )
index eee8e9f..738f647 100644 (file)
@@ -61,12 +61,12 @@ void KX_NetworkEventManager::NextFrame()
        // each frame, the logicmanager will call the network
        // eventmanager to look for network events, and process it's
        // 'network' sensors
-       set<class SCA_ISensor*>::iterator it;
-
-       for (it = m_sensors.begin(); !(it==m_sensors.end()); it++) {
+       SG_DList::iterator<SCA_ISensor> it(m_sensors);
+       for (it.begin();!it.end();++it)
+       {
 //         printf("KX_NetworkEventManager::proceed sensor %.2f\n", curtime);
            // process queue
-           (*it)->Activate(m_logicmgr, NULL);
+           (*it)->Activate(m_logicmgr);
        }
 
        // now a list of triggerer sensors has been built
index 7f21c49..6377335 100644 (file)
@@ -75,7 +75,7 @@ bool KX_NetworkMessageActuator::Update()
                        m_toPropName,
                        GetParent()->GetName(),
                        m_subject,
-                       GetParent()->GetPropertyText(m_body,""));
+                       GetParent()->GetPropertyText(m_body));
        } else
        {
                m_networkscene->SendMessage(
index 82e2437..8ddcd87 100644 (file)
@@ -85,7 +85,7 @@ CValue* KX_NetworkMessageSensor::GetReplica() {
 }
 
 // Return true only for flank (UP and DOWN)
-bool KX_NetworkMessageSensor::Evaluate(CValue* event)
+bool KX_NetworkMessageSensor::Evaluate()
 {
        bool result = false;
        bool WasUp = m_IsUp;
@@ -102,8 +102,8 @@ bool KX_NetworkMessageSensor::Evaluate(CValue* event)
                m_SubjectList = NULL;
        }
 
-       STR_String toname=GetParent()->GetName();
-       STR_String subject = this->m_subject;
+       STR_String& toname=GetParent()->GetName();
+       STR_String& subject = this->m_subject;
 
        vector<NG_NetworkMessage*> messages =
                m_NetworkScene->FindMessages(toname,"",subject,true);
@@ -123,9 +123,9 @@ bool KX_NetworkMessageSensor::Evaluate(CValue* event)
        for (mesit=messages.begin();mesit!=messages.end();mesit++)
        {
                // save the body
-               STR_String body = (*mesit)->GetMessageText();
+               const STR_String& body = (*mesit)->GetMessageText();
                // save the subject
-               STR_String messub = (*mesit)->GetSubject();
+               const STR_String& messub = (*mesit)->GetSubject();
 #ifdef NAN_NET_DEBUG
                if (body) {
                        cout << "body [" << body << "]\n";
index 3abba7c..53183f3 100644 (file)
@@ -63,7 +63,7 @@ public:
        virtual ~KX_NetworkMessageSensor();
 
        virtual CValue* GetReplica();
-       virtual bool Evaluate(CValue* event);
+       virtual bool Evaluate();
        virtual bool IsPositiveTrigger();
        virtual void Init();
        void EndFrame();
index ddcb036..ec30996 100644 (file)
@@ -40,6 +40,7 @@ CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
 CPPFLAGS += -I$(NAN_STRING)/include    
 CPPFLAGS += -I../../Expressions
 CPPFLAGS += -I../../GameLogic
+CPPFLAGS += -I../../Scenegraph
 CPPFLAGS += -I../../Network
 CPPFLAGS += -I../../../kernel/gen_system
 CPPFLAGS += -I..
index 2476ed1..26f95fa 100644 (file)
@@ -5,7 +5,7 @@ sources = env.Glob('*.cpp')
 
 incs = '. #source/kernel/gen_system #intern/string #source/gameengine/Ketsji'
 incs += ' #source/gameengine/GameLogic #source/gameengine/Expressions'
-incs += ' #source/gameengine/Network'
+incs += ' #source/gameengine/Network #source/gameengine/Scenegraph'
 
 incs += ' ' + env['BF_PYTHON_INC']
 
index 65a0266..3b8917e 100644 (file)
@@ -643,8 +643,7 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
 
                        if (mode &USECUSTOMUV)
                        {
-                               STR_String str = mMaterial->mapping[i].uvCoName;
-                               if (!str.IsEmpty())
+                               if (!mMaterial->mapping[i].uvCoName.IsEmpty())
                                        ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV2, i);
                                continue;
                        }
@@ -717,6 +716,8 @@ void KX_BlenderMaterial::setObjectMatrixData(int i, RAS_IRasterizer *ras)
        if(!obj) return;
        obj->Release(); /* FindValue() AddRef's */
 
+       obj->Release();
+
        glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
        glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
        glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
index e701a68..5f7197e 100644 (file)
@@ -454,7 +454,7 @@ PyObject* KX_CameraActuator::PyGetObject(PyObject* args)
                Py_RETURN_NONE;
        
        if (ret_name_only)
-               return PyString_FromString(m_ob->GetName());
+               return PyString_FromString(m_ob->GetName().ReadPtr());
        else
                return m_ob->GetProxy();
 }
index 2f5b563..4d01d96 100644 (file)
@@ -188,14 +188,14 @@ double KX_GameObject::GetNumber()
 
 
 
-STR_String KX_GameObject::GetName()
+STR_String& KX_GameObject::GetName()
 {
        return m_name;
 }
 
 
 
-void KX_GameObject::SetName(STR_String name)
+void KX_GameObject::SetName(const char *name)
 {
        m_name = name;
 };                                                             // Set the name of the value
@@ -452,14 +452,6 @@ void KX_GameObject::AddMeshUser()
        double* fl = GetOpenGLMatrixPtr()->getPointer();
        RAS_Deformer *deformer = GetDeformer();
 
-       //RAS_MeshSlot *ms;
-       //for(ms =static_cast<RAS_MeshSlot*>(m_meshSlots.QPeek());
-       //      ms!=static_cast<RAS_MeshSlot*>(m_meshSlots.Self());
-       //      ms =static_cast<RAS_MeshSlot*>(ms->QPeek()))
-       //{
-       //      ms->m_OpenGLMatrix = fl;
-       //      ms->SetDeformer(deformer);
-       //}
        SG_QList::iterator<RAS_MeshSlot> mit(m_meshSlots);
        for(mit.begin(); !mit.end(); ++mit)
        {
@@ -493,9 +485,7 @@ void KX_GameObject::UpdateBuckets( bool recursive )
 
                if (GetSGNode()->IsDirty())
                        GetOpenGLMatrix();
-               //for(ms =static_cast<RAS_MeshSlot*>(m_meshSlots.QPeek());
-               //    ms!=static_cast<RAS_MeshSlot*>(m_meshSlots.Self());
-               //    ms =static_cast<RAS_MeshSlot*>(ms->QPeek()))
+
                SG_QList::iterator<RAS_MeshSlot> mit(m_meshSlots);
                for(mit.begin(); !mit.end(); ++mit)
                {
@@ -1844,7 +1834,7 @@ int KX_GameObject::py_setattro(PyObject *attr, PyObject *value)   // py_setattro m
        
        if (ret==PY_SET_ATTR_COERCE_FAIL) {
                /* CValue attribute exists, remove CValue and add PyDict value */
-               RemoveProperty(STR_String(PyString_AsString(attr)));
+               RemoveProperty(PyString_AsString(attr));
                ret= PY_SET_ATTR_MISSING;
        }
        
@@ -1871,7 +1861,7 @@ int       KX_GameObject::py_delattro(PyObject *attr)
 {
        char *attr_str= PyString_AsString(attr); 
        
-       if (RemoveProperty(STR_String(attr_str))) // XXX - should call CValues instead but its only 2 lines here
+       if (RemoveProperty(attr_str)) // XXX - should call CValues instead but its only 2 lines here
                return 0;
        
        if (m_attr_dict && (PyDict_DelItem(m_attr_dict, attr) == 0))
index 8fafcc1..e5b2653 100644 (file)
@@ -241,7 +241,7 @@ public:
        /**
         * Inherited from CValue -- returns the name of this object.
         */
-               STR_String                      
+               STR_String&                     
        GetName(
        );
 
@@ -250,7 +250,7 @@ public:
         */
                void                            
        SetName(
-               STR_String name
+               const char *name
        );
 
        /** 
index efe0199..5e1785e 100644 (file)
@@ -164,14 +164,14 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
        // result = true if animation has to be continued, false if animation stops
        // maybe there are events for us in the queue !
        bool bNegativeEvent = false;
-       int numevents = 0;
+       bool numevents = false;
        bool bIpoStart = false;
 
        curtime -= KX_KetsjiEngine::GetSuspendedDelta();
 
        if (frame)
        {
-               numevents = m_events.size();
+               numevents = m_posevent || m_negevent;
                bNegativeEvent = IsNegativeEvent();
                RemoveAllEvents();
        }
@@ -273,7 +273,7 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
                        {
                                result = false;
                                m_bNegativeEvent = false;
-                               numevents = 0;
+                               numevents = false;
                        }
                        if (!m_bIpoPlaying)
                        {
index c0b0585..0d1bc28 100644 (file)
@@ -71,7 +71,6 @@ PyTypeObject KX_MeshProxy::Type = {
 
 PyParentObject KX_MeshProxy::Parents[] = {
        &KX_MeshProxy::Type,
-       &SCA_IObject::Type,
        &CValue::Type,
        &PyObjectPlus::Type,
        NULL
@@ -110,21 +109,21 @@ void KX_MeshProxy::SetMeshModified(bool v)
 
 PyObject* KX_MeshProxy::py_getattro(PyObject *attr)
 {
-       py_getattro_up(SCA_IObject);
+       py_getattro_up(CValue);
 }
 
 PyObject* KX_MeshProxy::py_getattro_dict() {
-       py_getattro_dict_up(SCA_IObject);
+       py_getattro_dict_up(CValue);
 }
 
 int KX_MeshProxy::py_setattro(PyObject *attr, PyObject* value)
 {
-       py_setattro_up(SCA_IObject);
+       py_setattro_up(CValue);
 }
 
 
 KX_MeshProxy::KX_MeshProxy(RAS_MeshObject* mesh)
-       : SCA_IObject(&Type), m_meshobj(mesh)
+       : CValue(&Type), m_meshobj(mesh)
 {
 }
 
@@ -140,8 +139,8 @@ CValue*             KX_MeshProxy::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValu
 
 const STR_String &     KX_MeshProxy::GetText() {return m_meshobj->GetName();};
 double         KX_MeshProxy::GetNumber() { return -1;}
-STR_String     KX_MeshProxy::GetName() { return m_meshobj->GetName();}
-void           KX_MeshProxy::SetName(STR_String name) { };
+STR_String&    KX_MeshProxy::GetName() { return m_meshobj->GetName();}
+void           KX_MeshProxy::SetName(const char *name) { };
 CValue*                KX_MeshProxy::GetReplica() { return NULL;}
 
 
index f775c96..bfdd4be 100644 (file)
@@ -34,7 +34,7 @@
 /* utility conversion function */
 bool ConvertPythonToMesh(PyObject * value, class RAS_MeshObject **object, bool py_none_ok, const char *error_prefix);
 
-class KX_MeshProxy     : public SCA_IObject
+class KX_MeshProxy     : public CValue
 {
        Py_Header;
 
@@ -51,8 +51,8 @@ public:
        virtual const STR_String &      GetText();
        virtual double          GetNumber();
        virtual RAS_MeshObject* GetMesh() { return m_meshobj; }
-       virtual STR_String      GetName();
-       virtual void            SetName(STR_String name);                                                               // Set the name of the value
+       virtual STR_String&     GetName();
+       virtual void            SetName(const char *name);                                                              // Set the name of the value
        virtual CValue*         GetReplica();
 
 // stuff for python integration
index 8b7c3cb..74b5c92 100644 (file)
@@ -86,7 +86,7 @@ void KX_MouseFocusSensor::Init()
        m_hitNormal.setValue(0,0,1);
 }
 
-bool KX_MouseFocusSensor::Evaluate(CValue* event)
+bool KX_MouseFocusSensor::Evaluate()
 {
        bool result = false;
        bool obHasFocus = false;
@@ -119,7 +119,7 @@ bool KX_MouseFocusSensor::Evaluate(CValue* event)
          * mode is never used, because the converter never makes this
          * sensor for a mouse-key event. It is here for
          * completeness. */
-               result = SCA_MouseSensor::Evaluate(event);
+               result = SCA_MouseSensor::Evaluate();
                m_positive_event = (m_val!=0);
        }
 
index 350fda1..29d674e 100644 (file)
@@ -69,7 +69,7 @@ class KX_MouseFocusSensor : public SCA_MouseSensor
        /**
         * @attention Overrides default evaluate. 
         */
-       virtual bool Evaluate(CValue* event);
+       virtual bool Evaluate();
        virtual void Init();
 
        virtual bool IsPositiveTrigger() {
index e7f0555..a3c4e95 100644 (file)
@@ -160,7 +160,7 @@ KX_NearSensor::~KX_NearSensor()
 }
 
 
-bool KX_NearSensor::Evaluate(CValue* event)
+bool KX_NearSensor::Evaluate()
 {
        bool result = false;
 //     KX_GameObject* parent = static_cast<KX_GameObject*>(GetParent());
index 5b65312..35136b7 100644 (file)
@@ -71,7 +71,7 @@ public:
        virtual void SynchronizeTransform();
        virtual CValue* GetReplica();
        virtual void ProcessReplica();
-       virtual bool Evaluate(CValue* event);
+       virtual bool Evaluate();
 
        virtual void ReParent(SCA_IObject* parent);
        virtual bool    NewHandleCollision(void* obj1,void* obj2,
index f55ffd4..c524878 100644 (file)
@@ -267,7 +267,7 @@ PyObject* KX_ParentActuator::PyGetObject(PyObject* args)
                Py_RETURN_NONE;
        
        if (ret_name_only)
-               return PyString_FromString(m_ob->GetName());
+               return PyString_FromString(m_ob->GetName().ReadPtr());
        else
                return m_ob->GetProxy();
 }
index ca38117..b56b550 100644 (file)
@@ -64,8 +64,8 @@ PyTypeObject KX_PolyProxy::Type = {
 
 PyParentObject KX_PolyProxy::Parents[] = {
        &KX_PolyProxy::Type,
-       &SCA_IObject::Type,
        &CValue::Type,
+       &PyObjectPlus::Type,
        NULL
 };
 
@@ -162,11 +162,11 @@ PyObject* KX_PolyProxy::py_getattro(PyObject *attr)
        {
                return PyInt_FromLong(m_polygon->IsCollider());
        }
-       py_getattro_up(SCA_IObject);
+       py_getattro_up(CValue);
 }
 
 PyObject* KX_PolyProxy::py_getattro_dict() {
-       py_getattro_dict_up(SCA_IObject);
+       py_getattro_dict_up(CValue);
 }
 
 KX_PolyProxy::KX_PolyProxy(const RAS_MeshObject*mesh, RAS_Polygon* polygon)
@@ -186,8 +186,8 @@ CValue*             KX_PolyProxy::CalcFinal(VALUE_DATA_TYPE, VALUE_OPERATOR, CValue *) { re
 STR_String     sPolyName="polygone";
 const STR_String &     KX_PolyProxy::GetText() {return sPolyName;};
 double         KX_PolyProxy::GetNumber() { return -1;}
-STR_String     KX_PolyProxy::GetName() { return sPolyName;}
-void           KX_PolyProxy::SetName(STR_String) { };
+STR_String&    KX_PolyProxy::GetName() { return sPolyName;}
+void           KX_PolyProxy::SetName(const char *) { };
 CValue*                KX_PolyProxy::GetReplica() { return NULL;}
 
 // stuff for python integration
index 223193e..d8fd36f 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "SCA_IObject.h"
 
-class KX_PolyProxy     : public SCA_IObject
+class KX_PolyProxy     : public CValue
 {
        Py_Header;
 protected:
@@ -46,8 +46,8 @@ public:
        CValue*         CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
        const STR_String &      GetText();
        double          GetNumber();
-       STR_String      GetName();
-       void            SetName(STR_String name);                                                               // Set the name of the value
+       STR_String&     GetName();
+       void            SetName(const char *name);                                                              // Set the name of the value
        CValue*         GetReplica();
 
 
index 039cf64..42b1850 100644 (file)
@@ -91,7 +91,7 @@ static PyObject *KX_PythonSeq_getIndex(KX_PythonSeq * self, int index)
        switch(self->type) {
                case KX_PYGENSEQ_CONT_TYPE_SENSORS:
                {
-                       vector<SCA_ISensor*> linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors();
+                       vector<SCA_ISensor*>& linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors();
                        if(index<0) index += linkedsensors.size();
                        if(index<0 || index>= linkedsensors.size()) {
                                PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range");
@@ -101,7 +101,7 @@ static PyObject *KX_PythonSeq_getIndex(KX_PythonSeq * self, int index)
                }
                case KX_PYGENSEQ_CONT_TYPE_ACTUATORS:
                {
-                       vector<SCA_IActuator*> linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators();
+                       vector<SCA_IActuator*>& linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators();
                        if(index<0) index += linkedactuators.size();
                        if(index<0 || index>= linkedactuators.size()) {
                                PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range");
@@ -168,7 +168,7 @@ static PyObject * KX_PythonSeq_subscript(KX_PythonSeq * self, PyObject *key)
        switch(self->type) {
                case KX_PYGENSEQ_CONT_TYPE_SENSORS:
                {
-                       vector<SCA_ISensor*> linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors();
+                       vector<SCA_ISensor*>& linkedsensors = ((SCA_IController *)self_plus)->GetLinkedSensors();
                        SCA_ISensor* sensor;
                        for (unsigned int index=0;index<linkedsensors.size();index++) {
                                sensor = linkedsensors[index];
@@ -179,7 +179,7 @@ static PyObject * KX_PythonSeq_subscript(KX_PythonSeq * self, PyObject *key)
                }
                case KX_PYGENSEQ_CONT_TYPE_ACTUATORS:
                {
-                       vector<SCA_IActuator*> linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators();
+                       vector<SCA_IActuator*>& linkedactuators = ((SCA_IController *)self_plus)->GetLinkedActuators();
                        SCA_IActuator* actuator;
                        for (unsigned int index=0;index<linkedactuators.size();index++) {
                                actuator = linkedactuators[index];
index 1af2915..50fa4f5 100644 (file)
@@ -44,9 +44,10 @@ using namespace std;
 
 void KX_RayEventManager::NextFrame()
 {
-       for (set<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
+       SG_DList::iterator<SCA_ISensor> it(m_sensors);
+       for (it.begin();!it.end();++it)
        {
-               (*i)->Activate(m_logicmgr, NULL);
+               (*it)->Activate(m_logicmgr);
        }
 }
 
index 43d8806..fdde5fd 100644 (file)
@@ -178,7 +178,7 @@ bool KX_RaySensor::NeedRayCast(KX_ClientObjectInfo* client)
        return true;
 }
 
-bool KX_RaySensor::Evaluate(CValue* event)
+bool KX_RaySensor::Evaluate()
 {
        bool result = false;
        bool reset = m_reset && m_level;
index 558840e..9efb046 100644 (file)
@@ -67,7 +67,7 @@ public:
        virtual ~KX_RaySensor();
        virtual CValue* GetReplica();
 
-       virtual bool Evaluate(CValue* event);
+       virtual bool Evaluate();
        virtual bool IsPositiveTrigger();
        virtual void Init();
 
index 2fd786e..3c72eac 100644 (file)
@@ -87,7 +87,7 @@ KX_SCA_AddObjectActuator::~KX_SCA_AddObjectActuator()
        if (m_OriginalObject)
                m_OriginalObject->UnregisterActuator(this);
        if (m_lastCreatedObject)
-               m_lastCreatedObject->Release();
+               m_lastCreatedObject->UnregisterActuator(this);
 } 
 
 
@@ -145,6 +145,12 @@ bool KX_SCA_AddObjectActuator::UnlinkObject(SCA_IObject* clientobj)
                m_OriginalObject = NULL;
                return true;
        }
+       if (clientobj == m_lastCreatedObject)
+       {
+               // this object is being deleted, we cannot continue to track it.
+               m_lastCreatedObject = NULL;
+               return true;
+       }
        return false;
 }
 
@@ -356,7 +362,7 @@ PyObject* KX_SCA_AddObjectActuator::PyGetObject(PyObject* args)
                Py_RETURN_NONE;
        
        if (ret_name_only)
-               return PyString_FromString(m_OriginalObject->GetName());
+               return PyString_FromString(m_OriginalObject->GetName().ReadPtr());
        else
                return m_OriginalObject->GetProxy();
 }
@@ -464,13 +470,21 @@ void      KX_SCA_AddObjectActuator::InstantAddObject()
                // keep a copy of the last object, to allow python scripters to change it
                if (m_lastCreatedObject)
                {
-                       //careful with destruction, it might still have outstanding collision callbacks
-                       m_scene->DelayedReleaseObject(m_lastCreatedObject);
-                       m_lastCreatedObject->Release();
+                       //Let's not keep a reference to the object: it's bad, if the object is deleted
+                       //this will force to keep a "zombie" in the game for no good reason.
+                       //m_scene->DelayedReleaseObject(m_lastCreatedObject);
+                       //m_lastCreatedObject->Release();
+
+                       //Instead we use the registration mechanism
+                       m_lastCreatedObject->UnregisterActuator(this);
+                       m_lastCreatedObject = NULL;
                }
                
                m_lastCreatedObject = replica;
-               m_lastCreatedObject->AddRef();
+               // no reference
+               //m_lastCreatedObject->AddRef();
+               // but registration
+               m_lastCreatedObject->RegisterActuator(this);
                // finished using replica? then release it
                replica->Release();
        }
index 208f8fc..84c6d37 100644 (file)
@@ -164,7 +164,6 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
        m_lightlist= new CListValue();
        m_inactivelist = new CListValue();
        m_euthanasyobjects = new CListValue();
-       m_delayReleaseObjects = new CListValue();
 
        m_logicmgr = new SCA_LogicManager();
        
@@ -223,8 +222,6 @@ KX_Scene::~KX_Scene()
        // It's still there but we remove all properties here otherwise some
        // reference might be hanging and causing late release of objects
        RemoveAllDebugProperties();
-       // early removal of sensor map to avoid massive slow down when there are many objects
-       m_logicmgr->RemoveSensorMap();
 
        while (GetRootParentList()->GetCount() > 0) 
        {
@@ -249,8 +246,6 @@ KX_Scene::~KX_Scene()
 
        if (m_euthanasyobjects)
                m_euthanasyobjects->Release();
-       if (m_delayReleaseObjects)
-               m_delayReleaseObjects->Release();
 
        if (m_logicmgr)
                delete m_logicmgr;
@@ -419,11 +414,11 @@ void KX_Scene::RemoveNodeDestructObject(class SG_IObject* node,class CValue* gam
        KX_GameObject* orgobj = (KX_GameObject*)gameobj;        
        if (NewRemoveObject(orgobj) != 0)
        {
-               // object is not yet deleted (this can happen when it hangs in an add object actuator
-               // last object created reference. It's a bad situation, don't know how to fix it exactly
-               // The least I can do, is remove the reference to the node in the object as the node
-               // will in any case be deleted. This ensures that the object will not try to use the node
-               // when it is finally deleted (see KX_GameObject destructor)
+               // object is not yet deleted because a reference is hanging somewhere.
+               // This should not happen anymore since we use proxy object for Python
+               // confident enough to put an assert?
+               //assert(false);
+               printf("Zombie object! name=%s\n", orgobj->GetName().ReadPtr());
                orgobj->SetSGNode(NULL);
                PHY_IGraphicController* ctrl = orgobj->GetGraphicController();
                if (ctrl)
@@ -550,8 +545,9 @@ void KX_Scene::ReplicateLogic(KX_GameObject* newobj)
                vector<SCA_IActuator*> linkedactuators = cont->GetLinkedActuators();
 
                // disconnect the sensors and actuators
-               cont->UnlinkAllSensors();
-               cont->UnlinkAllActuators();
+               // do it directly on the list at this controller is not connected to anything at this stage
+               cont->GetLinkedSensors().clear();
+               cont->GetLinkedActuators().clear();
                
                // now relink each sensor
                for (vector<SCA_ISensor*>::iterator its = linkedsensors.begin();!(its==linkedsensors.end());its++)
@@ -908,14 +904,6 @@ void KX_Scene::RemoveObject(class CValue* gameobj)
 {
        KX_GameObject* newobj = (KX_GameObject*) gameobj;
 
-       /* Invalidate the python reference, since the object may exist in script lists
-        * its possible that it wont be automatically invalidated, so do it manually here,
-        * 
-        * if for some reason the object is added back into the scene python can always get a new Proxy
-        */
-       gameobj->InvalidateProxy();
-       
-       
        // disconnect child from parent
        SG_Node* node = newobj->GetSGNode();
 
@@ -930,12 +918,6 @@ void KX_Scene::RemoveObject(class CValue* gameobj)
        //newobj->SetSGNode(0);
 }
 
-void KX_Scene::DelayedReleaseObject(CValue* gameobj)
-{
-       m_delayReleaseObjects->Add(gameobj->AddRef());
-}
-
-
 void KX_Scene::DelayedRemoveObject(class CValue* gameobj)
 {
        //KX_GameObject* newobj = (KX_GameObject*) gameobj;
@@ -952,6 +934,13 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj)
        int ret;
        KX_GameObject* newobj = (KX_GameObject*) gameobj;
 
+       /* Invalidate the python reference, since the object may exist in script lists
+        * its possible that it wont be automatically invalidated, so do it manually here,
+        * 
+        * if for some reason the object is added back into the scene python can always get a new Proxy
+        */
+       newobj->InvalidateProxy();
+
        // keep the blender->game object association up to date
        // note that all the replicas of an object will have the same
        // blender object, that's why we need to check the game object
@@ -981,7 +970,7 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj)
        for (SCA_ActuatorList::iterator ita = actuators.begin();
                 !(ita==actuators.end());ita++)
        {
-               m_logicmgr->RemoveDestroyedActuator(*ita);
+               m_logicmgr->RemoveActuator(*ita);
        }
        // the sensors/controllers/actuators must also be released, this is done in ~SCA_IObject
 
@@ -1464,23 +1453,16 @@ void KX_Scene::LogicEndFrame()
        m_logicmgr->EndFrame();
        int numobj = m_euthanasyobjects->GetCount();
        int i;
-       for (i = numobj - 1; i >= 0; i--)
-       {
-               KX_GameObject* gameobj = (KX_GameObject*)m_euthanasyobjects->GetValue(i);
-               // KX_Scene::RemoveObject will also remove the object from this list
-               // that's why we start from the end
-               this->RemoveObject(gameobj);
-       }
+       KX_GameObject* obj;
 
-       numobj= m_delayReleaseObjects->GetCount();
-       for (i = numobj-1;i>=0;i--)
+       while ((numobj = m_euthanasyobjects->GetCount()) > 0)
        {
-               KX_GameObject* gameobj = (KX_GameObject*)m_delayReleaseObjects->GetValue(i);
-               // This list is not for object removal, but just object release
-               gameobj->Release();
+               // remove the object from this list to make sure we will not hit it again
+               obj = (KX_GameObject*)m_euthanasyobjects->GetValue(numobj-1);
+               m_euthanasyobjects->Remove(numobj-1);
+               obj->Release();
+               RemoveObject(obj);
        }
-       // empty the list as we have removed all references
-       m_delayReleaseObjects->Resize(0);       
 }
 
 
index 0cfef8b..128f8d2 100644 (file)
@@ -108,11 +108,6 @@ protected:
         * LogicEndFrame() via a call to RemoveObject().
         */
        CListValue*     m_euthanasyobjects;
-       /**
-       * The list of objects that couldn't be released during logic update.
-       * for example, AddObject actuator sometimes releases an object that was cached from previous frame
-       */
-       CListValue*     m_delayReleaseObjects;
 
        CListValue*                     m_objectlist;
        CListValue*                     m_parentlist; // all 'root' parents
@@ -331,8 +326,6 @@ public:
        void RemoveObject(CValue* gameobj);
        void DelayedRemoveObject(CValue* gameobj);
        
-       void DelayedReleaseObject(CValue* gameobj);
-
        int NewRemoveObject(CValue* gameobj);
        void ReplaceMesh(CValue* gameobj,
                                         void* meshobj);
index 15eb354..07a880c 100644 (file)
@@ -83,17 +83,19 @@ CValue* KX_SoundActuator::GetReplica()
 {
        KX_SoundActuator* replica = new KX_SoundActuator(*this);
        replica->ProcessReplica();
+       return replica;
+};
+
+void KX_SoundActuator::ProcessReplica()
+{
+       SCA_IActuator::ProcessReplica();
        if (m_soundObject)
        {
            SND_SoundObject* soundobj = new SND_SoundObject(*m_soundObject);
-               replica->setSoundObject(soundobj);
+               setSoundObject(soundobj);
                m_soundScene->AddObject(soundobj);
        }
-       
-       return replica;
-};
-
-
+}      
 
 bool KX_SoundActuator::Update(double curtime, bool frame)
 {
index ad58087..a749135 100644 (file)
@@ -75,6 +75,7 @@ public:
        virtual bool Update(double curtime, bool frame);
 
        CValue* GetReplica();
+       void ProcessReplica();
 
        /* -------------------------------------------------------------------- */
        /* Python interface --------------------------------------------------- */
index 48d4cf5..8ae5fae 100644 (file)
@@ -100,7 +100,7 @@ bool         KX_TouchEventManager::newBroadphaseResponse(void *client_data,
 void KX_TouchEventManager::RegisterSensor(SCA_ISensor* sensor)
 {
        KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(sensor);
-       if (m_sensors.insert(touchsensor).second)
+       if (m_sensors.AddBack(touchsensor))
                // the sensor was effectively inserted, register it
                touchsensor->RegisterSumo(this);
 }
@@ -108,7 +108,7 @@ void KX_TouchEventManager::RegisterSensor(SCA_ISensor* sensor)
 void KX_TouchEventManager::RemoveSensor(SCA_ISensor* sensor)
 {
        KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(sensor);
-       if (m_sensors.erase(touchsensor))
+       if (touchsensor->Delink())
                // the sensor was effectively removed, unregister it
                touchsensor->UnregisterSumo(this);
 }
@@ -117,12 +117,10 @@ void KX_TouchEventManager::RemoveSensor(SCA_ISensor* sensor)
 
 void KX_TouchEventManager::EndFrame()
 {
-       set<SCA_ISensor*>::iterator it;
-       for ( it = m_sensors.begin();
-       !(it==m_sensors.end());it++)
+       SG_DList::iterator<KX_TouchSensor> it(m_sensors);
+       for (it.begin();!it.end();++it)
        {
-               ((KX_TouchSensor*)*it)->EndFrame();
-
+               (*it)->EndFrame();
        }
 }
 
@@ -130,12 +128,11 @@ void KX_TouchEventManager::EndFrame()
 
 void KX_TouchEventManager::NextFrame()
 {
-       if (m_sensors.size() > 0)
+       if (!m_sensors.Empty())
        {
-               set<SCA_ISensor*>::iterator it;
-               
-               for (it = m_sensors.begin();!(it==m_sensors.end());++it)
-                       static_cast<KX_TouchSensor*>(*it)->SynchronizeTransform();
+               SG_DList::iterator<KX_TouchSensor> it(m_sensors);
+               for (it.begin();!it.end();++it)
+                       (*it)->SynchronizeTransform();
                
                for (std::set<NewCollision>::iterator cit = m_newCollisions.begin(); cit != m_newCollisions.end(); ++cit)
                {
@@ -161,7 +158,7 @@ void KX_TouchEventManager::NextFrame()
                        
                m_newCollisions.clear();
                        
-               for (it = m_sensors.begin();!(it==m_sensors.end());++it)
-                       (*it)->Activate(m_logicmgr,NULL);
+               for (it.begin();!it.end();++it)
+                       (*it)->Activate(m_logicmgr);
        }
 }
index f000c16..2c02d94 100644 (file)
@@ -66,10 +66,10 @@ void KX_TouchSensor::UnregisterToManager()
 {
        // before unregistering the sensor, make sure we release all references
        EndFrame();
-       m_eventmgr->RemoveSensor(this);
+       SCA_ISensor::UnregisterToManager();
 }
 
-bool KX_TouchSensor::Evaluate(CValue* event)
+bool KX_TouchSensor::Evaluate()
 {
        bool result = false;
        bool reset = m_reset && m_level;
index 056b570..9c9c6bf 100644 (file)
@@ -86,7 +86,7 @@ public:
        virtual CValue* GetReplica();
        virtual void ProcessReplica();
        virtual void SynchronizeTransform();
-       virtual bool Evaluate(CValue* event);
+       virtual bool Evaluate();
        virtual void Init();
        virtual void ReParent(SCA_IObject* parent);
        
index 672b9e7..800da83 100644 (file)
@@ -83,6 +83,10 @@ KX_TrackToActuator::KX_TrackToActuator(SCA_IObject *gameobj,
                                // if so, store the initial local rotation
                                // this is needed to revert the effect of the parent inverse node (TBC)
                                m_parentlocalmat = m_parentobj->GetSGNode()->GetLocalOrientation();
+                               // use registration mechanism rather than AddRef, it creates zombie objects
+                               m_parentobj->RegisterActuator(this);
+                               // GetParent did AddRef, undo here
+                               m_parentobj->Release();
                        }
                }
        }
@@ -189,7 +193,7 @@ KX_TrackToActuator::~KX_TrackToActuator()
        if (m_object)
                m_object->UnregisterActuator(this);
        if (m_parentobj)
-               m_parentobj->Release();
+               m_parentobj->UnregisterActuator(this);
 } /* end of destructor */
 
 void KX_TrackToActuator::ProcessReplica()
@@ -198,7 +202,7 @@ void KX_TrackToActuator::ProcessReplica()
        if (m_object)
                m_object->RegisterActuator(this);
        if (m_parentobj)
-               m_parentobj->AddRef();
+               m_parentobj->RegisterActuator(this);
        SCA_IActuator::ProcessReplica();
 }
 
@@ -211,6 +215,11 @@ bool KX_TrackToActuator::UnlinkObject(SCA_IObject* clientobj)
                m_object = NULL;
                return true;
        }
+       if (clientobj == m_parentobj)
+       {
+               m_parentobj = NULL;
+               return true;
+       }
        return false;
 }
 
@@ -227,9 +236,9 @@ void KX_TrackToActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
        void **h_parobj = (*obj_map)[m_parentobj];
        if (h_parobj) {
                if (m_parentobj)
-                       m_parentobj->Release();
+                       m_parentobj->UnregisterActuator(this);
                m_parentobj= (KX_GameObject*)(*h_parobj);
-               m_parentobj->AddRef();
+               m_parentobj->RegisterActuator(this);
        }
 }
 
index 6563d04..4b0ad08 100644 (file)
@@ -62,8 +62,8 @@ PyTypeObject KX_VertexProxy::Type = {
 
 PyParentObject KX_VertexProxy::Parents[] = {
        &KX_VertexProxy::Type,
-       &SCA_IObject::Type,
        &CValue::Type,
+       &PyObjectPlus::Type,
        NULL
 };
 
@@ -162,11 +162,11 @@ KX