bdn::P<bdn::Button> button = bdn::newObj<bdn::Button>();
Idiomatic would be to use std::shared_ptr and std::make_shared, instead of yet-another-custom-smart-pointer. bdn::P<bdn::Button> button = bdn::newObj<bdn::Button>();
Idiomatic would be to use std::shared_ptr and std::make_shared, instead of yet-another-custom-smart-pointer.They also seem to have wrapped the STL, which I think is a big no-no. No real reason to relearn something new if there is an established standard. A modern C++ library shouldn't do that.
But on the other hand, not using the standard constructs definitely has a cost associated with it. We are happy for your feedback on this issue.
Note that we also think about the idea of transforming P and making it a specialization of std::shared_ptr for objects derived from bdn::Base. That would give us the best of both worlds. Feel free to let us know what you think.
The more logical model, to me, would be to have child views owned by parent views, and to only allow ownership-changing calls (i.e. adding or removing a child) from the main thread. That way all you really need is unique_ptr (from parent to children) and raw pointers (from children to parent, and from any observers). Although it would probably still be better to use shared_ptr just so that observers can use weak_ptr, since untangling lifetimes in callbacks can be tricky, and often it's easier to just check if the object is still there.
To give a specific code example, with unique_ptr, the same snippet would be:
_window = std::make_unique<bdn::Window>();
_window->setTitle("AwesomeApp");
auto button = std::make_unique<bdn::Button>();
button->setLabel("Hello World");
// The following *moves* button, such that _window takes ownership over it.
// It can only be called from the main thread.
_window->setContentView(button);
_window->requestAutoSize();
_window->requestCenter();
_window->setVisible(true);
And furthermore, _window wouldn't have to be a pointer at all - it can just be a member of MainViewController.