From 09f2730cc6d9774131c30987b73cd9b76799c094 Mon Sep 17 00:00:00 2001 From: Amorilia <amorilia@users.sourceforge.net> Date: Tue, 20 Sep 2011 21:55:53 +0100 Subject: [PATCH] Added missing_link_stack stuff to public interface, and added regression test for it. --- include/niflib.h | 11 ++++++ test/CMakeLists.txt | 3 +- test/missing_link_stack_test.cpp | 67 ++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 test/missing_link_stack_test.cpp diff --git a/include/niflib.h b/include/niflib.h index e55ca36d..8f4cc2a7 100644 --- a/include/niflib.h +++ b/include/niflib.h @@ -58,6 +58,7 @@ namespace Niflib { //Classes used class NiObject; +typedef Ref<NiObject> NiObjectRef; class NiNode; class NiAVObject; class NiControllerSequence; @@ -141,6 +142,16 @@ NIFLIB_API Ref<NiObject> ReadNifTree( string const & file_name, NifInfo * info = */ NIFLIB_API Ref<NiObject> ReadNifTree( istream & in, NifInfo * info = NULL ); +/*! + * Creates a new NIF file of the given file name by crawling through the data tree starting with the root objects given, and keeps track of links that cannot been written. + * \param[in] in The output stream to write the NIF data to. + * \param[in] roots The root objects to start from when writing out the NIF file. All decedents of these blocks will be written to the file in tree-descending order. + * \param[in] missing_link_stack stack of links which are referred to but which are not inside the tree rooted by roots. + * \param[in] info A NifInfo structure that contains information such as the version of the NIF file to create. + * \sa ReadNifList, WriteNifTree + */ +NIFLIB_API void WriteNifTree( ostream & in, list<NiObjectRef> const & roots, list<NiObject *> & missing_link_stack, const NifInfo & info = NifInfo() ); + /*! * Creates a new NIF file of the given file name by crawling through the data tree starting with the root object given. * \param[in] file_name The desired file name for the new NIF file. The path is relative to the working directory unless a full path is specified. diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6babbc28..37d342ea 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -9,7 +9,8 @@ foreach(TEST write_test skinpart_test ninode_test - skin_test) + skin_test + missing_link_stack_test) add_executable(${TEST} ${TEST}.cpp) target_link_libraries(${TEST} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} niflib) add_test(niflib::${TEST} ${TEST}) diff --git a/test/missing_link_stack_test.cpp b/test/missing_link_stack_test.cpp new file mode 100644 index 00000000..e25c3433 --- /dev/null +++ b/test/missing_link_stack_test.cpp @@ -0,0 +1,67 @@ +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MAIN +#include <boost/test/unit_test.hpp> + +#include <sstream> // stringstream + +// evil hack to allow testing of private and protected data +#define private public +#define protected public + +#include "niflib.h" +#include "obj/NiNode.h" +#include "obj/NiSkinInstance.h" +#include "obj/NiTriStrips.h" +#include "obj/NiTriStripsData.h" + +using namespace Niflib; +using namespace std; + +BOOST_AUTO_TEST_SUITE(missing_link_stack_test_suite) + +BOOST_AUTO_TEST_CASE(missing_link_stack_simple_test) +{ + stringstream ss; + stringstream ss2; + + // create a simple nif tree with a skin partition + NiNodeRef root = new NiNode; + NiNodeRef bone = new NiNode; + root->SetName("Root"); + bone->SetName("Bone"); + NiTriStripsRef shape = new NiTriStrips; + NiTriStripsDataRef data = new NiTriStripsData; + // set hierarchy + shape->SetData(data); + root->AddChild(DynamicCast<NiAVObject>(shape)); + root->AddChild(DynamicCast<NiAVObject>(bone)); + // bind skin to bone + { + vector<NiNodeRef> bones; + bones.push_back(bone); + shape->BindSkin(bones); + } + // write + list<NiObject *> missing_link_stack; + list<NiObjectRef> roots; + roots.push_back(StaticCast<NiObject>(shape)); + BOOST_CHECK_NO_THROW(WriteNifTree(ss, roots, missing_link_stack, NifInfo(VER_20_0_0_5))); + bool has_root = false; + bool has_bone = false; + // check that root and bone are missing + for (list<NiObject *>::iterator it = missing_link_stack.begin(); it != missing_link_stack.end(); it++) { + if ((*it) != NULL) { + if (!has_root && (*it) == root) { + has_root = true; + } else if (!has_bone && (*it) == bone) { + has_bone = true; + } else { + BOOST_CHECK(false); + } + }; + } + BOOST_CHECK_EQUAL(has_root, true); + BOOST_CHECK_EQUAL(has_bone, true); +} + +BOOST_AUTO_TEST_SUITE_END() -- GitLab