Browse Source

Merge default into minor

--HG--
branch : minor
Alex Szpakowski 9 years ago
parent
commit
2e5f385be3

+ 23 - 14
src/common/Object.h

@@ -59,14 +59,14 @@ public:
 	 * Retains the Object, i.e. increases the
 	 * Retains the Object, i.e. increases the
 	 * reference count by one.
 	 * reference count by one.
 	 **/
 	 **/
-	virtual void retain();
+	void retain();
 
 
 	/**
 	/**
 	 * Releases one reference to the Object, i.e. decrements the
 	 * Releases one reference to the Object, i.e. decrements the
 	 * reference count by one, and potentially deletes the Object
 	 * reference count by one, and potentially deletes the Object
 	 * if there are no more references.
 	 * if there are no more references.
 	 **/
 	 **/
-	virtual void release();
+	void release();
 
 
 private:
 private:
 
 
@@ -75,32 +75,41 @@ private:
 
 
 }; // Object
 }; // Object
 
 
-/**
- * Partial re-implementation + specialization of std::shared_ptr. We can't
- * use C++11's stdlib yet...
- **/
+
+enum class Acquire
+{
+	RETAIN,
+	NORETAIN,
+};
+
 template <typename T>
 template <typename T>
 class StrongRef
 class StrongRef
 {
 {
 public:
 public:
 
 
 	StrongRef()
 	StrongRef()
-	: object(nullptr)
+		: object(nullptr)
 	{
 	{
 	}
 	}
 
 
-	StrongRef(T *obj)
-	: object(obj)
+	StrongRef(T *obj, Acquire acquire = Acquire::RETAIN)
+		: object(obj)
 	{
 	{
-		if (object) object->retain();
+		if (object && acquire == Acquire::RETAIN) object->retain();
 	}
 	}
 
 
 	StrongRef(const StrongRef &other)
 	StrongRef(const StrongRef &other)
-	: object(other.get())
+		: object(other.get())
 	{
 	{
 		if (object) object->retain();
 		if (object) object->retain();
 	}
 	}
 
 
+	StrongRef(StrongRef &&other)
+		: object(other.object)
+	{
+		other.object = nullptr;
+	}
+
 	~StrongRef()
 	~StrongRef()
 	{
 	{
 		if (object) object->release();
 		if (object) object->release();
@@ -117,7 +126,7 @@ public:
 		return object;
 		return object;
 	}
 	}
 
 
-	operator bool() const
+	explicit operator bool() const
 	{
 	{
 		return object != nullptr;
 		return object != nullptr;
 	}
 	}
@@ -127,9 +136,9 @@ public:
 		return object;
 		return object;
 	}
 	}
 
 
-	void set(T *obj)
+	void set(T *obj, Acquire acquire = Acquire::RETAIN)
 	{
 	{
-		if (obj) obj->retain();
+		if (obj && acquire == Acquire::RETAIN) obj->retain();
 		if (object) object->release();
 		if (object) object->release();
 		object = obj;
 		object = obj;
 	}
 	}

+ 8 - 0
src/common/Variant.cpp

@@ -111,6 +111,14 @@ Variant::Variant(const Variant &v)
 		data.table->retain();
 		data.table->retain();
 }
 }
 
 
