Skip to content

Commit a13233a

Browse files
committed
Merge branches 'lua_api' and 'bugfixes' into feature
3 parents 5e51c59 + 7e08970 + f3d6eea commit a13233a

12 files changed

Lines changed: 146 additions & 26 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ jobs:
120120
if: startsWith(matrix.config.os, 'ubuntu-')
121121
run: |
122122
sudo apt-get update
123-
sudo apt-get install ninja-build build-essential libx11-dev libwxgtk3.0-gtk3-dev libfreetype6-dev pkg-config libfontconfig1-dev libass-dev libasound2-dev libffms2-dev intltool libboost-all-dev
123+
sudo apt-get install ninja-build build-essential libx11-dev libwxgtk3.0-gtk3-dev libfreetype6-dev pkg-config libfontconfig1-dev libass-dev libasound2-dev libffms2-dev intltool libboost-all-dev libhunspell-dev libuchardet-dev libpulse-dev libopenal-dev libjansson-dev
124124
125125
- name: Configure
126126
run: meson setup build ${{ matrix.config.args }} -Dbuildtype=${{ matrix.config.buildtype }}
@@ -188,7 +188,6 @@ jobs:
188188
189189
./linuxdeploy --appdir appdir --desktop-file=appdir/aegisub.desktop
190190
./appimagetool appdir
191-
# ./appimagetool -g -s appdir --comp xz
192191
193192
- name: Upload artifacts - Linux AppImage
194193
uses: actions/upload-artifact@v3

