From aa46c49403d8f80170b28fda4beca820c8e5b6fb Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Tue, 25 Mar 2014 14:49:26 -0700 Subject: [PATCH] Pull some of the context (de)init out of FrameMain And actually do deinitialize more of the stuff in the context. --- build/Aegisub/Aegisub.vcxproj | 1 + build/Aegisub/Aegisub.vcxproj.filters | 3 ++ src/Makefile | 1 + src/audio_box.cpp | 4 +- src/audio_marker.cpp | 4 +- src/auto4_lua.cpp | 8 ++-- src/command/subtitle.cpp | 2 +- src/command/time.cpp | 2 +- src/command/tool.cpp | 2 +- src/context.cpp | 49 +++++++++++++++++++++ src/dialog_automation.cpp | 2 +- src/dialog_fonts_collector.cpp | 2 +- src/dialog_kara_timing_copy.cpp | 2 +- src/dialog_search_replace.cpp | 2 +- src/dialog_selection.cpp | 2 +- src/dialog_style_manager.cpp | 7 +-- src/frame_main.cpp | 34 +-------------- src/include/aegisub/context.h | 62 +++++++++++++++++---------- src/subs_controller.cpp | 8 ++-- src/subs_controller.h | 1 + src/video_context.cpp | 29 ++++++------- src/video_context.h | 11 +---- src/visual_tool_drag.cpp | 2 +- 23 files changed, 139 insertions(+), 101 deletions(-) create mode 100644 src/context.cpp diff --git a/build/Aegisub/Aegisub.vcxproj b/build/Aegisub/Aegisub.vcxproj index dc1b4c5bf..9491799c9 100644 --- a/build/Aegisub/Aegisub.vcxproj +++ b/build/Aegisub/Aegisub.vcxproj @@ -329,6 +329,7 @@ + true diff --git a/build/Aegisub/Aegisub.vcxproj.filters b/build/Aegisub/Aegisub.vcxproj.filters index d23dbed0d..9b0ce6d9d 100644 --- a/build/Aegisub/Aegisub.vcxproj.filters +++ b/build/Aegisub/Aegisub.vcxproj.filters @@ -1184,6 +1184,9 @@ Utilities\Logging + + Main UI + diff --git a/src/Makefile b/src/Makefile index 900a8232b..8dc66b7ac 100644 --- a/src/Makefile +++ b/src/Makefile @@ -154,6 +154,7 @@ SRC += \ colorspace.cpp \ colour_button.cpp \ compat.cpp \ + context.cpp \ crash_writer.cpp \ dialog_about.cpp \ dialog_attachments.cpp \ diff --git a/src/audio_box.cpp b/src/audio_box.cpp index c474e7f4c..d85ca8509 100644 --- a/src/audio_box.cpp +++ b/src/audio_box.cpp @@ -75,11 +75,11 @@ enum { AudioBox::AudioBox(wxWindow *parent, agi::Context *context) : wxSashWindow(parent, -1, wxDefaultPosition, wxDefaultSize, wxSW_3D | wxCLIP_CHILDREN) -, controller(context->audioController) +, controller(context->audioController.get()) , context(context) , audio_open_connection(controller->AddAudioOpenListener(&AudioBox::OnAudioOpen, this)) , panel(new wxPanel(this, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxBORDER_RAISED)) -, audioDisplay(new AudioDisplay(panel, context->audioController, context)) +, audioDisplay(new AudioDisplay(panel, context->audioController.get(), context)) , HorizontalZoom(new wxSlider(panel, Audio_Horizontal_Zoom, -OPT_GET("Audio/Zoom/Horizontal")->GetInt(), -50, 30, wxDefaultPosition, wxSize(-1, 20), wxSL_VERTICAL|wxSL_BOTH)) , VerticalZoom(new wxSlider(panel, Audio_Vertical_Zoom, OPT_GET("Audio/Zoom/Vertical")->GetInt(), 0, 100, wxDefaultPosition, wxSize(-1, 20), wxSL_VERTICAL|wxSL_BOTH|wxSL_INVERSE)) , VolumeBar(new wxSlider(panel, Audio_Volume, OPT_GET("Audio/Volume")->GetInt(), 0, 100, wxDefaultPosition, wxSize(-1, 20), wxSL_VERTICAL|wxSL_BOTH|wxSL_INVERSE)) diff --git a/src/audio_marker.cpp b/src/audio_marker.cpp index de0a1953e..92022a8c5 100644 --- a/src/audio_marker.cpp +++ b/src/audio_marker.cpp @@ -45,7 +45,7 @@ public: }; AudioMarkerProviderKeyframes::AudioMarkerProviderKeyframes(agi::Context *c, const char *opt_name) -: vc(c->videoController) +: vc(c->videoController.get()) , keyframe_slot(vc->AddKeyframesListener(&AudioMarkerProviderKeyframes::Update, this)) , timecode_slot(vc->AddTimecodesListener(&AudioMarkerProviderKeyframes::Update, this)) , enabled_slot(OPT_SUB(opt_name, &AudioMarkerProviderKeyframes::Update, this)) @@ -107,7 +107,7 @@ public: }; VideoPositionMarkerProvider::VideoPositionMarkerProvider(agi::Context *c) -: vc(c->videoController) +: vc(c->videoController.get()) , video_seek_slot(vc->AddSeekListener(&VideoPositionMarkerProvider::Update, this)) , enable_opt_changed_slot(OPT_SUB("Audio/Display/Draw/Video Position", &VideoPositionMarkerProvider::OptChanged, this)) { diff --git a/src/auto4_lua.cpp b/src/auto4_lua.cpp index 6fc4cf3d3..a48bfd721 100644 --- a/src/auto4_lua.cpp +++ b/src/auto4_lua.cpp @@ -861,7 +861,7 @@ namespace Automation4 { set_context(L, c); GetFeatureFunction("validate"); - auto subsobj = new LuaAssFile(L, c->ass); + auto subsobj = new LuaAssFile(L, c->ass.get()); push_value(L, transform_selection(L, c)); int err = lua_pcall(L, 3, 2, 0); @@ -894,7 +894,7 @@ namespace Automation4 { stackcheck.check_stack(0); GetFeatureFunction("run"); - auto subsobj = new LuaAssFile(L, c->ass, true, true); + auto subsobj = new LuaAssFile(L, c->ass.get(), true, true); push_value(L, transform_selection(L, c)); try { @@ -966,7 +966,7 @@ namespace Automation4 { stackcheck.check_stack(0); GetFeatureFunction("isactive"); - auto subsobj = new LuaAssFile(L, c->ass); + auto subsobj = new LuaAssFile(L, c->ass.get()); push_value(L, transform_selection(L, c)); int err = lua_pcall(L, 3, 1, 0); @@ -1071,7 +1071,7 @@ namespace Automation4 { GetFeatureFunction("config"); // prepare function call - auto subsobj = new LuaAssFile(L, c->ass); + auto subsobj = new LuaAssFile(L, c->ass.get()); // stored options lua_newtable(L); // TODO, nothing for now diff --git a/src/command/subtitle.cpp b/src/command/subtitle.cpp index 2c510c7a2..760103f05 100644 --- a/src/command/subtitle.cpp +++ b/src/command/subtitle.cpp @@ -87,7 +87,7 @@ struct subtitle_attachment final : public Command { void operator()(agi::Context *c) override { c->videoController->Stop(); - DialogAttachments(c->parent, c->ass).ShowModal(); + DialogAttachments(c->parent, c->ass.get()).ShowModal(); } }; diff --git a/src/command/time.cpp b/src/command/time.cpp index 34d1a404c..53b7b5f7e 100644 --- a/src/command/time.cpp +++ b/src/command/time.cpp @@ -205,7 +205,7 @@ struct time_snap_scene final : public validate_video_loaded { STR_HELP("Set start and end of subtitles to the keyframes around current video frame") void operator()(agi::Context *c) override { - VideoContext *con = c->videoController; + VideoContext *con = c->videoController.get(); if (!con->IsLoaded() || !con->KeyFramesLoaded()) return; int curFrame = con->GetFrameN(); diff --git a/src/command/tool.cpp b/src/command/tool.cpp index 7034f424b..1bafb943b 100644 --- a/src/command/tool.cpp +++ b/src/command/tool.cpp @@ -120,7 +120,7 @@ struct tool_resampleres final : public Command { c->videoController->Stop(); ResampleSettings settings; if (DialogResample(c, settings).ShowModal() == wxID_OK) - ResampleResolution(c->ass, settings); + ResampleResolution(c->ass.get(), settings); } }; diff --git a/src/context.cpp b/src/context.cpp new file mode 100644 index 000000000..847dd208a --- /dev/null +++ b/src/context.cpp @@ -0,0 +1,49 @@ +// Copyright (c) 2014, Thomas Goyne +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// +// Aegisub Project http://www.aegisub.org/ + +#include "config.h" + +#include "include/aegisub/context.h" + +#include "ass_file.h" +#include "audio_controller.h" +#include "auto4_base.h" +#include "dialog_manager.h" +#include "initial_line_state.h" +#include "search_replace_engine.h" +#include "selection_controller.h" +#include "subs_controller.h" +#include "video_context.h" + +#include + +namespace agi { +Context::Context() +: ass(util::make_unique()) +, subsController(util::make_unique(this)) +, local_scripts(util::make_unique(this)) +, videoController(util::make_unique(this)) +, audioController(util::make_unique(this)) +, selectionController(util::make_unique(this)) +, initialLineState(util::make_unique(this)) +, search(util::make_unique(this)) +, dialog(util::make_unique()) +{ + subsController->SetSelectionController(selectionController.get()); +} + +Context::~Context() {} +} diff --git a/src/dialog_automation.cpp b/src/dialog_automation.cpp index 749848946..e773c38e2 100644 --- a/src/dialog_automation.cpp +++ b/src/dialog_automation.cpp @@ -61,7 +61,7 @@ using std::placeholders::_1; DialogAutomation::DialogAutomation(agi::Context *c) : wxDialog(c->parent, -1, _("Automation Manager"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) , context(c) -, local_manager(c->local_scripts) +, local_manager(c->local_scripts.get()) , local_scripts_changed(local_manager->AddScriptChangeListener(&DialogAutomation::RebuildList, this)) , global_manager(wxGetApp().global_scripts) , global_scripts_changed(global_manager->AddScriptChangeListener(&DialogAutomation::RebuildList, this)) diff --git a/src/dialog_fonts_collector.cpp b/src/dialog_fonts_collector.cpp index 7bf32b688..8bd444281 100644 --- a/src/dialog_fonts_collector.cpp +++ b/src/dialog_fonts_collector.cpp @@ -183,7 +183,7 @@ void FontsCollectorThread(AssFile *subs, agi::fs::path const& destination, FcMod DialogFontsCollector::DialogFontsCollector(agi::Context *c) : wxDialog(c->parent, -1, _("Fonts Collector")) -, subs(c->ass) +, subs(c->ass.get()) { SetIcon(GETICON(font_collector_button_16)); diff --git a/src/dialog_kara_timing_copy.cpp b/src/dialog_kara_timing_copy.cpp index 05ac952b8..74598e337 100644 --- a/src/dialog_kara_timing_copy.cpp +++ b/src/dialog_kara_timing_copy.cpp @@ -450,7 +450,7 @@ bool KaraokeLineMatchDisplay::UndoMatch() DialogKanjiTimer::DialogKanjiTimer(agi::Context *c) : wxDialog(c->parent, -1, _("Kanji timing")) -, subs(c->ass) +, subs(c->ass.get()) { SetIcon(GETICON(kara_timing_copier_16)); diff --git a/src/dialog_search_replace.cpp b/src/dialog_search_replace.cpp index 09aa69d4a..37c734ae8 100644 --- a/src/dialog_search_replace.cpp +++ b/src/dialog_search_replace.cpp @@ -136,7 +136,7 @@ void DialogSearchReplace::FindReplace(bool (SearchReplaceEngine::*func)()) { c->search->Configure(*settings); try { - (c->search->*func)(); + ((*c->search).*func)(); } catch (std::exception const& e) { wxMessageBox(to_wx(e.what()), "Error", wxOK | wxICON_ERROR | wxCENTER, this); diff --git a/src/dialog_selection.cpp b/src/dialog_selection.cpp index fb22f522a..d0eb3e731 100644 --- a/src/dialog_selection.cpp +++ b/src/dialog_selection.cpp @@ -178,7 +178,7 @@ void DialogSelection::Process(wxCommandEvent&) { from_wx(match_text->GetValue()), case_sensitive->IsChecked(), static_cast(match_mode->GetSelection()), select_unmatching_lines->GetValue(), apply_to_comments->IsChecked(), apply_to_dialogue->IsChecked(), - dialogue_field->GetSelection(), con->ass); + dialogue_field->GetSelection(), con->ass.get()); } catch (agi::Exception const&) { Close(); diff --git a/src/dialog_style_manager.cpp b/src/dialog_style_manager.cpp index da2bdc13f..d6ac56962 100644 --- a/src/dialog_style_manager.cpp +++ b/src/dialog_style_manager.cpp @@ -477,7 +477,7 @@ void DialogStyleManager::CopyToClipboard(wxListBox *list, T const& v) { void DialogStyleManager::PasteToCurrent() { add_styles( - std::bind(&AssFile::GetStyle, c->ass, _1), + [=](std::string const& str) { return c->ass->GetStyle(str); }, [=](AssStyle *s) { c->ass->Styles.push_back(*s); }); c->ass->Commit(_("style paste"), AssFile::COMMIT_STYLES); @@ -554,8 +554,9 @@ void DialogStyleManager::OnCurrentCopy() { int sel = get_single_sel(CurrentList); if (sel == -1) return; - ShowCurrentEditor(styleMap[sel], - unique_name(std::bind(&AssFile::GetStyle, c->ass, _1), styleMap[sel]->name)); + ShowCurrentEditor(styleMap[sel], unique_name( + [=](std::string const& str) { return c->ass->GetStyle(str); }, + styleMap[sel]->name)); } void DialogStyleManager::OnCurrentDelete() { diff --git a/src/frame_main.cpp b/src/frame_main.cpp index bf1a902fe..867066dd9 100644 --- a/src/frame_main.cpp +++ b/src/frame_main.cpp @@ -44,7 +44,6 @@ #include "ass_file.h" #include "audio_controller.h" #include "audio_box.h" -#include "auto4_base.h" #include "base_grid.h" #include "compat.h" #include "command/command.h" @@ -52,12 +51,9 @@ #include "dialog_manager.h" #include "dialog_version_check.h" #include "help_button.h" -#include "initial_line_state.h" #include "libresrc/libresrc.h" #include "main.h" #include "options.h" -#include "selection_controller.h" -#include "search_replace_engine.h" #include "subs_controller.h" #include "subs_edit_box.h" #include "subs_edit_ctrl.h" @@ -205,32 +201,17 @@ FrameMain::FrameMain() LOG_D("locale") << setlocale(LC_ALL, nullptr); #endif - StartupLog("Initializing context models"); - memset(context.get(), 0, sizeof(*context)); - context->ass = new AssFile; - StartupLog("Initializing context controls"); - context->subsController = new SubsController(context.get()); context->ass->AddCommitListener(&FrameMain::UpdateTitle, this); context->subsController->AddFileOpenListener(&FrameMain::OnSubtitlesOpen, this); context->subsController->AddFileSaveListener(&FrameMain::UpdateTitle, this); - - context->audioController = new AudioController(context.get()); context->audioController->AddAudioOpenListener(&FrameMain::OnAudioOpen, this); context->audioController->AddAudioCloseListener(&FrameMain::OnAudioClose, this); - - context->local_scripts = new Automation4::LocalScriptManager(context.get()); - - context->selectionController = new SelectionController(context.get()); - context->subsController->SetSelectionController(context->selectionController); - - context->videoController = VideoContext::Get(); // derp context->videoController->AddVideoOpenListener(&FrameMain::OnVideoOpen, this); StartupLog("Initializing context frames"); context->parent = this; context->frame = this; - context->previousFocus = nullptr; StartupLog("Install PNG handler"); wxImage::AddHandler(new wxPNGHandler); @@ -257,13 +238,9 @@ FrameMain::FrameMain() #endif StartupLog("Create views and inner main window controls"); - context->dialog = new DialogManager; InitContents(); OPT_SUB("Video/Detached/Enabled", &FrameMain::OnVideoDetach, this, agi::signal::_1); - StartupLog("Complete context initialization"); - context->videoController->SetContext(context.get()); - StartupLog("Set up drag/drop target"); SetDropTarget(new AegisubFileDropTarget(this)); @@ -307,10 +284,6 @@ FrameMain::~FrameMain () { context->audioController->CloseAudio(); DestroyChildren(); - - delete context->ass; - delete context->audioController; - delete context->local_scripts; } void FrameMain::InitToolbar() { @@ -339,8 +312,6 @@ void FrameMain::InitContents() { StartupLog("Create subtitles grid"); context->subsGrid = new BaseGrid(Panel, context.get()); - context->search = new SearchReplaceEngine(context.get()); - context->initialLineState = new InitialLineState(context.get()); StartupLog("Create video box"); videoBox = new VideoBox(Panel, false, context.get()); @@ -530,8 +501,7 @@ void FrameMain::OnCloseWindow(wxCloseEvent &event) { return; } - delete context->dialog; - context->dialog = nullptr; + context->dialog.reset(); // Store maximization state OPT_SET("App/Maximized")->SetBool(IsMaximized()); @@ -553,7 +523,7 @@ void FrameMain::OnAudioClose() { void FrameMain::OnSubtitlesOpen() { UpdateTitle(); - auto vc = context->videoController; + auto vc = context->videoController.get(); /// @todo figure out how to move this to the relevant controllers without /// prompting for each file loaded/unloaded diff --git a/src/include/aegisub/context.h b/src/include/aegisub/context.h index 4f037ba21..f3186240a 100644 --- a/src/include/aegisub/context.h +++ b/src/include/aegisub/context.h @@ -1,3 +1,21 @@ +// Copyright (c) 2014, Thomas Goyne +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// +// Aegisub Project http://www.aegisub.org/ + +#include + class AssFile; class AudioBox; class AudioController; @@ -9,7 +27,6 @@ class SearchReplaceEngine; class InitialLineState; class SelectionController; class SubsController; -class SubsTextEditCtrl; class BaseGrid; class TextSelectionController; class VideoContext; @@ -20,32 +37,33 @@ namespace Automation4 { class ScriptManager; } namespace agi { struct Context { - // Models - AssFile *ass; - Automation4::ScriptManager *local_scripts; - InitialLineState *initialLineState; - - // Controllers - AudioController *audioController; - SelectionController *selectionController; - SubsController *subsController; + // Note: order here matters quite a bit, as things need to be set up and + // torn down in the correct order + std::unique_ptr ass; + std::unique_ptr subsController; + std::unique_ptr local_scripts; + std::unique_ptr videoController; + std::unique_ptr audioController; + std::unique_ptr selectionController; + std::unique_ptr initialLineState; TextSelectionController *textSelectionController; - VideoContext *videoController; - - SearchReplaceEngine *search; + std::unique_ptr search; // Things that should probably be in some sort of UI-context-model - wxWindow *parent; - wxWindow *previousFocus; - wxWindow *videoSlider; + wxWindow *parent = nullptr; + wxWindow *previousFocus = nullptr; + wxWindow *videoSlider = nullptr; // Views (i.e. things that should eventually not be here at all) - AudioBox *audioBox; - AudioKaraoke *karaoke; - BaseGrid *subsGrid; - DialogManager *dialog; - FrameMain *frame; - VideoDisplay *videoDisplay; + AudioBox *audioBox = nullptr; + AudioKaraoke *karaoke = nullptr; + BaseGrid *subsGrid = nullptr; + std::unique_ptr dialog; + FrameMain *frame = nullptr; + VideoDisplay *videoDisplay = nullptr; + + Context(); + ~Context(); }; } diff --git a/src/subs_controller.cpp b/src/subs_controller.cpp index 94ed5ad4c..8a5085d6a 100644 --- a/src/subs_controller.cpp +++ b/src/subs_controller.cpp @@ -150,6 +150,8 @@ SubsController::SubsController(agi::Context *context) }); } +SubsController::~SubsController() { } + void SubsController::SetSelectionController(SelectionController *selection_controller) { active_line_connection = context->selectionController->AddActiveLineListener(&SubsController::OnActiveLineChanged, this); selection_connection = context->selectionController->AddSelectionListener(&SubsController::OnSelectionChanged, this); @@ -254,7 +256,7 @@ void SubsController::Save(agi::fs::path const& filename, std::string const& enco FileSave(); - writer->WriteFile(context->ass, filename, encoding); + writer->WriteFile(context->ass.get(), filename, encoding); } catch (...) { autosaved_commit_id = old_autosaved_commit_id; @@ -309,7 +311,7 @@ agi::fs::path SubsController::AutoSave() { path /= str(boost::format("%s.%s.AUTOSAVE.ass") % name.string() % agi::util::strftime("%Y-%m-%d-%H-%M-%S")); - SubtitleFormat::GetWriter(path)->WriteFile(context->ass, path); + SubtitleFormat::GetWriter(path)->WriteFile(context->ass.get(), path); autosaved_commit_id = commit_id; return path; @@ -317,7 +319,7 @@ agi::fs::path SubsController::AutoSave() { bool SubsController::CanSave() const { try { - return SubtitleFormat::GetWriter(filename)->CanSave(context->ass); + return SubtitleFormat::GetWriter(filename)->CanSave(context->ass.get()); } catch (...) { return false; diff --git a/src/subs_controller.h b/src/subs_controller.h index a380c34e4..fb03f61ae 100644 --- a/src/subs_controller.h +++ b/src/subs_controller.h @@ -69,6 +69,7 @@ class SubsController { public: SubsController(agi::Context *context); + ~SubsController(); /// Set the selection controller to use /// diff --git a/src/video_context.cpp b/src/video_context.cpp index a4206131a..f06d5df27 100644 --- a/src/video_context.cpp +++ b/src/video_context.cpp @@ -60,10 +60,17 @@ #include -VideoContext::VideoContext() -: playback(this) +static VideoContext *instance; + +VideoContext::VideoContext(agi::Context *c) +: context(c) +, playback(this) , playAudioOnStep(OPT_GET("Audio/Plays When Stepping Video")) { + instance = this; + context->ass->AddCommitListener(&VideoContext::OnSubtitlesCommit, this); + context->subsController->AddFileSaveListener(&VideoContext::OnSubtitlesSave, this); + Bind(EVT_VIDEO_ERROR, &VideoContext::OnVideoError, this); Bind(EVT_SUBTITLES_ERROR, &VideoContext::OnSubtitlesError, this); Bind(wxEVT_TIMER, &VideoContext::OnPlayTimer, this); @@ -80,12 +87,10 @@ VideoContext::VideoContext() OPT_SUB("Video/Force BT.601", &VideoContext::Reload, this); } -VideoContext::~VideoContext () { -} +VideoContext::~VideoContext () { } VideoContext *VideoContext::Get() { - static VideoContext instance; - return &instance; + return instance; } void VideoContext::Reset() { @@ -109,12 +114,6 @@ void VideoContext::Reset() { if (!ovr_fps.IsLoaded()) TimecodesOpen(video_fps); } -void VideoContext::SetContext(agi::Context *context) { - this->context = context; - context->ass->AddCommitListener(&VideoContext::OnSubtitlesCommit, this); - context->subsController->AddFileSaveListener(&VideoContext::OnSubtitlesSave, this); -} - void VideoContext::SetVideo(const agi::fs::path &filename) { Reset(); if (filename.empty()) { @@ -208,7 +207,7 @@ void VideoContext::SetVideo(const agi::fs::path &filename) { if (agi::fs::HasExtension(filename, "mkv")) has_subtitles = MatroskaWrapper::HasSubtitles(filename); - provider->LoadSubtitles(context->ass); + provider->LoadSubtitles(context->ass.get()); VideoOpen(); KeyframesOpen(keyframes); TimecodesOpen(FPS()); @@ -240,9 +239,9 @@ void VideoContext::OnSubtitlesCommit(int type, std::set con if (!IsLoaded()) return; if (changed.empty() || no_amend) - provider->LoadSubtitles(context->ass); + provider->LoadSubtitles(context->ass.get()); else - provider->UpdateSubtitles(context->ass, changed); + provider->UpdateSubtitles(context->ass.get(), changed); if (!IsPlaying()) GetFrameAsync(frame_n); diff --git a/src/video_context.h b/src/video_context.h index 5dc200b25..280ff6aba 100644 --- a/src/video_context.h +++ b/src/video_context.h @@ -90,7 +90,7 @@ class VideoContext final : public wxEvtHandler { /// The video provider owned by the threaded frame source, or nullptr if no /// video is open - VideoProvider *video_provider; + VideoProvider *video_provider = nullptr; /// Asynchronous provider of video frames std::unique_ptr provider; @@ -162,16 +162,9 @@ class VideoContext final : public wxEvtHandler { void Reset(); public: - VideoContext(); + VideoContext(agi::Context *context); ~VideoContext(); - /// @brief Set the context that this is the video controller for - /// @param context Initialized project context - /// - /// Once this is no longer a singleton this can probably be moved into - /// the constructor - void SetContext(agi::Context *context); - /// @brief Get the video provider used for the currently open video VideoProvider *GetProvider() const { return video_provider; } diff --git a/src/visual_tool_drag.cpp b/src/visual_tool_drag.cpp index 12587295e..672d68d2d 100644 --- a/src/visual_tool_drag.cpp +++ b/src/visual_tool_drag.cpp @@ -81,7 +81,7 @@ void VisualToolDrag::UpdateToggleButtons() { void VisualToolDrag::OnSubTool(wxCommandEvent &) { // Toggle \move <-> \pos - VideoContext *vc = c->videoController; + VideoContext *vc = c->videoController.get(); for (auto line : selection) { Vector2D p1, p2; int t1, t2;