blender/source/gameengine/Expressions/CMakeLists.txt
Porteries Tristan 95164a09a7 BGE: generic python callback list + replace KX_PythonSeq.
I made this patch to declared a python list without converting all elements in python object (too slow) or use a CListValue which required CValue items (too expensive in memory).  In the case of a big list of points like a collision contacts points list, to use a CListValue we must implement a new class based on CValue for 3D vector to create a python proxy even if mathutils do it perfectly, we must also convert all points (frequently ~100 points) when fill the CListValue even if the list is not used (in the case of the collision callback). The easy way is to use callback (it doesn't worth to do an inheritance) which convert the item in PyObject only during an acces.
5 callbacks are used :
- Check if the list is valid = allow acces (like PyObjectPlus.invalid)
- Get the list size
- Get an item in the list by index.
- Get an item name in the list by index (used for operator `list["name"]`)
- Set an item in the list at the index position.
All of these callback take as first argument the client instance.
Why do we use a void * for the client instance ? : In KX_PythonInitTypes.cpp we have to initialize each python inherited class, if we use a template (the only other way) we must add this class each time we use a new type with in KX_PythonInitTypes.cpp

To check if the list can be accessed from python by the user, we check if the python proxy,  which is the `m_base` member, is still a valid proxy like in PyObjectPlus. But we can use a callback for more control of user access (e.g a list of collision point invalidate a frame later, in this case no real python owner).

This python list is easily defined with :
```
CPythonCallBackList(
void *client, // The client instance
PyObject *base, // The python instance which owned this list, used to know if the list is valid (like in KX_PythonSeq)
bool (*checkValid)(void *), // A callback to check if this list is till valid (optional)
int (*getSize)(void *), // A callback to get size
PyObject *(*getItem)(void *, int), // A callback to get an item
const char *(*getItemName)(void *, int), // A callback to get an item name (optional) use for acces by string key
bool (*setItem)(void *, int, PyObject *) // A callback to set an item (optional)
)
```
To show its usecase i replaced the odd KX_PythonSeq, it modify KX_Gameobject.sensors/controllers/actuators, SCA_IController.sensors/actuators and BL_ArmatureObject.constraints/channels.

Example : {F245193}, See message in console, press R to erase the object and see invalid proxy error message.

Reviewers: brita_, #game_python, youle, campbellbarton, moguri, agoose77, sergey

Reviewed By: campbellbarton, moguri, agoose77, sergey

Subscribers: sergey

Projects: #game_engine

Differential Revision: https://developer.blender.org/D1363
2015-10-26 20:27:08 +01:00

92 lines
2.0 KiB
CMake

# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# The Original Code is Copyright (C) 2006, Blender Foundation
# All rights reserved.
#
# The Original Code is: all of this file.
#
# Contributor(s): Jacques Beaurain.
#
# ***** END GPL LICENSE BLOCK *****
set(INC
.
../SceneGraph
../../blender/blenlib
../../../intern/guardedalloc
../../../intern/string
)
set(INC_SYS
../../../intern/moto/include
)
set(SRC
intern/BoolValue.cpp
intern/ConstExpr.cpp
intern/EmptyValue.cpp
intern/ErrorValue.cpp
intern/Expression.cpp
intern/FloatValue.cpp
intern/IdentifierExpr.cpp
intern/IfExpr.cpp
intern/InputParser.cpp
intern/IntValue.cpp
intern/HashedPtr.cpp
intern/ListValue.cpp
intern/Operator1Expr.cpp
intern/Operator2Expr.cpp
intern/PyObjectPlus.cpp
intern/StringValue.cpp
intern/Value.cpp
intern/VectorValue.cpp
intern/ListWrapper.cpp
EXP_BoolValue.h
EXP_ConstExpr.h
EXP_EmptyValue.h
EXP_ErrorValue.h
EXP_Expression.h
EXP_FloatValue.h
EXP_HashedPtr.h
EXP_IdentifierExpr.h
EXP_IfExpr.h
EXP_InputParser.h
EXP_IntValue.h
EXP_ListValue.h
EXP_Operator1Expr.h
EXP_Operator2Expr.h
EXP_PyObjectPlus.h
EXP_Python.h
EXP_StringValue.h
EXP_Value.h
EXP_VectorValue.h
EXP_VoidValue.h
EXP_ListWrapper.h
)
if(WITH_PYTHON)
list(APPEND SRC
intern/PythonCallBack.cpp
EXP_PythonCallBack.h
)
endif()
blender_add_lib(ge_logic_expressions "${SRC}" "${INC}" "${INC_SYS}")