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 "ass_export_filter.h"
#include "utils.h"
#include <algorithm>
#include <boost/format.hpp> #include <boost/format.hpp>
static FilterList& filters() { 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; int filter_copy = 1;
std::string name = filter->name; std::string name = filter->name;
// Find a unique name // Find a unique name
@ -64,36 +61,22 @@ void AssExportFilterChain::Register(AssExportFilter *filter) {
// Look for place to insert // Look for place to insert
auto begin(filters().begin()), end(filters().end()); auto begin(filters().begin()), end(filters().end());
while (begin != end && (*begin)->priority >= filter->priority) ++begin; while (begin != end && begin->priority >= filter->priority) ++begin;
filters().insert(begin, filter); filters().insert(begin, *filter.release());
} }
void AssExportFilterChain::Unregister(AssExportFilter *filter) { FilterList *AssExportFilterChain::GetFilterList() {
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() {
return &filters(); return &filters();
} }
void AssExportFilterChain::Clear() { void AssExportFilterChain::Clear() {
while (filters().size() > 0) { filters().clear_and_dispose([](AssExportFilter *f) { delete f; });
AssExportFilter *f = filters().back();
delete f;
if (filters().size() && filters().back() == f)
filters().pop_back();
}
} }
AssExportFilter *AssExportFilterChain::GetFilter(std::string const& name) { AssExportFilter *AssExportFilterChain::GetFilter(std::string const& name) {
for (auto filter : filters()) { for (auto& filter : filters()) {
if (filter->name == name) if (filter.name == name)
return filter; return &filter;
} }
return 0; return nullptr;
} }

View File

@ -34,34 +34,17 @@
#pragma once #pragma once
#include <boost/intrusive/list.hpp>
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector>
class AssFile; class AssFile;
class AssExportFilter; class AssExportFilterChain;
class wxWindow; class wxWindow;
namespace agi { struct Context; } namespace agi { struct Context; }
typedef std::vector<AssExportFilter*> FilterList; class AssExportFilter : public boost::intrusive::make_list_base_hook<boost::intrusive::link_mode<boost::intrusive::auto_unlink>>::type {
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 {
/// The filter chain needs to be able to muck around with filter names when /// The filter chain needs to be able to muck around with filter names when
/// they're registered to avoid duplicates /// they're registered to avoid duplicates
friend class AssExportFilterChain; friend class AssExportFilterChain;
@ -98,3 +81,18 @@ public:
/// @param c Project context /// @param c Project context
virtual void LoadSettings(bool is_default, agi::Context *c) { } 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 "include/aegisub/context.h"
#include "subtitle_format.h" #include "subtitle_format.h"
#include <algorithm>
#include <memory> #include <memory>
#include <wx/sizer.h> #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) AssExporter::AssExporter(agi::Context *c)
: c(c) : c(c)
, is_default(true) , is_default(true)
@ -62,16 +53,16 @@ AssExporter::AssExporter(agi::Context *c)
void AssExporter::DrawSettings(wxWindow *parent, wxSizer *target_sizer) { void AssExporter::DrawSettings(wxWindow *parent, wxSizer *target_sizer) {
is_default = false; 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 // Make sure to construct static box sizer first, so it won't overlap
// the controls on wxMac. // the controls on wxMac.
wxSizer *box = new wxStaticBoxSizer(wxVERTICAL, parent, to_wx(filter->GetName())); wxSizer *box = new wxStaticBoxSizer(wxVERTICAL, parent, to_wx(filter.GetName()));
wxWindow *window = filter->GetConfigDialogWindow(parent, c); wxWindow *window = filter.GetConfigDialogWindow(parent, c);
if (window) { if (window) {
box->Add(window, 0, wxEXPAND, 0); box->Add(window, 0, wxEXPAND, 0);
target_sizer->Add(box, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5); target_sizer->Add(box, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
target_sizer->Show(box, false); target_sizer->Show(box, false);
Sizers[filter->GetName()] = box; Sizers[filter.GetName()] = box;
} }
else { else {
delete box; delete box;
@ -80,7 +71,7 @@ void AssExporter::DrawSettings(wxWindow *parent, wxSizer *target_sizer) {
} }
void AssExporter::AddFilter(std::string const& name) { void AssExporter::AddFilter(std::string const& name) {
AssExportFilter *filter = AssExportFilterChain::GetFilter(name); auto filter = AssExportFilterChain::GetFilter(name);
if (!filter) throw "Filter not found: " + 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> AssExporter::GetAllFilterNames() const {
std::vector<std::string> names; std::vector<std::string> names;
transform(filter_list_begin(), filter_list_end(), for (auto& filter : *AssExportFilterChain::GetFilterList())
back_inserter(names), std::mem_fun(&AssExportFilter::GetName)); names.emplace_back(filter.GetName());
return names; return names;
} }
AssFile *AssExporter::ExportTransform(wxWindow *export_dialog, bool copy) { void AssExporter::Export(agi::fs::path const& filename, std::string const& charset, wxWindow *export_dialog) {
AssFile *subs = copy ? new AssFile(*c->ass) : c->ass; AssFile subs(*c->ass);
for (auto filter : filters) { for (auto filter : filters) {
filter->LoadSettings(is_default, c); 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); const SubtitleFormat *writer = SubtitleFormat::GetWriter(filename);
if (!writer) if (!writer)
throw "Unknown file type."; throw "Unknown file type.";
writer->WriteFile(subs.get(), filename, charset); writer->WriteFile(&subs, filename, charset);
} }
wxSizer *AssExporter::GetSettingsSizer(std::string const& name) { 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 { std::string const& AssExporter::GetDescription(std::string const& name) const {
AssExportFilter *filter = AssExportFilterChain::GetFilter(name); auto filter = AssExportFilterChain::GetFilter(name);
if (filter) if (filter)
return filter->GetDescription(); return filter->GetDescription();
throw "Filter not found: " + name; throw "Filter not found: " + name;

View File

@ -44,16 +44,14 @@ namespace agi { struct Context; }
class wxSizer; class wxSizer;
class wxWindow; class wxWindow;
typedef std::vector<AssExportFilter*> FilterList;
class AssExporter { class AssExporter {
typedef FilterList::const_iterator filter_iterator; typedef std::vector<AssExportFilter*>::const_iterator filter_iterator;
/// Sizers for configuration panels /// Sizers for configuration panels
std::map<std::string, wxSizer*> Sizers; std::map<std::string, wxSizer*> Sizers;
/// Filters which will be applied to the subtitles /// Filters which will be applied to the subtitles
FilterList filters; std::vector<AssExportFilter*> filters;
/// Input context /// Input context
agi::Context *c; agi::Context *c;
@ -72,12 +70,6 @@ public:
/// @throws std::string if filter is not found /// @throws std::string if filter is not found
void AddFilter(std::string const& name); 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 /// Apply selected export filters and save with the given charset
/// @param file Target filename /// @param file Target filename
/// @param charset Target charset /// @param charset Target charset

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -21,9 +21,9 @@
#pragma once #pragma once
#include <libaegisub/scoped_ptr.h>
#include <libaegisub/signal.h> #include <libaegisub/signal.h>
#include <memory>
#include <vector> #include <vector>
#include <wx/string.h> #include <wx/string.h>
@ -135,7 +135,7 @@ class AudioMarkerProviderKeyframes : public AudioMarkerProvider {
std::vector<AudioMarkerKeyframe> markers; std::vector<AudioMarkerKeyframe> markers;
/// Pen used for all keyframe markers, stored here for performance reasons /// 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 /// Regenerate the list of markers
void Update(); void Update();
@ -158,7 +158,7 @@ public:
class VideoPositionMarkerProvider : public AudioMarkerProvider { class VideoPositionMarkerProvider : public AudioMarkerProvider {
VideoContext *vc; VideoContext *vc;
agi::scoped_ptr<VideoPositionMarker> marker; std::unique_ptr<VideoPositionMarker> marker;
agi::signal::Connection video_seek_slot; agi::signal::Connection video_seek_slot;
agi::signal::Connection enable_opt_changed_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 /// 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 /// Markers returned from last call to GetMarkers
mutable std::vector<Marker> markers; 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()); std::vector<std::string> list = GetClasses(OPT_GET("Audio/Player")->GetString());
if (list.empty()) throw agi::NoAudioPlayersError("No audio players are available.", 0); if (list.empty()) throw agi::NoAudioPlayersError("No audio players are available.", 0);
@ -88,5 +88,3 @@ void AudioPlayerFactory::RegisterProviders() {
Register<OSSPlayer>("OSS"); Register<OSSPlayer>("OSS");
#endif #endif
} }
template<> AudioPlayerFactory::map *FactoryBase<AudioPlayer *(*)(AudioProvider*)>::classes = nullptr;

View File

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

View File

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

View File

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

View File

@ -27,17 +27,19 @@
#include "audio_controller.h" #include "audio_controller.h"
#include "include/aegisub/audio_provider.h" #include "include/aegisub/audio_provider.h"
#include <libaegisub/scoped_ptr.h>
#include <libaegisub/log.h> #include <libaegisub/log.h>
#include <libaegisub/util.h>
#include <limits> #include <limits>
/// Base class for all wrapping converters /// Base class for all wrapping converters
class AudioProviderConverter : public AudioProvider { class AudioProviderConverter : public AudioProvider {
protected: protected:
agi::scoped_ptr<AudioProvider> source; std::unique_ptr<AudioProvider> source;
public: public:
AudioProviderConverter(AudioProvider *src) : source(src) { AudioProviderConverter(std::unique_ptr<AudioProvider>&& src)
: source(std::move(src))
{
channels = source->GetChannels(); channels = source->GetChannels();
num_samples = source->GetNumSamples(); num_samples = source->GetNumSamples();
sample_rate = source->GetSampleRate(); sample_rate = source->GetSampleRate();
@ -55,11 +57,11 @@ class BitdepthConvertAudioProvider : public AudioProviderConverter {
int src_bytes_per_sample; int src_bytes_per_sample;
bool src_is_native_endian; bool src_is_native_endian;
public: public:
BitdepthConvertAudioProvider(AudioProvider *src) : AudioProviderConverter(src) { BitdepthConvertAudioProvider(std::unique_ptr<AudioProvider>&& src) : AudioProviderConverter(std::move(src)) {
if (bytes_per_sample > 8) if (bytes_per_sample > 8)
throw agi::AudioProviderOpenError("Audio format converter: audio with bitdepths greater than 64 bits/sample is currently unsupported", 0); 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; src_bytes_per_sample = bytes_per_sample;
bytes_per_sample = sizeof(Target); bytes_per_sample = sizeof(Target);
} }
@ -110,8 +112,8 @@ public:
template<class Source, class Target> template<class Source, class Target>
class FloatConvertAudioProvider : public AudioProviderConverter { class FloatConvertAudioProvider : public AudioProviderConverter {
public: public:
FloatConvertAudioProvider(AudioProvider *src) : AudioProviderConverter(src) { FloatConvertAudioProvider(std::unique_ptr<AudioProvider>&& src) : AudioProviderConverter(std::move(src)) {
if (!src->AreSamplesNativeEndian()) if (!source->AreSamplesNativeEndian())
throw agi::AudioProviderOpenError("Audio format converter: Float audio with non-native endianness is currently unsupported.", 0); throw agi::AudioProviderOpenError("Audio format converter: Float audio with non-native endianness is currently unsupported.", 0);
bytes_per_sample = sizeof(Target); bytes_per_sample = sizeof(Target);
float_samples = false; float_samples = false;
@ -144,7 +146,7 @@ public:
class DownmixAudioProvider : public AudioProviderConverter { class DownmixAudioProvider : public AudioProviderConverter {
int src_channels; int src_channels;
public: public:
DownmixAudioProvider(AudioProvider *src) : AudioProviderConverter(src) { DownmixAudioProvider(std::unique_ptr<AudioProvider>&& src) : AudioProviderConverter(std::move(src)) {
if (bytes_per_sample != 2) if (bytes_per_sample != 2)
throw agi::InternalError("DownmixAudioProvider requires 16-bit input", 0); throw agi::InternalError("DownmixAudioProvider requires 16-bit input", 0);
if (channels == 1) 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 /// Requires 16-bit mono input
class SampleDoublingAudioProvider : public AudioProviderConverter { class SampleDoublingAudioProvider : public AudioProviderConverter {
public: public:
SampleDoublingAudioProvider(AudioProvider *src) : AudioProviderConverter(src) { SampleDoublingAudioProvider(std::unique_ptr<AudioProvider>&& src) : AudioProviderConverter(std::move(src)) {
if (src->GetBytesPerSample() != 2) if (source->GetBytesPerSample() != 2)
throw agi::InternalError("UpsampleAudioProvider requires 16-bit input", 0); 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); throw agi::InternalError("UpsampleAudioProvider requires mono input", 0);
sample_rate *= 2; sample_rate *= 2;
@ -210,33 +212,31 @@ public:
} }
}; };
AudioProvider *CreateConvertAudioProvider(AudioProvider *source_provider) { std::unique_ptr<AudioProvider> CreateConvertAudioProvider(std::unique_ptr<AudioProvider>&& provider) {
AudioProvider *provider = source_provider;
// Ensure 16-bit audio with proper endianness // Ensure 16-bit audio with proper endianness
if (provider->AreSamplesFloat()) { if (provider->AreSamplesFloat()) {
LOG_D("audio_provider") << "Converting float to S16"; LOG_D("audio_provider") << "Converting float to S16";
if (provider->GetBytesPerSample() == sizeof(float)) 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 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()) { if (provider->GetBytesPerSample() != 2 || !provider->AreSamplesNativeEndian()) {
LOG_D("audio_provider") << "Converting " << provider->GetBytesPerSample() << " bytes per sample or wrong endian to S16"; 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 // We currently only support mono audio
if (provider->GetChannels() != 1) { if (provider->GetChannels() != 1) {
LOG_D("audio_provider") << "Downmixing to mono from " << provider->GetChannels() << " channels"; 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 // Some players don't like low sample rate audio
while (provider->GetSampleRate() < 32000) { while (provider->GetSampleRate() < 32000) {
LOG_D("audio_provider") << "Doubling sample rate"; 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 /// @ingroup audio_input
/// ///
#include <memory>
class AudioProvider; class AudioProvider;
/// Get an audio provider which supplies audio in a format supported by Aegisub's players /// 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) { HDAudioProvider::HDAudioProvider(std::unique_ptr<AudioProvider>&& src, agi::BackgroundRunner *br) {
agi::scoped_ptr<AudioProvider> source(src);
assert(src->AreSamplesNativeEndian()); // Byteswapping should be done before caching assert(src->AreSamplesNativeEndian()); // Byteswapping should be done before caching
bytes_per_sample = source->GetBytesPerSample(); bytes_per_sample = src->GetBytesPerSample();
num_samples = source->GetNumSamples(); num_samples = src->GetNumSamples();
channels = source->GetChannels(); channels = src->GetChannels();
sample_rate = source->GetSampleRate(); sample_rate = src->GetSampleRate();
filename = source->GetFilename(); filename = src->GetFilename();
float_samples = source->AreSamplesFloat(); float_samples = src->AreSamplesFloat();
// Check free space // Check free space
if ((uint64_t)num_samples * channels * bytes_per_sample > agi::fs::FreeSpace(cache_dir())) 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 { try {
{ {
agi::io::Save out(diskCacheFilename, true); 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 (...) { catch (...) {
agi::fs::Remove(diskCacheFilename); agi::fs::Remove(diskCacheFilename);

View File

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

View File

@ -20,7 +20,9 @@
#include "audio_provider_lock.h" #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(); channels = source->GetChannels();
num_samples = source->GetNumSamples(); num_samples = source->GetNumSamples();
sample_rate = source->GetSampleRate(); 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; void FillBuffer(void *buf, int64_t start, int64_t count) const;
public: public:
LockAudioProvider(AudioProvider *source); LockAudioProvider(std::unique_ptr<AudioProvider>&& source);
bool AreSamplesNativeEndian() const { return source->AreSamplesNativeEndian(); } bool AreSamplesNativeEndian() const { return source->AreSamplesNativeEndian(); }
}; };

View File

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

View File

@ -81,4 +81,4 @@ protected:
}; };
// Construct the right PCM audio provider (if any) for the file // 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 "utils.h"
#include <libaegisub/background_runner.h> #include <libaegisub/background_runner.h>
#include <libaegisub/scoped_ptr.h>
#define CacheBits 22 #define CacheBits 22
#define CacheBlockSize (1 << CacheBits) #define CacheBlockSize (1 << CacheBits)
RAMAudioProvider::RAMAudioProvider(AudioProvider *src, agi::BackgroundRunner *br) RAMAudioProvider::RAMAudioProvider(std::unique_ptr<AudioProvider>&& src, agi::BackgroundRunner *br) {
{
agi::scoped_ptr<AudioProvider> source(src);
try { try {
blockcache.resize((src->GetNumSamples() * src->GetBytesPerSample() + CacheBlockSize - 1) >> CacheBits); blockcache.resize((src->GetNumSamples() * src->GetBytesPerSample() + CacheBlockSize - 1) >> CacheBits);
@ -59,15 +56,15 @@ RAMAudioProvider::RAMAudioProvider(AudioProvider *src, agi::BackgroundRunner *br
} }
// Copy parameters // Copy parameters
samples_native_endian = source->AreSamplesNativeEndian(); samples_native_endian = src->AreSamplesNativeEndian();
bytes_per_sample = source->GetBytesPerSample(); bytes_per_sample = src->GetBytesPerSample();
num_samples = source->GetNumSamples(); num_samples = src->GetNumSamples();
channels = source->GetChannels(); channels = src->GetChannels();
sample_rate = source->GetSampleRate(); sample_rate = src->GetSampleRate();
filename = source->GetFilename(); filename = src->GetFilename();
float_samples = source->AreSamplesFloat(); 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) { 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; void FillBuffer(void *buf, int64_t start, int64_t count) const;
public: public:
RAMAudioProvider(AudioProvider *source, agi::BackgroundRunner *br); RAMAudioProvider(std::unique_ptr<AudioProvider>&& source, agi::BackgroundRunner *br);
bool AreSamplesNativeEndian() const { return samples_native_endian; } bool AreSamplesNativeEndian() const { return samples_native_endian; }
}; };

View File

@ -45,11 +45,6 @@
#include "include/aegisub/audio_provider.h" #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; using std::placeholders::_1;
AudioRendererBitmapCacheBitmapFactory::AudioRendererBitmapCacheBitmapFactory(AudioRenderer *renderer) AudioRendererBitmapCacheBitmapFactory::AudioRendererBitmapCacheBitmapFactory(AudioRenderer *renderer)
@ -176,7 +171,7 @@ void AudioRenderer::ResetBlockCount()
double duration = provider->GetNumSamples() * 1000.0 / provider->GetSampleRate(); double duration = provider->GetNumSamples() * 1000.0 / provider->GetSampleRate();
size_t rendered_width = (size_t)ceil(duration / pixel_ms); size_t rendered_width = (size_t)ceil(duration / pixel_ms);
cache_numblocks = rendered_width / cache_bitmap_width; 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() void AudioRenderer::Invalidate()
{ {
for_each(bitmaps, std::bind(&AudioRendererBitmapCache::Age, _1, 0)); for (auto& bmp : bitmaps) bmp.Age(0);
needs_age = false; needs_age = false;
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -36,7 +36,7 @@
namespace Automation4 { namespace Automation4 {
class LuaScriptFactory : public ScriptFactory { 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: public:
LuaScriptFactory(); LuaScriptFactory();
}; };

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -55,6 +55,7 @@
#include <libaegisub/fs.h> #include <libaegisub/fs.h>
#include <libaegisub/path.h> #include <libaegisub/path.h>
#include <libaegisub/util.h>
#include <wx/msgdlg.h> #include <wx/msgdlg.h>
#include <wx/utils.h> #include <wx/utils.h>
@ -299,25 +300,25 @@ struct tool_translation_assistant_insert : public tool_translation_assistant_val
namespace cmd { namespace cmd {
void init_tool() { void init_tool() {
reg(new tool_export); reg(agi::util::make_unique<tool_export>());
reg(new tool_font_collector); reg(agi::util::make_unique<tool_font_collector>());
reg(new tool_line_select); reg(agi::util::make_unique<tool_line_select>());
reg(new tool_resampleres); reg(agi::util::make_unique<tool_resampleres>());
reg(new tool_style_assistant); reg(agi::util::make_unique<tool_style_assistant>());
reg(new tool_styling_assistant_commit); reg(agi::util::make_unique<tool_styling_assistant_commit>());
reg(new tool_styling_assistant_preview); reg(agi::util::make_unique<tool_styling_assistant_preview>());
reg(new tool_style_manager); reg(agi::util::make_unique<tool_style_manager>());
reg(new tool_time_kanji); reg(agi::util::make_unique<tool_time_kanji>());
reg(new tool_time_postprocess); reg(agi::util::make_unique<tool_time_postprocess>());
reg(new tool_translation_assistant); reg(agi::util::make_unique<tool_translation_assistant>());
#ifdef _WIN32 #ifdef _WIN32
if (agi::fs::FileExists(config::path->Decode("?data/ASSDraw3.exe"))) if (agi::fs::FileExists(config::path->Decode("?data/ASSDraw3.exe")))
reg(new tool_assdraw); reg(agi::util::make_unique<tool_assdraw>());
#endif #endif
reg(new tool_translation_assistant_commit); reg(agi::util::make_unique<tool_translation_assistant_commit>());
reg(new tool_translation_assistant_preview); reg(agi::util::make_unique<tool_translation_assistant_preview>());
reg(new tool_translation_assistant_next); reg(agi::util::make_unique<tool_translation_assistant_next>());
reg(new tool_translation_assistant_prev); reg(agi::util::make_unique<tool_translation_assistant_prev>());
reg(new tool_translation_assistant_insert); 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 { namespace cmd {
void init_video() { void init_video() {
reg(new video_aspect_cinematic); reg(agi::util::make_unique<video_aspect_cinematic>());
reg(new video_aspect_custom); reg(agi::util::make_unique<video_aspect_custom>());
reg(new video_aspect_default); reg(agi::util::make_unique<video_aspect_default>());
reg(new video_aspect_full); reg(agi::util::make_unique<video_aspect_full>());
reg(new video_aspect_wide); reg(agi::util::make_unique<video_aspect_wide>());
reg(new video_close); reg(agi::util::make_unique<video_close>());
reg(new video_copy_coordinates); reg(agi::util::make_unique<video_copy_coordinates>());
reg(new video_detach); reg(agi::util::make_unique<video_detach>());
reg(new video_details); reg(agi::util::make_unique<video_details>());
reg(new video_focus_seek); reg(agi::util::make_unique<video_focus_seek>());
reg(new video_frame_copy); reg(agi::util::make_unique<video_frame_copy>());
reg(new video_frame_copy_raw); reg(agi::util::make_unique<video_frame_copy_raw>());
reg(new video_frame_next); reg(agi::util::make_unique<video_frame_next>());
reg(new video_frame_next_boundary); reg(agi::util::make_unique<video_frame_next_boundary>());
reg(new video_frame_next_keyframe); reg(agi::util::make_unique<video_frame_next_keyframe>());
reg(new video_frame_next_large); reg(agi::util::make_unique<video_frame_next_large>());
reg(new video_frame_prev); reg(agi::util::make_unique<video_frame_prev>());
reg(new video_frame_prev_boundary); reg(agi::util::make_unique<video_frame_prev_boundary>());
reg(new video_frame_prev_keyframe); reg(agi::util::make_unique<video_frame_prev_keyframe>());
reg(new video_frame_prev_large); reg(agi::util::make_unique<video_frame_prev_large>());
reg(new video_frame_save); reg(agi::util::make_unique<video_frame_save>());
reg(new video_frame_save_raw); reg(agi::util::make_unique<video_frame_save_raw>());
reg(new video_jump); reg(agi::util::make_unique<video_jump>());
reg(new video_jump_end); reg(agi::util::make_unique<video_jump_end>());
reg(new video_jump_start); reg(agi::util::make_unique<video_jump_start>());
reg(new video_open); reg(agi::util::make_unique<video_open>());
reg(new video_open_dummy); reg(agi::util::make_unique<video_open_dummy>());
reg(new video_opt_autoscroll); reg(agi::util::make_unique<video_opt_autoscroll>());
reg(new video_play); reg(agi::util::make_unique<video_play>());
reg(new video_play_line); reg(agi::util::make_unique<video_play_line>());
reg(new video_show_overscan); reg(agi::util::make_unique<video_show_overscan>());
reg(new video_stop); reg(agi::util::make_unique<video_stop>());
reg(new video_zoom_100); reg(agi::util::make_unique<video_zoom_100>());
reg(new video_zoom_200); reg(agi::util::make_unique<video_zoom_200>());
reg(new video_zoom_50); reg(agi::util::make_unique<video_zoom_50>());
reg(new video_zoom_in); reg(agi::util::make_unique<video_zoom_in>());
reg(new video_zoom_out); reg(agi::util::make_unique<video_zoom_out>());
} }
} }

View File

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

View File

@ -47,6 +47,7 @@
#include "subtitle_format.h" #include "subtitle_format.h"
#include <algorithm> #include <algorithm>
#include <boost/range/algorithm.hpp>
#include <wx/button.h> #include <wx/button.h>
#include <wx/filedlg.h> #include <wx/filedlg.h>
@ -121,25 +122,13 @@ DialogAutomation::DialogAutomation(agi::Context *c)
RebuildList(); 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() void DialogAutomation::RebuildList()
{ {
script_info.clear(); script_info.clear();
list->DeleteAllItems(); list->DeleteAllItems();
for_each(local_manager->GetScripts(), std::bind(&DialogAutomation::AddScript, this, _1, false)); for (auto& script : local_manager->GetScripts()) AddScript(script.get(), false);
for_each(global_manager->GetScripts(), std::bind(&DialogAutomation::AddScript, this, _1, true)); for (auto& script : global_manager->GetScripts()) AddScript(script.get(), true);
UpdateDisplay(); UpdateDisplay();
} }
@ -180,7 +169,7 @@ template<class Container>
static bool has_file(Container const& c, agi::fs::path const& fn) static bool has_file(Container const& c, agi::fs::path const& fn)
{ {
return any_of(c.begin(), c.end(), 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 &) void DialogAutomation::OnAdd(wxCommandEvent &)
@ -232,7 +221,7 @@ void DialogAutomation::OnReload(wxCommandEvent &)
local_manager->Reload(ei.script); 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())); 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())); (int)local_manager->GetScripts().size()));
info.push_back(_("Scripting engines installed:")); 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) { 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:"), 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->GetFilename().wstring(),
ei->script->GetLoadedState() ? _("Correctly loaded") : _("Failed to load"))); ei->script->GetLoadedState() ? _("Correctly loaded") : _("Failed to load")));
transform(ei->script->GetMacros(), append_info, std::bind(cmd_to_str, _1, context)); boost::transform(ei->script->GetMacros(), append_info, std::bind(cmd_to_str, _1, context));
transform(ei->script->GetFilters(), append_info, filt_to_str); boost::transform(ei->script->GetFilters(), append_info, filt_to_str);
transform(ei->script->GetFormats(), append_info, form_to_str); boost::transform(ei->script->GetFormats(), append_info, form_to_str);
} }
wxMessageBox(wxJoin(info, '\n', 0), _("Automation Script Info")); wxMessageBox(wxJoin(info, '\n', 0), _("Automation Script Info"));

View File

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

View File

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

View File

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

View File

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

View File

@ -63,5 +63,5 @@ public:
class AudioPlayerFactory : public Factory1<AudioPlayer, AudioProvider*> { class AudioPlayerFactory : public Factory1<AudioPlayer, AudioProvider*> {
public: public:
static void RegisterProviders(); 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 /// Get a provider for the file
/// @param filename URI to open /// @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) DEFINE_BASE_EXCEPTION_NOINNER(AudioProviderError, agi::Exception)

View File

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

View File

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

View File

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

View File

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

View File

@ -42,30 +42,13 @@
#include "video_provider_manager.h" #include "video_provider_manager.h"
#include "auto4_lua_factory.h" #include "auto4_lua_factory.h"
PluginManager::PluginManager() { #include <libaegisub/util.h>
init = false;
lua = nullptr;
}
PluginManager::~PluginManager() { void RegisterBuiltInPlugins() {
VideoProviderFactory::Clear(); VideoProviderFactory::RegisterProviders();
AudioProviderFactory::Clear(); AudioProviderFactory::RegisterProviders();
AudioPlayerFactory::Clear(); AudioPlayerFactory::RegisterProviders();
SubtitlesProviderFactory::Clear(); SubtitlesProviderFactory::RegisterProviders();
SpellCheckerFactory::Clear(); SpellCheckerFactory::RegisterProviders();
Automation4::ScriptFactory::Unregister(lua); Automation4::ScriptFactory::Register(agi::util::make_unique<Automation4::LuaScriptFactory>());
}
/// @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;
} }

View File

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

View File

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

View File

@ -20,6 +20,7 @@
#include <deque> #include <deque>
#include <functional> #include <functional>
#include <map> #include <map>
#include <memory>
#include <wx/dialog.h> #include <wx/dialog.h>
@ -40,7 +41,7 @@ private:
wxTreebook *book; wxTreebook *book;
wxButton *applyButton; 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<Thunk> pending_callbacks;
std::deque<std::string> option_names; 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 /// 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 /// @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 /// All a function to call when the OK or Apply button is clicked
/// @param callback Function to call /// @param callback Function to call

View File

@ -28,8 +28,8 @@
#include "video_provider_manager.h" #include "video_provider_manager.h"
#include <libaegisub/path.h> #include <libaegisub/path.h>
#include <libaegisub/util.h>
#include <wx/any.h>
#include <wx/checkbox.h> #include <wx/checkbox.h>
#include <wx/combobox.h> #include <wx/combobox.h>
#include <wx/dirdlg.h> #include <wx/dirdlg.h>
@ -50,7 +50,7 @@
type(std::string const& n, Preferences *p) : name(n), parent(p) { } \ type(std::string const& n, Preferences *p) : name(n), parent(p) { } \
void operator()(evttype& evt) { \ void operator()(evttype& evt) { \
evt.Skip(); \ 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" #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()); std::vector<std::string> list = GetClasses(OPT_GET("Tool/Spell Checker/Backend")->GetString());
if (list.empty()) return nullptr; if (list.empty()) return nullptr;
std::string error; std::string error;
for (auto const& name : list) { for (auto const& name : list) {
try { try {
agi::SpellChecker *checker = Create(name); auto checker = Create(name);
if (checker) return checker; if (checker) return checker;
} }
catch (...) { error += name + " factory: Unknown error\n"; } catch (...) { error += name + " factory: Unknown error\n"; }
@ -60,5 +62,3 @@ void SpellCheckerFactory::RegisterProviders() {
Register<HunspellSpellChecker>("Hunspell"); Register<HunspellSpellChecker>("Hunspell");
#endif #endif
} }
template<> SpellCheckerFactory::map *FactoryBase<agi::SpellChecker *(*)()>::classes = nullptr;

View File

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

View File

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

View File

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

View File

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

View File

@ -47,8 +47,8 @@ struct CachedFrame : public AegiVideoFrame {
int frame_number; int frame_number;
}; };
VideoProviderCache::VideoProviderCache(VideoProvider *parent) VideoProviderCache::VideoProviderCache(std::unique_ptr<VideoProvider>&& parent)
: master(parent) : master(std::move(parent))
, max_cache_size(OPT_GET("Provider/Video/Cache/Size")->GetInt() << 20) // convert MB to bytes , 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 "include/aegisub/video_provider.h"
#include <libaegisub/scoped_ptr.h>
struct CachedFrame; struct CachedFrame;
/// @class VideoProviderCache /// @class VideoProviderCache
/// @brief A wrapper around a video provider which provides LRU caching /// @brief A wrapper around a video provider which provides LRU caching
class VideoProviderCache : public VideoProvider { class VideoProviderCache : public VideoProvider {
/// The source provider to get frames from /// 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 /// @brief Maximum size of the cache in bytes
/// ///
@ -56,7 +54,7 @@ class VideoProviderCache : public VideoProvider {
boost::container::list<CachedFrame> cache; boost::container::list<CachedFrame> cache;
public: public:
VideoProviderCache(VideoProvider *master); VideoProviderCache(std::unique_ptr<VideoProvider>&& master);
~VideoProviderCache(); ~VideoProviderCache();
const AegiVideoFrame GetFrame(int n); const AegiVideoFrame GetFrame(int n);

View File

@ -45,8 +45,9 @@
#include <libaegisub/fs.h> #include <libaegisub/fs.h>
#include <libaegisub/log.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()); std::vector<std::string> factories = GetClasses(OPT_GET("Video/Provider")->GetString());
factories.insert(factories.begin(), "YUV4MPEG"); factories.insert(factories.begin(), "YUV4MPEG");
factories.insert(factories.begin(), "Dummy"); factories.insert(factories.begin(), "Dummy");
@ -59,9 +60,9 @@ VideoProvider *VideoProviderFactory::GetProvider(agi::fs::path const& video_file
for (auto const& factory : factories) { for (auto const& factory : factories) {
std::string err; std::string err;
try { try {
VideoProvider *provider = Create(factory, video_file); auto provider = Create(factory, video_file);
LOG_I("manager/video/provider") << factory << ": opened " << 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&) { catch (agi::fs::FileNotFound const&) {
err = "file not found."; err = "file not found.";
@ -104,5 +105,3 @@ void VideoProviderFactory::RegisterProviders() {
Register<DummyVideoProvider>("Dummy", true); Register<DummyVideoProvider>("Dummy", true);
Register<YUV4MPEGVideoProvider>("YUV4MPEG", 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> { class VideoProviderFactory : public Factory1<VideoProvider, agi::fs::path> {
public: 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(); static void RegisterProviders();
}; };