+Variant::Variant(Variant &&v)
+	: type(std::move(v.type))
+	, udatatype(std::move(v.udatatype))
+	, data(std::move(v.data))
+{
+	v.type = NIL;
+}
+
 Variant::~Variant()
 Variant::~Variant()
 {
 {
 	switch (type)
 	switch (type)

+ 1 - 0
src/common/Variant.h

@@ -43,6 +43,7 @@ public:
 	Variant(love::Type udatatype, void *userdata);
 	Variant(love::Type udatatype, void *userdata);
 	Variant(std::vector<std::pair<Variant, Variant>> *table);
 	Variant(std::vector<std::pair<Variant, Variant>> *table);
 	Variant(const Variant &v);
 	Variant(const Variant &v);
+	Variant(Variant &&v);
 	~Variant();
 	~Variant();
 
 
 	Variant &operator = (const Variant &v);
 	Variant &operator = (const Variant &v);

+ 2 - 9
src/modules/audio/openal/Source.cpp

@@ -104,10 +104,7 @@ Source::Source(Pool *pool, love::sound::SoundData *soundData)
 	if (fmt == 0)
 	if (fmt == 0)
 		throw InvalidFormatException(soundData->getChannels(), soundData->getBitDepth());
 		throw InvalidFormatException(soundData->getChannels(), soundData->getBitDepth());
 
 
-	staticBuffer.set(new StaticDataBuffer(fmt, soundData->getData(), (ALsizei) soundData->getSize(), soundData->getSampleRate()));
-
-	// The buffer has a +2 retain count right now, but we want it to have +1.
-	staticBuffer->release();
+	staticBuffer.set(new StaticDataBuffer(fmt, soundData->getData(), (ALsizei) soundData->getSize(), sampleRate), Acquire::NORETAIN);
 
 
 	float z[3] = {0, 0, 0};
 	float z[3] = {0, 0, 0};
 
 
@@ -179,11 +176,7 @@ Source::Source(const Source &s)
 	if (type == TYPE_STREAM)
 	if (type == TYPE_STREAM)
 	{
 	{
 		if (s.decoder.get())
 		if (s.decoder.get())
-		{
-			love::sound::Decoder *dec = s.decoder->clone();
-			decoder.set(dec);
-			dec->release();
-		}
+			decoder.set(s.decoder->clone(), Acquire::NORETAIN);
 
 
 		alGenBuffers(MAX_BUFFERS, streamBuffers);
 		alGenBuffers(MAX_BUFFERS, streamBuffers);
 	}
 	}

+ 4 - 7
src/modules/event/wrap_Event.cpp

@@ -74,16 +74,14 @@ int w_wait(lua_State *L)
 
 
 int w_push(lua_State *L)
 int w_push(lua_State *L)
 {
 {
-	Message *m = Message::fromLua(L, 1);
+	StrongRef<Message> m(Message::fromLua(L, 1), Acquire::NORETAIN);
 
 
-	luax_pushboolean(L, m != nullptr);
+	luax_pushboolean(L, m.get() != nullptr);
 
 
-	if (m == nullptr)
+	if (m.get() == nullptr)
 		return 1;
 		return 1;
 
 
 	instance()->push(m);
 	instance()->push(m);
-	m->release();
-
 	return 1;
 	return 1;
 }
 }
 
 
@@ -101,9 +99,8 @@ int w_quit(lua_State *L)
 	if (Variant::fromLua(L, 1, &v))
 	if (Variant::fromLua(L, 1, &v))
 		args.push_back(v);
 		args.push_back(v);
 
 
-	Message *m = new Message("quit", args);
+	StrongRef<Message> m(new Message("quit", args), Acquire::NORETAIN);
 	instance()->push(m);
 	instance()->push(m);
-	m->release();
 
 
 	luax_pushboolean(L, true);
 	luax_pushboolean(L, true);
 	return 1;
 	return 1;

+ 1 - 1
src/modules/filesystem/FileData.cpp

@@ -78,7 +78,7 @@ bool FileData::getConstant(const char *in, Decoder &out)
 	return decoders.find(in, out);
 	return decoders.find(in, out);
 }
 }
 
 
-bool FileData::getConstant(Decoder in, const char  *&out)
+bool FileData::getConstant(Decoder in, const char *&out)
 {
 {
 	return decoders.find(in, out);
 	return decoders.find(in, out);
 }
 }

+ 1 - 1
src/modules/filesystem/FileData.h

@@ -55,7 +55,7 @@ public:
 	const std::string &getExtension() const;
 	const std::string &getExtension() const;
 
 
 	static bool getConstant(const char *in, Decoder &out);
 	static bool getConstant(const char *in, Decoder &out);
-	static bool getConstant(Decoder in, const char  *&out);
+	static bool getConstant(Decoder in, const char *&out);
 
 
 private:
 private:
 
 

+ 2 - 3
src/modules/filesystem/wrap_File.cpp

