Skip to content

Commit

Permalink
UPBGE: Use raw std::vector instead of EXP_ListValue for KX_GameObject…
Browse files Browse the repository at this point in the history
…::GetChildren.

The functions GetChildren and GetChildrenRecursive were not used only for
the python API but also for the animation and duplication process, in these
last cases the creation of a std::vector is cheaper and more easy to use.
For the python API prupose, EXP_ListValue now had a constructor taking
a std::vector to copy items from.
  • Loading branch information
panzergame committed Oct 20, 2017
1 parent 76aff7a commit 53ed0c4
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 35 deletions.
9 changes: 3 additions & 6 deletions source/gameengine/Converter/BL_BlenderDataConversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1447,9 +1447,9 @@ void BL_ConvertBlenderObjects(struct Main *maggie,
* Note: there may be descendents already if the children of the child were processed
* by this loop before the child. In that case, we must remove the children also
*/
EXP_ListValue<KX_GameObject> *childrenlist = childobj->GetChildrenRecursive();
std::vector<KX_GameObject *> childrenlist = childobj->GetChildrenRecursive();
// The returned list by GetChildrenRecursive is not owned by anyone and must not own items, so no AddRef().
childrenlist->Add(childobj);
childrenlist.push_back(childobj);
for (KX_GameObject *obj : childrenlist) {
if (sumolist->RemoveValue(obj)) {
obj->Release();
Expand All @@ -1461,7 +1461,6 @@ void BL_ConvertBlenderObjects(struct Main *maggie,
obj->Release();
}
}
childrenlist->Release();

converter.UnregisterGameObject(childobj);
kxscene->RemoveObject(childobj);
Expand Down Expand Up @@ -1565,15 +1564,13 @@ void BL_ConvertBlenderObjects(struct Main *maggie,
BL_ArmatureObject *armobj = static_cast<BL_ArmatureObject *>(gameobj);
armobj->LoadConstraints(converter);

EXP_ListValue<KX_GameObject> *children = armobj->GetChildren();
const std::vector<KX_GameObject *> children = armobj->GetChildren();
for (KX_GameObject *child : children) {
BL_ShapeDeformer *deformer = dynamic_cast<BL_ShapeDeformer *>(child->GetDeformer());
if (deformer) {
deformer->LoadShapeDrivers(armobj);
}
}

children->Release();
}
}

Expand Down
10 changes: 10 additions & 0 deletions source/gameengine/Expressions/EXP_ListValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ class EXP_ListValue : public EXP_BaseListValue
EXP_ListValue()
{
}

EXP_ListValue(const std::vector<ItemType *>& rawList)
{
const unsigned int size = rawList.size();
m_pValueArray.resize(size);
for (unsigned int i = 0; i < size; ++i) {
m_pValueArray[i] = rawList[i];
}
}

virtual ~EXP_ListValue()
{
}
Expand Down
39 changes: 21 additions & 18 deletions source/gameengine/Ketsji/KX_GameObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1498,18 +1498,18 @@ void KX_GameObject::Suspend()
}
}

