diff --git a/simgear/nasal/code.c b/simgear/nasal/code.c index 2bf46451..49e2e4c6 100644 --- a/simgear/nasal/code.c +++ b/simgear/nasal/code.c @@ -787,6 +787,11 @@ void naGCRelease(int key) naHash_delete(globals->save_hash, naNum(key)); } +int naNumSaved() +{ + return naHash_size(globals->save_hash) + naVec_size(globals->save_hash); +} + void naClearSaved() { naContext c; diff --git a/simgear/nasal/cppbind/NasalObjectHolder.hxx b/simgear/nasal/cppbind/NasalObjectHolder.hxx index 55fb5ba1..9b36bcf7 100644 --- a/simgear/nasal/cppbind/NasalObjectHolder.hxx +++ b/simgear/nasal/cppbind/NasalObjectHolder.hxx @@ -139,10 +139,9 @@ namespace nasal template ObjectHolder::ObjectHolder(naRef obj): _ref(obj), - _gc_key(0) + _gc_key(naIsNil(obj) ? 0 : naGCSave(obj)) { - if( !naIsNil(obj) ) - naGCSave(obj); + } //---------------------------------------------------------------------------- @@ -159,7 +158,7 @@ namespace nasal SGSharedPtr > ObjectHolder::makeShared(naRef obj) { - return SGSharedPtr >( new ObjectHolder(obj) ); + return SGSharedPtr >( new ObjectHolder(obj) ); } } // namespace nasal diff --git a/simgear/nasal/cppbind/test/nasal_gc_test.cxx b/simgear/nasal/cppbind/test/nasal_gc_test.cxx index c1cb6ca3..0d6e2e09 100644 --- a/simgear/nasal/cppbind/test/nasal_gc_test.cxx +++ b/simgear/nasal/cppbind/test/nasal_gc_test.cxx @@ -2,6 +2,9 @@ #include #include "TestContext.hxx" + +#include + #include #include @@ -91,3 +94,47 @@ BOOST_AUTO_TEST_CASE( ghost_gc ) BOOST_REQUIRE(active_instances.empty()); } + +//------------------------------------------------------------------------------ +BOOST_AUTO_TEST_CASE( object_holder_gc ) +{ + TestContext c; + BOOST_REQUIRE_EQUAL(naNumSaved(), 0); + BOOST_REQUIRE(active_instances.empty()); + + //----------------------------------------------- + // Put some ghosts in ObjectHolder and check if + // they are saved from gc + + naRef g1 = createTestGhost(c, 1), + g2 = createTestGhost(c, 2); + + nasal::ObjectHolder<> h1(g1); + BOOST_CHECK_EQUAL(naNumSaved(), 1); + BOOST_CHECK(naIsGhost(h1.get_naRef())); + + nasal::ObjectHolder<> h2(g2); + BOOST_CHECK_EQUAL(naNumSaved(), 2); + BOOST_CHECK(naIsGhost(h2.get_naRef())); + + c.runGC(); + + BOOST_CHECK_EQUAL(active_instances.size(), 2); + BOOST_CHECK_EQUAL(naNumSaved(), 2); + + h1.reset(naNum(1)); + h2.reset(naNum(2)); + BOOST_CHECK_EQUAL(naNumSaved(), 2); + + //----------------------------------------------- + // Check that the saved objects are released + + h1.reset(); + BOOST_CHECK_EQUAL(naNumSaved(), 1); + + h2.reset(); + BOOST_CHECK_EQUAL(naNumSaved(), 0); + + c.runGC(); + BOOST_CHECK_EQUAL(active_instances.size(), 0); +} diff --git a/simgear/nasal/nasal.h b/simgear/nasal/nasal.h index 8b6b2c92..7be9bb4f 100644 --- a/simgear/nasal/nasal.h +++ b/simgear/nasal/nasal.h @@ -58,6 +58,10 @@ int naGCSave(naRef obj); // by the garbage collector. void naGCRelease(int key); +// Get the number of currently saved and not yet again released objects +// (saved by naSave or naGCSave) +int naNumSaved(); + // Drop all saved references void naClearSaved();