Pull some of the context (de)init out of FrameMain

And actually do deinitialize more of the stuff in the context.
This commit is contained in:
Thomas Goyne 2014-03-25 14:49:26 -07:00
parent 821f54a372
commit aa46c49403
23 changed files with 139 additions and 101 deletions

View File

@ -329,6 +329,7 @@
<ClCompile Include="$(SrcDir)command\video.cpp" /> <ClCompile Include="$(SrcDir)command\video.cpp" />
<ClCompile Include="$(SrcDir)command\vis_tool.cpp" /> <ClCompile Include="$(SrcDir)command\vis_tool.cpp" />
<ClCompile Include="$(SrcDir)compat.cpp" /> <ClCompile Include="$(SrcDir)compat.cpp" />
<ClCompile Include="$(SrcDir)context.cpp" />
<ClCompile Include="$(SrcDir)crash_writer.cpp"> <ClCompile Include="$(SrcDir)crash_writer.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>

View File

@ -1184,6 +1184,9 @@
<ClCompile Include="$(SrcDir)crash_writer_minidump.cpp"> <ClCompile Include="$(SrcDir)crash_writer_minidump.cpp">
<Filter>Utilities\Logging</Filter> <Filter>Utilities\Logging</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(SrcDir)context.cpp">
<Filter>Main UI</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="$(SrcDir)res/res.rc"> <ResourceCompile Include="$(SrcDir)res/res.rc">

View File

@ -154,6 +154,7 @@ SRC += \
colorspace.cpp \ colorspace.cpp \
colour_button.cpp \ colour_button.cpp \
compat.cpp \ compat.cpp \
context.cpp \
crash_writer.cpp \ crash_writer.cpp \
dialog_about.cpp \ dialog_about.cpp \
dialog_attachments.cpp \ dialog_attachments.cpp \

View File

@ -75,11 +75,11 @@ enum {
AudioBox::AudioBox(wxWindow *parent, agi::Context *context) AudioBox::AudioBox(wxWindow *parent, agi::Context *context)
: wxSashWindow(parent, -1, wxDefaultPosition, wxDefaultSize, wxSW_3D | wxCLIP_CHILDREN) : wxSashWindow(parent, -1, wxDefaultPosition, wxDefaultSize, wxSW_3D | wxCLIP_CHILDREN)
, controller(context->audioController) , controller(context->audioController.get())
, context(context) , context(context)
, audio_open_connection(controller->AddAudioOpenListener(&AudioBox::OnAudioOpen, this)) , audio_open_connection(controller->AddAudioOpenListener(&AudioBox::OnAudioOpen, this))
, panel(new wxPanel(this, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxBORDER_RAISED)) , 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)) , 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)) , 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)) , VolumeBar(new wxSlider(panel, Audio_Volume, OPT_GET("Audio/Volume")->GetInt(), 0, 100, wxDefaultPosition, wxSize(-1, 20), wxSL_VERTICAL|wxSL_BOTH|wxSL_INVERSE))

View File

