diff --git a/examples/foo.cc b/examples/foo.cc index 5d9342d..7a51f16 100644 --- a/examples/foo.cc +++ b/examples/foo.cc @@ -114,3 +114,18 @@ Foobar* get_foobar_with_other_as_custodian (const SomeObject *other) { return new Foobar; } + +Foobar* create_new_foobar() +{ + return new Foobar; +} + +void set_foobar_with_other_as_custodian(Foobar *foobar, const SomeObject *other) +{ + // empty +} + +SomeObject * set_foobar_with_return_as_custodian(Foobar *foobar) +{ + return new SomeObject("xxx"); +} diff --git a/examples/foo.h b/examples/foo.h index b7b65b5..1c4420a 100644 --- a/examples/foo.h +++ b/examples/foo.h @@ -273,6 +273,8 @@ public: Foobar* get_foobar_with_other_as_custodian (const SomeObject *other) { return new Foobar; } + void set_foobar_with_self_as_custodian (Foobar *foobar) { + } }; @@ -304,5 +306,9 @@ namespace xpto Foobar* get_foobar_with_other_as_custodian(const SomeObject *other); +Foobar* create_new_foobar(); +void set_foobar_with_other_as_custodian(Foobar *foobar, const SomeObject *other); +SomeObject * set_foobar_with_return_as_custodian(Foobar *foobar); + #endif /* !FOO_H_ */ diff --git a/examples/foomodulegen.py b/examples/foomodulegen.py index a5e55f4..9f7dfa7 100755 --- a/examples/foomodulegen.py +++ b/examples/foomodulegen.py @@ -166,11 +166,26 @@ def my_module_gen(out_file): SomeObject.add_method(CppMethod( ReturnValue.new('Foobar*', custodian=1), 'get_foobar_with_other_as_custodian', [Parameter.new('SomeObject*', 'other', transfer_ownership=False)])) + SomeObject.add_method(CppMethod( + ReturnValue.new('void'), 'set_foobar_with_self_as_custodian', + [Parameter.new('Foobar*', 'foobar', custodian=0)])) mod.add_function(Function(ReturnValue.new('Foobar*', custodian=1), 'get_foobar_with_other_as_custodian', [Parameter.new('SomeObject*', 'other', transfer_ownership=False)])) + mod.add_function(Function(ReturnValue.new('Foobar*', caller_owns_return=True), + 'create_new_foobar', [])) + + mod.add_function(Function(ReturnValue.new('void'), + 'set_foobar_with_other_as_custodian', + [Parameter.new('Foobar*', 'foobar', custodian=2), + Parameter.new('SomeObject*', 'other', transfer_ownership=False)])) + + mod.add_function(Function(ReturnValue.new('SomeObject*', caller_owns_return=True), + 'set_foobar_with_return_as_custodian', + [Parameter.new('Foobar*', 'foobar', custodian=-1)])) + ## get/set recfcounted object Zbr SomeObject.add_method(CppMethod( diff --git a/examples/footest.py b/examples/footest.py index ab07ee8..03cbfdf 100644 --- a/examples/footest.py +++ b/examples/footest.py @@ -417,5 +417,81 @@ class TestFoo(unittest.TestCase): self.assertEqual(foo.Foobar.instance_count, Foobar_count1) + def test_custodian_function_param_other(self): + while gc.collect(): + pass + SomeObject_count_before = foo.SomeObject.instance_count + Foobar_count1 = foo.Foobar.instance_count + + obj1 = foo.SomeObject("xxx") + foo1 = foo.create_new_foobar() + foo.set_foobar_with_other_as_custodian(foo1, obj1) + Foobar_count2 = foo.Foobar.instance_count + + ## now, deleting foo1 should keep Foobar count the same, since + ## obj1 is keeping it alive + del foo1 + while gc.collect(): + pass + self.assertEqual(foo.Foobar.instance_count, Foobar_count2) + + ## now deleting obj1 should cause both foo1 and obj1 to be destroyed + del obj1 + while gc.collect(): + pass + self.assertEqual(foo.SomeObject.instance_count, SomeObject_count_before) + self.assertEqual(foo.Foobar.instance_count, Foobar_count1) + + + def test_custodian_function_param_return(self): + while gc.collect(): + pass + SomeObject_count_before = foo.SomeObject.instance_count + Foobar_count1 = foo.Foobar.instance_count + + foo1 = foo.create_new_foobar() + obj1 = foo.set_foobar_with_return_as_custodian(foo1) + Foobar_count2 = foo.Foobar.instance_count + + ## now, deleting foo1 should keep Foobar count the same, since + ## obj1 is keeping it alive + del foo1 + while gc.collect(): + pass + self.assertEqual(foo.Foobar.instance_count, Foobar_count2) + + ## now deleting obj1 should cause both foo1 and obj1 to be destroyed + del obj1 + while gc.collect(): + pass + self.assertEqual(foo.SomeObject.instance_count, SomeObject_count_before) + self.assertEqual(foo.Foobar.instance_count, Foobar_count1) + + + def test_custodian_method_param_self(self): + while gc.collect(): + pass + SomeObject_count_before = foo.SomeObject.instance_count + obj1 = foo.SomeObject("xxx") + Foobar_count1 = foo.Foobar.instance_count + foo1 = foo.create_new_foobar() + obj1.set_foobar_with_self_as_custodian(foo1) + Foobar_count2 = foo.Foobar.instance_count + self.assertEqual(Foobar_count2, Foobar_count1 + 1) + + ## now, deleting foo1 should keep the Foobar count the same, since + ## obj1 is keeping it alive + del foo1 + while gc.collect(): + pass + self.assertEqual(foo.Foobar.instance_count, Foobar_count2) + + ## now deleting obj1 should cause both foo1 and obj1 to be destroyed + del obj1 + while gc.collect(): + pass + self.assertEqual(foo.SomeObject.instance_count, SomeObject_count_before) + self.assertEqual(foo.Foobar.instance_count, Foobar_count1) + if __name__ == '__main__': unittest.main()