From 6ea1ebde9c43f4a4ad427b4f0427bfb07d7c7a5a Mon Sep 17 00:00:00 2001 From: Raidho Date: Fri, 10 Feb 2017 06:19:53 +0300 Subject: [PATCH] Data:clone ported to minor minor tweaks --HG-- branch : minor --- src/common/Data.h | 4 +++ src/modules/filesystem/FileData.cpp | 23 ++++++++++++++++ src/modules/filesystem/FileData.h | 2 ++ src/modules/filesystem/wrap_FileData.cpp | 10 +++++++ src/modules/font/Font.cpp | 1 + src/modules/font/GlyphData.cpp | 18 +++++++++++++ src/modules/font/GlyphData.h | 2 ++ src/modules/font/wrap_GlyphData.cpp | 10 +++++++ src/modules/image/CompressedImageData.h | 1 + src/modules/image/ImageData.h | 1 + .../image/magpie/CompressedImageData.cpp | 26 +++++++++++++++++++ .../image/magpie/CompressedImageData.h | 2 ++ src/modules/image/magpie/ImageData.cpp | 19 ++++++++++++++ src/modules/image/magpie/ImageData.h | 2 ++ .../image/wrap_CompressedImageData.cpp | 10 +++++++ src/modules/image/wrap_ImageData.cpp | 10 +++++++ src/modules/math/CompressedData.cpp | 23 ++++++++++++++++ src/modules/math/CompressedData.h | 2 ++ src/modules/math/wrap_CompressedData.cpp | 10 +++++++ src/modules/sound/SoundData.cpp | 15 +++++++++++ src/modules/sound/SoundData.h | 2 ++ src/modules/sound/wrap_SoundData.cpp | 10 +++++++ 22 files changed, 203 insertions(+) diff --git a/src/common/Data.h b/src/common/Data.h index 47f494201..2fbe6b718 100644 --- a/src/common/Data.h +++ b/src/common/Data.h @@ -45,6 +45,10 @@ public: **/ virtual ~Data() {} + /** + * Creates a duplicate of Data derived class instance. + **/ + virtual Data *clone() const = 0; /** * Gets a pointer to the data. This pointer will obviously not * be valid if the Data object is destroyed. diff --git a/src/modules/filesystem/FileData.cpp b/src/modules/filesystem/FileData.cpp index f6b18f882..c065a4976 100644 --- a/src/modules/filesystem/FileData.cpp +++ b/src/modules/filesystem/FileData.cpp @@ -56,11 +56,34 @@ FileData::FileData(uint64 size, const std::string &filename) name = filename; } +FileData::FileData(const FileData &c) + : data(nullptr) + , size(c.size) + , filename(c.filename) + , extension(c.extension) + , name(c.name) +{ + try + { + data = new char[(size_t) size]; + } + catch (std::bad_alloc &) + { + throw love::Exception("Out of memory."); + } + memcpy(data, c.data, size); +} + FileData::~FileData() { delete [] data; } +Data *FileData::clone() const +{ + return new FileData(*this); +} + void *FileData::getData() const { return data; diff --git a/src/modules/filesystem/FileData.h b/src/modules/filesystem/FileData.h index 2bcf1f26d..86a8385ba 100644 --- a/src/modules/filesystem/FileData.h +++ b/src/modules/filesystem/FileData.h @@ -40,10 +40,12 @@ public: static love::Type type; FileData(uint64 size, const std::string &filename); + FileData(const FileData &c); virtual ~FileData(); // Implements Data. + Data *clone() const; void *getData() const; size_t getSize() const; diff --git a/src/modules/filesystem/wrap_FileData.cpp b/src/modules/filesystem/wrap_FileData.cpp index 8439515cc..9f26e2593 100644 --- a/src/modules/filesystem/wrap_FileData.cpp +++ b/src/modules/filesystem/wrap_FileData.cpp @@ -32,6 +32,15 @@ FileData *luax_checkfiledata(lua_State *L, int idx) return luax_checktype(L, idx); } +int w_FileData_clone(lua_State *L) +{ + FileData *t = luax_checkfiledata(L, 1), *c = nullptr; + luax_catchexcept(L, [&](){ c = (FileData*)t->clone(); }); + luax_pushtype(L, c); + c->release(); + return 1; +} + int w_FileData_getFilename(lua_State *L) { FileData *t = luax_checkfiledata(L, 1); @@ -48,6 +57,7 @@ int w_FileData_getExtension(lua_State *L) static const luaL_Reg w_FileData_functions[] = { + { "clone", w_FileData_clone }, { "getFilename", w_FileData_getFilename }, { "getExtension", w_FileData_getExtension }, diff --git a/src/modules/font/Font.cpp b/src/modules/font/Font.cpp index 9a5de846d..c303504ad 100644 --- a/src/modules/font/Font.cpp +++ b/src/modules/font/Font.cpp @@ -37,6 +37,7 @@ class DefaultFontData : public love::Data { public: + Data *clone() const override { return new DefaultFontData(); } void *getData() const override { return Vera_ttf; } size_t getSize() const override { return sizeof(Vera_ttf); } }; diff --git a/src/modules/font/GlyphData.cpp b/src/modules/font/GlyphData.cpp index 95eab4029..4e8054144 100644 --- a/src/modules/font/GlyphData.cpp +++ b/src/modules/font/GlyphData.cpp @@ -48,11 +48,29 @@ GlyphData::GlyphData(uint32 glyph, GlyphMetrics glyphMetrics, PixelFormat f) data = new uint8[metrics.width * metrics.height * getPixelSize()]; } +GlyphData::GlyphData(const GlyphData &c) + : glyph(c.glyph) + , metrics(c.metrics) + , data(nullptr) + , format(c.format) +{ + if (metrics.width > 0 && metrics.height > 0) + { + data = new uint8[metrics.width * metrics.height * getPixelSize()]; + memcpy(data, c.data, c.getSize()); + } +} + GlyphData::~GlyphData() { delete[] data; } +Data *GlyphData::clone() const +{ + return new GlyphData(*this); +} + void *GlyphData::getData() const { return data; diff --git a/src/modules/font/GlyphData.h b/src/modules/font/GlyphData.h index 8728922fe..8c326b873 100644 --- a/src/modules/font/GlyphData.h +++ b/src/modules/font/GlyphData.h @@ -59,9 +59,11 @@ public: static love::Type type; GlyphData(uint32 glyph, GlyphMetrics glyphMetrics, PixelFormat f); + GlyphData(const GlyphData &c); virtual ~GlyphData(); // Implements Data. + Data *clone() const; void *getData() const; size_t getSize() const; diff --git a/src/modules/font/wrap_GlyphData.cpp b/src/modules/font/wrap_GlyphData.cpp index 29a67d018..32a536183 100644 --- a/src/modules/font/wrap_GlyphData.cpp +++ b/src/modules/font/wrap_GlyphData.cpp @@ -30,6 +30,15 @@ GlyphData *luax_checkglyphdata(lua_State *L, int idx) return luax_checktype(L, idx); } +int w_GlyphData_clone(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1), *c = nullptr; + luax_catchexcept(L, [&](){ c = (GlyphData*)t->clone(); }); + luax_pushtype(L, c); + c->release(); + return 1; +} + int w_GlyphData_getWidth(lua_State *L) { GlyphData *t = luax_checkglyphdata(L, 1); @@ -117,6 +126,7 @@ int w_GlyphData_getFormat(lua_State *L) const luaL_Reg w_GlyphData_functions[] = { + { "clone", w_GlyphData_clone }, { "getWidth", w_GlyphData_getWidth }, { "getHeight", w_GlyphData_getHeight }, { "getDimensions", w_GlyphData_getDimensions }, diff --git a/src/modules/image/CompressedImageData.h b/src/modules/image/CompressedImageData.h index f98aed9d8..69ee910bc 100644 --- a/src/modules/image/CompressedImageData.h +++ b/src/modules/image/CompressedImageData.h @@ -59,6 +59,7 @@ public: virtual ~CompressedImageData(); // Implements Data. + virtual Data *clone() const = 0; virtual void *getData() const; virtual size_t getSize() const; diff --git a/src/modules/image/ImageData.h b/src/modules/image/ImageData.h index 3e13d4ece..a2f1f519f 100644 --- a/src/modules/image/ImageData.h +++ b/src/modules/image/ImageData.h @@ -128,6 +128,7 @@ public: love::thread::Mutex *getMutex() const; // Implements Data. + virtual Data *clone() const = 0; virtual void *getData() const; virtual size_t getSize() const; diff --git a/src/modules/image/magpie/CompressedImageData.cpp b/src/modules/image/magpie/CompressedImageData.cpp index f487eb2ae..b7203ec5f 100644 --- a/src/modules/image/magpie/CompressedImageData.cpp +++ b/src/modules/image/magpie/CompressedImageData.cpp @@ -61,6 +61,32 @@ CompressedImageData::CompressedImageData(std::list fo } } +CompressedImageData::CompressedImageData(const CompressedImageData &c) +{ + format = c.format; + sRGB = c.sRGB; + dataSize = c.dataSize; + + data = new uint8[dataSize]; + memcpy(data, c.data, dataSize); + + for (auto i : c.dataImages ) + { + struct SubImage s; + s.width = i.width; + s.height = i.height; + s.size = i.size; + s.data = (uint8*)((intptr_t)data + (intptr_t)i.data - (intptr_t)c.data); + + dataImages.push_back(s); + } +} + +Data *CompressedImageData::clone() const +{ + return new CompressedImageData(*this); +} + CompressedImageData::~CompressedImageData() { delete[] data; diff --git a/src/modules/image/magpie/CompressedImageData.h b/src/modules/image/magpie/CompressedImageData.h index 21523c83e..eaf0d0328 100644 --- a/src/modules/image/magpie/CompressedImageData.h +++ b/src/modules/image/magpie/CompressedImageData.h @@ -41,8 +41,10 @@ class CompressedImageData : public love::image::CompressedImageData public: CompressedImageData(std::list formats, love::filesystem::FileData *filedata); + CompressedImageData(const CompressedImageData &c); virtual ~CompressedImageData(); + virtual Data *clone() const; }; // CompressedImageData } // magpie diff --git a/src/modules/image/magpie/ImageData.cpp b/src/modules/image/magpie/ImageData.cpp index b30b71c00..e44533357 100644 --- a/src/modules/image/magpie/ImageData.cpp +++ b/src/modules/image/magpie/ImageData.cpp @@ -78,6 +78,20 @@ ImageData::ImageData(std::list formatHandlers, int width, int h handler->retain(); } +ImageData::ImageData(const ImageData &c) + : formatHandlers(c.formatHandlers) + , decodeHandler(nullptr) +{ + width = c.width; + height = c.height; + format = c.format; + + for (FormatHandler *handler : formatHandlers) + handler->retain(); + + create(width, height, format, c.getData()); +} + ImageData::~ImageData() { if (decodeHandler) @@ -89,6 +103,11 @@ ImageData::~ImageData() handler->release(); } +Data *ImageData::clone() const +{ + return new ImageData(*this); +} + void ImageData::create(int width, int height, PixelFormat format, void *data) { size_t datasize = width * height * getPixelFormatSize(format); diff --git a/src/modules/image/magpie/ImageData.h b/src/modules/image/magpie/ImageData.h index 74c871efc..59003b1e1 100644 --- a/src/modules/image/magpie/ImageData.h +++ b/src/modules/image/magpie/ImageData.h @@ -42,8 +42,10 @@ public: ImageData(std::list formatHandlers, love::filesystem::FileData *data); ImageData(std::list formatHandlers, int width, int height, PixelFormat format = PIXELFORMAT_RGBA8); ImageData(std::list formatHandlers, int width, int height, PixelFormat format, void *data, bool own); + ImageData(const ImageData &c); virtual ~ImageData(); + virtual Data *clone() const; // Implements image::ImageData. virtual love::filesystem::FileData *encode(EncodedFormat encodedFormat, const char *filename); diff --git a/src/modules/image/wrap_CompressedImageData.cpp b/src/modules/image/wrap_CompressedImageData.cpp index 66a937c33..3c979dc7b 100644 --- a/src/modules/image/wrap_CompressedImageData.cpp +++ b/src/modules/image/wrap_CompressedImageData.cpp @@ -31,6 +31,15 @@ CompressedImageData *luax_checkcompressedimagedata(lua_State *L, int idx) return luax_checktype(L, idx); } +int w_CompressedImageData_clone(lua_State *L) +{ + CompressedImageData *t = luax_checkcompressedimagedata(L, 1), *c = nullptr; + luax_catchexcept(L, [&](){ c = (CompressedImageData *)t->clone(); }); + luax_pushtype(L, c); + c->release(); + return 1; +} + int w_CompressedImageData_getWidth(lua_State *L) { CompressedImageData *t = luax_checkcompressedimagedata(L, 1); @@ -96,6 +105,7 @@ int w_CompressedImageData_getFormat(lua_State *L) static const luaL_Reg w_CompressedImageData_functions[] = { + { "clone", w_CompressedImageData_clone }, { "getWidth", w_CompressedImageData_getWidth }, { "getHeight", w_CompressedImageData_getHeight }, { "getDimensions", w_CompressedImageData_getDimensions }, diff --git a/src/modules/image/wrap_ImageData.cpp b/src/modules/image/wrap_ImageData.cpp index 610d4a1fb..bf25750ab 100644 --- a/src/modules/image/wrap_ImageData.cpp +++ b/src/modules/image/wrap_ImageData.cpp @@ -43,6 +43,15 @@ ImageData *luax_checkimagedata(lua_State *L, int idx) return luax_checktype(L, idx); } +int w_ImageData_clone(lua_State *L) +{ + ImageData *t = luax_checkimagedata(L, 1), *c = nullptr; + luax_catchexcept(L, [&](){ c = (ImageData*)t->clone(); }); + luax_pushtype(L, c); + c->release(); + return 1; +} + int w_ImageData_getFormat(lua_State *L) { ImageData *t = luax_checkimagedata(L, 1); @@ -335,6 +344,7 @@ static FFI_ImageData ffifuncs = static const luaL_Reg w_ImageData_functions[] = { + { "clone", w_ImageData_clone }, { "getFormat", w_ImageData_getFormat }, { "getWidth", w_ImageData_getWidth }, { "getHeight", w_ImageData_getHeight }, diff --git a/src/modules/math/CompressedData.cpp b/src/modules/math/CompressedData.cpp index efeae98c4..e6fc4c8b1 100644 --- a/src/modules/math/CompressedData.cpp +++ b/src/modules/math/CompressedData.cpp @@ -51,11 +51,34 @@ CompressedData::CompressedData(Compressor::Format format, char *cdata, size_t co } } +CompressedData::CompressedData(const CompressedData &c) + : format(c.format) + , data(nullptr) + , dataSize(c.dataSize) + , originalSize(c.originalSize) +{ + try + { + data = new char[dataSize]; + } + catch (std::bad_alloc &) + { + throw love::Exception("Out of memory."); + } + + memcpy(data, c.data, dataSize); +} + CompressedData::~CompressedData() { delete[] data; } +Data *CompressedData::clone() const +{ + return new CompressedData(*this); +} + Compressor::Format CompressedData::getFormat() const { return format; diff --git a/src/modules/math/CompressedData.h b/src/modules/math/CompressedData.h index bc0daa905..41705ecd6 100644 --- a/src/modules/math/CompressedData.h +++ b/src/modules/math/CompressedData.h @@ -43,6 +43,7 @@ public: * Constructor just stores already-compressed data in the object. **/ CompressedData(Compressor::Format format, char *cdata, size_t compressedsize, size_t rawsize, bool own = true); + CompressedData(const CompressedData &c); virtual ~CompressedData(); /** @@ -57,6 +58,7 @@ public: size_t getDecompressedSize() const; // Implements Data. + Data *clone() const; void *getData() const override; size_t getSize() const override; diff --git a/src/modules/math/wrap_CompressedData.cpp b/src/modules/math/wrap_CompressedData.cpp index ce6b15345..50c678828 100644 --- a/src/modules/math/wrap_CompressedData.cpp +++ b/src/modules/math/wrap_CompressedData.cpp @@ -32,6 +32,15 @@ CompressedData *luax_checkcompresseddata(lua_State *L, int idx) return luax_checktype(L, idx); } +int w_CompressedData_clone(lua_State *L) +{ + CompressedData *t = luax_checkcompresseddata(L, 1), *c = nullptr; + luax_catchexcept(L, [&](){ c = (CompressedData *)t->clone(); }); + luax_pushtype(L, c); + c->release(); + return 1; +} + int w_CompressedData_getFormat(lua_State *L) { CompressedData *t = luax_checkcompresseddata(L, 1); @@ -46,6 +55,7 @@ int w_CompressedData_getFormat(lua_State *L) static const luaL_Reg w_CompressedData_functions[] = { + { "clone", w_CompressedData_clone }, { "getFormat", w_CompressedData_getFormat }, { 0, 0 }, }; diff --git a/src/modules/sound/SoundData.cpp b/src/modules/sound/SoundData.cpp index 66a69d93c..0023ac404 100644 --- a/src/modules/sound/SoundData.cpp +++ b/src/modules/sound/SoundData.cpp @@ -108,12 +108,27 @@ SoundData::SoundData(void *d, int samples, int sampleRate, int bitDepth, int cha load(samples, sampleRate, bitDepth, channels, d); } +SoundData::SoundData(const SoundData &c) + : data(0) + , size(0) + , sampleRate(0) + , bitDepth(0) + , channels(0) +{ + load(c.getSampleCount(), c.getSampleRate(), c.getBitDepth(), c.getChannels(), c.getData()); +} + SoundData::~SoundData() { if (data != 0) free(data); } +Data *SoundData::clone() const +{ + return new SoundData(*this); +} + void SoundData::load(int samples, int sampleRate, int bitDepth, int channels, void *newData) { if (samples <= 0) diff --git a/src/modules/sound/SoundData.h b/src/modules/sound/SoundData.h index c7d57d891..6ceff6c56 100644 --- a/src/modules/sound/SoundData.h +++ b/src/modules/sound/SoundData.h @@ -40,10 +40,12 @@ public: SoundData(Decoder *decoder); SoundData(int samples, int sampleRate, int bitDepth, int channels); SoundData(void *d, int samples, int sampleRate, int bitDepth, int channels); + SoundData(const SoundData &c); virtual ~SoundData(); // Implements Data. + Data *clone() const; void *getData() const; size_t getSize() const; diff --git a/src/modules/sound/wrap_SoundData.cpp b/src/modules/sound/wrap_SoundData.cpp index 8df058007..9085940bc 100644 --- a/src/modules/sound/wrap_SoundData.cpp +++ b/src/modules/sound/wrap_SoundData.cpp @@ -42,6 +42,15 @@ SoundData *luax_checksounddata(lua_State *L, int idx) return luax_checktype(L, idx); } +int w_SoundData_clone(lua_State *L) +{ + SoundData *t = luax_checksounddata(L, 1)*c = nullptr; + luax_catchexcept(L, [&](){ c = (SoundData*)t->clone(); }); + luax_pushtype(L, c); + c->release(); + return 1; +} + int w_SoundData_getChannels(lua_State *L) { SoundData *t = luax_checksounddata(L, 1); @@ -98,6 +107,7 @@ int w_SoundData_getSample(lua_State *L) static const luaL_Reg w_SoundData_functions[] = { + { "clone", w_SoundData_clone }, { "getChannels", w_SoundData_getChannels }, { "getBitDepth", w_SoundData_getBitDepth }, { "getSampleRate", w_SoundData_getSampleRate },