Browse Source

More robust object parenting.

vectorfields
Vladimír Vondruš 16 years ago
parent
commit
c38a1993db
  1. 16
      src/Object.cpp
  2. 6
      src/Object.h
  3. 3
      src/Scene.h
  4. 1
      src/Test/CMakeLists.txt
  5. 8
      src/Test/ObjectTest.cpp
  6. 38
      src/Test/SceneTest.cpp
  7. 33
      src/Test/SceneTest.h

16
src/Object.cpp

@ -22,15 +22,23 @@ namespace Magnum {
void Object::setParent(Object* parent) { void Object::setParent(Object* parent) {
if(_parent == parent) return; if(_parent == parent) return;
/* Remove the object from old parent children list */
if(_parent != 0)
_parent->_children.erase(this);
/* Set new parent and add the object to new parent children list */ /* Set new parent and add the object to new parent children list */
if(parent != 0) { if(parent != 0) {
/* Only Fry can be his own grandfather */
Object* p = parent;
while(p != 0 && p->parent() != p) {
if(p == this) return;
p = p->parent();
}
parent->_children.insert(this); parent->_children.insert(this);
} }
/* Remove the object from old parent children list */
if(_parent != 0)
_parent->_children.erase(this);
_parent = parent; _parent = parent;
} }

6
src/Object.h

@ -25,6 +25,8 @@
namespace Magnum { namespace Magnum {
class Scene;
/** /**
* @brief Base for all positioned objects * @brief Base for all positioned objects
* *
@ -34,6 +36,8 @@ namespace Magnum {
class Object { class Object {
DISABLE_COPY(Object) DISABLE_COPY(Object)
friend class Scene;
public: public:
/** /**
* @brief Constructor * @brief Constructor
@ -60,7 +64,7 @@ class Object {
inline const std::set<Object*>& children() const { return _children; } inline const std::set<Object*>& children() const { return _children; }
/** @brief Set parent object */ /** @brief Set parent object */
void setParent(Object* parent); virtual void setParent(Object* parent);
/** @brief Transformation matrix */ /** @brief Transformation matrix */
inline Matrix4 transformation() const { return _transformation; } inline Matrix4 transformation() const { return _transformation; }

3
src/Scene.h

@ -26,7 +26,7 @@ namespace Magnum {
/** @brief Scene */ /** @brief Scene */
class Scene: public Object { class Scene: public Object {
private: private:
Object::setParent; virtual void setParent(Object* parent) {}
Object::setTransformation; Object::setTransformation;
public: public:
@ -39,6 +39,7 @@ class Scene: public Object {
/** @brief Constructor */ /** @brief Constructor */
inline Scene(): Object(0), _features(0), _camera(0) { inline Scene(): Object(0), _features(0), _camera(0) {
_parent = this;
setClearColor(0.1f, 0.1f, 0.1f, 1.0f); setClearColor(0.1f, 0.1f, 0.1f, 1.0f);
} }

1
src/Test/CMakeLists.txt

@ -1,2 +1,3 @@
magnum_add_test(ObjectTest ObjectTest.h ObjectTest.cpp Magnum) magnum_add_test(ObjectTest ObjectTest.h ObjectTest.cpp Magnum)
magnum_add_test(CameraTest CameraTest.h CameraTest.cpp Magnum) magnum_add_test(CameraTest CameraTest.h CameraTest.cpp Magnum)
magnum_add_test(SceneTest SceneTest.h SceneTest.cpp Magnum)

8
src/Test/ObjectTest.cpp

@ -30,6 +30,14 @@ void ObjectTest::parenting() {
QVERIFY(childOne->parent() == &root); QVERIFY(childOne->parent() == &root);
QVERIFY(root.children().size() == 2); QVERIFY(root.children().size() == 2);
/* A object cannot be parent of itself */
childOne->setParent(childOne);
QVERIFY(childOne->parent() == &root);
/* In fact, cyclic dependencies are not allowed at all */
root.setParent(childTwo);
QVERIFY(root.parent() == 0);
/* Reparent to another */ /* Reparent to another */
childTwo->setParent(childOne); childTwo->setParent(childOne);
QVERIFY(root.children().size() == 1 && *root.children().begin() == childOne); QVERIFY(root.children().size() == 1 && *root.children().begin() == childOne);

38
src/Test/SceneTest.cpp

@ -0,0 +1,38 @@
/*
Copyright © 2010 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum 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 Lesser General Public License version 3 for more details.
*/
#include "SceneTest.h"
#include <QtTest/QTest>
#include "Scene.h"
QTEST_APPLESS_MAIN(Magnum::Test::SceneTest)
namespace Magnum { namespace Test {
void SceneTest::parent() {
Scene scene;
QVERIFY(scene.parent() == &scene);
/* Scene parent cannot be changed */
Object* scenePointer = &scene;
Object* object = new Object;
scenePointer->setParent(object);
QVERIFY(scene.parent() == &scene);
}
}}

33
src/Test/SceneTest.h

@ -0,0 +1,33 @@
#ifndef Magnum_Test_SceneTest_h
#define Magnum_Test_SceneTest_h
/*
Copyright © 2010 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum 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 Lesser General Public License version 3 for more details.
*/
#include <QtCore/QObject>
#include "Object.h"
namespace Magnum { namespace Test {
class SceneTest: public QObject {
Q_OBJECT
private slots:
void parent();
};
}}
#endif
Loading…
Cancel
Save