Reduced the number of explicit retain/release method calls on love objects. Less chance of bugs!

This commit is contained in:
Alex Szpakowski
2014-08-07 14:53:17 -03:00
parent a0fff798aa
commit d59c76a55f
38 changed files with 194 additions and 247 deletions
+2
View File
@@ -21,6 +21,8 @@
// LOVE // LOVE
#include "Object.h" #include "Object.h"
#include <stdio.h>
namespace love namespace love
{ {
+62
View File
@@ -92,11 +92,73 @@ public:
}; // AutoRelease }; // AutoRelease
/**
* Partial re-implementation + specialization of std::shared_ptr. We can't
* use C++11's stdlib yet...
**/
template <typename T>
class StrongRef
{
public:
StrongRef()
: object(nullptr)
{
}
StrongRef(T *obj)
: object(obj)
{
if (object) object->retain();
}
StrongRef(const StrongRef &other)
: object(other.get())
{
if (object) object->retain();
}
~StrongRef()
{
if (object) object->release();
}
StrongRef &operator = (const StrongRef &other)
{
set(other.get());
return *this;
}
T *operator->() const
{
return object;
}
void set(T *obj)
{
if (obj) obj->retain();
if (object) object->release();
object = obj;
}
T *get() const
{
return object;
}
private:
T *object;
}; // StrongRef
private: private:
// The reference count. // The reference count.
int count; int count;
}; // Object }; // Object
} // love } // love
#endif // LOVE_OBJECT_H #endif // LOVE_OBJECT_H
+8 -13
View File
@@ -98,7 +98,6 @@ Source::Source(Pool *pool, love::sound::Decoder *decoder)
, decoder(decoder) , decoder(decoder)
, toLoop(0) , toLoop(0)
{ {
decoder->retain();
alGenBuffers(MAX_BUFFERS, streamBuffers); alGenBuffers(MAX_BUFFERS, streamBuffers);
float z[3] = {0, 0, 0}; float z[3] = {0, 0, 0};
@@ -132,13 +131,15 @@ Source::Source(const Source &s)
{ {
if (type == TYPE_STREAM) if (type == TYPE_STREAM)
{ {
if (s.decoder) if (s.decoder.get())
decoder = s.decoder->clone(); {
love::sound::Decoder *dec = s.decoder->clone();
decoder.set(dec);
dec->release();
}
alGenBuffers(MAX_BUFFERS, streamBuffers); alGenBuffers(MAX_BUFFERS, streamBuffers);
} }
else
staticBuffer->retain();
setFloatv(position, s.position); setFloatv(position, s.position);
setFloatv(velocity, s.velocity); setFloatv(velocity, s.velocity);
@@ -152,12 +153,6 @@ Source::~Source()
if (type == TYPE_STREAM) if (type == TYPE_STREAM)
alDeleteBuffers(MAX_BUFFERS, streamBuffers); alDeleteBuffers(MAX_BUFFERS, streamBuffers);
if (staticBuffer)
staticBuffer->release();
if (decoder)
decoder->release();
} }
love::audio::Source *Source::clone() love::audio::Source *Source::clone()
@@ -269,7 +264,7 @@ bool Source::update()
offsetSamples += (curOffsetSamples - newOffsetSamples); offsetSamples += (curOffsetSamples - newOffsetSamples);
offsetSeconds += (curOffsetSecs - newOffsetSecs); offsetSeconds += (curOffsetSecs - newOffsetSecs);
streamAtomic(buffer, decoder); streamAtomic(buffer, decoder.get());
alSourceQueueBuffers(source, 1, &buffer); alSourceQueueBuffers(source, 1, &buffer);
} }
return true; return true;
@@ -510,7 +505,7 @@ bool Source::playAtomic()
for (unsigned int i = 0; i < MAX_BUFFERS; i++) for (unsigned int i = 0; i < MAX_BUFFERS; i++)
{ {
streamAtomic(streamBuffers[i], decoder); streamAtomic(streamBuffers[i], decoder.get());
++usedBuffers; ++usedBuffers;
if (decoder->isFinished()) if (decoder->isFinished())
break; break;
+2 -2
View File
@@ -148,7 +148,7 @@ private:
static const unsigned int MAX_BUFFERS = 32; static const unsigned int MAX_BUFFERS = 32;
ALuint streamBuffers[MAX_BUFFERS]; ALuint streamBuffers[MAX_BUFFERS];
StaticDataBuffer *staticBuffer; Object::StrongRef<StaticDataBuffer> staticBuffer;
float pitch; float pitch;
float volume; float volume;
@@ -182,7 +182,7 @@ private:
int channels; int channels;
love::sound::Decoder *decoder; Object::StrongRef<love::sound::Decoder> decoder;
unsigned int toLoop; unsigned int toLoop;
-2
View File
@@ -39,13 +39,11 @@ ImageRasterizer::ImageRasterizer(love::image::ImageData *data, uint32 *glyphs, i
, glyphs(glyphs) , glyphs(glyphs)
, numglyphs(numglyphs) , numglyphs(numglyphs)
{ {
imageData->retain();
load(); load();
} }
ImageRasterizer::~ImageRasterizer() ImageRasterizer::~ImageRasterizer()
{ {
imageData->release();
} }
int ImageRasterizer::getLineHeight() const int ImageRasterizer::getLineHeight() const
+1 -1
View File
@@ -53,7 +53,7 @@ private:
void load(); void load();
// The image data // The image data
love::image::ImageData *imageData; Object::StrongRef<love::image::ImageData> imageData;
// The glyphs in the font // The glyphs in the font
uint32 *glyphs; uint32 *glyphs;
@@ -51,14 +51,11 @@ TrueTypeRasterizer::TrueTypeRasterizer(FT_Library library, Data *data, int size)
metrics.ascent = s.ascender >> 6; metrics.ascent = s.ascender >> 6;
metrics.descent = s.descender >> 6; metrics.descent = s.descender >> 6;
metrics.height = s.height >> 6; metrics.height = s.height >> 6;
data->retain();
} }
TrueTypeRasterizer::~TrueTypeRasterizer() TrueTypeRasterizer::~TrueTypeRasterizer()
{ {
FT_Done_Face(face); FT_Done_Face(face);
data->release();
} }
int TrueTypeRasterizer::getLineHeight() const int TrueTypeRasterizer::getLineHeight() const
@@ -58,7 +58,7 @@ private:
FT_Face face; FT_Face face;
// File data // File data
Data *data; Object::StrongRef<Data> data;
}; // FreetypeRasterizer }; // FreetypeRasterizer
} // freetype } // freetype
-3
View File
@@ -87,13 +87,10 @@ Font::Font(love::font::Rasterizer *r, const Texture::Filter &filter)
} }
delete gd; delete gd;
rasterizer->retain();
} }
Font::~Font() Font::~Font()
{ {
rasterizer->release();
unloadVolatile(); unloadVolatile();
} }
+1 -1
View File
@@ -183,7 +183,7 @@ private:
Glyph *addGlyph(uint32 glyph); Glyph *addGlyph(uint32 glyph);
Glyph *findGlyph(uint32 glyph); Glyph *findGlyph(uint32 glyph);
love::font::Rasterizer *rasterizer; Object::StrongRef<love::font::Rasterizer> rasterizer;
int height; int height;
float lineHeight; float lineHeight;
+39 -80
View File
@@ -95,8 +95,8 @@ void Graphics::restoreState(const DisplayState &s)
else else
setScissor(); setScissor();
setFont(s.font); setFont(s.font.get());
setShader(s.shader); setShader(s.shader.get());
setCanvas(s.canvases); setCanvas(s.canvases);
setColorMask(s.colorMask); setColorMask(s.colorMask);
@@ -135,12 +135,12 @@ void Graphics::restoreStateChecked(const DisplayState &s)
setScissor(); setScissor();
} }
setFont(s.font); setFont(s.font.get());
setShader(s.shader); setShader(s.shader.get());
for (size_t i = 0; i < s.canvases.size() && i < cur.canvases.size(); i++) for (size_t i = 0; i < s.canvases.size() && i < cur.canvases.size(); i++)
{ {
if (s.canvases[i] != cur.canvases[i]) if (s.canvases[i].get() != cur.canvases[i].get())
{ {
setCanvas(s.canvases); setCanvas(s.canvases);
break; break;
@@ -606,19 +606,12 @@ Color Graphics::getBackgroundColor() const
void Graphics::setFont(Font *font) void Graphics::setFont(Font *font)
{ {
DisplayState &state = states.back(); DisplayState &state = states.back();
state.font.set(font);
if (font != nullptr)
font->retain();
if (state.font != nullptr)
state.font->release();
state.font = font;
} }
Font *Graphics::getFont() const Font *Graphics::getFont() const
{ {
return states.back().font; return states.back().font.get();
} }
void Graphics::setShader(Shader *shader) void Graphics::setShader(Shader *shader)
@@ -630,13 +623,7 @@ void Graphics::setShader(Shader *shader)
shader->attach(); shader->attach();
if (shader) state.shader.set(shader);
shader->retain();
if (state.shader)
state.shader->release();
state.shader = shader;
} }
void Graphics::setShader() void Graphics::setShader()
@@ -645,15 +632,12 @@ void Graphics::setShader()
Shader::detach(); Shader::detach();
if (state.shader) state.shader.set(nullptr);
state.shader->release();
state.shader = nullptr;
} }
Shader *Graphics::getShader() const Shader *Graphics::getShader() const
{ {
return states.back().shader; return states.back().shader.get();
} }
void Graphics::setCanvas(Canvas *canvas) void Graphics::setCanvas(Canvas *canvas)
@@ -665,13 +649,10 @@ void Graphics::setCanvas(Canvas *canvas)
canvas->startGrab(); canvas->startGrab();
canvas->retain(); std::vector<Object::StrongRef<Canvas>> canvasref;
canvasref.push_back(canvas);
for (Canvas *c : state.canvases) std::swap(state.canvases, canvasref);
c->release();
state.canvases.clear();
state.canvases.push_back(canvas);
} }
void Graphics::setCanvas(const std::vector<Canvas *> &canvases) void Graphics::setCanvas(const std::vector<Canvas *> &canvases)
@@ -686,13 +667,24 @@ void Graphics::setCanvas(const std::vector<Canvas *> &canvases)
auto attachments = std::vector<Canvas *>(canvases.begin() + 1, canvases.end()); auto attachments = std::vector<Canvas *>(canvases.begin() + 1, canvases.end());
canvases[0]->startGrab(attachments); canvases[0]->startGrab(attachments);
std::vector<Object::StrongRef<Canvas>> canvasrefs;
canvasrefs.reserve(canvases.size());
for (Canvas *c : canvases) for (Canvas *c : canvases)
c->retain(); canvasrefs.push_back(c);
for (Canvas *c : state.canvases) std::swap(state.canvases, canvasrefs);
c->release(); }
state.canvases = canvases; void Graphics::setCanvas(const std::vector<Object::StrongRef<Canvas>> &canvases)
{
std::vector<Canvas *> canvaslist;
canvaslist.reserve(canvases.size());
for (const Object::StrongRef<Canvas> &c : canvases)
canvaslist.push_back(c.get());
return setCanvas(canvaslist);
} }
void Graphics::setCanvas() void Graphics::setCanvas()
@@ -702,15 +694,18 @@ void Graphics::setCanvas()
if (Canvas::current != nullptr) if (Canvas::current != nullptr)
Canvas::current->stopGrab(); Canvas::current->stopGrab();
for (Canvas *c : state.canvases)
c->release();
state.canvases.clear(); state.canvases.clear();
} }
std::vector<Canvas *> Graphics::getCanvas() const std::vector<Canvas *> Graphics::getCanvas() const
{ {
return states.back().canvases; std::vector<Canvas *> canvases;
canvases.reserve(states.back().canvases.size());
for (const Object::StrongRef<Canvas> &c : states.back().canvases)
canvases.push_back(c.get());
return canvases;
} }
void Graphics::setColorMask(const bool mask[4]) void Graphics::setColorMask(const bool mask[4])
@@ -876,7 +871,7 @@ void Graphics::print(const std::string &str, float x, float y , float angle, flo
{ {
DisplayState &state = states.back(); DisplayState &state = states.back();
if (state.font != nullptr) if (state.font.get() != nullptr)
state.font->print(str, x, y, 0.0, angle, sx, sy, ox, oy, kx, ky); state.font->print(str, x, y, 0.0, angle, sx, sy, ox, oy, kx, ky);
} }
@@ -884,7 +879,7 @@ void Graphics::printf(const std::string &str, float x, float y, float wrap, Alig
{ {
DisplayState &state = states.back(); DisplayState &state = states.back();
if (state.font == nullptr) if (state.font.get() == nullptr)
return; return;
if (wrap < 0.0f) if (wrap < 0.0f)
@@ -1266,12 +1261,8 @@ void Graphics::pop()
// Hack: the Lua-facing love.graphics.print function will set the current // Hack: the Lua-facing love.graphics.print function will set the current
// font if needed, but only on its first call... we always want a font. // font if needed, but only on its first call... we always want a font.
if (newstate.font == nullptr) if (newstate.font.get() == nullptr)
{ newstate.font.set(states.back().font.get());
newstate.font = states.back().font;
if (newstate.font != nullptr)
newstate.font->retain();
}
restoreStateChecked(newstate); restoreStateChecked(newstate);
@@ -1347,27 +1338,10 @@ Graphics::DisplayState::DisplayState(const DisplayState &other)
{ {
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
colorMask[i] = other.colorMask[i]; colorMask[i] = other.colorMask[i];
if (font)
font->retain();
if (shader)
shader->retain();
for (Canvas *c : canvases)
c->retain();
} }
Graphics::DisplayState::~DisplayState() Graphics::DisplayState::~DisplayState()
{ {
for (Canvas *c : canvases)
c->release();
if (shader)
shader->release();
if (font)
font->release();
} }
Graphics::DisplayState &Graphics::DisplayState::operator = (const DisplayState &other) Graphics::DisplayState &Graphics::DisplayState::operator = (const DisplayState &other)
@@ -1383,23 +1357,8 @@ Graphics::DisplayState &Graphics::DisplayState::operator = (const DisplayState &
scissor = other.scissor; scissor = other.scissor;
scissorBox = other.scissorBox; scissorBox = other.scissorBox;
Object::AutoRelease fontrelease(font);
font = other.font; font = other.font;
if (font)
font->retain();
Object::AutoRelease shaderrelease(shader);
shader = other.shader; shader = other.shader;
if (shader)
shader->retain();
for (Canvas *c : other.canvases)
c->retain();
for (Canvas *c : canvases)
c->release();
canvases = other.canvases; canvases = other.canvases;
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
+5 -3
View File
@@ -208,6 +208,7 @@ public:
void setCanvas(Canvas *canvas); void setCanvas(Canvas *canvas);
void setCanvas(const std::vector<Canvas *> &canvases); void setCanvas(const std::vector<Canvas *> &canvases);
void setCanvas(const std::vector<Object::StrongRef<Canvas>> &canvases);
void setCanvas(); void setCanvas();
std::vector<Canvas *> getCanvas() const; std::vector<Canvas *> getCanvas() const;
@@ -459,9 +460,10 @@ private:
bool scissor; bool scissor;
OpenGL::Viewport scissorBox; OpenGL::Viewport scissorBox;
Font *font; Object::StrongRef<Font> font;
Shader *shader; Object::StrongRef<Shader> shader;
std::vector<Canvas *> canvases;
std::vector<Object::StrongRef<Canvas>> canvases;
// Color mask. // Color mask.
bool colorMask[4]; bool colorMask[4];
+13 -21
View File
@@ -50,8 +50,6 @@ Image::Image(love::image::ImageData *data, Format format)
{ {
width = data->getWidth(); width = data->getWidth();
height = data->getHeight(); height = data->getHeight();
data->retain();
preload(); preload();
} }
@@ -69,28 +67,22 @@ Image::Image(love::image::CompressedData *cdata, Format format)
{ {
width = cdata->getWidth(0); width = cdata->getWidth(0);
height = cdata->getHeight(0); height = cdata->getHeight(0);
cdata->retain();
preload(); preload();
} }
Image::~Image() Image::~Image()
{ {
if (data != nullptr)
data->release();
if (cdata != nullptr)
cdata->release();
unload(); unload();
} }
love::image::ImageData *Image::getImageData() const love::image::ImageData *Image::getImageData() const
{ {
return data; return data.get();
} }
love::image::CompressedData *Image::getCompressedData() const love::image::CompressedData *Image::getCompressedData() const
{ {
return cdata; return cdata.get();
} }
void Image::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) void Image::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
@@ -140,7 +132,7 @@ GLuint Image::getGLTexture() const
void Image::uploadCompressedMipmaps() void Image::uploadCompressedMipmaps()
{ {
if (!isCompressed() || !cdata || !hasCompressedTextureSupport(cdata->getFormat())) if (!isCompressed() || !cdata.get() || !hasCompressedTextureSupport(cdata->getFormat()))
return; return;
bind(); bind();
@@ -175,7 +167,7 @@ void Image::uploadCompressedMipmaps()
void Image::createMipmaps() void Image::createMipmaps()
{ {
// Only valid for Images created with ImageData. // Only valid for Images created with ImageData.
if (!data || isCompressed()) if (!data.get() || isCompressed())
return; return;
if (!hasMipmapSupport()) if (!hasMipmapSupport())
@@ -231,9 +223,9 @@ void Image::checkMipmapsCreated()
if (mipmapsCreated || filter.mipmap == FILTER_NONE || usingDefaultTexture) if (mipmapsCreated || filter.mipmap == FILTER_NONE || usingDefaultTexture)
return; return;
if (isCompressed() && cdata && hasCompressedTextureSupport(cdata->getFormat())) if (isCompressed() && cdata.get() && hasCompressedTextureSupport(cdata->getFormat()))
uploadCompressedMipmaps(); uploadCompressedMipmaps();
else if (data) else if (data.get())
createMipmaps(); createMipmaps();
else else
return; return;
@@ -334,7 +326,7 @@ bool Image::loadVolatile()
if (format == FORMAT_SRGB && !hasSRGBSupport()) if (format == FORMAT_SRGB && !hasSRGBSupport())
throw love::Exception("sRGB images are not supported on this system."); throw love::Exception("sRGB images are not supported on this system.");
if (isCompressed() && cdata && !hasCompressedTextureSupport(cdata->getFormat())) if (isCompressed() && cdata.get() && !hasCompressedTextureSupport(cdata->getFormat()))
{ {
const char *str; const char *str;
if (image::CompressedData::getConstant(cdata->getFormat(), str)) if (image::CompressedData::getConstant(cdata->getFormat(), str))
@@ -375,7 +367,7 @@ bool Image::loadVolatile()
// Mutex lock will potentially cover texture loading and mipmap creation. // Mutex lock will potentially cover texture loading and mipmap creation.
love::thread::EmptyLock lock; love::thread::EmptyLock lock;
if (data) if (data.get())
lock.setLock(data->getMutex()); lock.setLock(data->getMutex());
while (glGetError() != GL_NO_ERROR); // Clear errors. while (glGetError() != GL_NO_ERROR); // Clear errors.
@@ -398,13 +390,13 @@ bool Image::loadVolatile()
void Image::uploadTexturePadded() void Image::uploadTexturePadded()
{ {
if (isCompressed() && cdata) if (isCompressed() && cdata.get())
{ {
// Padded textures don't really work if they're compressed... // Padded textures don't really work if they're compressed...
throw love::Exception("Cannot create image: " throw love::Exception("Cannot create image: "
"compressed NPOT images are not supported on this system."); "compressed NPOT images are not supported on this system.");
} }
else if (data) else if (data.get())
{ {
GLenum iformat = (format == FORMAT_SRGB) ? GL_SRGB8_ALPHA8 : GL_RGBA8; GLenum iformat = (format == FORMAT_SRGB) ? GL_SRGB8_ALPHA8 : GL_RGBA8;
glTexImage2D(GL_TEXTURE_2D, glTexImage2D(GL_TEXTURE_2D,
@@ -430,7 +422,7 @@ void Image::uploadTexturePadded()
void Image::uploadTexture() void Image::uploadTexture()
{ {
if (isCompressed() && cdata) if (isCompressed() && cdata.get())
{ {
GLenum format = getCompressedFormat(cdata->getFormat()); GLenum format = getCompressedFormat(cdata->getFormat());
glCompressedTexImage2DARB(GL_TEXTURE_2D, glCompressedTexImage2DARB(GL_TEXTURE_2D,
@@ -442,7 +434,7 @@ void Image::uploadTexture()
GLsizei(cdata->getSize(0)), GLsizei(cdata->getSize(0)),
cdata->getData(0)); cdata->getData(0));
} }
else if (data) else if (data.get())
{ {
GLenum iformat = (format == FORMAT_SRGB) ? GL_SRGB8_ALPHA8 : GL_RGBA8; GLenum iformat = (format == FORMAT_SRGB) ? GL_SRGB8_ALPHA8 : GL_RGBA8;
glTexImage2D(GL_TEXTURE_2D, glTexImage2D(GL_TEXTURE_2D,
@@ -484,7 +476,7 @@ bool Image::refresh()
bind(); bind();
if (data && !isCompressed()) if (data.get() && !isCompressed())
lock.setLock(data->getMutex()); lock.setLock(data->getMutex());
while (glGetError() != GL_NO_ERROR); // Clear errors. while (glGetError() != GL_NO_ERROR); // Clear errors.
+2 -2
View File
@@ -156,11 +156,11 @@ private:
// The ImageData from which the texture is created. May be null if // The ImageData from which the texture is created. May be null if
// Compressed image data was used to create the texture. // Compressed image data was used to create the texture.
love::image::ImageData *data; Object::StrongRef<love::image::ImageData> data;
// Or the Compressed Image Data from which the texture is created. May be // Or the Compressed Image Data from which the texture is created. May be
// null if raw ImageData was used to create the texture. // null if raw ImageData was used to create the texture.
love::image::CompressedData *cdata; Object::StrongRef<love::image::CompressedData> cdata;
// Real dimensions of the texture, if it was auto-padded to POT size. // Real dimensions of the texture, if it was auto-padded to POT size.
int paddedWidth, paddedHeight; int paddedWidth, paddedHeight;
+5 -16
View File
@@ -79,9 +79,6 @@ Mesh::Mesh(int vertexcount, Mesh::DrawMode mode)
Mesh::~Mesh() Mesh::~Mesh()
{ {
if (texture)
texture->release();
delete vbo; delete vbo;
delete ibo; delete ibo;
} }
@@ -264,25 +261,17 @@ size_t Mesh::getVertexMapCount() const
void Mesh::setTexture(Texture *tex) void Mesh::setTexture(Texture *tex)
{ {
tex->retain(); texture.set(tex);
if (texture)
texture->release();
texture = tex;
} }
void Mesh::setTexture() void Mesh::setTexture()
{ {
if (texture) texture.set(nullptr);
texture->release();
texture = nullptr;
} }
Texture *Mesh::getTexture() const Texture *Mesh::getTexture() const
{ {
return texture; return texture.get();
} }
void Mesh::setDrawMode(Mesh::DrawMode mode) void Mesh::setDrawMode(Mesh::DrawMode mode)
@@ -334,7 +323,7 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo
if (vertex_count == 0) if (vertex_count == 0)
return; return;
if (texture) if (texture.get())
texture->predraw(); texture->predraw();
else else
gl.bindTexture(0); gl.bindTexture(0);
@@ -412,7 +401,7 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo
gl.setColor(gl.getColor()); gl.setColor(gl.getColor());
} }
if (texture) if (texture.get())
texture->postdraw(); texture->postdraw();
} }
+1 -1
View File
@@ -178,7 +178,7 @@ private:
int range_min; int range_min;
int range_max; int range_max;
Texture *texture; Object::StrongRef<Texture> texture;
// Whether the per-vertex colors are used when drawing. // Whether the per-vertex colors are used when drawing.
bool colors_enabled; bool colors_enabled;
+17 -32
View File
@@ -102,7 +102,6 @@ ParticleSystem::ParticleSystem(Texture *texture, uint32 size)
sizes.push_back(1.0f); sizes.push_back(1.0f);
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f)); colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
setBufferSize(size); setBufferSize(size);
texture->retain();
} }
ParticleSystem::ParticleSystem(const ParticleSystem &p) ParticleSystem::ParticleSystem(const ParticleSystem &p)
@@ -150,22 +149,10 @@ ParticleSystem::ParticleSystem(const ParticleSystem &p)
, relativeRotation(p.relativeRotation) , relativeRotation(p.relativeRotation)
{ {
setBufferSize(maxParticles); setBufferSize(maxParticles);
if (texture != nullptr)
texture->retain();
for (Quad *quad : quads)
quad->retain();
} }
ParticleSystem::~ParticleSystem() ParticleSystem::~ParticleSystem()
{ {
if (texture != nullptr)
texture->release();
for (Quad *quad : quads)
quad->release();
deleteBuffers(); deleteBuffers();
} }
@@ -422,19 +409,14 @@ ParticleSystem::Particle *ParticleSystem::removeParticle(Particle *p)
return pNext; return pNext;
} }
void ParticleSystem::setTexture(Texture *texture) void ParticleSystem::setTexture(Texture *tex)
{ {
Object::AutoRelease imagerelease(this->texture); texture.set(tex);
this->texture = texture;
if (texture)
texture->retain();
} }
Texture *ParticleSystem::getTexture() const Texture *ParticleSystem::getTexture() const
{ {
return texture; return texture.get();
} }
void ParticleSystem::setInsertMode(InsertMode mode) void ParticleSystem::setInsertMode(InsertMode mode)
@@ -732,26 +714,29 @@ std::vector<Color> ParticleSystem::getColor() const
void ParticleSystem::setQuads(const std::vector<Quad *> &newQuads) void ParticleSystem::setQuads(const std::vector<Quad *> &newQuads)
{ {
for (Quad *quad : newQuads) std::vector<StrongRef<Quad>> quadlist;
quad->retain(); quadlist.reserve(newQuads.size());
for (Quad *quad : quads) for (Quad *q : newQuads)
quad->release(); quadlist.push_back(q);
quads = newQuads; quads = quadlist;
} }
void ParticleSystem::setQuads() void ParticleSystem::setQuads()
{ {
for (Quad *quad : quads)
quad->release();
quads.clear(); quads.clear();
} }
const std::vector<Quad *> &ParticleSystem::getQuads() const std::vector<Quad *> ParticleSystem::getQuads() const
{ {
return quads; std::vector<Quad *> quadlist;
quadlist.reserve(quads.size());
for (const Object::StrongRef<Quad> &q : quads)
quadlist.push_back(q.get());
return quadlist;
} }
void ParticleSystem::setRelativeRotation(bool enable) void ParticleSystem::setRelativeRotation(bool enable)
@@ -838,7 +823,7 @@ bool ParticleSystem::isFull() const
void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
{ {
uint32 pCount = getCount(); uint32 pCount = getCount();
if (pCount == 0 || texture == nullptr || pMem == nullptr || particleVerts == nullptr) if (pCount == 0 || texture.get() == nullptr || pMem == nullptr || particleVerts == nullptr)
return; return;
Color curcolor = gl.getColor(); Color curcolor = gl.getColor();
+3 -3
View File
@@ -431,7 +431,7 @@ public:
/** /**
* Gets the Quads used when drawing the particles. * Gets the Quads used when drawing the particles.
**/ **/
const std::vector<Quad *> &getQuads() const; std::vector<Quad *> getQuads() const;
/** /**
* sets whether particle angles & rotations are relative to their velocities. * sets whether particle angles & rotations are relative to their velocities.
@@ -563,7 +563,7 @@ protected:
Vertex *particleVerts; Vertex *particleVerts;
// The texture to be drawn. // The texture to be drawn.
Texture *texture; Object::StrongRef<Texture> texture;
// Whether the particle emitter is active. // Whether the particle emitter is active.
bool active; bool active;
@@ -640,7 +640,7 @@ protected:
std::vector<Colorf> colors; std::vector<Colorf> colors;
// Quads. // Quads.
std::vector<Quad *> quads; std::vector<Object::StrongRef<Quad>> quads;
bool relativeRotation; bool relativeRotation;
+2 -9
View File
@@ -88,14 +88,10 @@ SpriteBatch::SpriteBatch(Texture *texture, int size, int usage)
delete element_buf; delete element_buf;
throw love::Exception("Out of memory."); throw love::Exception("Out of memory.");
} }
texture->retain();
} }
SpriteBatch::~SpriteBatch() SpriteBatch::~SpriteBatch()
{ {
texture->release();
delete color; delete color;
delete array_buf; delete array_buf;
delete element_buf; delete element_buf;
@@ -172,15 +168,12 @@ void SpriteBatch::flush()
void SpriteBatch::setTexture(Texture *newtexture) void SpriteBatch::setTexture(Texture *newtexture)
{ {
Object::AutoRelease imagerelease(texture); texture.set(newtexture);
newtexture->retain();
texture = newtexture;
} }
Texture *SpriteBatch::getTexture() Texture *SpriteBatch::getTexture()
{ {
return texture; return texture.get();
} }
void SpriteBatch::setColor(const Color &color) void SpriteBatch::setColor(const Color &color)
+1 -1
View File
@@ -126,7 +126,7 @@ private:
*/ */
void setColorv(Vertex *v, const Color &color); void setColorv(Vertex *v, const Color &color);
Texture *texture; Object::StrongRef<Texture> texture;
// Max number of sprites in the batch. // Max number of sprites in the batch.
int size; int size;
+7 -13
View File
@@ -77,11 +77,11 @@ Mouse::Mouse()
Mouse::~Mouse() Mouse::~Mouse()
{ {
if (curCursor) if (curCursor.get())
setCursor(); setCursor();
for (auto it = systemCursors.begin(); it != systemCursors.end(); ++it) for (auto &c : systemCursors)
it->second->release(); c.second->release();
} }
love::mouse::Cursor *Mouse::newCursor(love::image::ImageData *data, int hotx, int hoty) love::mouse::Cursor *Mouse::newCursor(love::image::ImageData *data, int hotx, int hoty)
@@ -91,7 +91,7 @@ love::mouse::Cursor *Mouse::newCursor(love::image::ImageData *data, int hotx, in
love::mouse::Cursor *Mouse::getSystemCursor(Cursor::SystemCursor cursortype) love::mouse::Cursor *Mouse::getSystemCursor(Cursor::SystemCursor cursortype)
{ {
Cursor *cursor = NULL; Cursor *cursor = nullptr;
auto it = systemCursors.find(cursortype); auto it = systemCursors.find(cursortype);
if (it != systemCursors.end()) if (it != systemCursors.end())
@@ -107,25 +107,19 @@ love::mouse::Cursor *Mouse::getSystemCursor(Cursor::SystemCursor cursortype)
void Mouse::setCursor(love::mouse::Cursor *cursor) void Mouse::setCursor(love::mouse::Cursor *cursor)
{ {
Object::AutoRelease cursorrelease(curCursor); curCursor.set(cursor);
curCursor = cursor;
curCursor->retain();
SDL_SetCursor((SDL_Cursor *) cursor->getHandle()); SDL_SetCursor((SDL_Cursor *) cursor->getHandle());
} }
void Mouse::setCursor() void Mouse::setCursor()
{ {
Object::AutoRelease cursorrelease(curCursor); curCursor.set(nullptr);
curCursor = NULL;
SDL_SetCursor(SDL_GetDefaultCursor()); SDL_SetCursor(SDL_GetDefaultCursor());
} }
love::mouse::Cursor *Mouse::getCursor() const love::mouse::Cursor *Mouse::getCursor() const
{ {
return curCursor; return curCursor.get();
} }
int Mouse::getX() const int Mouse::getX() const
+1 -1
View File
@@ -67,7 +67,7 @@ public:
private: private:
love::mouse::Cursor *curCursor; Object::StrongRef<love::mouse::Cursor> curCursor;
std::map<Cursor::SystemCursor, Cursor *> systemCursors; std::map<Cursor::SystemCursor, Cursor *> systemCursors;
+2 -5
View File
@@ -41,7 +41,6 @@ Body::Body(World *world, b2Vec2 p, Body::Type type)
{ {
udata = new bodyudata(); udata = new bodyudata();
udata->ref = nullptr; udata->ref = nullptr;
world->retain();
b2BodyDef def; b2BodyDef def;
def.position = Physics::scaleDown(p); def.position = Physics::scaleDown(p);
def.userData = (void *) udata; def.userData = (void *) udata;
@@ -57,8 +56,7 @@ Body::Body(b2Body *b)
, udata(nullptr) , udata(nullptr)
{ {
udata = (bodyudata *) b->GetUserData(); udata = (bodyudata *) b->GetUserData();
world = (World *)Memoizer::find(b->GetWorld()); world.set((World *) Memoizer::find(b->GetWorld()));
world->retain();
// Box2D body holds a reference to the love Body. // Box2D body holds a reference to the love Body.
this->retain(); this->retain();
Memoizer::add(body, this); Memoizer::add(body, this);
@@ -69,7 +67,6 @@ Body::~Body()
if (udata != nullptr) if (udata != nullptr)
delete udata->ref; delete udata->ref;
delete udata; delete udata;
world->release();
} }
float Body::getX() float Body::getX()
@@ -420,7 +417,7 @@ bool Body::isFixedRotation() const
World *Body::getWorld() const World *Body::getWorld() const
{ {
return world; return world.get();
} }
int Body::getFixtureList(lua_State *L) const int Body::getFixtureList(lua_State *L) const
+1 -1
View File
@@ -436,7 +436,7 @@ private:
// //
// This ensures that a World only can be destroyed // This ensures that a World only can be destroyed
// once all bodies have been destroyed too. // once all bodies have been destroyed too.
World *world; Object::StrongRef<World> world;
bodyudata *udata; bodyudata *udata;
+2 -2
View File
@@ -40,7 +40,7 @@ namespace box2d
{ {
Joint::Joint(Body *body1) Joint::Joint(Body *body1)
: world(body1->world) : world(body1->world.get())
, udata(nullptr) , udata(nullptr)
, body1(body1) , body1(body1)
, body2(nullptr) , body2(nullptr)
@@ -50,7 +50,7 @@ Joint::Joint(Body *body1)
} }
Joint::Joint(Body *body1, Body *body2) Joint::Joint(Body *body1, Body *body2)
: world(body1->world) : world(body1->world.get())
, udata(nullptr) , udata(nullptr)
, body1(body1) , body1(body1)
, body2(body2) , body2(body2)
+3 -6
View File
@@ -259,23 +259,20 @@ void World::update(float dt)
world->Step(dt, 8, 6); world->Step(dt, 8, 6);
// Destroy all objects marked during the time step. // Destroy all objects marked during the time step.
for (auto i = destructBodies.begin(); i < destructBodies.end(); i++) for (Body *b : destructBodies)
{ {
Body *b = *i;
if (b->body != 0) b->destroy(); if (b->body != 0) b->destroy();
// Release for reference in vector. // Release for reference in vector.
b->release(); b->release();
} }
for (auto i = destructFixtures.begin(); i < destructFixtures.end(); i++) for (Fixture *f : destructFixtures)
{ {
Fixture *f = *i;
if (f->isValid()) f->destroy(); if (f->isValid()) f->destroy();
// Release for reference in vector. // Release for reference in vector.
f->release(); f->release();
} }
for (auto i = destructJoints.begin(); i < destructJoints.end(); i++) for (Joint *j : destructJoints)
{ {
Joint *j = *i;
if (j->isValid()) j->destroyJoint(); if (j->isValid()) j->destroyJoint();
// Release for reference in vector. // Release for reference in vector.
j->release(); j->release();
-3
View File
@@ -37,7 +37,6 @@ Decoder::Decoder(Data *data, const std::string &ext, int bufferSize)
, buffer(0) , buffer(0)
, eof(false) , eof(false)
{ {
data->retain();
buffer = new char[bufferSize]; buffer = new char[bufferSize];
} }
@@ -45,8 +44,6 @@ Decoder::~Decoder()
{ {
if (buffer != 0) if (buffer != 0)
delete [](char *) buffer; delete [](char *) buffer;
if (data != 0)
data->release();
} }
void *Decoder::getBuffer() const void *Decoder::getBuffer() const
+1 -1
View File
@@ -53,7 +53,7 @@ protected:
// The encoded data. This should be replaced with buffered file // The encoded data. This should be replaced with buffered file
// reads in the future. // reads in the future.
Data *data; Object::StrongRef<Data> data;
// File extension. // File extension.
std::string ext; std::string ext;
+1 -1
View File
@@ -69,7 +69,7 @@ bool FLACDecoder::accepts(const std::string &ext)
love::sound::Decoder *FLACDecoder::clone() love::sound::Decoder *FLACDecoder::clone()
{ {
return new FLACDecoder(data, ext, bufferSize, sampleRate); return new FLACDecoder(data.get(), ext, bufferSize, sampleRate);
} }
int FLACDecoder::decode() int FLACDecoder::decode()
+1 -1
View File
@@ -86,7 +86,7 @@ bool GmeDecoder::accepts(const std::string &ext)
love::sound::Decoder *GmeDecoder::clone() love::sound::Decoder *GmeDecoder::clone()
{ {
return new GmeDecoder(data, ext, bufferSize); return new GmeDecoder(data.get(), ext, bufferSize);
} }
int GmeDecoder::decode() int GmeDecoder::decode()
+1 -1
View File
@@ -98,7 +98,7 @@ bool ModPlugDecoder::accepts(const std::string &ext)
love::sound::Decoder *ModPlugDecoder::clone() love::sound::Decoder *ModPlugDecoder::clone()
{ {
return new ModPlugDecoder(data, ext, bufferSize); return new ModPlugDecoder(data.get(), ext, bufferSize);
} }
int ModPlugDecoder::decode() int ModPlugDecoder::decode()
+1 -1
View File
@@ -96,7 +96,7 @@ void Mpg123Decoder::quit()
love::sound::Decoder *Mpg123Decoder::clone() love::sound::Decoder *Mpg123Decoder::clone()
{ {
return new Mpg123Decoder(data, ext, bufferSize); return new Mpg123Decoder(data.get(), ext, bufferSize);
} }
int Mpg123Decoder::decode() int Mpg123Decoder::decode()
+1 -1
View File
@@ -179,7 +179,7 @@ bool VorbisDecoder::accepts(const std::string &ext)
love::sound::Decoder *VorbisDecoder::clone() love::sound::Decoder *VorbisDecoder::clone()
{ {
return new VorbisDecoder(data, ext, bufferSize); return new VorbisDecoder(data.get(), ext, bufferSize);
} }
int VorbisDecoder::decode() int VorbisDecoder::decode()
+1 -1
View File
@@ -117,7 +117,7 @@ bool WaveDecoder::accepts(const std::string &ext)
love::sound::Decoder *WaveDecoder::clone() love::sound::Decoder *WaveDecoder::clone()
{ {
return new WaveDecoder(data, ext, bufferSize); return new WaveDecoder(data.get(), ext, bufferSize);
} }
int WaveDecoder::decode() int WaveDecoder::decode()
-3
View File
@@ -37,14 +37,11 @@ LuaThread::LuaThread(const std::string &name, love::Data *code)
, args(0) , args(0)
, nargs(0) , nargs(0)
{ {
code->retain();
threadName = name; threadName = name;
} }
LuaThread::~LuaThread() LuaThread::~LuaThread()
{ {
code->release();
// No args should still exist at this point, // No args should still exist at this point,
// but you never know. // but you never know.
for (int i = 0; i < nargs; ++i) for (int i = 0; i < nargs; ++i)
+1 -1
View File
@@ -50,7 +50,7 @@ private:
void onError(); void onError();
love::Data *code; Object::StrongRef<love::Data> code;
std::string name; std::string name;
std::string error; std::string error;
+4 -10
View File
@@ -48,9 +48,6 @@ Window::Window()
Window::~Window() Window::~Window()
{ {
if (curMode.icon)
curMode.icon->release();
if (window) if (window)
SDL_DestroyWindow(window); SDL_DestroyWindow(window);
@@ -185,8 +182,8 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
} }
// Make sure the window keeps any previously set icon. // Make sure the window keeps any previously set icon.
if (window && curMode.icon) if (window && curMode.icon.get())
setIcon(curMode.icon); setIcon(curMode.icon.get());
} }
if (!window) if (!window)
@@ -563,10 +560,7 @@ bool Window::setIcon(love::image::ImageData *imgd)
if (!imgd) if (!imgd)
return false; return false;
imgd->retain(); curMode.icon.set(imgd);
if (curMode.icon)
curMode.icon->release();
curMode.icon = imgd;
if (!window) if (!window)
return false; return false;
@@ -607,7 +601,7 @@ bool Window::setIcon(love::image::ImageData *imgd)
love::image::ImageData *Window::getIcon() love::image::ImageData *Window::getIcon()
{ {
return curMode.icon; return curMode.icon.get();
} }
void Window::minimize() void Window::minimize()
+1 -1
View File
@@ -114,7 +114,7 @@ private:
int width; int width;
int height; int height;
WindowSettings settings; WindowSettings settings;
love::image::ImageData *icon; Object::StrongRef<love::image::ImageData> icon;
} curMode; } curMode;