@@ -108,13 +108,13 @@ int w_File_isOpen(lua_State *L)
 int w_File_read(lua_State *L)
 int w_File_read(lua_State *L)
 {
 {
 	File *file = luax_checkfile(L, 1);
 	File *file = luax_checkfile(L, 1);
-	Data *d = 0;
+	StrongRef<Data> d = nullptr;
 
 
 	int64 size = (int64) luaL_optnumber(L, 2, (lua_Number) File::ALL);
 	int64 size = (int64) luaL_optnumber(L, 2, (lua_Number) File::ALL);
 
 
 	try
 	try
 	{
 	{
-		d = file->read(size);
+		d.set(file->read(size), Acquire::NORETAIN);
 	}
 	}
 	catch (love::Exception &e)
 	catch (love::Exception &e)
 	{
 	{
@@ -123,7 +123,6 @@ int w_File_read(lua_State *L)
 
 
 	lua_pushlstring(L, (const char *) d->getData(), d->getSize());
 	lua_pushlstring(L, (const char *) d->getData(), d->getSize());
 	lua_pushnumber(L, d->getSize());
 	lua_pushnumber(L, d->getSize());
-	d->release();
 	return 2;
 	return 2;
 }
 }
 
 

+ 2 - 3
src/modules/filesystem/wrap_Filesystem.cpp

@@ -223,17 +223,16 @@ int w_newFileData(lua_State *L)
 		{
 		{
 			File *file = luax_checkfile(L, 1);
 			File *file = luax_checkfile(L, 1);
 
 
-			FileData *data = 0;
+			StrongRef<FileData> data;
 			try
 			try
 			{
 			{
-				data = file->read();
+				data.set(file->read(), Acquire::NORETAIN);
 			}
 			}
 			catch (love::Exception &e)
 			catch (love::Exception &e)
 			{
 			{
 				return luax_ioError(L, "%s", e.what());
 				return luax_ioError(L, "%s", e.what());
 			}
 			}
 			luax_pushtype(L, FILESYSTEM_FILE_DATA_ID, data);
 			luax_pushtype(L, FILESYSTEM_FILE_DATA_ID, data);
-			data->release();
 			return 1;
 			return 1;
 		}
 		}
 		else
 		else

+ 4 - 5
src/modules/font/BMFontRasterizer.cpp

@@ -198,12 +198,11 @@ void BMFontRasterizer::parseConfig(const std::string &configtext)
 				if (!imagemodule)
 				if (!imagemodule)
 					throw love::Exception("Image module not loaded!");
 					throw love::Exception("Image module not loaded!");
 
 
-				// Release these variables right away since StrongRef retains.
-				StrongRef<FileData> data = filesystem->read(filename.c_str());
-				data->release();
+				// read() returns a retained ref already.
+				StrongRef<FileData> data(filesystem->read(filename.c_str()), Acquire::NORETAIN);
 
 
-				images[pageindex].set(imagemodule->newImageData(data.get()));
-				images[pageindex]->release();
+				// Same with newImageData.
+				images[pageindex].set(imagemodule->newImageData(data.get()), Acquire::NORETAIN);
 			}
 			}
 		}
 		}
 		else if (tag == "char")
 		else if (tag == "char")

+ 1 - 3
src/modules/font/Font.cpp

@@ -43,9 +43,7 @@ public:
 
 
 Rasterizer *Font::newTrueTypeRasterizer(int size, TrueTypeRasterizer::Hinting hinting)
 Rasterizer *Font::newTrueTypeRasterizer(int size, TrueTypeRasterizer::Hinting hinting)
 {
 {
-	StrongRef<DefaultFontData> data(new DefaultFontData);
-	data->release();
-
+	StrongRef<DefaultFontData> data(new DefaultFontData, Acquire::NORETAIN);
 	return newTrueTypeRasterizer(data.get(), size, hinting);
 	return newTrueTypeRasterizer(data.get(), size, hinting);
 }
 }
 
 

+ 23 - 26
src/modules/font/GlyphData.cpp

