diff --git a/libaegisub/common/mru.cpp b/libaegisub/common/mru.cpp index 733576e2f..4616caf53 100644 --- a/libaegisub/common/mru.cpp +++ b/libaegisub/common/mru.cpp @@ -12,10 +12,6 @@ // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -/// @file mru.cpp -/// @brief Most Recently Used (MRU) Lists -/// @ingroup libaegisub - #include "libaegisub/mru.h" #include "libaegisub/cajun/writer.h" @@ -27,20 +23,19 @@ #include "libaegisub/option_value.h" namespace agi { - MRUManager::MRUManager(agi::fs::path const& config, std::pair default_config, agi::Options *options) : config_name(config) , options(options) +, option_names({ + {"Audio", "Limits/MRU"}, + {"Find", "Limits/Find Replace"}, + {"Keyframes", "Limits/MRU"}, + {"Replace", "Limits/Find Replace"}, + {"Subtitle", "Limits/MRU"}, + {"Timecodes", "Limits/MRU"}, + {"Video", "Limits/MRU"}, +}) { - option_names["Audio"] = "Limits/MRU"; - option_names["Keyframes"] = "Limits/MRU"; - option_names["Subtitle"] = "Limits/MRU"; - option_names["Timecodes"] = "Limits/MRU"; - option_names["Video"] = "Limits/MRU"; - - option_names["Find"] = "Limits/Find Replace"; - option_names["Replace"] = "Limits/Find Replace"; - LOG_D("agi/mru") << "Loading MRU List"; json::Object root(json_util::file(config, default_config)); @@ -48,9 +43,6 @@ MRUManager::MRUManager(agi::fs::path const& config, std::pair #include #include -#include namespace { - static const int64_t default_denominator = 1000000000; using agi::line_iterator; using namespace agi::vfr; @@ -85,26 +83,6 @@ TimecodeRange v1_parse_line(std::string const& str) { return range; } -/// @brief Generate override ranges for all frames with assumed fpses -/// @param ranges List with ranges which is mutated -/// @param fps Assumed fps to use for gaps -void v1_fill_range_gaps(std::list &ranges, double fps) { - // Range for frames between start and first override - if (ranges.empty() || ranges.front().start > 0) - ranges.push_front(TimecodeRange{0, ranges.empty() ? 0 : ranges.front().start - 1, fps}); - - for (auto cur = ++begin(ranges), prev = begin(ranges); cur != end(ranges); ++cur, ++prev) { - if (prev->end >= cur->start) - // mkvmerge allows overlapping timecode ranges, but does completely - // broken things with them - throw UnorderedTimecodes("Override ranges must not overlap"); - if (prev->end + 1 < cur->start) { - ranges.insert(cur, TimecodeRange{prev->end + 1, cur->start - 1, fps}); - ++prev; - } - } -} - /// @brief Parse a v1 timecode file /// @param file Iterator of lines in the file /// @param line Header of file with assumed fps @@ -116,17 +94,29 @@ int64_t v1_parse(line_iterator file, std::string line, std::vector< if (fps <= 0.) throw BadFPS("Assumed FPS must be greater than zero"); if (fps > 1000.) throw BadFPS("Assumed FPS must not be greater than 1000"); - std::list ranges; - transform(file, end(file), back_inserter(ranges), v1_parse_line); - ranges.erase(boost::remove_if(ranges, [](TimecodeRange const& r) { return r.fps == 0; }), ranges.end()); + std::vector ranges; + for (auto const& line : file) { + auto range = v1_parse_line(line); + if (range.fps != 0) + ranges.push_back(range); + } - ranges.sort(); - v1_fill_range_gaps(ranges, fps); - timecodes.reserve(ranges.back().end); + std::sort(begin(ranges), end(ranges)); + timecodes.reserve(ranges.back().end + 2); double time = 0.; + int frame = 0; for (auto const& range : ranges) { - for (int frame = range.start; frame <= range.end; ++frame) { + if (frame > range.start) { + // mkvmerge allows overlapping timecode ranges, but does completely + // broken things with them + throw UnorderedTimecodes("Override ranges must not overlap"); + } + for (; frame < range.start; ++frame) { + timecodes.push_back(int(time + .5)); + time += 1000. / fps; + } + for (; frame <= range.end; ++frame) { timecodes.push_back(int(time + .5)); time += 1000. / range.fps; } @@ -135,12 +125,9 @@ int64_t v1_parse(line_iterator file, std::string line, std::vector< last = int64_t(time * fps * default_denominator); return int64_t(fps * default_denominator); } - } -namespace agi { -namespace vfr { - +namespace agi { namespace vfr { Framerate::Framerate(double fps) : denominator(default_denominator) , numerator(int64_t(fps * denominator)) @@ -339,5 +326,4 @@ int Framerate::TimeAtSmpte(int h, int m, int s, int f) const { return TimeAtFrame(FrameAtSmpte(h, m, s, f)); } -} -} +} } diff --git a/libaegisub/include/libaegisub/mru.h b/libaegisub/include/libaegisub/mru.h index ee38daebc..e722a022f 100644 --- a/libaegisub/include/libaegisub/mru.h +++ b/libaegisub/include/libaegisub/mru.h @@ -12,12 +12,7 @@ // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -/// @file mru.h -/// @brief Public interface for MRU (Most Recently Used) lists. -/// @ingroup libaegisub - #include -#include #include #include @@ -30,10 +25,7 @@ namespace json { } namespace agi { - class Options; -} - -namespace agi { +class Options; DEFINE_BASE_EXCEPTION_NOINNER(MRUError,Exception) DEFINE_SIMPLE_EXCEPTION_NOINNER(MRUErrorInvalidKey, MRUError, "mru/invalid") @@ -46,11 +38,10 @@ DEFINE_SIMPLE_EXCEPTION_NOINNER(MRUErrorIndexOutOfRange, MRUError, "mru/invalid" /// entry or update it if it already exists. /// /// If a file fails to open, Remove() should be called. -/// class MRUManager { public: /// @brief Map for time->value pairs. - typedef std::list MRUListMap; + using MRUListMap = std::vector; /// @brief Constructor /// @param config File to load MRU values from @@ -60,9 +51,6 @@ public: MRUManager(agi::fs::path const& file, const char (&default_config)[N]) : MRUManager(file, {default_config, N - 1}) { } - /// Destructor - ~MRUManager(); - /// @brief Add entry to the list. /// @param key List name /// @param entry Entry to add @@ -99,15 +87,20 @@ private: /// @brief Map for MRUListMap values. /// @param std::string Name /// @param MRUListMap instance. - typedef std::map MRUMap; + using MRUMap = std::map; /// Internal MRUMap values. MRUMap mru; /// Map from MRU name to option name - std::map option_names; + const std::map option_names; + /// @brief Load MRU Lists. + /// @param key List name. + /// @param array json::Array of values. void Load(std::string const& key, ::json::Array const& array); + /// @brief Prune MRUListMap to the desired length. + /// This uses the user-set values for MRU list length. void Prune(std::string const& key, MRUListMap& map) const; MRUListMap &Find(std::string const& key); }; diff --git a/libaegisub/lagi_pre.h b/libaegisub/lagi_pre.h index a3411c677..5156899ba 100644 --- a/libaegisub/lagi_pre.h +++ b/libaegisub/lagi_pre.h @@ -35,14 +35,11 @@ #include #include #include -#include #include #include #include -#include #include #include -#include #include #ifdef _MSC_VER @@ -50,7 +47,6 @@ #endif // Boost -#include #include #define BOOST_NO_SCOPED_ENUMS #include diff --git a/src/agi_pre.h b/src/agi_pre.h index c18513f01..b2519bab2 100644 --- a/src/agi_pre.h +++ b/src/agi_pre.h @@ -54,6 +54,7 @@ // General headers #include #include +#include #include #include #include @@ -67,6 +68,7 @@ #include #endif +#include #include #include #include