mirror of https://github.com/odrling/Aegisub
More unique_ptr
This commit is contained in:
parent
eee4da0642
commit
95ef444c20
|
@ -88,7 +88,7 @@ UnknownElement::UnknownElement() : m_pImp(new Imp_T
|
||||||
UnknownElement::UnknownElement(const UnknownElement& unknown) : m_pImp(unknown.m_pImp->Clone()) {}
|
UnknownElement::UnknownElement(const UnknownElement& unknown) : m_pImp(unknown.m_pImp->Clone()) {}
|
||||||
UnknownElement::UnknownElement(int number) : m_pImp(new Imp_T<Integer>(number)) {}
|
UnknownElement::UnknownElement(int number) : m_pImp(new Imp_T<Integer>(number)) {}
|
||||||
UnknownElement::UnknownElement(const char *string) : m_pImp(new Imp_T<String>(string)) {}
|
UnknownElement::UnknownElement(const char *string) : m_pImp(new Imp_T<String>(string)) {}
|
||||||
UnknownElement::~UnknownElement() { delete m_pImp; }
|
UnknownElement::~UnknownElement() { }
|
||||||
|
|
||||||
#define DEFINE_UE_TYPE(Type) \
|
#define DEFINE_UE_TYPE(Type) \
|
||||||
UnknownElement::UnknownElement(Type const& val) : m_pImp(new Imp_T<Type>(val)) { } \
|
UnknownElement::UnknownElement(Type const& val) : m_pImp(new Imp_T<Type>(val)) { } \
|
||||||
|
@ -105,8 +105,7 @@ DEFINE_UE_TYPE(Null)
|
||||||
|
|
||||||
UnknownElement& UnknownElement::operator =(const UnknownElement& unknown)
|
UnknownElement& UnknownElement::operator =(const UnknownElement& unknown)
|
||||||
{
|
{
|
||||||
delete m_pImp;
|
m_pImp.reset(unknown.m_pImp->Clone());
|
||||||
m_pImp = unknown.m_pImp->Clone();
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ Author: Terry Caton
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
@ -126,7 +127,7 @@ private:
|
||||||
template <typename ElementTypeT>
|
template <typename ElementTypeT>
|
||||||
ElementTypeT& CastTo();
|
ElementTypeT& CastTo();
|
||||||
|
|
||||||
Imp* m_pImp;
|
std::unique_ptr<Imp> m_pImp;
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -87,8 +87,9 @@ void AssFile::swap(AssFile &that) throw() {
|
||||||
}
|
}
|
||||||
|
|
||||||
AssFile::AssFile(const AssFile &from) {
|
AssFile::AssFile(const AssFile &from) {
|
||||||
Line.clone_from(from.Line, std::mem_fun_ref(&AssEntry::Clone), delete_ptr());
|
Line.clone_from(from.Line, std::mem_fun_ref(&AssEntry::Clone), [](AssEntry *e) { delete e; });
|
||||||
}
|
}
|
||||||
|
|
||||||
AssFile& AssFile::operator=(AssFile from) {
|
AssFile& AssFile::operator=(AssFile from) {
|
||||||
std::swap(*this, from);
|
std::swap(*this, from);
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
@ -31,20 +31,20 @@
|
||||||
/// @brief Base classes for audio renderers (spectrum, waveform, ...)
|
/// @brief Base classes for audio renderers (spectrum, waveform, ...)
|
||||||
/// @ingroup audio_ui
|
/// @ingroup audio_ui
|
||||||
|
|
||||||
|
|
||||||
// Headers
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "audio_renderer.h"
|
#include "audio_renderer.h"
|
||||||
|
|
||||||
|
#include "include/aegisub/audio_provider.h"
|
||||||
|
|
||||||
|
#include <libaegisub/util.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include <wx/bitmap.h>
|
#include <wx/bitmap.h>
|
||||||
#include <wx/dcmemory.h>
|
#include <wx/dcmemory.h>
|
||||||
|
|
||||||
#include "include/aegisub/audio_provider.h"
|
|
||||||
|
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
AudioRendererBitmapCacheBitmapFactory::AudioRendererBitmapCacheBitmapFactory(AudioRenderer *renderer)
|
AudioRendererBitmapCacheBitmapFactory::AudioRendererBitmapCacheBitmapFactory(AudioRenderer *renderer)
|
||||||
|
@ -53,14 +53,9 @@ AudioRendererBitmapCacheBitmapFactory::AudioRendererBitmapCacheBitmapFactory(Aud
|
||||||
assert(renderer);
|
assert(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxBitmap *AudioRendererBitmapCacheBitmapFactory::ProduceBlock(int /* i */)
|
std::unique_ptr<wxBitmap> AudioRendererBitmapCacheBitmapFactory::ProduceBlock(int /* i */)
|
||||||
{
|
{
|
||||||
return new wxBitmap(renderer->cache_bitmap_width, renderer->pixel_height, 24);
|
return agi::util::make_unique<wxBitmap>(renderer->cache_bitmap_width, renderer->pixel_height, 24);
|
||||||
}
|
|
||||||
|
|
||||||
void AudioRendererBitmapCacheBitmapFactory::DisposeBlock(wxBitmap *bmp)
|
|
||||||
{
|
|
||||||
delete bmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t AudioRendererBitmapCacheBitmapFactory::GetBlockSize() const
|
size_t AudioRendererBitmapCacheBitmapFactory::GetBlockSize() const
|
||||||
|
@ -79,7 +74,8 @@ AudioRenderer::AudioRenderer()
|
||||||
, renderer(0)
|
, renderer(0)
|
||||||
, provider(0)
|
, provider(0)
|
||||||
{
|
{
|
||||||
bitmaps.resize(AudioStyle_MAX, AudioRendererBitmapCache(256, AudioRendererBitmapCacheBitmapFactory(this)));
|
for (int i = 0; i < AudioStyle_MAX; ++i)
|
||||||
|
bitmaps.emplace_back(256, AudioRendererBitmapCacheBitmapFactory(this));
|
||||||
|
|
||||||
// Make sure there's *some* values for those fields, and in the caches
|
// Make sure there's *some* values for those fields, and in the caches
|
||||||
SetMillisecondsPerPixel(1);
|
SetMillisecondsPerPixel(1);
|
||||||
|
|
|
@ -54,6 +54,8 @@ class AudioRenderer;
|
||||||
/// @class AudioRendererBitmapCacheBitmapFactory
|
/// @class AudioRendererBitmapCacheBitmapFactory
|
||||||
/// @brief Produces wxBitmap objects for DataBlockCache storage for the audio renderer
|
/// @brief Produces wxBitmap objects for DataBlockCache storage for the audio renderer
|
||||||
struct AudioRendererBitmapCacheBitmapFactory {
|
struct AudioRendererBitmapCacheBitmapFactory {
|
||||||
|
typedef std::unique_ptr<wxBitmap> BlockType;
|
||||||
|
|
||||||
/// The audio renderer we're producing bitmaps for
|
/// The audio renderer we're producing bitmaps for
|
||||||
AudioRenderer *renderer;
|
AudioRenderer *renderer;
|
||||||
|
|
||||||
|
@ -66,13 +68,7 @@ struct AudioRendererBitmapCacheBitmapFactory {
|
||||||
/// @return A fresh wxBitmap
|
/// @return A fresh wxBitmap
|
||||||
///
|
///
|
||||||
/// Produces a wxBitmap with dimensions pulled from our master AudioRenderer.
|
/// Produces a wxBitmap with dimensions pulled from our master AudioRenderer.
|
||||||
wxBitmap *ProduceBlock(int i);
|
std::unique_ptr<wxBitmap> ProduceBlock(int i);
|
||||||
|
|
||||||
/// @brief Delete a bitmap
|
|
||||||
/// @param bmp The bitmap to delete
|
|
||||||
///
|
|
||||||
/// Deletes said bitmap.
|
|
||||||
void DisposeBlock(wxBitmap *bmp);
|
|
||||||
|
|
||||||
/// @brief Calculate the size of bitmaps
|
/// @brief Calculate the size of bitmaps
|
||||||
/// @return The size of bitmaps created
|
/// @return The size of bitmaps created
|
||||||
|
@ -83,7 +79,6 @@ struct AudioRendererBitmapCacheBitmapFactory {
|
||||||
typedef DataBlockCache<wxBitmap, 8, AudioRendererBitmapCacheBitmapFactory> AudioRendererBitmapCache;
|
typedef DataBlockCache<wxBitmap, 8, AudioRendererBitmapCacheBitmapFactory> AudioRendererBitmapCache;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @class AudioRenderer
|
/// @class AudioRenderer
|
||||||
/// @brief Renders audio to bitmap images for display on screen
|
/// @brief Renders audio to bitmap images for display on screen
|
||||||
///
|
///
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
|
|
||||||
/// Allocates blocks of derived data for the audio spectrum
|
/// Allocates blocks of derived data for the audio spectrum
|
||||||
struct AudioSpectrumCacheBlockFactory {
|
struct AudioSpectrumCacheBlockFactory {
|
||||||
|
typedef std::unique_ptr<float, std::default_delete<float[]>> BlockType;
|
||||||
|
|
||||||
/// Pointer back to the owning spectrum renderer
|
/// Pointer back to the owning spectrum renderer
|
||||||
AudioSpectrumRenderer *spectrum;
|
AudioSpectrumRenderer *spectrum;
|
||||||
|
|
||||||
|
@ -66,18 +68,11 @@ struct AudioSpectrumCacheBlockFactory {
|
||||||
/// @return Newly allocated and filled block
|
/// @return Newly allocated and filled block
|
||||||
///
|
///
|
||||||
/// The filling is delegated to the spectrum renderer
|
/// The filling is delegated to the spectrum renderer
|
||||||
float *ProduceBlock(size_t i)
|
BlockType ProduceBlock(size_t i)
|
||||||
{
|
{
|
||||||
float *res = new float[((size_t)1)<<spectrum->derivation_size];
|
float *res = new float[((size_t)1)<<spectrum->derivation_size];
|
||||||
spectrum->FillBlock(i, res);
|
spectrum->FillBlock(i, res);
|
||||||
return res;
|
return BlockType(res);
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief De-allocate a cache block
|
|
||||||
/// @param block The block to dispose of
|
|
||||||
void DisposeBlock(float *block)
|
|
||||||
{
|
|
||||||
delete[] block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Calculate the in-memory size of a spec
|
/// @brief Calculate the in-memory size of a spec
|
||||||
|
@ -118,7 +113,7 @@ AudioSpectrumRenderer::AudioSpectrumRenderer(std::string const& color_scheme_nam
|
||||||
AudioSpectrumRenderer::~AudioSpectrumRenderer()
|
AudioSpectrumRenderer::~AudioSpectrumRenderer()
|
||||||
{
|
{
|
||||||
// This sequence will clean up
|
// This sequence will clean up
|
||||||
provider = 0;
|
provider = nullptr;
|
||||||
RecreateCache();
|
RecreateCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -307,7 +307,7 @@ namespace Automation4 {
|
||||||
std::string version;
|
std::string version;
|
||||||
|
|
||||||
std::vector<cmd::Command*> macros;
|
std::vector<cmd::Command*> macros;
|
||||||
std::vector<ExportFilter*> filters;
|
std::vector<std::unique_ptr<ExportFilter>> filters;
|
||||||
|
|
||||||
/// load script and create internal structures etc.
|
/// load script and create internal structures etc.
|
||||||
void Create();
|
void Create();
|
||||||
|
@ -337,7 +337,7 @@ namespace Automation4 {
|
||||||
bool GetLoadedState() const { return L != 0; }
|
bool GetLoadedState() const { return L != 0; }
|
||||||
|
|
||||||
std::vector<cmd::Command*> GetMacros() const { return macros; }
|
std::vector<cmd::Command*> GetMacros() const { return macros; }
|
||||||
std::vector<ExportFilter*> GetFilters() const { return filters; }
|
std::vector<ExportFilter*> GetFilters() const;
|
||||||
std::vector<SubtitleFormat*> GetFormats() const { return std::vector<SubtitleFormat*>(); }
|
std::vector<SubtitleFormat*> GetFormats() const { return std::vector<SubtitleFormat*>(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -492,12 +492,20 @@ namespace Automation4 {
|
||||||
for (int i = macros.size() - 1; i >= 0; --i)
|
for (int i = macros.size() - 1; i >= 0; --i)
|
||||||
cmd::unreg(macros[i]->name());
|
cmd::unreg(macros[i]->name());
|
||||||
|
|
||||||
delete_clear(filters);
|
filters.clear();
|
||||||
|
|
||||||
lua_close(L);
|
lua_close(L);
|
||||||
L = nullptr;
|
L = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<ExportFilter*> LuaScript::GetFilters() const
|
||||||
|
{
|
||||||
|
std::vector<ExportFilter *> ret;
|
||||||
|
ret.reserve(filters.size());
|
||||||
|
for (auto& filter : filters) ret.push_back(filter.get());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void LuaScript::RegisterCommand(LuaCommand *command)
|
void LuaScript::RegisterCommand(LuaCommand *command)
|
||||||
{
|
{
|
||||||
for (auto macro : macros) {
|
for (auto macro : macros) {
|
||||||
|
@ -517,7 +525,7 @@ namespace Automation4 {
|
||||||
|
|
||||||
void LuaScript::RegisterFilter(LuaExportFilter *filter)
|
void LuaScript::RegisterFilter(LuaExportFilter *filter)
|
||||||
{
|
{
|
||||||
filters.push_back(filter);
|
filters.emplace_back(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
LuaScript* LuaScript::GetScriptObject(lua_State *L)
|
LuaScript* LuaScript::GetScriptObject(lua_State *L)
|
||||||
|
|
|
@ -83,7 +83,7 @@ namespace Automation4 {
|
||||||
/// Commits to apply once processing completes successfully
|
/// Commits to apply once processing completes successfully
|
||||||
std::deque<PendingCommit> pending_commits;
|
std::deque<PendingCommit> pending_commits;
|
||||||
/// Lines to delete once processing complete successfully
|
/// Lines to delete once processing complete successfully
|
||||||
std::deque<AssEntry*> lines_to_delete;
|
std::deque<std::unique_ptr<AssEntry>> lines_to_delete;
|
||||||
|
|
||||||
int ObjectIndexRead(lua_State *L);
|
int ObjectIndexRead(lua_State *L);
|
||||||
void ObjectIndexWrite(lua_State *L);
|
void ObjectIndexWrite(lua_State *L);
|
||||||
|
@ -101,7 +101,7 @@ namespace Automation4 {
|
||||||
void LuaSetUndoPoint(lua_State *L);
|
void LuaSetUndoPoint(lua_State *L);
|
||||||
|
|
||||||
// LuaAssFile can only be deleted by the reference count hitting zero
|
// LuaAssFile can only be deleted by the reference count hitting zero
|
||||||
~LuaAssFile() { }
|
~LuaAssFile();
|
||||||
public:
|
public:
|
||||||
static LuaAssFile *GetObjPointer(lua_State *L, int idx);
|
static LuaAssFile *GetObjPointer(lua_State *L, int idx);
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,8 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Automation4 {
|
namespace Automation4 {
|
||||||
|
LuaAssFile::~LuaAssFile() { }
|
||||||
|
|
||||||
void LuaAssFile::CheckAllowModify()
|
void LuaAssFile::CheckAllowModify()
|
||||||
{
|
{
|
||||||
if (!can_modify)
|
if (!can_modify)
|
||||||
|
@ -376,7 +378,7 @@ namespace Automation4 {
|
||||||
auto e = LuaToAssEntry(L);
|
auto e = LuaToAssEntry(L);
|
||||||
modification_type |= modification_mask(e.get());
|
modification_type |= modification_mask(e.get());
|
||||||
CheckBounds(n);
|
CheckBounds(n);
|
||||||
lines_to_delete.push_back(lines[n - 1]);
|
lines_to_delete.emplace_back(lines[n - 1]);
|
||||||
lines[n - 1] = e.release();
|
lines[n - 1] = e.release();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -416,7 +418,7 @@ namespace Automation4 {
|
||||||
for (size_t i = 0; i < lines.size(); ++i) {
|
for (size_t i = 0; i < lines.size(); ++i) {
|
||||||
if (id_idx < ids.size() && ids[id_idx] == i) {
|
if (id_idx < ids.size() && ids[id_idx] == i) {
|
||||||
modification_type |= modification_mask(lines[i]);
|
modification_type |= modification_mask(lines[i]);
|
||||||
lines_to_delete.push_back(lines[i]);
|
lines_to_delete.emplace_back(lines[i]);
|
||||||
++id_idx;
|
++id_idx;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -438,7 +440,7 @@ namespace Automation4 {
|
||||||
|
|
||||||
for (; b < lines.size(); ++a, ++b) {
|
for (; b < lines.size(); ++a, ++b) {
|
||||||
modification_type |= modification_mask(lines[a]);
|
modification_type |= modification_mask(lines[a]);
|
||||||
lines_to_delete.push_back(lines[a]);
|
lines_to_delete.emplace_back(lines[a]);
|
||||||
lines[a] = lines[b];
|
lines[a] = lines[b];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,7 +611,7 @@ namespace Automation4 {
|
||||||
if (modification_type && can_set_undo && !undo_description.empty())
|
if (modification_type && can_set_undo && !undo_description.empty())
|
||||||
ass->Commit(undo_description, modification_type);
|
ass->Commit(undo_description, modification_type);
|
||||||
|
|
||||||
delete_clear(lines_to_delete);
|
lines_to_delete.clear();
|
||||||
|
|
||||||
references--;
|
references--;
|
||||||
if (!references) delete this;
|
if (!references) delete this;
|
||||||
|
@ -617,6 +619,7 @@ namespace Automation4 {
|
||||||
|
|
||||||
void LuaAssFile::Cancel()
|
void LuaAssFile::Cancel()
|
||||||
{
|
{
|
||||||
|
for (auto& line : lines_to_delete) line.release();
|
||||||
references--;
|
references--;
|
||||||
if (!references) delete this;
|
if (!references) delete this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,25 +49,18 @@
|
||||||
/// requested blocks in to avoid the default allocator.
|
/// requested blocks in to avoid the default allocator.
|
||||||
template <typename BlockT>
|
template <typename BlockT>
|
||||||
struct BasicDataBlockFactory {
|
struct BasicDataBlockFactory {
|
||||||
|
typedef std::unique_ptr<BlockT> BlockType;
|
||||||
|
|
||||||
/// @brief Allocates a block and returns it
|
/// @brief Allocates a block and returns it
|
||||||
/// @param i Index of the block to allocate
|
/// @param i Index of the block to allocate
|
||||||
/// @return A pointer to the allocated block
|
/// @return A pointer to the allocated block
|
||||||
///
|
///
|
||||||
/// This default implementation does not use the i parameter. Custom implementations
|
/// This default implementation does not use the i parameter. Custom implementations
|
||||||
/// of block factories should use i to determine what data to fill into the block.
|
/// of block factories should use i to determine what data to fill into the block.
|
||||||
BlockT *ProduceBlock(size_t i)
|
std::unique_ptr<BlockT> ProduceBlock(size_t i)
|
||||||
{
|
{
|
||||||
(void)i;
|
(void)i;
|
||||||
return new BlockT;
|
return std::unique_ptr<BlockT>(new BlockT);
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief De-allocate a block
|
|
||||||
/// @param block Pointer to the block to de-allocate
|
|
||||||
///
|
|
||||||
/// It is guaranteed that block was returned by ProduceBlock.
|
|
||||||
void DisposeBlock(BlockT *block)
|
|
||||||
{
|
|
||||||
delete block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Retrieve the amount of memory consumed by a single block
|
/// @brief Retrieve the amount of memory consumed by a single block
|
||||||
|
@ -94,9 +87,8 @@ template <
|
||||||
typename BlockFactoryT = BasicDataBlockFactory<BlockT>
|
typename BlockFactoryT = BasicDataBlockFactory<BlockT>
|
||||||
>
|
>
|
||||||
class DataBlockCache {
|
class DataBlockCache {
|
||||||
|
|
||||||
/// Type of an array of blocks
|
/// Type of an array of blocks
|
||||||
typedef std::vector<BlockT*> BlockArray;
|
typedef std::vector<typename BlockFactoryT::BlockType> BlockArray;
|
||||||
|
|
||||||
struct MacroBlock {
|
struct MacroBlock {
|
||||||
/// This macroblock's position in the age list
|
/// This macroblock's position in the age list
|
||||||
|
@ -105,6 +97,16 @@ class DataBlockCache {
|
||||||
|
|
||||||
/// The blocks contained in the macroblock
|
/// The blocks contained in the macroblock
|
||||||
BlockArray blocks;
|
BlockArray blocks;
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
MacroBlock() { }
|
||||||
|
MacroBlock(MacroBlock&& rgt) : position(rgt.position), blocks(std::move(rgt.blocks)) { }
|
||||||
|
MacroBlock& operator=(MacroBlock&& rgt) {
|
||||||
|
position = rgt.position;
|
||||||
|
blocks = std::move(rgt.blocks);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Type of an array of macro blocks
|
/// Type of an array of macro blocks
|
||||||
|
@ -135,17 +137,21 @@ class DataBlockCache {
|
||||||
if (mb.blocks.empty())
|
if (mb.blocks.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (auto block : mb.blocks)
|
|
||||||
{
|
|
||||||
if (block)
|
|
||||||
factory.DisposeBlock(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
mb.blocks.clear();
|
mb.blocks.clear();
|
||||||
age.erase(mb.position);
|
age.erase(mb.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
DataBlockCache(DataBlockCache&& rgt)
|
||||||
|
: data(std::move(rgt.data))
|
||||||
|
, age(std::move(rgt.age))
|
||||||
|
, macroblock_size(rgt.macroblock_size)
|
||||||
|
, macroblock_index_mask(rgt.macroblock_index_mask)
|
||||||
|
, factory(std::move(rgt.factory))
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @brief Constructor
|
/// @brief Constructor
|
||||||
/// @param block_count Total number of blocks the cache will manage
|
/// @param block_count Total number of blocks the cache will manage
|
||||||
/// @param factory Factory object to use for producing blocks
|
/// @param factory Factory object to use for producing blocks
|
||||||
|
@ -155,22 +161,12 @@ public:
|
||||||
///
|
///
|
||||||
/// The factory object passed must respond well to copying.
|
/// The factory object passed must respond well to copying.
|
||||||
DataBlockCache(size_t block_count, BlockFactoryT factory = BlockFactoryT())
|
DataBlockCache(size_t block_count, BlockFactoryT factory = BlockFactoryT())
|
||||||
: factory(factory)
|
: factory(factory)
|
||||||
{
|
{
|
||||||
SetBlockCount(block_count);
|
SetBlockCount(block_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// @brief Destructor
|
|
||||||
///
|
|
||||||
/// Disposes of all cached blocks
|
|
||||||
~DataBlockCache()
|
|
||||||
{
|
|
||||||
// Clear all blocks by aging to zero bytes
|
|
||||||
Age(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Change the number of blocks in cache
|
/// @brief Change the number of blocks in cache
|
||||||
/// @param block_count New number of blocks to hold
|
/// @param block_count New number of blocks to hold
|
||||||
///
|
///
|
||||||
|
@ -184,7 +180,7 @@ public:
|
||||||
|
|
||||||
macroblock_index_mask = ~(((~0) >> MacroblockExponent) << MacroblockExponent);
|
macroblock_index_mask = ~(((~0) >> MacroblockExponent) << MacroblockExponent);
|
||||||
|
|
||||||
data.resize( (block_count + macroblock_size - 1) >> MacroblockExponent );
|
data.resize((block_count + macroblock_size - 1) >> MacroblockExponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -201,8 +197,10 @@ public:
|
||||||
// Quick way out: get rid of everything
|
// Quick way out: get rid of everything
|
||||||
if (max_size == 0)
|
if (max_size == 0)
|
||||||
{
|
{
|
||||||
for (auto& mb : data)
|
size_t block_count = data.size();
|
||||||
KillMacroBlock(mb);
|
data.clear();
|
||||||
|
SetBlockCount(block_count);
|
||||||
|
age.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,14 +210,12 @@ public:
|
||||||
auto it = age.begin();
|
auto it = age.begin();
|
||||||
for (; it != age.end() && cur_size < max_size; ++it)
|
for (; it != age.end() && cur_size < max_size; ++it)
|
||||||
{
|
{
|
||||||
BlockArray &ba = (*it)->blocks;
|
auto& ba = (*it)->blocks;
|
||||||
cur_size += (ba.size() - std::count(ba.begin(), ba.end(), nullptr)) * block_size;
|
cur_size += (ba.size() - std::count(ba.begin(), ba.end(), nullptr)) * block_size;
|
||||||
}
|
}
|
||||||
// Hit max, clear all remaining blocks
|
// Hit max, clear all remaining blocks
|
||||||
for (; it != age.end();)
|
for (; it != age.end(); )
|
||||||
{
|
|
||||||
KillMacroBlock(**it++);
|
KillMacroBlock(**it++);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -229,21 +225,17 @@ public:
|
||||||
/// @return A pointer to the block in cache
|
/// @return A pointer to the block in cache
|
||||||
///
|
///
|
||||||
/// It is legal to pass 0 (null) for created, in this case nothing is returned in it.
|
/// It is legal to pass 0 (null) for created, in this case nothing is returned in it.
|
||||||
BlockT *Get(size_t i, bool *created = 0)
|
BlockT *Get(size_t i, bool *created = nullptr)
|
||||||
{
|
{
|
||||||
size_t mbi = i >> MacroblockExponent;
|
size_t mbi = i >> MacroblockExponent;
|
||||||
assert(mbi < data.size());
|
assert(mbi < data.size());
|
||||||
|
|
||||||
MacroBlock &mb = data[mbi];
|
MacroBlock &mb = data[mbi];
|
||||||
|
|
||||||
if (mb.blocks.size() == 0)
|
if (mb.blocks.empty())
|
||||||
{
|
|
||||||
mb.blocks.resize(macroblock_size);
|
mb.blocks.resize(macroblock_size);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
age.erase(mb.position);
|
age.erase(mb.position);
|
||||||
}
|
|
||||||
|
|
||||||
// Move this macroblock to the front of the age list
|
// Move this macroblock to the front of the age list
|
||||||
age.push_front(&mb);
|
age.push_front(&mb);
|
||||||
|
@ -252,13 +244,13 @@ public:
|
||||||
size_t block_index = i & macroblock_index_mask;
|
size_t block_index = i & macroblock_index_mask;
|
||||||
assert(block_index < mb.blocks.size());
|
assert(block_index < mb.blocks.size());
|
||||||
|
|
||||||
BlockT *b = mb.blocks[block_index];
|
BlockT *b = mb.blocks[block_index].get();
|
||||||
|
|
||||||
if (!b)
|
if (!b)
|
||||||
{
|
{
|
||||||
b = factory.ProduceBlock(i);
|
mb.blocks[block_index] = factory.ProduceBlock(i);
|
||||||
|
b = mb.blocks[block_index].get();
|
||||||
assert(b != 0);
|
assert(b != 0);
|
||||||
mb.blocks[block_index] = b;
|
|
||||||
|
|
||||||
if (created) *created = true;
|
if (created) *created = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,22 +114,6 @@ void SetClipboard(wxBitmap const& new_value);
|
||||||
|
|
||||||
#define countof(array) (sizeof(array) / sizeof(array[0]))
|
#define countof(array) (sizeof(array) / sizeof(array[0]))
|
||||||
|
|
||||||
/// Polymorphic delete functor
|
|
||||||
struct delete_ptr {
|
|
||||||
template<class T> void operator()(T* ptr) const {
|
|
||||||
delete ptr;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Delete all of the items in a container of pointers and clear the container
|
|
||||||
template<class T>
|
|
||||||
void delete_clear(T& container) {
|
|
||||||
if (!container.empty()) {
|
|
||||||
std::for_each(container.begin(), container.end(), delete_ptr());
|
|
||||||
container.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Out>
|
template<class Out>
|
||||||
struct cast {
|
struct cast {
|
||||||
template<class In>
|
template<class In>
|
||||||
|
|
Loading…
Reference in New Issue