@ -45,7 +45,7 @@ public:
}; };
AudioMarkerProviderKeyframes::AudioMarkerProviderKeyframes(agi::Context *c, const char *opt_name) AudioMarkerProviderKeyframes::AudioMarkerProviderKeyframes(agi::Context *c, const char *opt_name)
: vc(c->videoController) : vc(c->videoController.get())
, keyframe_slot(vc->AddKeyframesListener(&AudioMarkerProviderKeyframes::Update, this)) , keyframe_slot(vc->AddKeyframesListener(&AudioMarkerProviderKeyframes::Update, this))
, timecode_slot(vc->AddTimecodesListener(&AudioMarkerProviderKeyframes::Update, this)) , timecode_slot(vc->AddTimecodesListener(&AudioMarkerProviderKeyframes::Update, this))
, enabled_slot(OPT_SUB(opt_name, &AudioMarkerProviderKeyframes::Update, this)) , enabled_slot(OPT_SUB(opt_name, &AudioMarkerProviderKeyframes::Update, this))
@ -107,7 +107,7 @@ public:
}; };
VideoPositionMarkerProvider::VideoPositionMarkerProvider(agi::Context *c) VideoPositionMarkerProvider::VideoPositionMarkerProvider(agi::Context *c)
: vc(c->videoController) : vc(c->videoController.get())
, video_seek_slot(vc->AddSeekListener(&VideoPositionMarkerProvider::Update, this)) , video_seek_slot(vc->AddSeekListener(&VideoPositionMarkerProvider::Update, this))
, enable_opt_changed_slot(OPT_SUB("Audio/Display/Draw/Video Position", &VideoPositionMarkerProvider::OptChanged, this)) , enable_opt_changed_slot(OPT_SUB("Audio/Display/Draw/Video Position", &VideoPositionMarkerProvider::OptChanged, this))
{ {

View File

@ -861,7 +861,7 @@ namespace Automation4 {
set_context(L, c); set_context(L, c);
GetFeatureFunction("validate"); GetFeatureFunction("validate");
auto subsobj = new LuaAssFile(L, c->ass); auto subsobj = new LuaAssFile(L, c->ass.get());
push_value(L, transform_selection(L, c)); push_value(L, transform_selection(L, c));
int err = lua_pcall(L, 3, 2, 0); int err = lua_pcall(L, 3, 2, 0);
@ -894,7 +894,7 @@ namespace Automation4 {
stackcheck.check_stack(0); stackcheck.check_stack(0);
GetFeatureFunction("run"); 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)); push_value(L, transform_selection(L, c));
try { try {
@ -966,7 +966,7 @@ namespace Automation4 {
stackcheck.check_stack(0); stackcheck.check_stack(0);
GetFeatureFunction("isactive"); GetFeatureFunction("isactive");
auto subsobj = new LuaAssFile(L, c->ass); auto subsobj = new LuaAssFile(L, c->ass.get());
push_value(L, transform_selection(L, c)); push_value(L, transform_selection(L, c));
int err = lua_pcall(L, 3, 1, 0); int err = lua_pcall(L, 3, 1, 0);
@ -1071,7 +1071,7 @@ namespace Automation4 {
GetFeatureFunction("config"); GetFeatureFunction("config");
// prepare function call // prepare function call
auto subsobj = new LuaAssFile(L, c->ass); auto subsobj = new LuaAssFile(L, c->ass.get());
// stored options // stored options
lua_newtable(L); // TODO, nothing for now lua_newtable(L); // TODO, nothing for now

View File

@ -87,7 +87,7 @@ struct subtitle_attachment final : public Command {
void operator()(agi::Context *c) override { void operator()(agi::Context *c) override {
c->videoController->Stop(); c->videoController->Stop();
DialogAttachments(c->parent, c->ass).ShowModal(); DialogAttachments(c->parent, c->ass.get()).ShowModal();
} }
}; };

View File

@ -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") STR_HELP("Set start and end of subtitles to the keyframes around current video frame")
void operator()(agi::Context *c) override { void operator()(agi::Context *c) override {
VideoContext *con = c->videoController; VideoContext *con = c->videoController.get();
if (!con->IsLoaded() || !con->KeyFramesLoaded()) return; if (!con->IsLoaded() || !con->KeyFramesLoaded()) return;
int curFrame = con->GetFrameN(); int curFrame = con->GetFrameN();

View File

@ -120,7 +120,7 @@ struct tool_resampleres final : public Command {
c->videoController->Stop(); c->videoController->Stop();
ResampleSettings settings; ResampleSettings settings;
if (DialogResample(c, settings).ShowModal() == wxID_OK) if (DialogResample(c, settings).ShowModal() == wxID_OK)
ResampleResolution(c->ass, settings); ResampleResolution(c->ass.get(), settings);
} }
}; };

49
src/context.cpp Normal file
View File

@ -0,0 +1,49 @@
// Copyright (c) 2014, Thomas Goyne <plorkyeran@aegisub.org>
//
// 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 <libaegisub/util.h>
namespace agi {
Context::Context()
: ass(util::make_unique<AssFile>())
, subsController(util::make_unique<SubsController>(this))
, local_scripts(util::make_unique<Automation4::LocalScriptManager>(this))
, videoController(util::make_unique<VideoContext>(this))
, audioController(util::make_unique<AudioController>(this))
, selectionController(util::make_unique<SelectionController>(this))
, initialLineState(util::make_unique<InitialLineState>(this))
, search(util::make_unique<SearchReplaceEngine>(this))
, dialog(util::make_unique<DialogManager>())
{
subsController->SetSelectionController(selectionController.get());
}
Context::~Context() {}
}

View File

@ -61,7 +61,7 @@ using std::placeholders::_1;
DialogAutomation::DialogAutomation(agi::Context *c) DialogAutomation::DialogAutomation(agi::Context *c)
: wxDialog(c->parent, -1, _("Automation Manager"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) : wxDialog(c->parent, -1, _("Automation Manager"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
, context(c) , context(c)
, local_manager(c->local_scripts) , local_manager(c->local_scripts.get())
, local_scripts_changed(local_manager->AddScriptChangeListener(&DialogAutomation::RebuildList, this)) , local_scripts_changed(local_manager->AddScriptChangeListener(&DialogAutomation::RebuildList, this))
, global_manager(wxGetApp().global_scripts) , global_manager(wxGetApp().global_scripts)
, global_scripts_changed(global_manager->AddScriptChangeListener(&DialogAutomation::RebuildList, this)) , global_scripts_changed(global_manager->AddScriptChangeListener(&DialogAutomation::RebuildList, this))

View File

@ -183,7 +183,7 @@ void FontsCollectorThread(AssFile *subs, agi::fs::path const& destination, FcMod
DialogFontsCollector::DialogFontsCollector(agi::Context *c) DialogFontsCollector::DialogFontsCollector(agi::Context *c)
: wxDialog(c->parent, -1, _("Fonts Collector")) : wxDialog(c->parent, -1, _("Fonts Collector"))
, subs(c->ass) , subs(c->ass.get())
{ {
SetIcon(GETICON(font_collector_button_16)); SetIcon(GETICON(font_collector_button_16));

View File

@ -450,7 +450,7 @@ bool KaraokeLineMatchDisplay::UndoMatch()
DialogKanjiTimer::DialogKanjiTimer(agi::Context *c) DialogKanjiTimer::DialogKanjiTimer(agi::Context *c)
: wxDialog(c->parent, -1, _("Kanji timing")) : wxDialog(c->parent, -1, _("Kanji timing"))
, subs(c->ass) , subs(c->ass.get())
{ {
SetIcon(GETICON(kara_timing_copier_16)); SetIcon(GETICON(kara_timing_copier_16));

View File

@ -136,7 +136,7 @@ void DialogSearchReplace::FindReplace(bool (SearchReplaceEngine::*func)()) {
c->search->Configure(*settings); c->search->Configure(*settings);
try { try {
(c->search->*func)(); ((*c->search).*func)();
} }
catch (std::exception const& e) { catch (std::exception const& e) {
wxMessageBox(to_wx(e.what()), "Error", wxOK | wxICON_ERROR | wxCENTER, this); wxMessageBox(to_wx(e.what()), "Error", wxOK | wxICON_ERROR | wxCENTER, this);

View File

@ -178,7 +178,7 @@ void DialogSelection::Process(wxCommandEvent&) {
from_wx(match_text->GetValue()), case_sensitive->IsChecked(), from_wx(match_text->GetValue()), case_sensitive->IsChecked(),
static_cast<Mode>(match_mode->GetSelection()), select_unmatching_lines->GetValue(), static_cast<Mode>(match_mode->GetSelection()), select_unmatching_lines->GetValue(),
apply_to_comments->IsChecked(), apply_to_dialogue->IsChecked(), apply_to_comments->IsChecked(), apply_to_dialogue->IsChecked(),
dialogue_field->GetSelection(), con->ass); dialogue_field->GetSelection(), con->ass.get());
} }
catch (agi::Exception const&) { catch (agi::Exception const&) {
Close(); Close();

View File

@ -477,7 +477,7 @@ void DialogStyleManager::CopyToClipboard(wxListBox *list, T const& v) {
void DialogStyleManager::PasteToCurrent() { void DialogStyleManager::PasteToCurrent() {
add_styles( 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); }); [=](AssStyle *s) { c->ass->Styles.push_back(*s); });
c->ass->Commit(_("style paste"), AssFile::COMMIT_STYLES); c->ass->Commit(_("style paste"), AssFile::COMMIT_STYLES);
@ -554,8 +554,9 @@ void DialogStyleManager::OnCurrentCopy() {
int sel = get_single_sel(CurrentList); int sel = get_single_sel(CurrentList);
if (sel == -1) return; if (sel == -1) return;
ShowCurrentEditor(styleMap[sel], ShowCurrentEditor(styleMap[sel], unique_name(
unique_name(std::bind(&AssFile::GetStyle, c->ass, _1), styleMap[sel]->name)); [=](std::string const& str) { return c->ass->GetStyle(str); },
styleMap[sel]->name));
} }
void DialogStyleManager::OnCurrentDelete() { void DialogStyleManager::OnCurrentDelete() {

View File

@ -44,7 +44,6 @@
#include "ass_file.h" #include "ass_file.h"
#include "audio_controller.h" #include "audio_controller.h"
#include "audio_box.h" #include "audio_box.h"
#include "auto4_base.h"
#include "base_grid.h" #include "base_grid.h"
#include "compat.h" #include "compat.h"
#include "command/command.h" #include "command/command.h"
@ -52,12 +51,9 @@
#include "dialog_manager.h" #include "dialog_manager.h"
#include "dialog_version_check.h" #include "dialog_version_check.h"
#include "help_button.h" #include "help_button.h"
#include "initial_line_state.h"
#include "libresrc/libresrc.h" #include "libresrc/libresrc.h"
#include "main.h" #include "main.h"
#include "options.h" #include "options.h"
#include "selection_controller.h"
#include "search_replace_engine.h"
#include "subs_controller.h" #include "subs_controller.h"
#include "subs_edit_box.h" #include "subs_edit_box.h"
#include "subs_edit_ctrl.h" #include "subs_edit_ctrl.h"
@ -205,32 +201,17 @@ FrameMain::FrameMain()
LOG_D("locale") << setlocale(LC_ALL, nullptr); LOG_D("locale") << setlocale(LC_ALL, nullptr);
#endif #endif
StartupLog("Initializing context models");
memset(context.get(), 0, sizeof(*context));
context->ass = new AssFile;
StartupLog("Initializing context controls"); StartupLog("Initializing context controls");
context->subsController = new SubsController(context.get());
context->ass->AddCommitListener(&FrameMain::UpdateTitle, this); context->ass->AddCommitListener(&FrameMain::UpdateTitle, this);
context->subsController->AddFileOpenListener(&FrameMain::OnSubtitlesOpen, this); context->subsController->AddFileOpenListener(&FrameMain::OnSubtitlesOpen, this);
context->subsController->AddFileSaveListener(&FrameMain::UpdateTitle, this); context->subsController->AddFileSaveListener(&FrameMain::UpdateTitle, this);
context->audioController = new AudioController(context.get());
context->audioController->AddAudioOpenListener(&FrameMain::OnAudioOpen, this); context->audioController->AddAudioOpenListener(&FrameMain::OnAudioOpen, this);
context->audioController->AddAudioCloseListener(&FrameMain::OnAudioClose, 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); context->videoController->AddVideoOpenListener(&FrameMain::OnVideoOpen, this);
StartupLog("Initializing context frames"); StartupLog("Initializing context frames");
context->parent = this; context->parent = this;
context->frame = this; context->frame = this;
context->previousFocus = nullptr;
StartupLog("Install PNG handler"); StartupLog("Install PNG handler");
wxImage::AddHandler(new wxPNGHandler); wxImage::AddHandler(new wxPNGHandler);
@ -257,13 +238,9 @@ FrameMain::FrameMain()
#endif #endif
StartupLog("Create views and inner main window controls"); StartupLog("Create views and inner main window controls");
context->dialog = new DialogManager;
InitContents(); InitContents();
OPT_SUB("Video/Detached/Enabled", &FrameMain::OnVideoDetach, this, agi::signal::_1); 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"); StartupLog("Set up drag/drop target");
SetDropTarget(new AegisubFileDropTarget(this)); SetDropTarget(new AegisubFileDropTarget(this));
@ -307,10 +284,6 @@ FrameMain::~FrameMain () {
context->audioController->CloseAudio(); context->audioController->CloseAudio();
DestroyChildren(); DestroyChildren();
delete context->ass;
delete context->audioController;
delete context->local_scripts;
} }
void FrameMain::InitToolbar() { void FrameMain::InitToolbar() {
@ -339,8 +312,6 @@ void FrameMain::InitContents() {
StartupLog("Create subtitles grid"); StartupLog("Create subtitles grid");
context->subsGrid = new BaseGrid(Panel, context.get()); context->subsGrid = new BaseGrid(Panel, context.get());
context->search = new SearchReplaceEngine(context.get());
context->initialLineState = new InitialLineState(context.get());
StartupLog("Create video box"); StartupLog("Create video box");
videoBox = new VideoBox(Panel, false, context.get()); videoBox = new VideoBox(Panel, false, context.get());
@ -530,8 +501,7 @@ void FrameMain::OnCloseWindow(wxCloseEvent &event) {
return; return;
} }
delete context->dialog; context->dialog.reset();
context->dialog = nullptr;
// Store maximization state // Store maximization state
OPT_SET("App/Maximized")->SetBool(IsMaximized()); OPT_SET("App/Maximized")->SetBool(IsMaximized());
@ -553,7 +523,7 @@ void FrameMain::OnAudioClose() {
void FrameMain::OnSubtitlesOpen() { void FrameMain::OnSubtitlesOpen() {
UpdateTitle(); UpdateTitle();
auto vc = context->videoController; auto vc = context->videoController.get();
/// @todo figure out how to move this to the relevant controllers without /// @todo figure out how to move this to the relevant controllers without
/// prompting for each file loaded/unloaded /// prompting for each file loaded/unloaded

View File

@ -1,3 +1,21 @@
// Copyright (c) 2014, Thomas Goyne <plorkyeran@aegisub.org>
//
// 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 <memory>
class AssFile; class AssFile;
class AudioBox; class AudioBox;
class AudioController; class AudioController;
@ -9,7 +27,6 @@ class SearchReplaceEngine;
class InitialLineState; class InitialLineState;
class SelectionController; class SelectionController;
class SubsController; class SubsController;
class SubsTextEditCtrl;
class BaseGrid; class BaseGrid;
class TextSelectionController; class TextSelectionController;
class VideoContext; class VideoContext;
@ -20,32 +37,33 @@ namespace Automation4 { class ScriptManager; }
namespace agi { namespace agi {
struct Context { struct Context {
// Models // Note: order here matters quite a bit, as things need to be set up and
AssFile *ass; // torn down in the correct order
Automation4::ScriptManager *local_scripts; std::unique_ptr<AssFile> ass;
InitialLineState *initialLineState; std::unique_ptr<SubsController> subsController;
std::unique_ptr<Automation4::ScriptManager> local_scripts;
// Controllers std::unique_ptr<VideoContext> videoController;
AudioController *audioController; std::unique_ptr<AudioController> audioController;
SelectionController *selectionController; std::unique_ptr<SelectionController> selectionController;
SubsController *subsController; std::unique_ptr<InitialLineState> initialLineState;
TextSelectionController *textSelectionController; TextSelectionController *textSelectionController;
VideoContext *videoController; std::unique_ptr<SearchReplaceEngine> search;
SearchReplaceEngine *search;
// Things that should probably be in some sort of UI-context-model // Things that should probably be in some sort of UI-context-model
wxWindow *parent; wxWindow *parent = nullptr;
wxWindow *previousFocus; wxWindow *previousFocus = nullptr;
wxWindow *videoSlider; wxWindow *videoSlider = nullptr;
// Views (i.e. things that should eventually not be here at all) // Views (i.e. things that should eventually not be here at all)
AudioBox *audioBox; AudioBox *audioBox = nullptr;
AudioKaraoke *karaoke; AudioKaraoke *karaoke = nullptr;
BaseGrid *subsGrid; BaseGrid *subsGrid = nullptr;
DialogManager *dialog; std::unique_ptr<DialogManager> dialog;
FrameMain *frame; FrameMain *frame = nullptr;
VideoDisplay *videoDisplay; VideoDisplay *videoDisplay = nullptr;
Context();
~Context();
}; };
} }

View File

@ -150,6 +150,8 @@ SubsController::SubsController(agi::Context *context)
}); });
} }
SubsController::~SubsController() { }
void SubsController::SetSelectionController(SelectionController *selection_controller) { void SubsController::SetSelectionController(SelectionController *selection_controller) {
active_line_connection = context->selectionController->AddActiveLineListener(&SubsController::OnActiveLineChanged, this); active_line_connection = context->selectionController->AddActiveLineListener(&SubsController::OnActiveLineChanged, this);
selection_connection = context->selectionController->AddSelectionListener(&SubsController::OnSelectionChanged, 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(); FileSave();
writer->WriteFile(context->ass, filename, encoding); writer->WriteFile(context->ass.get(), filename, encoding);
} }
catch (...) { catch (...) {
autosaved_commit_id = old_autosaved_commit_id; 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")); 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; autosaved_commit_id = commit_id;
return path; return path;
@ -317,7 +319,7 @@ agi::fs::path SubsController::AutoSave() {
bool SubsController::CanSave() const { bool SubsController::CanSave() const {
try { try {
return SubtitleFormat::GetWriter(filename)->CanSave(context->ass); return SubtitleFormat::GetWriter(filename)->CanSave(context->ass.get());
} }
catch (...) { catch (...) {
return false; return false;

View File

@ -69,6 +69,7 @@ class SubsController {
public: public:
SubsController(agi::Context *context); SubsController(agi::Context *context);
~SubsController();
/// Set the selection controller to use /// Set the selection controller to use
/// ///

View File

@ -60,10 +60,17 @@
#include <wx/msgdlg.h> #include <wx/msgdlg.h>
VideoContext::VideoContext() static VideoContext *instance;
: playback(this)
VideoContext::VideoContext(agi::Context *c)
: context(c)
, playback(this)
, playAudioOnStep(OPT_GET("Audio/Plays When Stepping Video")) , 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_VIDEO_ERROR, &VideoContext::OnVideoError, this);
Bind(EVT_SUBTITLES_ERROR, &VideoContext::OnSubtitlesError, this); Bind(EVT_SUBTITLES_ERROR, &VideoContext::OnSubtitlesError, this);
Bind(wxEVT_TIMER, &VideoContext::OnPlayTimer, this); Bind(wxEVT_TIMER, &VideoContext::OnPlayTimer, this);
@ -80,12 +87,10 @@ VideoContext::VideoContext()
OPT_SUB("Video/Force BT.601", &VideoContext::Reload, this); OPT_SUB("Video/Force BT.601", &VideoContext::Reload, this);
} }
VideoContext::~VideoContext () { VideoContext::~VideoContext () { }
}
VideoContext *VideoContext::Get() { VideoContext *VideoContext::Get() {
static VideoContext instance; return instance;
return &instance;
} }
void VideoContext::Reset() { void VideoContext::Reset() {
@ -109,12 +114,6 @@ void VideoContext::Reset() {
if (!ovr_fps.IsLoaded()) TimecodesOpen(video_fps); 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) { void VideoContext::SetVideo(const agi::fs::path &filename) {
Reset(); Reset();
if (filename.empty()) { if (filename.empty()) {
@ -208,7 +207,7 @@ void VideoContext::SetVideo(const agi::fs::path &filename) {
if (agi::fs::HasExtension(filename, "mkv")) if (agi::fs::HasExtension(filename, "mkv"))
has_subtitles = MatroskaWrapper::HasSubtitles(filename); has_subtitles = MatroskaWrapper::HasSubtitles(filename);
provider->LoadSubtitles(context->ass); provider->LoadSubtitles(context->ass.get());
VideoOpen(); VideoOpen();
KeyframesOpen(keyframes); KeyframesOpen(keyframes);
TimecodesOpen(FPS()); TimecodesOpen(FPS());
@ -240,9 +239,9 @@ void VideoContext::OnSubtitlesCommit(int type, std::set<const AssDialogue *> con
if (!IsLoaded()) return; if (!IsLoaded()) return;
if (changed.empty() || no_amend) if (changed.empty() || no_amend)
provider->LoadSubtitles(context->ass); provider->LoadSubtitles(context->ass.get());
else else
provider->UpdateSubtitles(context->ass, changed); provider->UpdateSubtitles(context->ass.get(), changed);
if (!IsPlaying()) if (!IsPlaying())
GetFrameAsync(frame_n); GetFrameAsync(frame_n);

View File

@ -90,7 +90,7 @@ class VideoContext final : public wxEvtHandler {
/// The video provider owned by the threaded frame source, or nullptr if no /// The video provider owned by the threaded frame source, or nullptr if no
/// video is open /// video is open
VideoProvider *video_provider; VideoProvider *video_provider = nullptr;
/// Asynchronous provider of video frames /// Asynchronous provider of video frames
std::unique_ptr<ThreadedFrameSource> provider; std::unique_ptr<ThreadedFrameSource> provider;
@ -162,16 +162,9 @@ class VideoContext final : public wxEvtHandler {
void Reset(); void Reset();
public: public:
VideoContext(); VideoContext(agi::Context *context);
~VideoContext(); ~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 /// @brief Get the video provider used for the currently open video
VideoProvider *GetProvider() const { return video_provider; } VideoProvider *GetProvider() const { return video_provider; }

View File

@ -81,7 +81,7 @@ void VisualToolDrag::UpdateToggleButtons() {
void VisualToolDrag::OnSubTool(wxCommandEvent &) { void VisualToolDrag::OnSubTool(wxCommandEvent &) {
// Toggle \move <-> \pos // Toggle \move <-> \pos
VideoContext *vc = c->videoController; VideoContext *vc = c->videoController.get();
for (auto line : selection) { for (auto line : selection) {
Vector2D p1, p2; Vector2D p1, p2;
int t1, t2; int t1, t2;