Use unique_ptr for most non-wx owning pointers

This commit is contained in:
Thomas Goyne 2013-06-07 21:19:40 -07:00
parent d81dfc1e73
commit f21a72992b
74 changed files with 610 additions and 750 deletions

View File

@ -36,9 +36,6 @@
#include "ass_export_filter.h"
#include "utils.h"
#include <algorithm>
#include <boost/format.hpp>
static FilterList& filters() {
@ -53,7 +50,7 @@ AssExportFilter::AssExportFilter(std::string const& name, std::string const& des
{
}
void AssExportFilterChain::Register(AssExportFilter *filter) {
void AssExportFilterChain::Register(std::unique_ptr<AssExportFilter>&& filter) {
int filter_copy = 1;
std::string name = filter->name;
// Find a unique name
@ -64,36 +61,22 @@ void AssExportFilterChain::Register(AssExportFilter *filter) {
// Look for place to insert
auto begin(filters().begin()), end(filters().end());
while (begin != end && (*begin)->priority >= filter->priority) ++begin;
filters().insert(begin, filter);
while (begin != end && begin->priority >= filter->priority) ++begin;
filters().insert(begin, *filter.release());
}
void AssExportFilterChain::Unregister(AssExportFilter *filter) {
auto it = remove(begin(filters()), end(filters()), filter);
if (it == end(filters()))
throw wxString::Format("Unregister export filter: name \"%s\" is not registered.", filter->name);
filters().pop_back();
}
const FilterList *AssExportFilterChain::GetFilterList() {
FilterList *AssExportFilterChain::GetFilterList() {
return &filters();
}
void AssExportFilterChain::Clear() {
while (filters().size() > 0) {
AssExportFilter *f = filters().back();
delete f;
if (filters().size() && filters().back() == f)
filters().pop_back();
}
filters().clear_and_dispose([](AssExportFilter *f) { delete f; });
}
AssExportFilter *AssExportFilterChain::GetFilter(std::string const& name) {
for (auto filter : filters()) {
if (filter->name == name)
return filter;
for (auto& filter : filters()) {
if (filter.name == name)
return &filter;
}
return 0;
return nullptr;
}

View File

@ -34,34 +34,17 @@
#pragma once
#include <boost/intrusive/list.hpp>
#include <memory>
#include <string>
#include <vector>
class AssFile;
class AssExportFilter;
class AssExportFilterChain;
class wxWindow;
namespace agi { struct Context; }
typedef std::vector<AssExportFilter*> FilterList;
class AssExportFilterChain {
public:
/// Register an export filter
static void Register(AssExportFilter *filter);
/// Unregister an export filter; must have been registered
static void Unregister(AssExportFilter *filter);
/// Unregister and delete all export filters
static void Clear();
/// Get a filter by name or nullptr if it doesn't exist
static AssExportFilter *GetFilter(std::string const& name);
/// Get the list of registered filters
static const FilterList *GetFilterList();
};
class AssExportFilter {
class AssExportFilter : public boost::intrusive::make_list_base_hook<boost::intrusive::link_mode<boost::intrusive::auto_unlink>>::type {
/// The filter chain needs to be able to muck around with filter names when
/// they're registered to avoid duplicates
friend class AssExportFilterChain;
@ -98,3 +81,18 @@ public:
/// @param c Project context
virtual void LoadSettings(bool is_default, agi::Context *c) { }
};
typedef boost::intrusive::make_list<AssExportFilter, boost::intrusive::constant_time_size<false>>::type FilterList;
class AssExportFilterChain {
public:
/// Register an export filter
static void Register(std::unique_ptr<AssExportFilter>&& filter);
/// Unregister and delete all export filters
static void Clear();
/// Get a filter by name or nullptr if it doesn't exist
static AssExportFilter *GetFilter(std::string const& name);
/// Get the list of registered filters
static FilterList *GetFilterList();
};

View File

@ -42,18 +42,9 @@
#include "include/aegisub/context.h"
#include "subtitle_format.h"
#include <algorithm>
#include <memory>
#include <wx/sizer.h>
static inline FilterList::const_iterator filter_list_begin() {
return AssExportFilterChain::GetFilterList()->begin();
}
static inline FilterList::const_iterator filter_list_end() {
return AssExportFilterChain::GetFilterList()->end();
}
AssExporter::AssExporter(agi::Context *c)
: c(c)
, is_default(true)
@ -62,16 +53,16 @@ AssExporter::AssExporter(agi::Context *c)
void AssExporter::DrawSettings(wxWindow *parent, wxSizer *target_sizer) {
is_default = false;
for (auto filter : *AssExportFilterChain::GetFilterList()) {
for (auto& filter : *AssExportFilterChain::GetFilterList()) {
// Make sure to construct static box sizer first, so it won't overlap
// the controls on wxMac.
wxSizer *box = new wxStaticBoxSizer(wxVERTICAL, parent, to_wx(filter->GetName()));
wxWindow *window = filter->GetConfigDialogWindow(parent, c);
wxSizer *box = new wxStaticBoxSizer(wxVERTICAL, parent, to_wx(filter.GetName()));
wxWindow *window = filter.GetConfigDialogWindow(parent, c);
if (window) {
box->Add(window, 0, wxEXPAND, 0);
target_sizer->Add(box, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
target_sizer->Show(box, false);
Sizers[filter->GetName()] = box;
Sizers[filter.GetName()] = box;
}
else {
delete box;
@ -80,7 +71,7 @@ void AssExporter::DrawSettings(wxWindow *parent, wxSizer *target_sizer) {
}
void AssExporter::AddFilter(std::string const& name) {
AssExportFilter *filter = AssExportFilterChain::GetFilter(name);
auto filter = AssExportFilterChain::GetFilter(name);
if (!filter) throw "Filter not found: " + name;
@ -89,29 +80,24 @@ void AssExporter::AddFilter(std::string const& name) {
std::vector<std::string> AssExporter::GetAllFilterNames() const {
std::vector<std::string> names;
transform(filter_list_begin(), filter_list_end(),
back_inserter(names), std::mem_fun(&AssExportFilter::GetName));
for (auto& filter : *AssExportFilterChain::GetFilterList())
names.emplace_back(filter.GetName());
return names;
}
AssFile *AssExporter::ExportTransform(wxWindow *export_dialog, bool copy) {
AssFile *subs = copy ? new AssFile(*c->ass) : c->ass;
void AssExporter::Export(agi::fs::path const& filename, std::string const& charset, wxWindow *export_dialog) {
AssFile subs(*c->ass);
for (auto filter : filters) {
filter->LoadSettings(is_default, c);
filter->ProcessSubs(subs, export_dialog);
filter->ProcessSubs(&subs, export_dialog);
}
return subs;
}
void AssExporter::Export(agi::fs::path const& filename, std::string const& charset, wxWindow *export_dialog) {
std::unique_ptr<AssFile> subs(ExportTransform(export_dialog, true));
const SubtitleFormat *writer = SubtitleFormat::GetWriter(filename);
if (!writer)
throw "Unknown file type.";
writer->WriteFile(subs.get(), filename, charset);
writer->WriteFile(&subs, filename, charset);
}
wxSizer *AssExporter::GetSettingsSizer(std::string const& name) {
@ -120,7 +106,7 @@ wxSizer *AssExporter::GetSettingsSizer(std::string const& name) {
}
std::string const& AssExporter::GetDescription(std::string const& name) const {
AssExportFilter *filter = AssExportFilterChain::GetFilter(name);
auto filter = AssExportFilterChain::GetFilter(name);
if (filter)
return filter->GetDescription();
throw "Filter not found: " + name;

View File

@ -44,16 +44,14 @@ namespace agi { struct Context; }
class wxSizer;
class wxWindow;
typedef std::vector<AssExportFilter*> FilterList;
class AssExporter {
typedef FilterList::const_iterator filter_iterator;
typedef std::vector<AssExportFilter*>::const_iterator filter_iterator;
/// Sizers for configuration panels
std::map<std::string, wxSizer*> Sizers;
/// Filters which will be applied to the subtitles
FilterList filters;
std::vector<AssExportFilter*> filters;
/// Input context
agi::Context *c;
@ -72,12 +70,6 @@ public:
/// @throws std::string if filter is not found
void AddFilter(std::string const& name);
/// Run all added export filters
/// @param parent_window Parent window the filters should use when opening dialogs
/// @param copy Should the file be copied rather than transformed in-place?
/// @return The new subtitle file (which is the old one if copy is false)
AssFile *ExportTransform(wxWindow *parent_window = 0, bool copy = false);
/// Apply selected export filters and save with the given charset
/// @param file Target filename
/// @param charset Target charset

View File

@ -46,9 +46,9 @@
#include <boost/algorithm/string/predicate.hpp>
#include <fstream>
AssStyleStorage::~AssStyleStorage() {
agi::util::delete_clear(style);
}
AssStyleStorage::~AssStyleStorage() { }
void AssStyleStorage::clear() { style.clear(); }
void AssStyleStorage::push_back( std::unique_ptr<AssStyle>&& new_style ) { style.emplace_back(std::move(new_style)); }
void AssStyleStorage::Save() const {
if (file.empty()) return;
@ -58,19 +58,19 @@ void AssStyleStorage::Save() const {
agi::io::Save out(file);
out.Get() << "\xEF\xBB\xBF";
for (const AssStyle *cur : style)
for (auto const& cur : style)
out.Get() << cur->GetEntryData() << std::endl;
}
void AssStyleStorage::Load(agi::fs::path const& filename) {
file = filename;
Clear();
clear();
try {
std::unique_ptr<std::ifstream> in(agi::io::Open(file));
for (auto const& line : agi::line_iterator<std::string>(*in)) {
try {
style.push_back(new AssStyle(line));
style.emplace_back(agi::util::make_unique<AssStyle>(line));
} catch(...) {
/* just ignore invalid lines for now */
}
@ -81,26 +81,21 @@ void AssStyleStorage::Load(agi::fs::path const& filename) {
}
}
void AssStyleStorage::Clear() {
agi::util::delete_clear(style);
}
void AssStyleStorage::Delete(int idx) {
delete style[idx];
style.erase(style.begin() + idx);
}
std::vector<std::string> AssStyleStorage::GetNames() {
std::vector<std::string> names;
for (const AssStyle *cur : style)
for (auto const& cur : style)
names.emplace_back(cur->name);
return names;
}
AssStyle *AssStyleStorage::GetStyle(std::string const& name) {
for (AssStyle *cur : style) {
for (auto& cur : style) {
if (boost::iequals(cur->name, name))
return cur;
return cur.get();
}
return 0;
}

View File

@ -35,7 +35,7 @@
#include <libaegisub/fs_fwd.h>
#include <boost/filesystem/path.hpp>
#include <deque>
#include <memory>
#include <string>
#include <vector>
@ -43,28 +43,26 @@ class AssStyle;
class AssStyleStorage {
agi::fs::path file;
std::deque<AssStyle*> style;
std::vector<std::unique_ptr<AssStyle>> style;
public:
~AssStyleStorage();
typedef std::deque<AssStyle*>::iterator iterator;
typedef std::deque<AssStyle*>::const_iterator const_iterator;
typedef std::vector<std::unique_ptr<AssStyle>>::iterator iterator;
typedef std::vector<std::unique_ptr<AssStyle>>::const_iterator const_iterator;
iterator begin() { return style.begin(); }
iterator end() { return style.end(); }
const_iterator begin() const { return style.begin(); }
const_iterator end() const { return style.end(); }
void push_back(AssStyle *new_style) { style.push_back(new_style); }
AssStyle *back() { return style.back(); }
AssStyle *operator[](size_t idx) const { return style[idx]; }
void push_back(std::unique_ptr<AssStyle>&& new_style);
AssStyle *back() { return style.back().get(); }
AssStyle *operator[](size_t idx) const { return style[idx].get(); }
size_t size() const { return style.size(); }
void clear();
/// Get the names of all styles in this storage
std::vector<std::string> GetNames();
/// Delete all styles in this storage
void Clear();
/// Delete the style at the given index
void Delete(int idx);

View File

@ -58,8 +58,6 @@
AudioController::AudioController(agi::Context *context)
: context(context)
, subtitle_save_slot(context->subsController->AddFileSaveListener(&AudioController::OnSubtitlesSave, this))
, player(0)
, provider(0)
, playback_mode(PM_NotPlaying)
, playback_timer(this)
{
@ -107,8 +105,7 @@ void AudioController::OnPlaybackTimer(wxTimerEvent &)
void AudioController::OnComputerSuspending(wxPowerEvent &)
{
Stop();
delete player;
player = 0;
player.reset();
}
void AudioController::OnComputerResuming(wxPowerEvent &)
@ -117,7 +114,7 @@ void AudioController::OnComputerResuming(wxPowerEvent &)
{
try
{
player = AudioPlayerFactory::GetAudioPlayer(provider);
player = AudioPlayerFactory::GetAudioPlayer(provider.get());
}
catch (...)
{
@ -133,11 +130,11 @@ void AudioController::OnAudioPlayerChanged()
Stop();
delete player;
player.reset();
try
{
player = AudioPlayerFactory::GetAudioPlayer(provider);
player = AudioPlayerFactory::GetAudioPlayer(provider.get());
}
catch (...)
{
@ -159,7 +156,7 @@ void AudioController::OpenAudio(agi::fs::path const& url)
if (url.empty())
throw agi::InternalError("AudioController::OpenAudio() was passed an empty string. This must not happen.", 0);
AudioProvider *new_provider = 0;
std::unique_ptr<AudioProvider> new_provider;
try {
new_provider = AudioProviderFactory::GetProvider(url);
config::path->SetToken("?audio", url);
@ -173,16 +170,15 @@ void AudioController::OpenAudio(agi::fs::path const& url)
}
CloseAudio();
provider = new_provider;
provider = std::move(new_provider);
try
{
player = AudioPlayerFactory::GetAudioPlayer(provider);
player = AudioPlayerFactory::GetAudioPlayer(provider.get());
}
catch (...)
{
delete provider;
provider = 0;
provider.reset();
throw;
}
@ -192,7 +188,7 @@ void AudioController::OpenAudio(agi::fs::path const& url)
try
{
AnnounceAudioOpen(provider);
AnnounceAudioOpen(provider.get());
}
catch (...)
{
@ -205,8 +201,8 @@ void AudioController::CloseAudio()
{
Stop();
delete player;
delete provider;
player.reset();
provider.reset();
player = 0;
provider = 0;

View File

@ -86,10 +86,10 @@ class AudioController : public wxEvtHandler {
agi::signal::Signal<> AnnounceTimingControllerChanged;
/// The audio output object
AudioPlayer *player;
std::unique_ptr<AudioPlayer> player;
/// The audio provider
AudioProvider *provider;
std::unique_ptr<AudioProvider> provider;
/// The current timing mode, if any; owned by the audio controller
std::unique_ptr<AudioTimingController> timing_controller;

View File

@ -37,12 +37,6 @@
#include "audio_display.h"
#include <algorithm>
#include <wx/dcbuffer.h>
#include <wx/dcclient.h>
#include <wx/mousestate.h>
#include "ass_time.h"
#include "audio_colorscheme.h"
#include "audio_controller.h"
@ -59,6 +53,14 @@
#include "utils.h"
#include "video_context.h"
#include <libaegisub/util.h>
#include <algorithm>
#include <wx/dcbuffer.h>
#include <wx/dcclient.h>
#include <wx/mousestate.h>
/// @brief Colourscheme-based UI colour provider
///
/// This class provides UI colours corresponding to the supplied audio colour
@ -729,7 +731,7 @@ void AudioDisplay::ReloadRenderingSettings()
if (OPT_GET("Audio/Spectrum")->GetBool())
{
colour_scheme_name = OPT_GET("Colour/Audio Display/Spectrum")->GetString();
AudioSpectrumRenderer *audio_spectrum_renderer = new AudioSpectrumRenderer(colour_scheme_name);
auto audio_spectrum_renderer = agi::util::make_unique<AudioSpectrumRenderer>(colour_scheme_name);
int64_t spectrum_quality = OPT_GET("Audio/Renderer/Spectrum/Quality")->GetInt();
#ifdef WITH_FFTW3
@ -746,12 +748,12 @@ void AudioDisplay::ReloadRenderingSettings()
spectrum_width[spectrum_quality],
spectrum_distance[spectrum_quality]);
audio_renderer_provider.reset(audio_spectrum_renderer);
audio_renderer_provider = std::move(audio_spectrum_renderer);
}
else
{
colour_scheme_name = OPT_GET("Colour/Audio Display/Waveform")->GetString();
audio_renderer_provider.reset(new AudioWaveformRenderer(colour_scheme_name));
audio_renderer_provider = agi::util::make_unique<AudioWaveformRenderer>(colour_scheme_name);
}
audio_renderer->SetRenderer(audio_renderer_provider.get());
@ -1061,7 +1063,7 @@ void AudioDisplay::OnMouseEvent(wxMouseEvent& event)
if (markers.size())
{
RemoveTrackCursor();
audio_marker.reset(new AudioMarkerInteractionObject(markers, timing, this, (wxMouseButton)event.GetButton()));
audio_marker = agi::util::make_unique<AudioMarkerInteractionObject>(markers, timing, this, (wxMouseButton)event.GetButton());
SetDraggedObject(audio_marker.get());
return;
}

View File

@ -33,16 +33,16 @@
/// @ingroup audio_ui
///
#include <cstdint>
#include <deque>
#include <map>
#include <cstdint>
#include <memory>
#include <wx/gdicmn.h>
#include <wx/string.h>
#include <wx/timer.h>
#include <wx/window.h>
#include <libaegisub/scoped_ptr.h>
#include <libaegisub/signal.h>
namespace agi { struct Context; }
@ -105,22 +105,22 @@ class AudioDisplay: public wxWindow {
agi::Context *context;
/// The audio renderer manager
agi::scoped_ptr<AudioRenderer> audio_renderer;
std::unique_ptr<AudioRenderer> audio_renderer;
/// The current audio renderer
agi::scoped_ptr<AudioRendererBitmapProvider> audio_renderer_provider;
std::unique_ptr<AudioRendererBitmapProvider> audio_renderer_provider;
/// The controller managing us
AudioController *controller;
/// Scrollbar helper object
agi::scoped_ptr<AudioDisplayScrollbar> scrollbar;
std::unique_ptr<AudioDisplayScrollbar> scrollbar;
/// Timeline helper object
agi::scoped_ptr<AudioDisplayTimeline> timeline;
std::unique_ptr<AudioDisplayTimeline> timeline;
/// The interaction object for the last-dragged audio marker
agi::scoped_ptr<AudioMarkerInteractionObject> audio_marker;
std::unique_ptr<AudioMarkerInteractionObject> audio_marker;
/// Current object on display being dragged, if any

View File

@ -28,6 +28,8 @@
#include "pen.h"
#include "video_context.h"
#include <libaegisub/util.h>
#include <algorithm>
class AudioMarkerKeyframe : public AudioMarker {
@ -123,7 +125,7 @@ void VideoPositionMarkerProvider::Update(int frame_number) {
void VideoPositionMarkerProvider::OptChanged(agi::OptionValue const& opt) {
if (opt.GetBool()) {
video_seek_slot.Unblock();
marker.reset(new VideoPositionMarker);
marker = agi::util::make_unique<VideoPositionMarker>();
marker->SetPosition(vc->GetFrameN());
}
else {

View File

@ -21,9 +21,9 @@
#pragma once
#include <libaegisub/scoped_ptr.h>
#include <libaegisub/signal.h>
#include <memory>
#include <vector>
#include <wx/string.h>
@ -135,7 +135,7 @@ class AudioMarkerProviderKeyframes : public AudioMarkerProvider {
std::vector<AudioMarkerKeyframe> markers;
/// Pen used for all keyframe markers, stored here for performance reasons
agi::scoped_ptr<Pen> style;
std::unique_ptr<Pen> style;
/// Regenerate the list of markers
void Update();
@ -158,7 +158,7 @@ public:
class VideoPositionMarkerProvider : public AudioMarkerProvider {
VideoContext *vc;
agi::scoped_ptr<VideoPositionMarker> marker;
std::unique_ptr<VideoPositionMarker> marker;
agi::signal::Connection video_seek_slot;
agi::signal::Connection enable_opt_changed_slot;
@ -188,7 +188,7 @@ class SecondsMarkerProvider : public AudioMarkerProvider {
};
/// Pen used by all seconds markers, here for performance
agi::scoped_ptr<Pen> pen;
std::unique_ptr<Pen> pen;
/// Markers returned from last call to GetMarkers
mutable std::vector<Marker> markers;

View File

@ -51,7 +51,7 @@ AudioPlayer::AudioPlayer(AudioProvider *provider)
{
}
AudioPlayer* AudioPlayerFactory::GetAudioPlayer(AudioProvider *provider) {
std::unique_ptr<AudioPlayer> AudioPlayerFactory::GetAudioPlayer(AudioProvider *provider) {
std::vector<std::string> list = GetClasses(OPT_GET("Audio/Player")->GetString());
if (list.empty()) throw agi::NoAudioPlayersError("No audio players are available.", 0);
@ -88,5 +88,3 @@ void AudioPlayerFactory::RegisterProviders() {
Register<OSSPlayer>("OSS");
#endif
}
template<> AudioPlayerFactory::map *FactoryBase<AudioPlayer *(*)(AudioProvider*)>::classes = nullptr;

View File

@ -35,12 +35,6 @@
#include "config.h"
#ifdef WITH_DIRECTSOUND
#include <mmsystem.h>
#include <process.h>
#include <dsound.h>
#include <libaegisub/log.h>
#include "audio_player_dsound2.h"
#include "audio_controller.h"
@ -50,6 +44,14 @@
#include "options.h"
#include "utils.h"
#include <libaegisub/scoped_ptr.h>
#include <libaegisub/log.h>
#include <libaegisub/util.h>
#include <mmsystem.h>
#include <process.h>
#include <dsound.h>
/// @brief RAII support class to init and de-init the COM library
struct COMInitialization {
@ -812,7 +814,7 @@ DirectSoundPlayer2::DirectSoundPlayer2(AudioProvider *provider)
try
{
thread.reset(new DirectSoundPlayer2Thread(provider, WantedLatency, BufferLength));
thread = agi::util::make_unique<DirectSoundPlayer2Thread>(provider, WantedLatency, BufferLength);
}
catch (const char *msg)
{

View File

@ -36,8 +36,6 @@
#include "include/aegisub/audio_player.h"
#include <libaegisub/scoped_ptr.h>
class DirectSoundPlayer2Thread;
/// @class DirectSoundPlayer2
@ -48,7 +46,7 @@ class DirectSoundPlayer2Thread;
/// send commands to the playback thread.
class DirectSoundPlayer2 : public AudioPlayer {
/// The playback thread
agi::scoped_ptr<DirectSoundPlayer2Thread> thread;
std::unique_ptr<DirectSoundPlayer2Thread> thread;
/// Desired length in milliseconds to write ahead of the playback cursor
int WantedLatency;

View File

@ -52,6 +52,7 @@
#include <libaegisub/fs.h>
#include <libaegisub/log.h>
#include <libaegisub/util.h>
void AudioProvider::GetAudioWithVolume(void *buf, int64_t start, int64_t count, double volume) const {
GetAudio(buf, start, count);
@ -116,9 +117,9 @@ struct provider_creator {
provider_creator() : found_file(false) , found_audio(false) { }
template<typename Factory>
AudioProvider *try_create(std::string const& name, Factory&& create) {
std::unique_ptr<AudioProvider> try_create(std::string const& name, Factory&& create) {
try {
AudioProvider *provider = create();
std::unique_ptr<AudioProvider> provider = create();
if (provider)
LOG_I("audio_provider") << "Using audio provider: " << name;
return provider;
@ -144,11 +145,13 @@ struct provider_creator {
};
}
AudioProvider *AudioProviderFactory::GetProvider(agi::fs::path const& filename) {
std::unique_ptr<AudioProvider> AudioProviderFactory::GetProvider(agi::fs::path const& filename) {
provider_creator creator;
AudioProvider *provider = nullptr;
std::unique_ptr<AudioProvider> provider;
provider = creator.try_create("Dummy audio provider", [&]() { return new DummyAudioProvider(filename); });
provider = creator.try_create("Dummy audio provider", [&]() {
return agi::util::make_unique<DummyAudioProvider>(filename);
});
// Try a PCM provider first
if (!provider && !OPT_GET("Provider/Audio/PCM/Disable")->GetBool())
@ -176,20 +179,20 @@ AudioProvider *AudioProviderFactory::GetProvider(agi::fs::path const& filename)
// Give it a converter if needed
if (provider->GetBytesPerSample() != 2 || provider->GetSampleRate() < 32000 || provider->GetChannels() != 1)
provider = CreateConvertAudioProvider(provider);
provider = CreateConvertAudioProvider(std::move(provider));
// Change provider to RAM/HD cache if needed
int cache = OPT_GET("Audio/Cache/Type")->GetInt();
if (!cache || !needsCache)
return new LockAudioProvider(provider);
return agi::util::make_unique<LockAudioProvider>(std::move(provider));
DialogProgress progress(wxGetApp().frame, _("Load audio"));
// Convert to RAM
if (cache == 1) return new RAMAudioProvider(provider, &progress);
if (cache == 1) return agi::util::make_unique<RAMAudioProvider>(std::move(provider), &progress);
// Convert to HD
if (cache == 2) return new HDAudioProvider(provider, &progress);
if (cache == 2) return agi::util::make_unique<HDAudioProvider>(std::move(provider), &progress);
throw agi::AudioCacheOpenError("Unknown caching method", 0);
}
@ -202,5 +205,3 @@ void AudioProviderFactory::RegisterProviders() {
Register<FFmpegSourceAudioProvider>("FFmpegSource");
#endif
}
template<> AudioProviderFactory::map *FactoryBase<AudioProvider *(*)(agi::fs::path)>::classes = nullptr;

View File

@ -27,17 +27,19 @@
#include "audio_controller.h"
#include "include/aegisub/audio_provider.h"
#include <libaegisub/scoped_ptr.h>
#include <libaegisub/log.h>
#include <libaegisub/util.h>
#include <limits>
/// Base class for all wrapping converters
class AudioProviderConverter : public AudioProvider {
protected:
agi::scoped_ptr<AudioProvider> source;
std::unique_ptr<AudioProvider> source;
public:
AudioProviderConverter(AudioProvider *src) : source(src) {
AudioProviderConverter(std::unique_ptr<AudioProvider>&& src)
: source(std::move(src))
{
channels = source->GetChannels();
num_samples = source->GetNumSamples();
sample_rate = source->GetSampleRate();
@ -55,11 +57,11 @@ class BitdepthConvertAudioProvider : public AudioProviderConverter {
int src_bytes_per_sample;
bool src_is_native_endian;
public:
BitdepthConvertAudioProvider(AudioProvider *src) : AudioProviderConverter(src) {
BitdepthConvertAudioProvider(std::unique_ptr<AudioProvider>&& src) : AudioProviderConverter(std::move(src)) {
if (bytes_per_sample > 8)
throw agi::AudioProviderOpenError("Audio format converter: audio with bitdepths greater than 64 bits/sample is currently unsupported", 0);
src_is_native_endian = src->AreSamplesNativeEndian();
src_is_native_endian = source->AreSamplesNativeEndian();
src_bytes_per_sample = bytes_per_sample;
bytes_per_sample = sizeof(Target);
}
@ -110,8 +112,8 @@ public:
template<class Source, class Target>
class FloatConvertAudioProvider : public AudioProviderConverter {
public:
FloatConvertAudioProvider(AudioProvider *src) : AudioProviderConverter(src) {
if (!src->AreSamplesNativeEndian())
FloatConvertAudioProvider(std::unique_ptr<AudioProvider>&& src) : AudioProviderConverter(std::move(src)) {
if (!source->AreSamplesNativeEndian())
throw agi::AudioProviderOpenError("Audio format converter: Float audio with non-native endianness is currently unsupported.", 0);
bytes_per_sample = sizeof(Target);
float_samples = false;
@ -144,7 +146,7 @@ public:
class DownmixAudioProvider : public AudioProviderConverter {
int src_channels;
public:
DownmixAudioProvider(AudioProvider *src) : AudioProviderConverter(src) {
DownmixAudioProvider(std::unique_ptr<AudioProvider>&& src) : AudioProviderConverter(std::move(src)) {
if (bytes_per_sample != 2)
throw agi::InternalError("DownmixAudioProvider requires 16-bit input", 0);
if (channels == 1)
@ -170,14 +172,14 @@ public:
}
};
/// Sample doubler with linear interpolation for the new samples
/// Sample doubler with linear interpolation for the agi::util::make_unique<samples>
/// Requires 16-bit mono input
class SampleDoublingAudioProvider : public AudioProviderConverter {
public:
SampleDoublingAudioProvider(AudioProvider *src) : AudioProviderConverter(src) {
if (src->GetBytesPerSample() != 2)
SampleDoublingAudioProvider(std::unique_ptr<AudioProvider>&& src) : AudioProviderConverter(std::move(src)) {
if (source->GetBytesPerSample() != 2)
throw agi::InternalError("UpsampleAudioProvider requires 16-bit input", 0);
if (src->GetChannels() != 1)
if (source->GetChannels() != 1)
throw agi::InternalError("UpsampleAudioProvider requires mono input", 0);
sample_rate *= 2;
@ -210,33 +212,31 @@ public:
}
};
AudioProvider *CreateConvertAudioProvider(AudioProvider *source_provider) {
AudioProvider *provider = source_provider;
std::unique_ptr<AudioProvider> CreateConvertAudioProvider(std::unique_ptr<AudioProvider>&& provider) {
// Ensure 16-bit audio with proper endianness
if (provider->AreSamplesFloat()) {
LOG_D("audio_provider") << "Converting float to S16";
if (provider->GetBytesPerSample() == sizeof(float))
provider = new FloatConvertAudioProvider<float, int16_t>(provider);
provider = agi::util::make_unique<FloatConvertAudioProvider<float, int16_t>>(std::move(provider));
else
provider = new FloatConvertAudioProvider<double, int16_t>(provider);
provider = agi::util::make_unique<FloatConvertAudioProvider<double, int16_t>>(std::move(provider));
}
if (provider->GetBytesPerSample() != 2 || !provider->AreSamplesNativeEndian()) {
LOG_D("audio_provider") << "Converting " << provider->GetBytesPerSample() << " bytes per sample or wrong endian to S16";
provider = new BitdepthConvertAudioProvider<int16_t>(provider);
provider = agi::util::make_unique<BitdepthConvertAudioProvider<int16_t>>(std::move(provider));
}
// We currently only support mono audio
if (provider->GetChannels() != 1) {
LOG_D("audio_provider") << "Downmixing to mono from " << provider->GetChannels() << " channels";
provider = new DownmixAudioProvider(provider);
provider = agi::util::make_unique<DownmixAudioProvider>(std::move(provider));
}
// Some players don't like low sample rate audio
while (provider->GetSampleRate() < 32000) {
LOG_D("audio_provider") << "Doubling sample rate";
provider = new SampleDoublingAudioProvider(provider);
provider = agi::util::make_unique<SampleDoublingAudioProvider>(std::move(provider));
}
return provider;
return std::move(provider);
}

View File

@ -19,7 +19,9 @@
/// @ingroup audio_input
///
#include <memory>
class AudioProvider;
/// Get an audio provider which supplies audio in a format supported by Aegisub's players
AudioProvider *CreateConvertAudioProvider(AudioProvider *source_provider);
std::unique_ptr<AudioProvider> CreateConvertAudioProvider(std::unique_ptr<AudioProvider>&& source_provider);

View File

@ -91,16 +91,15 @@ public:
}
HDAudioProvider::HDAudioProvider(AudioProvider *src, agi::BackgroundRunner *br) {
agi::scoped_ptr<AudioProvider> source(src);
HDAudioProvider::HDAudioProvider(std::unique_ptr<AudioProvider>&& src, agi::BackgroundRunner *br) {
assert(src->AreSamplesNativeEndian()); // Byteswapping should be done before caching
bytes_per_sample = source->GetBytesPerSample();
num_samples = source->GetNumSamples();
channels = source->GetChannels();
sample_rate = source->GetSampleRate();
filename = source->GetFilename();
float_samples = source->AreSamplesFloat();
bytes_per_sample = src->GetBytesPerSample();
num_samples = src->GetNumSamples();
channels = src->GetChannels();
sample_rate = src->GetSampleRate();
filename = src->GetFilename();
float_samples = src->AreSamplesFloat();
// Check free space
if ((uint64_t)num_samples * channels * bytes_per_sample > agi::fs::FreeSpace(cache_dir()))
@ -111,9 +110,9 @@ HDAudioProvider::HDAudioProvider(AudioProvider *src, agi::BackgroundRunner *br)
try {
{
agi::io::Save out(diskCacheFilename, true);
br->Run(bind(&HDAudioProvider::FillCache, this, src, &out.Get(), std::placeholders::_1));
br->Run(bind(&HDAudioProvider::FillCache, this, src.get(), &out.Get(), std::placeholders::_1));
}
cache_provider.reset(new RawAudioProvider(diskCacheFilename, src));
cache_provider = agi::util::make_unique<RawAudioProvider>(diskCacheFilename, src.get());
}
catch (...) {
agi::fs::Remove(diskCacheFilename);

View File

@ -34,8 +34,6 @@
#include "include/aegisub/audio_provider.h"
#include <libaegisub/scoped_ptr.h>
namespace agi {
class BackgroundRunner;
class ProgressSink;
@ -45,7 +43,7 @@ class HDAudioProvider : public AudioProvider {
/// Name of the file which the decoded audio is written to
agi::fs::path diskCacheFilename;
/// Audio provider which reads from the decoded cache
agi::scoped_ptr<AudioProvider> cache_provider;
std::unique_ptr<AudioProvider> cache_provider;
/// Fill the cache with all of the data from the source audio provider
/// @param src Audio data to cache
@ -56,7 +54,7 @@ class HDAudioProvider : public AudioProvider {
void FillBuffer(void *buf, int64_t start, int64_t count) const;
public:
HDAudioProvider(AudioProvider *source, agi::BackgroundRunner *br);
HDAudioProvider(std::unique_ptr<AudioProvider>&& source, agi::BackgroundRunner *br);
~HDAudioProvider();
bool AreSamplesNativeEndian() const { return true; }

View File

@ -20,7 +20,9 @@
#include "audio_provider_lock.h"
LockAudioProvider::LockAudioProvider(AudioProvider *source) : source(source) {
LockAudioProvider::LockAudioProvider(std::unique_ptr<AudioProvider>&& source)
: source(std::move(source))
{
channels = source->GetChannels();
num_samples = source->GetNumSamples();
sample_rate = source->GetSampleRate();

View File

@ -27,6 +27,6 @@ class LockAudioProvider : public AudioProvider {
void FillBuffer(void *buf, int64_t start, int64_t count) const;
public:
LockAudioProvider(AudioProvider *source);
LockAudioProvider(std::unique_ptr<AudioProvider>&& source);
bool AreSamplesNativeEndian() const { return source->AreSamplesNativeEndian(); }
};

View File

@ -42,6 +42,7 @@
#include <libaegisub/fs.h>
#include <libaegisub/log.h>
#include <libaegisub/util.h>
#include <cassert>
#include <cstdint>
@ -487,12 +488,12 @@ public:
}
};
AudioProvider *CreatePCMAudioProvider(agi::fs::path const& filename) {
std::unique_ptr<AudioProvider> CreatePCMAudioProvider(agi::fs::path const& filename) {
bool wrong_file_type = true;
std::string msg;
try {
return new RiffWavPCMAudioProvider(filename);
return agi::util::make_unique<RiffWavPCMAudioProvider>(filename);
}
catch (agi::AudioDataNotFoundError const& err) {
msg = "RIFF PCM WAV audio provider: " + err.GetMessage();
@ -503,7 +504,7 @@ AudioProvider *CreatePCMAudioProvider(agi::fs::path const& filename) {
}
try {
return new Wave64AudioProvider(filename);
return agi::util::make_unique<Wave64AudioProvider>(filename);
}
catch (agi::AudioDataNotFoundError const& err) {
msg += "\nWave64 audio provider: " + err.GetMessage();

View File

@ -81,4 +81,4 @@ protected:
};
// Construct the right PCM audio provider (if any) for the file
AudioProvider *CreatePCMAudioProvider(agi::fs::path const& filename);
std::unique_ptr<AudioProvider> CreatePCMAudioProvider(agi::fs::path const& filename);

View File

@ -42,14 +42,11 @@
#include "utils.h"
#include <libaegisub/background_runner.h>
#include <libaegisub/scoped_ptr.h>
#define CacheBits 22
#define CacheBlockSize (1 << CacheBits)
RAMAudioProvider::RAMAudioProvider(AudioProvider *src, agi::BackgroundRunner *br)
{
agi::scoped_ptr<AudioProvider> source(src);
RAMAudioProvider::RAMAudioProvider(std::unique_ptr<AudioProvider>&& src, agi::BackgroundRunner *br) {
try {
blockcache.resize((src->GetNumSamples() * src->GetBytesPerSample() + CacheBlockSize - 1) >> CacheBits);
@ -59,15 +56,15 @@ RAMAudioProvider::RAMAudioProvider(AudioProvider *src, agi::BackgroundRunner *br
}
// Copy parameters
samples_native_endian = source->AreSamplesNativeEndian();
bytes_per_sample = source->GetBytesPerSample();
num_samples = source->GetNumSamples();
channels = source->GetChannels();
sample_rate = source->GetSampleRate();
filename = source->GetFilename();
float_samples = source->AreSamplesFloat();
samples_native_endian = src->AreSamplesNativeEndian();
bytes_per_sample = src->GetBytesPerSample();
num_samples = src->GetNumSamples();
channels = src->GetChannels();
sample_rate = src->GetSampleRate();
filename = src->GetFilename();
float_samples = src->AreSamplesFloat();
br->Run(std::bind(&RAMAudioProvider::FillCache, this, src, std::placeholders::_1));
br->Run(std::bind(&RAMAudioProvider::FillCache, this, src.get(), std::placeholders::_1));
}
void RAMAudioProvider::FillCache(AudioProvider *source, agi::ProgressSink *ps) {

View File

@ -54,7 +54,7 @@ class RAMAudioProvider : public AudioProvider {
void FillBuffer(void *buf, int64_t start, int64_t count) const;
public:
RAMAudioProvider(AudioProvider *source, agi::BackgroundRunner *br);
RAMAudioProvider(std::unique_ptr<AudioProvider>&& source, agi::BackgroundRunner *br);
bool AreSamplesNativeEndian() const { return samples_native_endian; }
};

View File

@ -45,11 +45,6 @@
#include "include/aegisub/audio_provider.h"
template<class C, class F> static void for_each(C &container, F const& func)
{
std::for_each(container.begin(), container.end(), func);
}
using std::placeholders::_1;
AudioRendererBitmapCacheBitmapFactory::AudioRendererBitmapCacheBitmapFactory(AudioRenderer *renderer)
@ -176,7 +171,7 @@ void AudioRenderer::ResetBlockCount()
double duration = provider->GetNumSamples() * 1000.0 / provider->GetSampleRate();
size_t rendered_width = (size_t)ceil(duration / pixel_ms);
cache_numblocks = rendered_width / cache_bitmap_width;
for_each(bitmaps, std::bind(&AudioRendererBitmapCache::SetBlockCount, _1, cache_numblocks));
for (auto& bmp : bitmaps) bmp.SetBlockCount(cache_numblocks);
}
}
@ -247,7 +242,7 @@ void AudioRenderer::Render(wxDC &dc, wxPoint origin, int start, int length, Audi
void AudioRenderer::Invalidate()
{
for_each(bitmaps, std::bind(&AudioRendererBitmapCache::Age, _1, 0));
for (auto& bmp : bitmaps) bmp.Age(0);
needs_age = false;
}

View File

@ -50,6 +50,7 @@
#include <libaegisub/dispatch.h>
#include <libaegisub/fs.h>
#include <libaegisub/path.h>
#include <libaegisub/util.h>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/trim.hpp>
@ -178,12 +179,6 @@ namespace Automation4 {
ExportFilter::ExportFilter(std::string const& name, std::string const& description, int priority)
: AssExportFilter(name, description, priority)
{
AssExportFilterChain::Register(this);
}
ExportFilter::~ExportFilter()
{
AssExportFilterChain::Unregister(this);
}
std::string ExportFilter::GetScriptSettingsIdentifier()
@ -293,47 +288,41 @@ namespace Automation4 {
// ScriptManager
ScriptManager::~ScriptManager()
{
delete_clear(scripts);
}
void ScriptManager::Add(Script *script)
void ScriptManager::Add(std::unique_ptr<Script>&& script)
{
if (find(scripts.begin(), scripts.end(), script) == scripts.end())
scripts.push_back(script);
scripts.emplace_back(std::move(script));
ScriptsChanged();
}
void ScriptManager::Remove(Script *script)
{
auto i = find(scripts.begin(), scripts.end(), script);
if (i != scripts.end()) {
delete *i;
auto i = find_if(scripts.begin(), scripts.end(), [&](std::unique_ptr<Script> const& s) { return s.get() == script; });
if (i != scripts.end())
scripts.erase(i);
}
ScriptsChanged();
}
void ScriptManager::RemoveAll()
{
delete_clear(scripts);
scripts.clear();
ScriptsChanged();
}
void ScriptManager::Reload(Script *script)
{
if (find(scripts.begin(), scripts.end(), script) != scripts.end())
{
script->Reload();
ScriptsChanged();
}
script->Reload();
ScriptsChanged();
}
const std::vector<cmd::Command*>& ScriptManager::GetMacros()
{
macros.clear();
for (auto script : scripts) {
for (auto& script : scripts) {
std::vector<cmd::Command*> sfs = script->GetMacros();
copy(sfs.begin(), sfs.end(), back_inserter(macros));
}
@ -349,7 +338,7 @@ namespace Automation4 {
void AutoloadScriptManager::Reload()
{
delete_clear(scripts);
scripts.clear();
int error_count = 0;
@ -359,10 +348,10 @@ namespace Automation4 {
if (!agi::fs::DirectoryExists(dirname)) continue;
for (auto filename : agi::fs::DirectoryIterator(dirname, "*.*")) {
Script *s = ScriptFactory::CreateFromFile(dirname/filename, false, false);
auto s = ScriptFactory::CreateFromFile(dirname/filename, false, false);
if (s) {
scripts.push_back(s);
if (!s->GetLoadedState()) ++error_count;
scripts.emplace_back(std::move(s));
}
}
}
@ -386,7 +375,7 @@ namespace Automation4 {
void LocalScriptManager::Reload()
{
delete_clear(scripts);
scripts.clear();
auto local_scripts = context->ass->GetScriptInfo("Automation Scripts");
if (local_scripts.empty()) {
@ -415,7 +404,7 @@ namespace Automation4 {
}
auto sfname = basepath/trimmed;
if (agi::fs::FileExists(sfname))
scripts.push_back(Automation4::ScriptFactory::CreateFromFile(sfname, true));
scripts.emplace_back(Automation4::ScriptFactory::CreateFromFile(sfname, true));
else {
wxLogWarning("Automation Script referenced could not be found.\nFilename specified: %c%s\nSearched relative to: %s\nResolved filename: %s",
first_char, to_wx(trimmed), basepath.wstring(), sfname.wstring());
@ -436,7 +425,7 @@ namespace Automation4 {
std::string scripts_string;
agi::fs::path autobasefn(OPT_GET("Path/Automation/Base")->GetString());
for (auto script : GetScripts()) {
for (auto& script : GetScripts()) {
if (!scripts_string.empty())
scripts_string += "|";
@ -464,27 +453,18 @@ namespace Automation4 {
{
}
void ScriptFactory::Register(ScriptFactory *factory)
void ScriptFactory::Register(std::unique_ptr<ScriptFactory>&& factory)
{
if (find(Factories().begin(), Factories().end(), factory) != Factories().end())
throw agi::InternalError("Automation 4: Attempt to register the same script factory multiple times. This should never happen.", 0);
Factories().push_back(factory);
Factories().emplace_back(std::move(factory));
}
void ScriptFactory::Unregister(ScriptFactory *factory)
std::unique_ptr<Script> ScriptFactory::CreateFromFile(agi::fs::path const& filename, bool complain_about_unrecognised, bool create_unknown)
{
auto i = find(Factories().begin(), Factories().end(), factory);
if (i != Factories().end()) {
delete *i;
Factories().erase(i);
}
}
Script* ScriptFactory::CreateFromFile(agi::fs::path const& filename, bool complain_about_unrecognised, bool create_unknown)
{
for (auto factory : Factories()) {
Script *s = factory->Produce(filename);
for (auto& factory : Factories()) {
auto s = factory->Produce(filename);
if (s) {
if (!s->GetLoadedState()) {
wxLogError(_("An Automation script failed to load. File name: '%s', error reported: %s"), filename.wstring(), s->GetDescription());
@ -497,16 +477,16 @@ namespace Automation4 {
wxLogError(_("The file was not recognised as an Automation script: %s"), filename.wstring());
}
return create_unknown ? new UnknownScript(filename) : nullptr;
return create_unknown ? agi::util::make_unique<UnknownScript>(filename) : nullptr;
}
std::vector<ScriptFactory*>& ScriptFactory::Factories()
std::vector<std::unique_ptr<ScriptFactory>>& ScriptFactory::Factories()
{
static std::vector<ScriptFactory*> factories;
static std::vector<std::unique_ptr<ScriptFactory>> factories;
return factories;
}
const std::vector<ScriptFactory*>& ScriptFactory::GetFactories()
const std::vector<std::unique_ptr<ScriptFactory>>& ScriptFactory::GetFactories()
{
return Factories();
}
@ -514,7 +494,7 @@ namespace Automation4 {
std::string ScriptFactory::GetWildcardStr()
{
std::string fnfilter, catchall;
for (auto fact : Factories()) {
for (auto& fact : Factories()) {
if (fact->GetEngineName().empty() || fact->GetFilenamePattern().empty())
continue;

View File

@ -80,7 +80,6 @@ namespace Automation4 {
public:
ExportFilter(std::string const& name, std::string const& description, int priority);
virtual ~ExportFilter();
wxWindow* GetConfigDialogWindow(wxWindow *parent, agi::Context *c);
void LoadSettings(bool is_default, agi::Context *c);
@ -189,7 +188,7 @@ namespace Automation4 {
/// A manager of loaded automation scripts
class ScriptManager {
protected:
std::vector<Script*> scripts;
std::vector<std::unique_ptr<Script>> scripts;
std::vector<cmd::Command*> macros;
agi::signal::Signal<> ScriptsChanged;
@ -197,8 +196,8 @@ namespace Automation4 {
public:
/// Deletes all scripts managed
virtual ~ScriptManager();
/// Add a script to the manager. The ScriptManager takes ownership of the script and will automatically delete it.
void Add(Script *script);
/// Add a script to the manager.
void Add(std::unique_ptr<Script>&& script);
/// Remove a script from the manager, and delete the Script object.
void Remove(Script *script);
/// Deletes all scripts managed
@ -209,7 +208,7 @@ namespace Automation4 {
virtual void Reload(Script *script);
/// Get all managed scripts (both loaded and invalid)
const std::vector<Script*>& GetScripts() const { return scripts; }
const std::vector<std::unique_ptr<Script>>& GetScripts() const { return scripts; }
const std::vector<cmd::Command*>& GetMacros();
// No need to have getters for the other kinds of features, I think.
@ -250,24 +249,23 @@ namespace Automation4 {
///
/// This is private as it should only ever be called through
/// CreateFromFile
virtual Script* Produce(agi::fs::path const& filename) const = 0;
virtual std::unique_ptr<Script> Produce(agi::fs::path const& filename) const = 0;
static inline std::vector<ScriptFactory*>& Factories();
static std::vector<std::unique_ptr<ScriptFactory>>& Factories();
protected:
ScriptFactory(std::string const& engine_name, std::string const& filename_pattern);
virtual ~ScriptFactory() { }
public:
virtual ~ScriptFactory() { }
/// Name of this automation engine
const std::string& GetEngineName() const { return engine_name; }
/// Extension which this engine supports
const std::string& GetFilenamePattern() const { return filename_pattern; }
/// Register an automation engine. Calling code retains ownership of pointer
static void Register(ScriptFactory *factory);
/// Unregister and delete an automation engine
static void Unregister(ScriptFactory *factory);
/// Register an automation engine.
static void Register(std::unique_ptr<ScriptFactory>&& factory);
/// Get the full wildcard string for all loaded engines
static std::string GetWildcardStr();
@ -276,9 +274,9 @@ namespace Automation4 {
/// @param filename Script to load
/// @param complain_about_unrecognised Should an error be displayed for files that aren't automation scripts?
/// @param create_unknown Create a placeholder rather than returning nullptr if no script engine supports the file
static Script* CreateFromFile(agi::fs::path const& filename, bool complain_about_unrecognised, bool create_unknown=true);
static std::unique_ptr<Script> CreateFromFile(agi::fs::path const& filename, bool complain_about_unrecognised, bool create_unknown=true);
static const std::vector<ScriptFactory*>& GetFactories();
static const std::vector<std::unique_ptr<ScriptFactory>>& GetFactories();
};
/// A script which represents a file not recognized by any registered

View File

@ -53,7 +53,7 @@
#include <libaegisub/access.h>
#include <libaegisub/path.h>
#include <libaegisub/scoped_ptr.h>
#include <libaegisub/util.h>
#include <algorithm>
#include <boost/algorithm/string/classification.hpp>
@ -272,7 +272,7 @@ namespace {
luaL_argcheck(L, lua_isstring(L, 2), 2, "");
lua_pushvalue(L, 1);
agi::scoped_ptr<AssEntry> et(Automation4::LuaAssFile::LuaToAssEntry(L));
std::unique_ptr<AssEntry> et(Automation4::LuaAssFile::LuaToAssEntry(L));
AssStyle *st = dynamic_cast<AssStyle*>(et.get());
lua_pop(L, 1);
if (!st)
@ -657,7 +657,7 @@ namespace Automation4 {
// LuaFeatureMacro
int LuaCommand::LuaRegister(lua_State *L)
{
cmd::reg(new LuaCommand(L));
cmd::reg(agi::util::make_unique<LuaCommand>(L));
return 0;
}
@ -900,8 +900,7 @@ namespace Automation4 {
int LuaExportFilter::LuaRegister(lua_State *L)
{
(void)new LuaExportFilter(L);
AssExportFilterChain::Register(agi::util::make_unique<LuaExportFilter>(L));
return 0;
}
@ -974,13 +973,12 @@ namespace Automation4 {
LuaScriptFactory::LuaScriptFactory()
: ScriptFactory("Lua", "*.lua,*.moon")
{
Register(this);
}
Script* LuaScriptFactory::Produce(agi::fs::path const& filename) const
std::unique_ptr<Script> LuaScriptFactory::Produce(agi::fs::path const& filename) const
{
if (agi::fs::HasExtension(filename, "lua") || agi::fs::HasExtension(filename, "moon"))
return new LuaScript(filename);
return agi::util::make_unique<LuaScript>(filename);
return nullptr;
}
}

View File

@ -32,15 +32,15 @@
/// @ingroup scripting
///
#include "auto4_base.h"
#include "command/command.h"
#include <deque>
#include <wx/event.h>
#include <wx/thread.h>
#include "auto4_base.h"
#include "command/command.h"
class AssEntry;
class wxWindow;
struct lua_State;
@ -241,8 +241,8 @@ namespace Automation4 {
wxString help;
int cmd_type;
LuaCommand(lua_State *L);
public:
LuaCommand(lua_State *L);
~LuaCommand();
const char* name() const { return cmd_name.c_str(); }
@ -264,13 +264,11 @@ namespace Automation4 {
LuaDialog *config_dialog;
protected:
LuaExportFilter(lua_State *L);
ScriptDialog* GenerateConfigDialog(wxWindow *parent, agi::Context *c);
public:
static int LuaRegister(lua_State *L);
virtual ~LuaExportFilter() { }
public:
LuaExportFilter(lua_State *L);
static int LuaRegister(lua_State *L);
void ProcessSubs(AssFile *subs, wxWindow *export_dialog);
};

View File

@ -36,7 +36,7 @@
namespace Automation4 {
class LuaScriptFactory : public ScriptFactory {
Script* Produce(agi::fs::path const& filename) const;
std::unique_ptr<Script> Produce(agi::fs::path const& filename) const override;
public:
LuaScriptFactory();
};

View File

@ -41,6 +41,7 @@
#include "command.h"
#include <libaegisub/log.h>
#include <libaegisub/util.h>
#include "../audio_controller.h"
#include "../compat.h"
@ -297,20 +298,20 @@ struct app_updates : public Command {
namespace cmd {
void init_app() {
reg(new app_about);
reg(new app_display_audio_subs);
reg(new app_display_full);
reg(new app_display_subs);
reg(new app_display_video_subs);
reg(new app_exit);
reg(new app_language);
reg(new app_log);
reg(new app_new_window);
reg(new app_options);
reg(new app_toggle_global_hotkeys);
reg(new app_toggle_toolbar);
reg(agi::util::make_unique<app_about>());
reg(agi::util::make_unique<app_display_audio_subs>());
reg(agi::util::make_unique<app_display_full>());
reg(agi::util::make_unique<app_display_subs>());
reg(agi::util::make_unique<app_display_video_subs>());
reg(agi::util::make_unique<app_exit>());
reg(agi::util::make_unique<app_language>());
reg(agi::util::make_unique<app_log>());
reg(agi::util::make_unique<app_new_window>());
reg(agi::util::make_unique<app_options>());
reg(agi::util::make_unique<app_toggle_global_hotkeys>());
reg(agi::util::make_unique<app_toggle_toolbar>());
#ifdef WITH_UPDATE_CHECKER
reg(new app_updates);
reg(agi::util::make_unique<app_updates>());
#endif
}
}

View File

@ -50,6 +50,8 @@
#include "../utils.h"
#include "../video_context.h"
#include <libaegisub/util.h>
#include <wx/msgdlg.h>
namespace {
@ -587,36 +589,36 @@ struct audio_karaoke : public Command {
namespace cmd {
void init_audio() {
reg(new audio_autocommit);
reg(new audio_autonext);
reg(new audio_autoscroll);
reg(new audio_close);
reg(new audio_commit);
reg(new audio_commit_default);
reg(new audio_commit_next);
reg(new audio_commit_stay);
reg(new audio_go_to);
reg(new audio_karaoke);
reg(new audio_open);
reg(new audio_open_blank);
reg(new audio_open_noise);
reg(new audio_open_video);
reg(new audio_play_after);
reg(new audio_play_before);
reg(new audio_play_begin);
reg(new audio_play_end);
reg(new audio_play_current_selection);
reg(new audio_play_current_line);
reg(new audio_play_selection);
reg(new audio_play_to_end);
reg(new audio_play_toggle);
reg(new audio_save_clip);
reg(new audio_scroll_left);
reg(new audio_scroll_right);
reg(new audio_stop);
reg(new audio_toggle_spectrum);
reg(new audio_vertical_link);
reg(new audio_view_spectrum);
reg(new audio_view_waveform);
reg(agi::util::make_unique<audio_autocommit>());
reg(agi::util::make_unique<audio_autonext>());
reg(agi::util::make_unique<audio_autoscroll>());
reg(agi::util::make_unique<audio_close>());
reg(agi::util::make_unique<audio_commit>());
reg(agi::util::make_unique<audio_commit_default>());
reg(agi::util::make_unique<audio_commit_next>());
reg(agi::util::make_unique<audio_commit_stay>());
reg(agi::util::make_unique<audio_go_to>());
reg(agi::util::make_unique<audio_karaoke>());
reg(agi::util::make_unique<audio_open>());
reg(agi::util::make_unique<audio_open_blank>());
reg(agi::util::make_unique<audio_open_noise>());
reg(agi::util::make_unique<audio_open_video>());
reg(agi::util::make_unique<audio_play_after>());
reg(agi::util::make_unique<audio_play_before>());
reg(agi::util::make_unique<audio_play_begin>());
reg(agi::util::make_unique<audio_play_end>());
reg(agi::util::make_unique<audio_play_current_selection>());
reg(agi::util::make_unique<audio_play_current_line>());
reg(agi::util::make_unique<audio_play_selection>());
reg(agi::util::make_unique<audio_play_to_end>());
reg(agi::util::make_unique<audio_play_toggle>());
reg(agi::util::make_unique<audio_save_clip>());
reg(agi::util::make_unique<audio_scroll_left>());
reg(agi::util::make_unique<audio_scroll_right>());
reg(agi::util::make_unique<audio_stop>());
reg(agi::util::make_unique<audio_toggle_spectrum>());
reg(agi::util::make_unique<audio_vertical_link>());
reg(agi::util::make_unique<audio_view_spectrum>());
reg(agi::util::make_unique<audio_view_waveform>());
}
}

View File

@ -49,6 +49,8 @@
#include "../utils.h"
#include "../video_context.h"
#include <libaegisub/util.h>
namespace {
using cmd::Command;
/// @defgroup cmd-am Automation commands
@ -113,9 +115,9 @@ struct meta : public Command {
namespace cmd {
void init_automation() {
reg(new meta);
reg(new open_manager);
reg(new reload_all);
reg(new reload_autoload);
reg(agi::util::make_unique<meta>());
reg(agi::util::make_unique<open_manager>());
reg(agi::util::make_unique<reload_all>());
reg(agi::util::make_unique<reload_autoload>());
}
}

View File

@ -26,8 +26,8 @@
#include <wx/intl.h>
namespace cmd {
static std::map<std::string, Command*> cmd_map;
typedef std::map<std::string, Command*>::iterator iterator;
static std::map<std::string, std::unique_ptr<Command>> cmd_map;
typedef std::map<std::string, std::unique_ptr<Command>>::iterator iterator;
static iterator find_command(std::string const& name) {
iterator it = cmd_map.find(name);
@ -36,21 +36,16 @@ namespace cmd {
return it;
}
void reg(Command *cmd) {
std::string name = cmd->name();
if (cmd_map.count(name))
delete cmd_map[name];
cmd_map[name] = cmd;
void reg(std::unique_ptr<Command>&& cmd) {
cmd_map[cmd->name()] = std::move(cmd);
}
void unreg(std::string const& name) {
iterator it = find_command(name);
delete it->second;
cmd_map.erase(it);
cmd_map.erase(find_command(name));
}
Command *get(std::string const& name) {
return find_command(name)->second;
return find_command(name)->second.get();
}
void call(std::string const& name, agi::Context*c) {
@ -108,8 +103,6 @@ namespace cmd {
}
void clear() {
for (auto& it : cmd_map)
delete it.second;
cmd_map.clear();
}
}

View File

@ -137,8 +137,8 @@ namespace cmd {
void init_builtin_commands();
/// Register a command.
/// @param cmd Command object to register. The command system takes ownership of this object.
void reg(Command *cmd);
/// @param cmd Command object to register.
void reg(std::unique_ptr<Command>&& cmd);
/// Unregister a command.
/// @param cmd Command name to unregister. The associated command object is deleted.

View File

@ -58,6 +58,7 @@
#include "../video_context.h"
#include <libaegisub/of_type_adaptor.h>
#include <libaegisub/util.h>
#include <algorithm>
#include <boost/algorithm/string/join.hpp>
@ -1008,36 +1009,36 @@ struct edit_insert_original : public Command {
namespace cmd {
void init_edit() {
reg(new edit_color_primary);
reg(new edit_color_secondary);
reg(new edit_color_outline);
reg(new edit_color_shadow);
reg(new edit_font);
reg(new edit_find_replace);
reg(new edit_line_copy);
reg(new edit_line_cut);
reg(new edit_line_delete);
reg(new edit_line_duplicate);
reg(new edit_line_duplicate_shift);
reg(new edit_line_duplicate_shift_back);
reg(new edit_line_join_as_karaoke);
reg(new edit_line_join_concatenate);
reg(new edit_line_join_keep_first);
reg(new edit_line_paste);
reg(new edit_line_paste_over);
reg(new edit_line_recombine);
reg(new edit_line_split_by_karaoke);
reg(new edit_line_split_estimate);
reg(new edit_line_split_preserve);
reg(new edit_style_bold);
reg(new edit_style_italic);
reg(new edit_style_underline);
reg(new edit_style_strikeout);
reg(new edit_redo);
reg(new edit_undo);
reg(new edit_revert);
reg(new edit_insert_original);
reg(new edit_clear);
reg(new edit_clear_text);
reg(agi::util::make_unique<edit_color_primary>());
reg(agi::util::make_unique<edit_color_secondary>());
reg(agi::util::make_unique<edit_color_outline>());
reg(agi::util::make_unique<edit_color_shadow>());
reg(agi::util::make_unique<edit_font>());
reg(agi::util::make_unique<edit_find_replace>());
reg(agi::util::make_unique<edit_line_copy>());
reg(agi::util::make_unique<edit_line_cut>());
reg(agi::util::make_unique<edit_line_delete>());
reg(agi::util::make_unique<edit_line_duplicate>());
reg(agi::util::make_unique<edit_line_duplicate_shift>());
reg(agi::util::make_unique<edit_line_duplicate_shift_back>());
reg(agi::util::make_unique<edit_line_join_as_karaoke>());
reg(agi::util::make_unique<edit_line_join_concatenate>());
reg(agi::util::make_unique<edit_line_join_keep_first>());
reg(agi::util::make_unique<edit_line_paste>());
reg(agi::util::make_unique<edit_line_paste_over>());
reg(agi::util::make_unique<edit_line_recombine>());
reg(agi::util::make_unique<edit_line_split_by_karaoke>());
reg(agi::util::make_unique<edit_line_split_estimate>());
reg(agi::util::make_unique<edit_line_split_preserve>());
reg(agi::util::make_unique<edit_style_bold>());
reg(agi::util::make_unique<edit_style_italic>());
reg(agi::util::make_unique<edit_style_underline>());
reg(agi::util::make_unique<edit_style_strikeout>());
reg(agi::util::make_unique<edit_redo>());
reg(agi::util::make_unique<edit_undo>());
reg(agi::util::make_unique<edit_revert>());
reg(agi::util::make_unique<edit_insert_original>());
reg(agi::util::make_unique<edit_clear>());
reg(agi::util::make_unique<edit_clear_text>());
}
}

View File

@ -47,6 +47,8 @@
#include "../selection_controller.h"
#include "../utils.h"
#include <libaegisub/util.h>
namespace {
using cmd::Command;
/// @defgroup cmd-grid Subtitle grid commands.
@ -429,27 +431,27 @@ struct grid_swap : public Command {
namespace cmd {
void init_grid() {
reg(new grid_line_next);
reg(new grid_line_next_create);
reg(new grid_line_prev);
reg(new grid_sort_actor);
reg(new grid_sort_effect);
reg(new grid_sort_end);
reg(new grid_sort_layer);
reg(new grid_sort_start);
reg(new grid_sort_style);
reg(new grid_sort_actor_selected);
reg(new grid_sort_effect_selected);
reg(new grid_sort_end_selected);
reg(new grid_sort_layer_selected);
reg(new grid_sort_start_selected);
reg(new grid_sort_style_selected);
reg(new grid_move_down);
reg(new grid_move_up);
reg(new grid_swap);
reg(new grid_tag_cycle_hiding);
reg(new grid_tags_hide);
reg(new grid_tags_show);
reg(new grid_tags_simplify);
reg(agi::util::make_unique<grid_line_next>());
reg(agi::util::make_unique<grid_line_next_create>());
reg(agi::util::make_unique<grid_line_prev>());
reg(agi::util::make_unique<grid_sort_actor>());
reg(agi::util::make_unique<grid_sort_effect>());
reg(agi::util::make_unique<grid_sort_end>());
reg(agi::util::make_unique<grid_sort_layer>());
reg(agi::util::make_unique<grid_sort_start>());
reg(agi::util::make_unique<grid_sort_style>());
reg(agi::util::make_unique<grid_sort_actor_selected>());
reg(agi::util::make_unique<grid_sort_effect_selected>());
reg(agi::util::make_unique<grid_sort_end_selected>());
reg(agi::util::make_unique<grid_sort_layer_selected>());
reg(agi::util::make_unique<grid_sort_start_selected>());
reg(agi::util::make_unique<grid_sort_style_selected>());
reg(agi::util::make_unique<grid_move_down>());
reg(agi::util::make_unique<grid_move_up>());
reg(agi::util::make_unique<grid_swap>());
reg(agi::util::make_unique<grid_tag_cycle_hiding>());
reg(agi::util::make_unique<grid_tags_hide>());
reg(agi::util::make_unique<grid_tags_show>());
reg(agi::util::make_unique<grid_tags_simplify>());
}
}

View File

@ -36,16 +36,17 @@
#include "../config.h"
#include <wx/msgdlg.h>
#include <libaegisub/util_osx.h>
#include "command.h"
#include "../help_button.h"
#include "../include/aegisub/context.h"
#include "../options.h"
#include <libaegisub/util.h>
#include <libaegisub/util_osx.h>
#include <wx/msgdlg.h>
namespace {
using cmd::Command;
/// @defgroup cmd-help Help commands.
@ -152,14 +153,14 @@ struct help_website : public Command {
namespace cmd {
void init_help() {
reg(new help_bugs);
reg(new help_contents);
reg(agi::util::make_unique<help_bugs>());
reg(agi::util::make_unique<help_contents>());
#ifdef __WXMAC__
reg(new help_files);
reg(agi::util::make_unique<help_files>());
#endif
reg(new help_forums);
reg(new help_irc);
reg(new help_video);
reg(new help_website);
reg(agi::util::make_unique<help_forums>());
reg(agi::util::make_unique<help_irc>());
reg(agi::util::make_unique<help_video>());
reg(agi::util::make_unique<help_website>());
}
}

View File

@ -43,6 +43,8 @@
#include "../utils.h"
#include "../video_context.h"
#include <libaegisub/util.h>
namespace {
using cmd::Command;
/// @defgroup cmd-keyframed Keyframe commands.
@ -107,8 +109,8 @@ struct keyframe_save : public Command {
namespace cmd {
void init_keyframe() {
reg(new keyframe_close);
reg(new keyframe_open);
reg(new keyframe_save);
reg(agi::util::make_unique<keyframe_close>());
reg(agi::util::make_unique<keyframe_open>());
reg(agi::util::make_unique<keyframe_save>());
}
}

View File

@ -44,6 +44,8 @@
#include "../subs_controller.h"
#include "../video_context.h"
#include <libaegisub/util.h>
#include <wx/event.h>
#include <wx/msgdlg.h>
@ -138,19 +140,19 @@ public:
namespace cmd {
void init_recent() {
reg(new recent_audio);
reg(new recent_keyframes);
reg(new recent_subtitle);
reg(new recent_timecodes);
reg(new recent_video);
reg(agi::util::make_unique<recent_audio>());
reg(agi::util::make_unique<recent_keyframes>());
reg(agi::util::make_unique<recent_subtitle>());
reg(agi::util::make_unique<recent_timecodes>());
reg(agi::util::make_unique<recent_video>());
/// @todo 16 is an implementation detail that maybe needs to be exposed
for (int i = 0; i < 16; ++i) {
reg(new mru_wrapper<recent_audio_entry>(i));
reg(new mru_wrapper<recent_keyframes_entry>(i));
reg(new mru_wrapper<recent_subtitle_entry>(i));
reg(new mru_wrapper<recent_timecodes_entry>(i));
reg(new mru_wrapper<recent_video_entry>(i));
reg(agi::util::make_unique<mru_wrapper<recent_audio_entry>>(i));
reg(agi::util::make_unique<mru_wrapper<recent_keyframes_entry>>(i));
reg(agi::util::make_unique<mru_wrapper<recent_subtitle_entry>>(i));
reg(agi::util::make_unique<mru_wrapper<recent_timecodes_entry>>(i));
reg(agi::util::make_unique<mru_wrapper<recent_video_entry>>(i));
}
}
}

View File

@ -57,11 +57,12 @@
#include "../utils.h"
#include "../video_context.h"
#include <libaegisub/charset_conv.h>
#include <libaegisub/util.h>
#include <wx/msgdlg.h>
#include <wx/choicdlg.h>
#include <libaegisub/charset_conv.h>
namespace {
using cmd::Command;
/// @defgroup cmd-subtitle Subtitle commands.
@ -456,23 +457,23 @@ struct subtitle_spellcheck : public Command {
namespace cmd {
void init_subtitle() {
reg(new subtitle_attachment);
reg(new subtitle_find);
reg(new subtitle_find_next);
reg(new subtitle_insert_after);
reg(new subtitle_insert_after_videotime);
reg(new subtitle_insert_before);
reg(new subtitle_insert_before_videotime);
reg(new subtitle_new);
reg(new subtitle_open);
reg(new subtitle_open_autosave);
reg(new subtitle_open_charset);
reg(new subtitle_open_video);
reg(new subtitle_properties);
reg(new subtitle_save);
reg(new subtitle_save_as);
reg(new subtitle_select_all);
reg(new subtitle_select_visible);
reg(new subtitle_spellcheck);
reg(agi::util::make_unique<subtitle_attachment>());
reg(agi::util::make_unique<subtitle_find>());
reg(agi::util::make_unique<subtitle_find_next>());
reg(agi::util::make_unique<subtitle_insert_after>());
reg(agi::util::make_unique<subtitle_insert_after_videotime>());
reg(agi::util::make_unique<subtitle_insert_before>());
reg(agi::util::make_unique<subtitle_insert_before_videotime>());
reg(agi::util::make_unique<subtitle_new>());
reg(agi::util::make_unique<subtitle_open>());
reg(agi::util::make_unique<subtitle_open_autosave>());
reg(agi::util::make_unique<subtitle_open_charset>());
reg(agi::util::make_unique<subtitle_open_video>());
reg(agi::util::make_unique<subtitle_properties>());
reg(agi::util::make_unique<subtitle_save>());
reg(agi::util::make_unique<subtitle_save_as>());
reg(agi::util::make_unique<subtitle_select_all>());
reg(agi::util::make_unique<subtitle_select_visible>());
reg(agi::util::make_unique<subtitle_spellcheck>());
}
}

View File

@ -51,6 +51,7 @@
#include "../video_context.h"
#include <libaegisub/of_type_adaptor.h>
#include <libaegisub/util.h>
#include <algorithm>
@ -373,23 +374,23 @@ struct time_prev : public Command {
namespace cmd {
void init_time() {
reg(new time_add_lead_both);
reg(new time_add_lead_in);
reg(new time_add_lead_out);
reg(new time_continuous_end);
reg(new time_continuous_start);
reg(new time_frame_current);
reg(new time_length_decrease);
reg(new time_length_decrease_shift);
reg(new time_length_increase);
reg(new time_length_increase_shift);
reg(new time_next);
reg(new time_prev);
reg(new time_shift);
reg(new time_snap_end_video);
reg(new time_snap_scene);
reg(new time_snap_start_video);
reg(new time_start_decrease);
reg(new time_start_increase);
reg(agi::util::make_unique<time_add_lead_both>());
reg(agi::util::make_unique<time_add_lead_in>());
reg(agi::util::make_unique<time_add_lead_out>());
reg(agi::util::make_unique<time_continuous_end>());
reg(agi::util::make_unique<time_continuous_start>());
reg(agi::util::make_unique<time_frame_current>());
reg(agi::util::make_unique<time_length_decrease>());
reg(agi::util::make_unique<time_length_decrease_shift>());
reg(agi::util::make_unique<time_length_increase>());
reg(agi::util::make_unique<time_length_increase_shift>());
reg(agi::util::make_unique<time_next>());
reg(agi::util::make_unique<time_prev>());
reg(agi::util::make_unique<time_shift>());
reg(agi::util::make_unique<time_snap_end_video>());
reg(agi::util::make_unique<time_snap_scene>());
reg(agi::util::make_unique<time_snap_start_video>());
reg(agi::util::make_unique<time_start_decrease>());
reg(agi::util::make_unique<time_start_increase>());
}
}

View File

@ -43,6 +43,8 @@
#include "../utils.h"
#include "../video_context.h"
#include <libaegisub/util.h>
namespace {
using cmd::Command;
/// @defgroup cmd-timecode Timecode commands.
@ -105,8 +107,8 @@ struct timecode_save : public Command {
namespace cmd {
void init_timecode() {
reg(new timecode_close);
reg(new timecode_open);
reg(new timecode_save);
reg(agi::util::make_unique<timecode_close>());
reg(agi::util::make_unique<timecode_open>());
reg(agi::util::make_unique<timecode_save>());
}
}

View File

@ -55,6 +55,7 @@
#include <libaegisub/fs.h>
#include <libaegisub/path.h>
#include <libaegisub/util.h>
#include <wx/msgdlg.h>
#include <wx/utils.h>
@ -299,25 +300,25 @@ struct tool_translation_assistant_insert : public tool_translation_assistant_val
namespace cmd {
void init_tool() {
reg(new tool_export);
reg(new tool_font_collector);
reg(new tool_line_select);
reg(new tool_resampleres);
reg(new tool_style_assistant);
reg(new tool_styling_assistant_commit);
reg(new tool_styling_assistant_preview);
reg(new tool_style_manager);
reg(new tool_time_kanji);
reg(new tool_time_postprocess);
reg(new tool_translation_assistant);
reg(agi::util::make_unique<tool_export>());
reg(agi::util::make_unique<tool_font_collector>());
reg(agi::util::make_unique<tool_line_select>());
reg(agi::util::make_unique<tool_resampleres>());
reg(agi::util::make_unique<tool_style_assistant>());
reg(agi::util::make_unique<tool_styling_assistant_commit>());
reg(agi::util::make_unique<tool_styling_assistant_preview>());
reg(agi::util::make_unique<tool_style_manager>());
reg(agi::util::make_unique<tool_time_kanji>());
reg(agi::util::make_unique<tool_time_postprocess>());
reg(agi::util::make_unique<tool_translation_assistant>());
#ifdef _WIN32
if (agi::fs::FileExists(config::path->Decode("?data/ASSDraw3.exe")))
reg(new tool_assdraw);
reg(agi::util::make_unique<tool_assdraw>());
#endif
reg(new tool_translation_assistant_commit);
reg(new tool_translation_assistant_preview);
reg(new tool_translation_assistant_next);
reg(new tool_translation_assistant_prev);
reg(new tool_translation_assistant_insert);
reg(agi::util::make_unique<tool_translation_assistant_commit>());
reg(agi::util::make_unique<tool_translation_assistant_preview>());
reg(agi::util::make_unique<tool_translation_assistant_next>());
reg(agi::util::make_unique<tool_translation_assistant_prev>());
reg(agi::util::make_unique<tool_translation_assistant_insert>());
}
}

View File

@ -751,42 +751,42 @@ struct video_zoom_out : public validator_video_attached {
namespace cmd {
void init_video() {
reg(new video_aspect_cinematic);
reg(new video_aspect_custom);
reg(new video_aspect_default);
reg(new video_aspect_full);
reg(new video_aspect_wide);
reg(new video_close);
reg(new video_copy_coordinates);
reg(new video_detach);
reg(new video_details);
reg(new video_focus_seek);
reg(new video_frame_copy);
reg(new video_frame_copy_raw);
reg(new video_frame_next);
reg(new video_frame_next_boundary);
reg(new video_frame_next_keyframe);
reg(new video_frame_next_large);
reg(new video_frame_prev);
reg(new video_frame_prev_boundary);
reg(new video_frame_prev_keyframe);
reg(new video_frame_prev_large);
reg(new video_frame_save);
reg(new video_frame_save_raw);
reg(new video_jump);
reg(new video_jump_end);
reg(new video_jump_start);
reg(new video_open);
reg(new video_open_dummy);
reg(new video_opt_autoscroll);
reg(new video_play);
reg(new video_play_line);
reg(new video_show_overscan);
reg(new video_stop);
reg(new video_zoom_100);
reg(new video_zoom_200);
reg(new video_zoom_50);
reg(new video_zoom_in);
reg(new video_zoom_out);
reg(agi::util::make_unique<video_aspect_cinematic>());
reg(agi::util::make_unique<video_aspect_custom>());
reg(agi::util::make_unique<video_aspect_default>());
reg(agi::util::make_unique<video_aspect_full>());
reg(agi::util::make_unique<video_aspect_wide>());
reg(agi::util::make_unique<video_close>());
reg(agi::util::make_unique<video_copy_coordinates>());
reg(agi::util::make_unique<video_detach>());
reg(agi::util::make_unique<video_details>());
reg(agi::util::make_unique<video_focus_seek>());
reg(agi::util::make_unique<video_frame_copy>());
reg(agi::util::make_unique<video_frame_copy_raw>());
reg(agi::util::make_unique<video_frame_next>());
reg(agi::util::make_unique<video_frame_next_boundary>());
reg(agi::util::make_unique<video_frame_next_keyframe>());
reg(agi::util::make_unique<video_frame_next_large>());
reg(agi::util::make_unique<video_frame_prev>());
reg(agi::util::make_unique<video_frame_prev_boundary>());
reg(agi::util::make_unique<video_frame_prev_keyframe>());
reg(agi::util::make_unique<video_frame_prev_large>());
reg(agi::util::make_unique<video_frame_save>());
reg(agi::util::make_unique<video_frame_save_raw>());
reg(agi::util::make_unique<video_jump>());
reg(agi::util::make_unique<video_jump_end>());
reg(agi::util::make_unique<video_jump_start>());
reg(agi::util::make_unique<video_open>());
reg(agi::util::make_unique<video_open_dummy>());
reg(agi::util::make_unique<video_opt_autoscroll>());
reg(agi::util::make_unique<video_play>());
reg(agi::util::make_unique<video_play_line>());
reg(agi::util::make_unique<video_show_overscan>());
reg(agi::util::make_unique<video_stop>());
reg(agi::util::make_unique<video_zoom_100>());
reg(agi::util::make_unique<video_zoom_200>());
reg(agi::util::make_unique<video_zoom_50>());
reg(agi::util::make_unique<video_zoom_in>());
reg(agi::util::make_unique<video_zoom_out>());
}
}

View File

@ -35,6 +35,8 @@
#include "../visual_tool_scale.h"
#include "../visual_tool_vector_clip.h"
#include <libaegisub/util.h>
namespace {
using cmd::Command;
/// @defgroup cmd-visual Visual typesetting tools commands
@ -111,12 +113,12 @@ namespace {
namespace cmd {
void init_visual_tools() {
reg(new visual_mode_cross);
reg(new visual_mode_drag);
reg(new visual_mode_rotate_z);
reg(new visual_mode_rotate_xy);
reg(new visual_mode_scale);
reg(new visual_mode_clip);
reg(new visual_mode_vector_clip);
reg(agi::util::make_unique<visual_mode_cross>());
reg(agi::util::make_unique<visual_mode_drag>());
reg(agi::util::make_unique<visual_mode_rotate_z>());
reg(agi::util::make_unique<visual_mode_rotate_xy>());
reg(agi::util::make_unique<visual_mode_scale>());
reg(agi::util::make_unique<visual_mode_clip>());
reg(agi::util::make_unique<visual_mode_vector_clip>());
}
}

View File

@ -47,6 +47,7 @@
#include "subtitle_format.h"
#include <algorithm>
#include <boost/range/algorithm.hpp>
#include <wx/button.h>
#include <wx/filedlg.h>
@ -121,25 +122,13 @@ DialogAutomation::DialogAutomation(agi::Context *c)
RebuildList();
}
template<class Container, class Pred>
static inline void for_each(Container const& c, Pred p)
{
std::for_each(c.begin(), c.end(), p);
}
template<class Container, class Out, class Func>
static inline void transform(Container const& c, Out o, Func f)
{
std::transform(c.begin(), c.end(), o, f);
}
void DialogAutomation::RebuildList()
{
script_info.clear();
list->DeleteAllItems();
for_each(local_manager->GetScripts(), std::bind(&DialogAutomation::AddScript, this, _1, false));
for_each(global_manager->GetScripts(), std::bind(&DialogAutomation::AddScript, this, _1, true));
for (auto& script : local_manager->GetScripts()) AddScript(script.get(), false);
for (auto& script : global_manager->GetScripts()) AddScript(script.get(), true);
UpdateDisplay();
}
@ -180,7 +169,7 @@ template<class Container>
static bool has_file(Container const& c, agi::fs::path const& fn)
{
return any_of(c.begin(), c.end(),
[&](const Automation4::Script *s) { return fn == s->GetFilename(); });
[&](std::unique_ptr<Automation4::Script> const& s) { return fn == s->GetFilename(); });
}
void DialogAutomation::OnAdd(wxCommandEvent &)
@ -232,7 +221,7 @@ void DialogAutomation::OnReload(wxCommandEvent &)
local_manager->Reload(ei.script);
}
static wxString fac_to_str(const Automation4::ScriptFactory* f) {
static wxString fac_to_str(std::unique_ptr<Automation4::ScriptFactory> const& f) {
return wxString::Format("- %s (%s)", to_wx(f->GetEngineName()), to_wx(f->GetFilenamePattern()));
}
@ -263,7 +252,7 @@ void DialogAutomation::OnInfo(wxCommandEvent &)
(int)local_manager->GetScripts().size()));
info.push_back(_("Scripting engines installed:"));
transform(Automation4::ScriptFactory::GetFactories(), append_info, fac_to_str);
boost::transform(Automation4::ScriptFactory::GetFactories(), append_info, fac_to_str);
if (ei) {
info.push_back(wxString::Format(_("\nScript info:\nName: %s\nDescription: %s\nAuthor: %s\nVersion: %s\nFull path: %s\nState: %s\n\nFeatures provided by script:"),
@ -274,9 +263,9 @@ void DialogAutomation::OnInfo(wxCommandEvent &)
ei->script->GetFilename().wstring(),
ei->script->GetLoadedState() ? _("Correctly loaded") : _("Failed to load")));
transform(ei->script->GetMacros(), append_info, std::bind(cmd_to_str, _1, context));
transform(ei->script->GetFilters(), append_info, filt_to_str);
transform(ei->script->GetFormats(), append_info, form_to_str);
boost::transform(ei->script->GetMacros(), append_info, std::bind(cmd_to_str, _1, context));
boost::transform(ei->script->GetFilters(), append_info, filt_to_str);
boost::transform(ei->script->GetFormats(), append_info, form_to_str);
}
wxMessageBox(wxJoin(info, '\n', 0), _("Automation Script Info"));

View File

@ -20,13 +20,12 @@
///
#include <map>
#include <memory>
#include <set>
#include <wx/dialog.h>
#include <wx/arrstr.h>
#include <libaegisub/scoped_ptr.h>
namespace agi { struct Context; }
namespace agi { class SpellChecker; }
class AssDialogue;
@ -38,7 +37,7 @@ class wxTextCtrl;
class DialogSpellChecker : public wxDialog {
agi::Context *context; ///< The project context
agi::scoped_ptr<agi::SpellChecker> spellchecker; ///< The spellchecking engine
std::unique_ptr<agi::SpellChecker> spellchecker; ///< The spellchecking engine
/// Words which the user has indicated should always be corrected
std::map<std::string, std::string> auto_replace;

View File

@ -451,7 +451,7 @@ void DialogStyleEditor::Apply(bool apply, bool close) {
style->UpdateData();
if (is_new) {
if (store)
store->push_back(style);
store->push_back(std::unique_ptr<AssStyle>(style));
else
c->ass->InsertLine(style);
is_new = false;

View File

@ -54,6 +54,7 @@
#include <libaegisub/fs.h>
#include <libaegisub/path.h>
#include <libaegisub/of_type_adaptor.h>
#include <libaegisub/util.h>
#include <algorithm>
#include <boost/algorithm/string/trim.hpp>
@ -328,7 +329,7 @@ void DialogStyleManager::LoadCatalog() {
// Create a default storage if there are none
if (CatalogList->IsListEmpty()) {
Store.Load(config::path->Decode("?user/catalog/Default.sty"));
Store.push_back(new AssStyle);
Store.push_back(agi::util::make_unique<AssStyle>());
Store.Save();
CatalogList->Append("Default");
}
@ -409,7 +410,7 @@ void DialogStyleManager::OnCopyToStorage() {
}
}
else {
Store.push_back(new AssStyle(*styleMap.at(selections[i])));
Store.push_back(agi::util::make_unique<AssStyle>(*styleMap.at(selections[i])));
copied.push_back(styleName);
}
}
@ -476,7 +477,7 @@ void DialogStyleManager::PasteToCurrent() {
void DialogStyleManager::PasteToStorage() {
add_styles(
std::bind(&AssStyleStorage::GetStyle, &Store, _1),
std::bind(&AssStyleStorage::push_back, &Store, _1));
[=](AssStyle *s) { Store.push_back(std::unique_ptr<AssStyle>(s)); });
UpdateStorage();
StorageList->SetStringSelection(to_wx(Store.back()->name));
@ -686,6 +687,11 @@ void DialogStyleManager::UpdateButtons() {
CurrentSort->Enable(itemsCurr > 1);
}
struct cmp_name {
template<typename T>
bool operator()(T const& lft, T const& rgt) const { return lft->name < rgt->name; }
};
template<class Cont>
static void do_move(Cont& styls, int type, int& first, int& last, bool storage) {
auto begin = styls.begin();
@ -724,9 +730,7 @@ static void do_move(Cont& styls, int type, int& first, int& last, bool storage)
if (res == wxNO) return;
}
sort(styls.begin(), styls.end(), [](const AssStyle *lft, const AssStyle *rgt) {
return lft->name < rgt->name;
});
sort(styls.begin(), styls.end(), cmp_name());
first = 0;
last = 0;

View File

@ -23,6 +23,7 @@
#include <algorithm>
#include <map>
#include <memory>
#include <string>
#include <vector>
@ -32,66 +33,54 @@ protected:
typedef std::map<std::string, std::pair<bool, func>> map;
typedef typename map::iterator iterator;
static map *classes;
static map& classes() {
static map classes;
return classes;
}
static void DoRegister(func function, std::string name, bool hide, std::vector<std::string> &subtypes) {
if (!classes) classes = new map;
if (subtypes.empty()) {
classes->insert(std::make_pair(name, std::make_pair(hide, function)));
}
if (subtypes.empty())
classes().insert(std::make_pair(name, std::make_pair(hide, function)));
else {
for (auto const& subtype : subtypes)
classes->insert(std::make_pair(name + '/' + subtype, std::make_pair(hide, function)));
classes().insert(std::make_pair(name + '/' + subtype, std::make_pair(hide, function)));
}
}
static func Find(std::string name) {
if (!classes) return nullptr;
iterator factory = classes->find(name);
if (factory != classes->end()) return factory->second.second;
return nullptr;
static func Find(std::string const& name) {
iterator factory = classes().find(name);
return factory != classes().end() ? factory->second.second : nullptr;
}
public:
static void Clear() {
delete classes;
}
static std::vector<std::string> GetClasses(std::string favourite="") {
std::vector<std::string> list;
if (!classes) return list;
std::string cmp;
std::transform(favourite.begin(), favourite.end(), favourite.begin(), ::tolower);
for (auto const& cls : *classes) {
for (auto const& cls : classes()) {
cmp.clear();
std::transform(cls.first.begin(), cls.first.end(), std::back_inserter(cmp), ::tolower);
if (cmp == favourite) list.insert(list.begin(), cls.first);
else if (!cls.second.first) list.push_back(cls.first);
if (cmp == favourite)
list.insert(list.begin(), cls.first);
else if (!cls.second.first)
list.push_back(cls.first);
}
return list;
}
virtual ~FactoryBase() {
delete classes;
}
};
template<class Base>
class Factory0 : public FactoryBase<Base *(*)()> {
typedef Base *(*func)();
class Factory0 : public FactoryBase<std::unique_ptr<Base>(*)()> {
typedef std::unique_ptr<Base>(*func)();
template<class T>
static Base* create() {
return new T;
static std::unique_ptr<Base> create() {
return std::unique_ptr<Base>(new T);
}
public:
static Base* Create(std::string name) {
static std::unique_ptr<Base> Create(std::string const& name) {
func factory = FactoryBase<func>::Find(name);
if (factory) {
return factory();
}
else {
return nullptr;
}
return factory ? factory() : nullptr;
}
template<class T>
@ -101,21 +90,17 @@ public:
};
template<class Base, class Arg1>
class Factory1 : public FactoryBase<Base *(*)(Arg1)> {
typedef Base *(*func)(Arg1);
class Factory1 : public FactoryBase<std::unique_ptr<Base>(*)(Arg1)> {
typedef std::unique_ptr<Base>(*func)(Arg1);
template<class T>
static Base* create(Arg1 a1) {
return new T(a1);
static std::unique_ptr<Base> create(Arg1 a1) {
return std::unique_ptr<Base>(new T(a1));
}
public:
static Base* Create(std::string name, Arg1 a1) {
static std::unique_ptr<Base> Create(std::string const& name, Arg1 a1) {
func factory = FactoryBase<func>::Find(name);
if (factory) {
return factory(a1);
}
else {
return nullptr;
}
return factory ? factory(a1) : nullptr;
}
template<class T>

View File

@ -63,5 +63,5 @@ public:
class AudioPlayerFactory : public Factory1<AudioPlayer, AudioProvider*> {
public:
static void RegisterProviders();
static AudioPlayer *GetAudioPlayer(AudioProvider *provider);
static std::unique_ptr<AudioPlayer> GetAudioPlayer(AudioProvider *provider);
};

View File

@ -80,7 +80,7 @@ public:
/// Get a provider for the file
/// @param filename URI to open
static AudioProvider *GetProvider(agi::fs::path const& filename);
static std::unique_ptr<AudioProvider> GetProvider(agi::fs::path const& filename);
};
DEFINE_BASE_EXCEPTION_NOINNER(AudioProviderError, agi::Exception)

View File

@ -25,6 +25,6 @@ namespace agi { class SpellChecker; }
class SpellCheckerFactory : public Factory0<agi::SpellChecker> {
public:
static agi::SpellChecker *GetSpellChecker();
static std::unique_ptr<agi::SpellChecker> GetSpellChecker();
static void RegisterProviders();
};

View File

@ -49,6 +49,6 @@ public:
class SubtitlesProviderFactory : public Factory1<SubtitlesProvider, std::string> {
public:
static SubtitlesProvider *GetProvider();
static std::unique_ptr<SubtitlesProvider> GetProvider();
static void RegisterProviders();
};

View File

@ -221,8 +221,7 @@ bool AegisubApp::OnInit() {
locale.Init(lang);
// Load plugins
plugins = new PluginManager();
plugins->RegisterBuiltInPlugins();
RegisterBuiltInPlugins();
// Load Automation scripts
StartupLog("Load global Automation scripts");
@ -230,8 +229,8 @@ bool AegisubApp::OnInit() {
// Load export filters
StartupLog("Register export filters");
AssExportFilterChain::Register(new AssFixStylesFilter);
AssExportFilterChain::Register(new AssTransformFramerateFilter);
AssExportFilterChain::Register(agi::util::make_unique<AssFixStylesFilter>());
AssExportFilterChain::Register(agi::util::make_unique<AssTransformFramerateFilter>());
// Open main frame
StartupLog("Create main window");
@ -279,7 +278,6 @@ int AegisubApp::OnExit() {
delete frame;
SubtitleFormat::DestroyFormats();
delete plugins;
delete config::opt;
delete config::mru;
hotkey::clear();

View File

@ -41,13 +41,10 @@
#endif
class FrameMain;
class PluginManager;
namespace Automation4 { class AutoloadScriptManager; }
class AegisubApp: public wxApp {
PluginManager *plugins;
bool OnInit();
int OnExit();
int OnRun();

View File

@ -42,30 +42,13 @@
#include "video_provider_manager.h"
#include "auto4_lua_factory.h"
PluginManager::PluginManager() {
init = false;
lua = nullptr;
}
#include <libaegisub/util.h>
PluginManager::~PluginManager() {
VideoProviderFactory::Clear();
AudioProviderFactory::Clear();
AudioPlayerFactory::Clear();
SubtitlesProviderFactory::Clear();
SpellCheckerFactory::Clear();
Automation4::ScriptFactory::Unregister(lua);
}
/// @brief Registers all built-in plugins
void PluginManager::RegisterBuiltInPlugins() {
if (!init) {
VideoProviderFactory::RegisterProviders();
AudioProviderFactory::RegisterProviders();
AudioPlayerFactory::RegisterProviders();
SubtitlesProviderFactory::RegisterProviders();
SpellCheckerFactory::RegisterProviders();
lua = new Automation4::LuaScriptFactory();
}
init = true;
void RegisterBuiltInPlugins() {
VideoProviderFactory::RegisterProviders();
AudioProviderFactory::RegisterProviders();
AudioPlayerFactory::RegisterProviders();
SubtitlesProviderFactory::RegisterProviders();
SpellCheckerFactory::RegisterProviders();
Automation4::ScriptFactory::Register(agi::util::make_unique<Automation4::LuaScriptFactory>());
}

View File

@ -27,20 +27,4 @@
//
// Aegisub Project http://www.aegisub.org/
/// @file plugin_manager.h
/// @see plugin_manager.cpp
/// @ingroup main
///
namespace Automation4 { class ScriptFactory; }
class PluginManager {
bool init;
Automation4::ScriptFactory *lua;
public:
PluginManager();
~PluginManager();
void RegisterBuiltInPlugins();
};
void RegisterBuiltInPlugins();

View File

@ -590,11 +590,8 @@ Advanced_Video::Advanced_Video(wxTreebook *book, Preferences *parent): OptionPag
SetSizerAndFit(sizer);
}
void Preferences::SetOption(agi::OptionValue *new_value) {
std::string name = new_value->GetName();
if (pending_changes.count(name))
delete pending_changes[name];
pending_changes[name] = new_value;
void Preferences::SetOption(std::unique_ptr<agi::OptionValue>&& new_value) {
pending_changes[new_value->GetName()] = std::move(new_value);
if (IsEnabled())
applyButton->Enable(true);
}
@ -615,10 +612,8 @@ void Preferences::OnOK(wxCommandEvent &event) {
}
void Preferences::OnApply(wxCommandEvent &) {
for (auto const& change : pending_changes) {
OPT_SET(change.first)->Set(change.second);
delete change.second;
}
for (auto const& change : pending_changes)
OPT_SET(change.first)->Set(change.second.get());
pending_changes.clear();
for (auto const& thunk : pending_callbacks)
@ -699,6 +694,4 @@ Preferences::Preferences(wxWindow *parent): wxDialog(parent, -1, _("Preferences"
}
Preferences::~Preferences() {
for (auto& change : pending_changes)
delete change.second;
}

View File

@ -20,6 +20,7 @@
#include <deque>
#include <functional>
#include <map>
#include <memory>
#include <wx/dialog.h>
@ -40,7 +41,7 @@ private:
wxTreebook *book;
wxButton *applyButton;
std::map<std::string, agi::OptionValue*> pending_changes;
std::map<std::string, std::unique_ptr<agi::OptionValue>> pending_changes;
std::deque<Thunk> pending_callbacks;
std::deque<std::string> option_names;
@ -55,7 +56,7 @@ public:
/// Add an option to be set when the OK or Apply button is clicked
/// @param new_value Clone of the option with the new value to copy over
void SetOption(agi::OptionValue *new_value);
void SetOption(std::unique_ptr<agi::OptionValue>&& new_value);
/// All a function to call when the OK or Apply button is clicked
/// @param callback Function to call

View File

@ -28,8 +28,8 @@
#include "video_provider_manager.h"
#include <libaegisub/path.h>
#include <libaegisub/util.h>
#include <wx/any.h>
#include <wx/checkbox.h>
#include <wx/combobox.h>
#include <wx/dirdlg.h>
@ -50,7 +50,7 @@
type(std::string const& n, Preferences *p) : name(n), parent(p) { } \
void operator()(evttype& evt) { \
evt.Skip(); \
parent->SetOption(new agi::opt(name, body)); \
parent->SetOption(agi::util::make_unique<agi::opt>(name, body));\
} \
}

View File

@ -39,14 +39,16 @@
#include "options.h"
agi::SpellChecker *SpellCheckerFactory::GetSpellChecker() {
#include <libaegisub/spellchecker.h>
std::unique_ptr<agi::SpellChecker> SpellCheckerFactory::GetSpellChecker() {
std::vector<std::string> list = GetClasses(OPT_GET("Tool/Spell Checker/Backend")->GetString());
if (list.empty()) return nullptr;
std::string error;
for (auto const& name : list) {
try {
agi::SpellChecker *checker = Create(name);
auto checker = Create(name);
if (checker) return checker;
}
catch (...) { error += name + " factory: Unknown error\n"; }
@ -60,5 +62,3 @@ void SpellCheckerFactory::RegisterProviders() {
Register<HunspellSpellChecker>("Hunspell");
#endif
}
template<> SpellCheckerFactory::map *FactoryBase<agi::SpellChecker *(*)()>::classes = nullptr;

View File

@ -32,13 +32,12 @@
/// @ingroup main_ui
///
#include <memory>
#include <string>
#include <vector>
#include "scintilla_text_ctrl.h"
#include <libaegisub/scoped_ptr.h>
class SubsEditBox;
class Thesaurus;
namespace agi {
@ -52,12 +51,12 @@ namespace agi {
/// @brief A Scintilla control with spell checking and syntax highlighting
class SubsTextEditCtrl : public ScintillaTextCtrl {
/// Backend spellchecker to use
agi::scoped_ptr<agi::SpellChecker> spellchecker;
std::unique_ptr<agi::SpellChecker> spellchecker;
/// Backend thesaurus to use
agi::scoped_ptr<Thesaurus> thesaurus;
std::unique_ptr<Thesaurus> thesaurus;
agi::scoped_ptr<agi::CalltipProvider> calltip_provider;
std::unique_ptr<agi::CalltipProvider> calltip_provider;
/// Project context, for splitting lines
agi::Context *context;

View File

@ -35,9 +35,6 @@
#include "config.h"
#include <wx/dcclient.h>
#include <wx/msgdlg.h>
#include "ass_dialogue.h"
#include "ass_file.h"
#include "ass_style.h"
@ -45,20 +42,25 @@
#include "include/aegisub/subtitles_provider.h"
#include "video_provider_dummy.h"
#include <libaegisub/util.h>
#include <wx/dcclient.h>
#include <wx/msgdlg.h>
SubtitlesPreview::SubtitlesPreview(wxWindow *parent, wxSize size, int winStyle, agi::Color col)
: wxWindow(parent, -1, wxDefaultPosition, size, winStyle)
, style(new AssStyle)
, backColour(col)
, subFile(new AssFile)
, back_color(col)
, sub_file(agi::util::make_unique<AssFile>())
, line(new AssDialogue)
{
line->Text = "{\\q2}preview";
SetStyle(*style);
subFile->LoadDefault();
subFile->InsertLine(style);
subFile->Line.push_back(*line);
sub_file->LoadDefault();
sub_file->InsertLine(style);
sub_file->Line.push_back(*line);
SetSizeHints(size.GetWidth(), size.GetHeight(), -1, -1);
wxSizeEvent evt(size);
@ -72,8 +74,8 @@ SubtitlesPreview::SubtitlesPreview(wxWindow *parent, wxSize size, int winStyle,
SubtitlesPreview::~SubtitlesPreview() {
}
void SubtitlesPreview::SetStyle(AssStyle const& newStyle) {
*style = newStyle;
void SubtitlesPreview::SetStyle(AssStyle const& new_style) {
*style = new_style;
style->name = "Default";
style->alignment = 5;
std::fill(style->Margin.begin(), style->Margin.end(), 0);
@ -82,17 +84,17 @@ void SubtitlesPreview::SetStyle(AssStyle const& newStyle) {
}
void SubtitlesPreview::SetText(std::string const& text) {
std::string newText = "{\\q2}" + text;
if (newText != line->Text) {
line->Text = newText;
std::string new_text = "{\\q2}" + text;
if (new_text != line->Text) {
line->Text = new_text;
UpdateBitmap();
}
}
void SubtitlesPreview::SetColour(agi::Color col) {
if (col != backColour) {
backColour = col;
vid.reset(new DummyVideoProvider(0.0, 10, bmp->GetWidth(), bmp->GetHeight(), backColour, true));
if (col != back_color) {
back_color = col;
vid.reset(new DummyVideoProvider(0.0, 10, bmp->GetWidth(), bmp->GetHeight(), back_color, true));
UpdateBitmap();
}
}
@ -105,7 +107,7 @@ void SubtitlesPreview::UpdateBitmap() {
if (provider) {
try {
provider->LoadSubtitles(subFile.get());
provider->LoadSubtitles(sub_file.get());
provider->DrawSubtitles(frame, 0.1);
}
catch (...) { }
@ -127,11 +129,11 @@ void SubtitlesPreview::OnSize(wxSizeEvent &evt) {
int w = evt.GetSize().GetWidth();
int h = evt.GetSize().GetHeight();
bmp.reset(new wxBitmap(w, h, -1));
vid.reset(new DummyVideoProvider(0.0, 10, w, h, backColour, true));
bmp = agi::util::make_unique<wxBitmap>(w, h, -1);
vid.reset(new DummyVideoProvider(0.0, 10, w, h, back_color, true));
try {
if (!provider)
provider.reset(SubtitlesProviderFactory::GetProvider());
provider = SubtitlesProviderFactory::GetProvider();
}
catch (...) {
wxMessageBox(
@ -140,8 +142,8 @@ void SubtitlesPreview::OnSize(wxSizeEvent &evt) {
"No subtitles provider", wxOK | wxICON_ERROR | wxCENTER);
}
subFile->SetScriptInfo("PlayResX", std::to_string(w));
subFile->SetScriptInfo("PlayResY", std::to_string(h));
sub_file->SetScriptInfo("PlayResX", std::to_string(w));
sub_file->SetScriptInfo("PlayResY", std::to_string(h));
UpdateBitmap();
}

View File

@ -32,11 +32,10 @@
/// @ingroup custom_control
///
#include <memory>
#include <wx/window.h>
#include <wx/bitmap.h>
#include <libaegisub/scoped_ptr.h>
class AssFile;
class AssStyle;
class SubtitlesProvider;
@ -45,17 +44,17 @@ class VideoProvider;
/// Preview window to show a short string with a given ass style
class SubtitlesPreview : public wxWindow {
/// The subtitle provider used to render the string
agi::scoped_ptr<SubtitlesProvider> provider;
std::unique_ptr<SubtitlesProvider> provider;
/// Bitmap to render into
agi::scoped_ptr<wxBitmap> bmp;
std::unique_ptr<wxBitmap> bmp;
/// The currently display style
AssStyle* style;
/// Video provider to render into
agi::scoped_ptr<VideoProvider> vid;
std::unique_ptr<VideoProvider> vid;
/// Current background color
agi::Color backColour;
agi::Color back_color;
/// Subtitle file containing the style and displayed line
agi::scoped_ptr<AssFile> subFile;
std::unique_ptr<AssFile> sub_file;
/// Line used to render the specified text
AssDialogue* line;

View File

@ -39,7 +39,7 @@
#include "subtitles_provider_libass.h"
#include "include/aegisub/subtitles_provider.h"
SubtitlesProvider* SubtitlesProviderFactory::GetProvider() {
std::unique_ptr<SubtitlesProvider> SubtitlesProviderFactory::GetProvider() {
std::vector<std::string> list = GetClasses(OPT_GET("Subtitle/Provider")->GetString());
if (list.empty()) throw std::string("No subtitle providers are available.");
@ -48,7 +48,7 @@ SubtitlesProvider* SubtitlesProviderFactory::GetProvider() {
try {
size_t pos = factory.find('/');
std::string subType = pos < factory.size() - 1 ? factory.substr(pos + 1) : "";
SubtitlesProvider *provider = Create(factory, subType);
auto provider = Create(factory, subType);
if (provider) return provider;
}
catch (agi::UserCancelException const&) { throw; }
@ -71,5 +71,3 @@ void SubtitlesProviderFactory::RegisterProviders() {
LibassSubtitlesProvider::CacheFonts();
#endif
}
template<> SubtitlesProviderFactory::map *FactoryBase<SubtitlesProvider *(*)(std::string)>::classes = nullptr;

View File

@ -102,7 +102,7 @@ std::shared_ptr<AegiVideoFrame> ThreadedFrameSource::ProcFrame(int frame_number,
return frame;
}
static SubtitlesProvider *get_subs_provider(wxEvtHandler *parent) {
static std::unique_ptr<SubtitlesProvider> get_subs_provider(wxEvtHandler *parent) {
try {
return SubtitlesProviderFactory::GetProvider();
}

View File

@ -47,8 +47,8 @@ struct CachedFrame : public AegiVideoFrame {
int frame_number;
};
VideoProviderCache::VideoProviderCache(VideoProvider *parent)
: master(parent)
VideoProviderCache::VideoProviderCache(std::unique_ptr<VideoProvider>&& parent)
: master(std::move(parent))
, max_cache_size(OPT_GET("Provider/Video/Cache/Size")->GetInt() << 20) // convert MB to bytes
{
}

View File

@ -36,15 +36,13 @@
#include "include/aegisub/video_provider.h"
#include <libaegisub/scoped_ptr.h>
struct CachedFrame;
/// @class VideoProviderCache
/// @brief A wrapper around a video provider which provides LRU caching
class VideoProviderCache : public VideoProvider {
/// The source provider to get frames from
agi::scoped_ptr<VideoProvider> master;
std::unique_ptr<VideoProvider> master;
/// @brief Maximum size of the cache in bytes
///
@ -56,7 +54,7 @@ class VideoProviderCache : public VideoProvider {
boost::container::list<CachedFrame> cache;
public:
VideoProviderCache(VideoProvider *master);
VideoProviderCache(std::unique_ptr<VideoProvider>&& master);
~VideoProviderCache();
const AegiVideoFrame GetFrame(int n);

View File

@ -45,8 +45,9 @@
#include <libaegisub/fs.h>
#include <libaegisub/log.h>
#include <libaegisub/util.h>
VideoProvider *VideoProviderFactory::GetProvider(agi::fs::path const& video_file) {
std::unique_ptr<VideoProvider> VideoProviderFactory::GetProvider(agi::fs::path const& video_file) {
std::vector<std::string> factories = GetClasses(OPT_GET("Video/Provider")->GetString());
factories.insert(factories.begin(), "YUV4MPEG");
factories.insert(factories.begin(), "Dummy");
@ -59,9 +60,9 @@ VideoProvider *VideoProviderFactory::GetProvider(agi::fs::path const& video_file
for (auto const& factory : factories) {
std::string err;
try {
VideoProvider *provider = Create(factory, video_file);
auto provider = Create(factory, video_file);
LOG_I("manager/video/provider") << factory << ": opened " << video_file;
return provider->WantsCaching() ? new VideoProviderCache(provider) : provider;
return provider->WantsCaching() ? agi::util::make_unique<VideoProviderCache>(std::move(provider)) : std::move(provider);
}
catch (agi::fs::FileNotFound const&) {
err = "file not found.";
@ -104,5 +105,3 @@ void VideoProviderFactory::RegisterProviders() {
Register<DummyVideoProvider>("Dummy", true);
Register<YUV4MPEGVideoProvider>("YUV4MPEG", true);
}
template<> VideoProviderFactory::map *FactoryBase<VideoProvider *(*)(agi::fs::path)>::classes = nullptr;

View File

@ -21,6 +21,6 @@
class VideoProviderFactory : public Factory1<VideoProvider, agi::fs::path> {
public:
static VideoProvider *GetProvider(agi::fs::path const& video_file);
static std::unique_ptr<VideoProvider> GetProvider(agi::fs::path const& video_file);
static void RegisterProviders();
};