@@ -40,18 +40,7 @@ GlyphData::GlyphData(uint32 glyph, GlyphMetrics glyphMetrics, GlyphData::Format
 	, format(f)
 	, format(f)
 {
 {
 	if (metrics.width > 0 && metrics.height > 0)
 	if (metrics.width > 0 && metrics.height > 0)
-	{
-		switch (f)
-		{
-		case GlyphData::FORMAT_LUMINANCE_ALPHA:
-			data = new unsigned char[metrics.width * metrics.height * 2];
-			break;
-		case GlyphData::FORMAT_RGBA:
-		default:
-			data = new unsigned char[metrics.width * metrics.height * 4];
-			break;
-		}
-	}
+		data = new uint8[metrics.width * metrics.height * getPixelSize()];
 }
 }
 
 
 GlyphData::~GlyphData()
 GlyphData::~GlyphData()
@@ -61,22 +50,30 @@ GlyphData::~GlyphData()
 
 
 void *GlyphData::getData() const
 void *GlyphData::getData() const
 {
 {
-	return (void *) data;
+	return data;
 }
 }
 
 
-size_t GlyphData::getSize() const
+size_t GlyphData::getPixelSize() const
 {
 {
 	switch (format)
 	switch (format)
 	{
 	{
-	case GlyphData::FORMAT_LUMINANCE_ALPHA:
-		return size_t(getWidth() * getHeight() * 2);
-		break;
-	case GlyphData::FORMAT_RGBA:
+	case FORMAT_LUMINANCE_ALPHA:
+		return 2;
+	case FORMAT_RGBA:
 	default:
 	default:
-		return size_t(getWidth() * getHeight() * 4);
-		break;
+		return 4;
 	}
 	}
+}
 
 
+void *GlyphData::getData(int x, int y) const
+{
+	size_t offset = (y * getWidth() + x) * getPixelSize();
+	return data + offset;
+}
+
+size_t GlyphData::getSize() const
+{
+	return size_t(getWidth() * getHeight()) * getPixelSize();
 }
 }
 
 
 int GlyphData::getHeight() const
 int GlyphData::getHeight() const
@@ -133,22 +130,22 @@ int GlyphData::getBearingY() const
 
 
 int GlyphData::getMinX() const
 int GlyphData::getMinX() const
 {
 {
-	return this->getBearingX();
+	return getBearingX();
 }
 }
 
 
 int GlyphData::getMinY() const
 int GlyphData::getMinY() const
 {
 {
-	return this->getHeight() - this->getBearingY();
+	return getHeight() - getBearingY();
 }
 }
 
 
 int GlyphData::getMaxX() const
 int GlyphData::getMaxX() const
 {
 {
-	return this->getBearingX() + this->getWidth();
+	return getBearingX() + getWidth();
 }
 }
 
 
 int GlyphData::getMaxY() const
 int GlyphData::getMaxY() const
 {
 {
-	return this->getBearingY();
+	return getBearingY();
 }
 }
 
 
 GlyphData::Format GlyphData::getFormat() const
 GlyphData::Format GlyphData::getFormat() const
@@ -168,8 +165,8 @@ bool GlyphData::getConstant(GlyphData::Format in, const char *&out)
 
 
 StringMap<GlyphData::Format, GlyphData::FORMAT_MAX_ENUM>::Entry GlyphData::formatEntries[] =
 StringMap<GlyphData::Format, GlyphData::FORMAT_MAX_ENUM>::Entry GlyphData::formatEntries[] =
 {
 {
-	{"luminancealpha", GlyphData::FORMAT_LUMINANCE_ALPHA},
-	{"rgba", GlyphData::FORMAT_RGBA},
+	{"luminancealpha", FORMAT_LUMINANCE_ALPHA},
+	{"rgba", FORMAT_RGBA},
 };
 };
 
 
 StringMap<GlyphData::Format, GlyphData::FORMAT_MAX_ENUM> GlyphData::formats(GlyphData::formatEntries, sizeof(GlyphData::formatEntries));
 StringMap<GlyphData::Format, GlyphData::FORMAT_MAX_ENUM> GlyphData::formats(GlyphData::formatEntries, sizeof(GlyphData::formatEntries));

+ 11 - 1
src/modules/font/GlyphData.h

@@ -69,6 +69,16 @@ public:
 	void *getData() const;
 	void *getData() const;
 	size_t getSize() const;
 	size_t getSize() const;
 
 
+	/**
+	 * Gets the data starting at a specific pixel in the glyph.
+	 **/
+	void *getData(int x, int y) const;
+
+	/**
+	 * Gets the size in bytes of each pixel in the glyph.
+	 **/
+	size_t getPixelSize() const;
+
 	/**
 	/**
 	 * Gets the height of the glyph.
 	 * Gets the height of the glyph.
 	 **/
 	 **/
@@ -141,7 +151,7 @@ private:
 	GlyphMetrics metrics;
 	GlyphMetrics metrics;
 
 
 	// Glyph texture data.
 	// Glyph texture data.
-	unsigned char *data;
+	uint8 *data;
 
 
 	// The format the data's in.
 	// The format the data's in.
 	Format format;
 	Format format;

+ 3 - 4
src/modules/graphics/opengl/Graphics.cpp

@@ -203,11 +203,10 @@ void Graphics::checkSetDefaultFont()
 		if (!fontmodule)
 		if (!fontmodule)
 			throw love::Exception("Font module has not been loaded.");
 			throw love::Exception("Font module has not been loaded.");
 
 
-		StrongRef<font::Rasterizer> r(fontmodule->newTrueTypeRasterizer(12, font::TrueTypeRasterizer::HINTING_NORMAL));
-		r->release();
+		auto hinting = font::TrueTypeRasterizer::HINTING_NORMAL;
+		StrongRef<font::Rasterizer> r(fontmodule->newTrueTypeRasterizer(12, hinting), Acquire::NORETAIN);
 
 
-		defaultFont.set(newFont(r.get()));
-		defaultFont->release();
+		defaultFont.set(newFont(r.get()), Acquire::NORETAIN);
 	}
 	}
 
 
 	states.back().font.set(defaultFont.get());
 	states.back().font.set(defaultFont.get());

