A Look at C++11 Shared Pointers in Leadwerks 5
C++11 introduces shared pointers, a powerful language feature that provides easy memory management without the overhead of garbage collection. The example below should look familiar to you:
#include "Leadwerks.h" using namespace Leadwerks; int main(int argc, const char *argv[]) { shared_ptr<Leadwerks::Window> window = Leadwerks::Window::Create(); shared_ptr<Context> context = Context::Create(window); shared_ptr<World> world = World::Create(); shared_ptr<Camera> camera = Camera::Create(); camera->SetRotation(35, 0, 0); camera->Move(0, 0, -6); shared_ptr<Light> light = DirectionalLight::Create(); light->SetRotation(35, 35, 0); shared_ptr<Model> model = Model::Box(); model->SetColor(1.0, 0.0, 0.0); model->SetPosition(-4, 0, 0); while (true) { if (window->Closed() || window->KeyDown(Key::Escape)) return false; Leadwerks::Time::Update(); world->Update(); world->Render(); context->Sync(); } //Everything will get automatically deleted when we return from this function return 0; }
Using the auto keyword simplifies everything (and it makes this code compatible with Leadwerks 4):
#include "Leadwerks.h" using namespace Leadwerks; int main(int argc, const char *argv[]) { auto window = Leadwerks::Window::Create(); auto context = Context::Create(window); auto world = World::Create(); auto camera = Camera::Create(); camera->SetRotation(35, 0, 0); camera->Move(0, 0, -6); auto light = DirectionalLight::Create(); light->SetRotation(35, 35, 0); auto model = Model::Box(); model->SetColor(1.0, 0.0, 0.0); model->SetPosition(-4, 0, 0); while (true) { if (window->Closed() || window->KeyDown(Key::Escape)) return false; Leadwerks::Time::Update(); world->Update(); world->Render(); context->Sync(); } //Everything will get automatically deleted when we return from this function return 0; }
Now things get interesting. This function would normally cause a horrible memory leak, but with shared pointers everything is fine:
void SaveTexture(shared_ptr<Texture> tex) { auto bank = Bank::Create(tex->GetMipmapSize()); tex->GetPixels(bank->buf); bank->Save("pixeldata.dat"); }
Yet shared pointers can still equal nullptr:
auto bank = Bank::Create(); bank.reset(); Debug::Assert(bank==nullptr);
You can even simply set a shared pointer to nullptr, and if that was the last pointer that referenced it, it gets deleted!
auto bank = Bank::Create(); bank = nullptr;// auto deletion here!
How to Delete an Entity
The code below will not delete the entity, because a shared pointer is still stored in the world.
auto entity = Pivot::Create(); entity = nullptr;
The entity must be have its world set to NULL, and the shared pointer must be set to NULL or go out of scope:
entity = Pivot::Create(); entity->SetWorld(nullptr); entity = nullptr;
Children use a weak pointer to the parent, so they will not cause self-referencing.
Asset Management
You no longer have to worry about calling Release() when loading assets:
auto material = Material::Create(); auto texture = Texture::Load("mytex.tex"); material->SetTexture(texture); texture = nullptr;
Unused assets will automatically be deleted if they go out of scope:
auto material = Material::Create(); auto texture = Texture::Load("mytex.tex"); material->SetTexture(texture); texture = nullptr; material = nullptr;
But if they are in use, they will be retained in memory:
auto material = Material::Create(); auto texture = Texture::Load("mytex.tex"); material->SetTexture(texture); model->SetMaterial(material); texture = nullptr; material = nullptr;
In conclusion, shared pointers automate many of the tasks we have been doing manually with the Leadwerks reference counting system and the AddRef and Release commands.
4 Comments
Recommended Comments