It's modestly faster, significantly more type-safe, and doesn't assert
when there's too few arguments, which causes problems for plural forms.
Closes#1733.
It drags in a ton of crap, is kinda slow at runtime due to using
std::deque, and doesn't actually make the code much simpler than just
using a manual ring buffer.
Add a new Project class which is responsible for everything related to
opening and closing audio, video, subtitles, timecodes and keyframes.
This pulls almost everything not directly related to playing audio/video
out of the audio and video controllers, pulls more crap out of
FrameMain, and happens to make things a little simpler in the process.
In preparation for switching to LuaJIT, which doesn't support PUC Lua's
thing of using C++ exceptions for lua_error.
Requires replacing all uses of lua_error (and things calling lua_error)
with custom versions that throw an exception instead and adding an
exception -> lua error wrapper at all C++ -> Lua boundaries.
This requires shuffling a bunch of stuff around to get a CLI lua
executable that uses an automation-like environment, but that's
something that'll be nice to have in the future anyway.
Busted indirectly depends on lfs and we currently can't use external
binary modules, so add a copy of lfs to the repo and build it with
Aegisub.
Use explicitly defaulted destructors for base cases when possible,
eliminate aggregate initialization constructors where possible, and push
some more stuff to NSDMIs.
Since luabins generates binary data which grows up to 3x by escaping,
it's more efficient to uuencode that instead.
A marker is placed as the first character of the value field, either
'e' for inline_string escaped text, or 'u' for uuencoded binary data.
The key is always inline_string escaped, as it will typically be
human readable.
Simply zero the memory for audio which hasn't been decoded yet, modify
the audio renderer to avoid caching blocks which aren't ready yet, and
add a progress indiciator to the audio display scrollbar.
ICU docs say not to create a new break iterator each time as
boost.locale does, and in fact creating the break iterator is about 90%
of the run time of the character counter, so use ICU directly and cache
the break iterator.