+ 5 - 1
src/modules/graphics/opengl/Image.cpp

@@ -133,7 +133,11 @@ Image::Image(const std::vector<love::image::CompressedImageData *> &compressedda
 		if (compresseddata[0]->getMipmapCount() == 1)
 		if (compresseddata[0]->getMipmapCount() == 1)
 			this->flags.mipmaps = false;
 			this->flags.mipmaps = false;
 		else
 		else
-			throw love::Exception("Image cannot have mipmaps: compressed image data does not have all required mipmap levels.");
+		{
+			throw love::Exception("Image cannot have mipmaps: compressed image data does not have all required mipmap levels (expected %d, got %d)",
+			                      getMipmapCount(width, height),
+			                      compresseddata[0]->getMipmapCount());
+		}
 	}
 	}
 
 
 	for (const auto &cd : compresseddata)
 	for (const auto &cd : compresseddata)

+ 1 - 4
src/modules/image/magpie/ImageData.cpp

@@ -124,10 +124,7 @@ void ImageData::decode(love::filesystem::FileData *data)
 	// The decoder *must* output a 32 bits-per-pixel image.
 	// The decoder *must* output a 32 bits-per-pixel image.
 	if (decodedimage.size != decodedimage.width*decodedimage.height*sizeof(pixel))
 	if (decodedimage.size != decodedimage.width*decodedimage.height*sizeof(pixel))
 	{
 	{
-		if (decodeHandler)
-			decodeHandler->free(decodedimage.data);
-		else
-			delete[] decodedimage.data;
+		decoder->free(decodedimage.data);
 		throw love::Exception("Could not convert image!");
 		throw love::Exception("Could not convert image!");
 	}
 	}
 
 

+ 6 - 1
src/modules/image/magpie/STBHandler.cpp

@@ -75,7 +75,12 @@ FormatHandler::DecodedImage STBHandler::decode(love::filesystem::FileData *data)
 	                                 &comp, 4);
 	                                 &comp, 4);
 
 
 	if (img.data == nullptr || img.width <= 0 || img.height <= 0)
 	if (img.data == nullptr || img.width <= 0 || img.height <= 0)
-		throw love::Exception("Could not decode image with stb_image.");
+	{
+		const char *err = stbi_failure_reason();
+		if (err == nullptr)
+			err = "unknown error";
+		throw love::Exception("Could not decode image with stb_image (%s).", err);
+	}
 
 
 	img.size = img.width * img.height * 4;
 	img.size = img.width * img.height * 4;
 
 

+ 2 - 3
src/modules/physics/box2d/wrap_Fixture.cpp