libaegisub/common/dispatch.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ namespace {
2929
boost::asio::io_service *service;
3030
std::function<void (agi::dispatch::Thunk)> invoke_main;
3131
std::atomic<uint_fast32_t> threads_running;
32+
thread_local bool is_main_thread;
3233

3334
class MainQueue final : public agi::dispatch::Queue {
3435
void DoInvoke(agi::dispatch::Thunk thunk) override {
@@ -78,10 +79,12 @@ void Init(std::function<void (Thunk)> invoke_main) {
7879
static IOServiceThreadPool thread_pool;
7980
::service = &thread_pool.io_service;
8081
::invoke_main = invoke_main;
82+
::is_main_thread = true;
8183

8284
thread_pool.threads.reserve(std::max<unsigned>(4, std::thread::hardware_concurrency()));
8385
for (size_t i = 0; i < thread_pool.threads.capacity(); ++i) {
8486
thread_pool.threads.emplace_back([]{
87+
::is_main_thread = false;
8588
++threads_running;
8689
agi::util::SetThreadName("Dispatch Worker");
8790
service->run();
@@ -123,6 +126,14 @@ void Queue::Sync(Thunk thunk) {
123126
if (e) std::rethrow_exception(e);
124127
}
125128

129+
void EnsureMain(Thunk thunk) {
130+
if (::is_main_thread) {
131+
thunk();
132+
} else {
133+
Main().Sync(thunk);
134+
}
135+
}
136+
126137
Queue& Main() {
127138
static MainQueue q;
128139
return q;

libaegisub/include/libaegisub/dispatch.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ namespace agi {
4141
/// Get the main queue, which runs on the GUI thread
4242
Queue& Main();
4343

44+
45+
/// Ensure that the thunk is run on the main thread, without deadlocking
46+
/// when already on the main thread
47+
void EnsureMain(Thunk thunk);
48+
4449
/// Get the generic background queue, which runs thunks in parallel
4550
Queue& Background();
4651

libaegisub/include/libaegisub/lua/utils.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ struct LuaStackcheck {
129129
void dump();
130130

131131
LuaStackcheck(lua_State *L) : L(L), startstack(lua_gettop(L)) { }
132-
~LuaStackcheck() { check_stack(0); }
133132
};
134133
#else
135134
struct LuaStackcheck {

src/auto4_base.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,14 +208,15 @@ namespace Automation4 {
208208

209209
void ProgressSink::ShowDialog(ScriptDialog *config_dialog)
210210
{
211-
agi::dispatch::Main().Sync([=] {
211+
agi::dispatch::EnsureMain([=] {
212212
wxDialog w; // container dialog box
213213
w.SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
214214
w.Create(bsr->GetParentWindow(), -1, to_wx(bsr->GetTitle()));
215215
auto s = new wxBoxSizer(wxHORIZONTAL); // sizer for putting contents in
216216
wxWindow *ww = config_dialog->CreateWindow(&w); // generate actual dialog contents
217217
s->Add(ww, 0, wxALL, 5); // add contents to dialog
218218
w.SetSizerAndFit(s);
219+
w.SetLayoutAdaptationMode(wxDIALOG_ADAPTATION_MODE_ENABLED);
219220
w.CenterOnParent();
220221
w.ShowModal();
221222
});

src/auto4_lua.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ namespace {
128128
const char *clipboard_get()
129129
{
130130
std::string data;
131-
agi::dispatch::Main().Sync([&] { data = GetClipboard(); });
131+
agi::dispatch::EnsureMain([&] { data = GetClipboard(); });
132132
if (data.empty())
133133
return nullptr;
134134
return strndup(data);
@@ -138,7 +138,7 @@ namespace {
138138
{
139139
bool succeeded = false;
140140

141-
agi::dispatch::Main().Sync([&] {
141+
agi::dispatch::EnsureMain([&] {
142142
wxClipboard &cb = *wxTheClipboard;
143143
if (cb.Open()) {
144144
succeeded = cb.SetData(new wxTextDataObject(wxString::FromUTF8(str)));
@@ -677,6 +677,7 @@ namespace {
677677
if (lua_isnumber(L, -1) && lua_tointeger(L, -1) == 3) {
678678
lua_pop(L, 1); // just to avoid tripping the stackcheck in debug
679679
description = "Attempted to load an Automation 3 script as an Automation 4 Lua script. Automation 3 is no longer supported.";
680+
stackcheck.check_stack(0);
680681
return;
681682
}
682683

@@ -689,6 +690,7 @@ namespace {
689690
name = GetPrettyFilename().string();
690691

691692
lua_pop(L, 1);
693+
stackcheck.check_stack(0);
692694
// if we got this far, the script should be ready
693695
loaded = true;
694696
}
@@ -1136,7 +1138,7 @@ namespace {
11361138

11371139
// config
11381140
if (has_config && config_dialog) {
1139-
int results_produced = config_dialog->LuaReadBack(L);
1141+
int results_produced = config_dialog->LuaReadBack();
11401142
assert(results_produced == 1);
11411143
(void) results_produced; // avoid warning on release builds
11421144
// TODO, write back stored options here

src/auto4_lua.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ namespace Automation4 {
7878
std::deque<PendingCommit> pending_commits;
7979
/// Lines to delete once processing complete successfully
8080
std::vector<std::unique_ptr<AssEntry>> lines_to_delete;
81+
/// Lines that were allocated here and need to be deleted if the script is cancelled.
82+
std::vector<AssEntry *> allocated_lines;
8183

8284
/// Create copies of all of the lines in the script info section if it
8385
/// hasn't already happened. This is done lazily, since it only needs
@@ -118,6 +120,8 @@ namespace Automation4 {
118120
/// assumes a Lua representation of AssEntry on the top of the stack, and creates an AssEntry object of it
119121
static std::unique_ptr<AssEntry> LuaToAssEntry(lua_State *L, AssFile *ass=nullptr);
120122

123+
std::unique_ptr<AssEntry> LuaToTrackedAssEntry(lua_State *L);
124+
121125
/// @brief Signal that the script using this file is now done running
122126
/// @param set_undo If there's any uncommitted changes to the file,
123127
/// they will be automatically committed with this

src/auto4_lua_assfile.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,12 @@ namespace Automation4 {
328328
return result;
329329
}
330330

331+
std::unique_ptr<AssEntry> LuaAssFile::LuaToTrackedAssEntry(lua_State *L) {
332+
std::unique_ptr<AssEntry> e = LuaToAssEntry(L, ass);
333+
allocated_lines.push_back(e.get());
334+
return e;
335+
}
336+
331337
int LuaAssFile::ObjectIndexRead(lua_State *L)
332338
{
333339
switch (lua_type(L, 2)) {
@@ -453,7 +459,7 @@ namespace Automation4 {
453459
// insert
454460
CheckBounds(n);
455461

456-
auto e = LuaToAssEntry(L, ass);
462+
auto e = LuaToTrackedAssEntry(L);
457463
modification_type |= modification_mask(e.get());
458464
QueueLineForDeletion(n - 1);
459465
AssignLine(n - 1, std::move(e));
@@ -542,7 +548,7 @@ namespace Automation4 {
542548

543549
for (int i = 1; i <= n; i++) {
544550
lua_pushvalue(L, i);
545-
auto e = LuaToAssEntry(L, ass);
551+
auto e = LuaToTrackedAssEntry(L);
546552
modification_type |= modification_mask(e.get());
547553

548554
if (lines.empty()) {
@@ -586,7 +592,7 @@ namespace Automation4 {
586592
new_entries.reserve(n - 1);
587593
for (int i = 2; i <= n; i++) {
588594
lua_pushvalue(L, i);
589-
auto e = LuaToAssEntry(L, ass);
595+
auto e = LuaToTrackedAssEntry(L);
590596
modification_type |= modification_mask(e.get());
591597
InsertLine(new_entries, i - 2, std::move(e));
592598
lua_pop(L, 1);
@@ -625,7 +631,7 @@ namespace Automation4 {
625631

626632
int LuaAssFile::LuaParseKaraokeData(lua_State *L)
627633
{
628-
auto e = LuaToAssEntry(L, ass);
634+
auto e = LuaToTrackedAssEntry(L);
629635
auto dia = check_cast_constptr<AssDialogue>(e.get());
630636
argcheck(L, !!dia, 1, "Subtitle line must be a dialogue line");
631637

@@ -734,6 +740,7 @@ namespace Automation4 {
734740
void LuaAssFile::Cancel()
735741
{
736742
for (auto& line : lines_to_delete) line.release();
743+
for (AssEntry *line : allocated_lines) delete line;
737744
references--;
738745
if (!references) delete this;
739746
}

0 commit comments

Comments
 (0)