diff options
author | Benoit Bolsee <benoit.bolsee@online.be> | 2008-07-19 11:45:19 +0400 |
---|---|---|
committer | Benoit Bolsee <benoit.bolsee@online.be> | 2008-07-19 11:45:19 +0400 |
commit | 9ed079bf5cbe8a5a371190a8dedec970bcbd3ac2 (patch) | |
tree | 7f32f799d89c308743a7e3fdf74cd5bc8f168415 /source/gameengine/Ketsji/KX_ParentActuator.cpp | |
parent | 5e2ee191877d1073a20da32c52d9e97cfab8f5c8 (diff) |
BGE patch: Relink actuators with target within group when duplicating group; generalize protection against object deletion for all actuators that point to objects.
Certain actuators hold a pointer to an objects: Property,
SceneCamera, AddObject, Camera, Parent, TractTo. When a
group is duplicated, the actuators that point to objects
within the group will be relinked to point to the
replicated objects and not to the original objects.
This helps to setup self-contained group with a camera
following a character for example.
This feature also works when adding a single object
(and all its children) with the AddObject actuator.
The second part of the patch extends the protection
against object deletion to all the actuators of the above
list (previously, only the TrackTo, AddObject and
Property actuators were protected). In case the target
object of these actuators is deleted, the BGE won't
crash.
Diffstat (limited to 'source/gameengine/Ketsji/KX_ParentActuator.cpp')
-rw-r--r-- | source/gameengine/Ketsji/KX_ParentActuator.cpp | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp index 8b379bcd44f..fd1b56838e2 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.cpp +++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp @@ -46,19 +46,22 @@ KX_ParentActuator::KX_ParentActuator(SCA_IObject *gameobj, int mode, - CValue *ob, + SCA_IObject *ob, PyTypeObject* T) : SCA_IActuator(gameobj, T), m_mode(mode), m_ob(ob) { + if (m_ob) + m_ob->RegisterActuator(this); } KX_ParentActuator::~KX_ParentActuator() { - /* intentionally empty */ + if (m_ob) + m_ob->UnregisterActuator(this); } @@ -73,6 +76,36 @@ CValue* KX_ParentActuator::GetReplica() return replica; } +void KX_ParentActuator::ProcessReplica() +{ + if (m_ob) + m_ob->RegisterActuator(this); + SCA_IActuator::ProcessReplica(); +} + + +bool KX_ParentActuator::UnlinkObject(SCA_IObject* clientobj) +{ + if (clientobj == m_ob) + { + // this object is being deleted, we cannot continue to track it. + m_ob = NULL; + return true; + } + return false; +} + +void KX_ParentActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map) +{ + void **h_obj = (*obj_map)[m_ob]; + if (h_obj) { + if (m_ob) + m_ob->UnregisterActuator(this); + m_ob = (SCA_IObject*)(*h_obj); + m_ob->RegisterActuator(this); + } +} + bool KX_ParentActuator::Update() @@ -87,7 +120,8 @@ bool KX_ParentActuator::Update() KX_Scene *scene = PHY_GetActiveScene(); switch (m_mode) { case KX_PARENT_SET: - obj->SetParent(scene, (KX_GameObject*)m_ob); + if (m_ob) + obj->SetParent(scene, (KX_GameObject*)m_ob); break; case KX_PARENT_REMOVE: obj->RemoveParent(scene); @@ -148,7 +182,11 @@ PyObject* KX_ParentActuator::PySetObject(PyObject* self, PyObject* args, PyObjec PyObject* gameobj; if (PyArg_ParseTuple(args, "O!", &KX_GameObject::Type, &gameobj)) { - m_ob = (CValue*)gameobj; + if (m_ob != NULL) + m_ob->UnregisterActuator(this); + m_ob = (SCA_IObject*)gameobj; + if (m_ob) + m_ob->RegisterActuator(this); Py_Return; } PyErr_Clear(); @@ -156,10 +194,13 @@ PyObject* KX_ParentActuator::PySetObject(PyObject* self, PyObject* args, PyObjec char* objectname; if (PyArg_ParseTuple(args, "s", &objectname)) { - CValue *object = (CValue*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(objectname)); + SCA_IObject *object = (SCA_IObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(objectname)); if(object) { + if (m_ob != NULL) + m_ob->UnregisterActuator(this); m_ob = object; + m_ob->RegisterActuator(this); Py_Return; } } |