@@ -118,8 +118,8 @@ int w_Fixture_getBody(lua_State *L)
 int w_Fixture_getShape(lua_State *L)
 int w_Fixture_getShape(lua_State *L)
 {
 {
 	Fixture *t = luax_checkfixture(L, 1);
 	Fixture *t = luax_checkfixture(L, 1);
-	Shape *shape = t->getShape();
-	if (shape == 0)
+	StrongRef<Shape> shape(t->getShape(), Acquire::NORETAIN);
+	if (shape.get() == nullptr)
 		return 0;
 		return 0;
 	switch (shape->getType())
 	switch (shape->getType())
 	{
 	{
@@ -139,7 +139,6 @@ int w_Fixture_getShape(lua_State *L)
 		luax_pushtype(L, PHYSICS_SHAPE_ID, shape);
 		luax_pushtype(L, PHYSICS_SHAPE_ID, shape);
 		break;
 		break;
 	}
 	}
-	shape->release();
 	return 1;
 	return 1;
 }
 }
 
 

+ 13 - 22
src/modules/thread/Channel.cpp

@@ -58,12 +58,17 @@ Channel *Channel::getChannel(const std::string &name)
 	if (!namedChannelMutex)
 	if (!namedChannelMutex)
 		namedChannelMutex = newMutex();
 		namedChannelMutex = newMutex();
 
 
-	Lock l(namedChannelMutex);
-	if (!namedChannels.count(name))
-		namedChannels[name] = new Channel(name);
-	else
-		namedChannels[name]->retain();
+	Lock lock(namedChannelMutex);
 
 
+	auto it = namedChannels.find(name);
+
+	if (it != namedChannels.end())
+	{
+		it->second->retain();
+		return it->second;
+	}
+
+	namedChannels[name] = new Channel(name);
 	return namedChannels[name];
 	return namedChannels[name];
 }
 }
 
 
@@ -92,7 +97,10 @@ Channel::~Channel()
 	delete cond;
 	delete cond;
 
 
 	if (named)
 	if (named)
+	{
+		Lock l(namedChannelMutex);
 		namedChannels.erase(name);
 		namedChannels.erase(name);
+	}
 }
 }
 
 
 unsigned long Channel::push(const Variant &var)
 unsigned long Channel::push(const Variant &var)
@@ -196,22 +204,5 @@ void Channel::unlockMutex()
 	mutex->unlock();
 	mutex->unlock();
 }
 }
 
 
-void Channel::retain()
-{
-	EmptyLock l;
-	if (named)
-		l.setLock(namedChannelMutex);
-
-	Object::retain();
-}
-
-void Channel::release()
-{
-	EmptyLock l;
-	if (named)
-		l.setLock(namedChannelMutex);
-
-	Object::release();
-}
 } // thread
 } // thread
 } // love
 } // love

+ 0 - 3
src/modules/thread/Channel.h

@@ -54,9 +54,6 @@ public:
 	int getCount();
 	int getCount();
 	void clear();
 	void clear();
 
 
-	void retain();
-	void release();
-
 private:
 private:
 
 
 	Channel(const std::string &name);
 	Channel(const std::string &name);

+ 1 - 2
src/modules/thread/LuaThread.cpp

@@ -116,9 +116,8 @@ void LuaThread::onError()
 		Variant(error.c_str(), error.length())
 		Variant(error.c_str(), error.length())
 	};
 	};
 
 
-	event::Message *msg = new event::Message("threaderror", vargs);
+	StrongRef<event::Message> msg(new event::Message("threaderror", vargs), Acquire::NORETAIN);
 	eventmodule->push(msg);
 	eventmodule->push(msg);
-	msg->release();
 }
 }
 
 
 } // thread
 } // thread

+ 1 - 2
src/modules/thread/ThreadModule.cpp

@@ -27,8 +27,7 @@ namespace thread
 
 
 LuaThread *ThreadModule::newThread(const std::string &name, love::Data *data)
 LuaThread *ThreadModule::newThread(const std::string &name, love::Data *data)
 {
 {
-	LuaThread *lt = new LuaThread(name, data);
-	return lt;
+	return new LuaThread(name, data);
 }
 }
 
 
 Channel *ThreadModule::newChannel()
 Channel *ThreadModule::newChannel()

+ 1 - 2
src/modules/video/theora/VideoStream.cpp

@@ -64,8 +64,7 @@ VideoStream::VideoStream(love::filesystem::File *file)
 		throw ex;
 		throw ex;
 	}
 	}
 
 
-	frameSync = new DeltaSync();
-	frameSync->release();
+	frameSync.set(new DeltaSync(), Acquire::NORETAIN);
 }
 }
 
 
 VideoStream::~VideoStream()
 VideoStream::~VideoStream()