static void walk_children(SG_Node* node, EXP_ListValue<KX_GameObject> *list, bool recursive)
static void walk_children(const SG_Node* node, std::vector<KX_GameObject *>& list, bool recursive)
{
if (!node)
return;
NodeList& children = node->GetSGChildren();
const NodeList& children = node->GetSGChildren();

for (SG_Node *childnode : children) {
KX_GameObject *childobj = static_cast<KX_GameObject *>(childnode->GetSGClientObject());
if (childobj != nullptr) // This is a GameObject
{
// add to the list, no AddRef because the list doesn't own its items.
list->Add(childobj);
list.push_back(childobj);
}

// if the childobj is nullptr then this may be an inverse parent link
Expand All @@ -1520,22 +1520,17 @@ static void walk_children(SG_Node* node, EXP_ListValue<KX_GameObject> *list, boo
}
}

EXP_ListValue<KX_GameObject> *KX_GameObject::GetChildren()
std::vector<KX_GameObject *> KX_GameObject::GetChildren() const
{
EXP_ListValue<KX_GameObject> *list = new EXP_ListValue<KX_GameObject>();
/* The list must not own any data because is temporary and we can't
* ensure that it will freed before item's in it (e.g python owner). */
list->SetReleaseOnDestruct(false);
walk_children(GetSGNode(), list, 0); /* GetSGNode() is always valid or it would have raised an exception before this */
std::vector<KX_GameObject *> list;
// GetSGNode() is always valid or it would have raised an exception before this.
walk_children(GetSGNode(), list, 0);
return list;
}

EXP_ListValue<KX_GameObject> *KX_GameObject::GetChildrenRecursive()
std::vector<KX_GameObject *> KX_GameObject::GetChildrenRecursive() const
{
EXP_ListValue<KX_GameObject> *list = new EXP_ListValue<KX_GameObject>();
/* The list must not own any data because is temporary and we can't
* ensure that it will freed before item's in it (e.g python owner). */
list->SetReleaseOnDestruct(false);
std::vector<KX_GameObject *> list;
walk_children(GetSGNode(), list, 1);
return list;
}
Expand Down Expand Up @@ -3158,14 +3153,22 @@ PyObject *KX_GameObject::pyattr_get_actuators(EXP_PyObjectPlus *self_v, const EX

PyObject *KX_GameObject::pyattr_get_children(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef)
{
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
return self->GetChildren()->NewProxy(true);
KX_GameObject *self = static_cast<KX_GameObject *>(self_v);
EXP_ListValue<KX_GameObject> *list = new EXP_ListValue<KX_GameObject>(self->GetChildren());
/* The list must not own any data because is temporary and we can't
* ensure that it will freed before item's in it (e.g python owner). */
list->SetReleaseOnDestruct(false);
return list->NewProxy(true);
}

PyObject *KX_GameObject::pyattr_get_children_recursive(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef)
{
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
return self->GetChildrenRecursive()->NewProxy(true);
KX_GameObject *self = static_cast<KX_GameObject *>(self_v);
EXP_ListValue<KX_GameObject> *list = new EXP_ListValue<KX_GameObject>(self->GetChildrenRecursive());
/* The list must not own any data because is temporary and we can't
* ensure that it will freed before item's in it (e.g python owner). */
list->SetReleaseOnDestruct(false);
return list->NewProxy(true);
}

PyObject *KX_GameObject::pyattr_get_attrDict(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef)
Expand Down
4 changes: 2 additions & 2 deletions source/gameengine/Ketsji/KX_GameObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -866,8 +866,8 @@ class KX_GameObject : public SCA_IObject

KX_ClientObjectInfo* getClientInfo() { return m_pClient_info; }

EXP_ListValue<KX_GameObject> *GetChildren();
EXP_ListValue<KX_GameObject> *GetChildrenRecursive();
std::vector<KX_GameObject *> GetChildren() const;
std::vector<KX_GameObject *> GetChildrenRecursive() const;

/// Returns the component list.
EXP_ListValue<KX_PythonComponent> *GetComponents() const;
Expand Down
9 changes: 2 additions & 7 deletions source/gameengine/Ketsji/KX_Scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1325,7 +1325,6 @@ void KX_Scene::AddAnimatedObject(KX_GameObject *gameobj)
static void update_anim_thread_func(TaskPool *pool, void *taskdata, int UNUSED(threadid))
{
KX_GameObject *gameobj, *parent;
EXP_ListValue<KX_GameObject> *children;
bool needs_update;
KX_Scene::AnimationPoolData *data = (KX_Scene::AnimationPoolData *)BLI_task_pool_userdata(pool);
double curtime = data->curtime;
Expand All @@ -1338,7 +1337,7 @@ static void update_anim_thread_func(TaskPool *pool, void *taskdata, int UNUSED(t
if (!needs_update) {
// If we got here, we're looking to update an armature, so check its children meshes
// to see if we need to bother with a more expensive pose update
children = gameobj->GetChildren();
const std::vector<KX_GameObject *> children = gameobj->GetChildren();

bool has_mesh = false, has_non_mesh = false;

Expand All @@ -1360,15 +1359,13 @@ static void update_anim_thread_func(TaskPool *pool, void *taskdata, int UNUSED(t
// armature has only non-mesh children.
if (!needs_update && !has_mesh && has_non_mesh)
needs_update = true;

children->Release();
}

// If the object is a culled armature, then we manage only the animation time and end of its animations.
gameobj->UpdateActionManager(curtime, needs_update);

if (needs_update) {
children = gameobj->GetChildren();
const std::vector<KX_GameObject *> children = gameobj->GetChildren();
parent = gameobj->GetParent();

// Only do deformers here if they are not parented to an armature, otherwise the armature will
Expand All @@ -1381,8 +1378,6 @@ static void update_anim_thread_func(TaskPool *pool, void *taskdata, int UNUSED(t
child->GetDeformer()->Update();
}
}

children->Release();
}
}

Expand Down
2 changes: 1 addition & 1 deletion source/gameengine/SceneGraph/SG_Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ bool SG_Node::IsAncessor(const SG_Node *child) const
(child->m_SGparent == this) ? true : IsAncessor(child->m_SGparent);
}

NodeList& SG_Node::GetSGChildren()
const NodeList& SG_Node::GetSGChildren() const
{
return m_children;
}
Expand Down
2 changes: 1 addition & 1 deletion source/gameengine/SceneGraph/SG_Node.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class SG_Node : public SG_QList
* that.
* \return a reference to the list of children of this node.
*/
NodeList& GetSGChildren();
const NodeList& GetSGChildren() const;

/**
* Clear the list of children associated with this node
Expand Down

0 comments on commit 53ed0c4

Please sign in to comment.