diff --git a/aegisub/src/factory_manager.h b/aegisub/src/factory_manager.h index 2ec10dd42..fcfd01f82 100644 --- a/aegisub/src/factory_manager.h +++ b/aegisub/src/factory_manager.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012, Thomas Goyne +// 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 @@ -27,9 +27,11 @@ #include #include -template -class FactoryBase { -protected: +namespace agi { class ProgressSink; } + +template +class Factory { + typedef Base *(*func)(Args const&...); typedef std::map> map; static map& classes() { @@ -37,81 +39,37 @@ protected: return classes; } - static void DoRegister(func function, std::string name, bool hide, std::vector &subtypes) { - if (subtypes.empty()) - classes().insert(std::make_pair(name, std::make_pair(hide, function))); - else { - for (auto const& subtype : subtypes) - classes().insert(std::make_pair(name + '/' + subtype, std::make_pair(hide, function))); - } - } - - static func Find(std::string const& name) { - auto factory = classes().find(name); - return factory != classes().end() ? factory->second.second : nullptr; - } - public: - static std::vector GetClasses(std::string favourite="") { + static std::vector GetClasses(std::string favorite="") { std::vector list; std::string cmp; - std::transform(favourite.begin(), favourite.end(), favourite.begin(), ::tolower); + for (auto& c : favorite) c = ::tolower(c); for (auto const& cls : classes()) { cmp.clear(); std::transform(cls.first.begin(), cls.first.end(), std::back_inserter(cmp), ::tolower); - if (cmp == favourite) + if (cmp == favorite) list.insert(list.begin(), cls.first); else if (!cls.second.first) list.push_back(cls.first); } return list; } -}; -template -class Factory : public FactoryBase { - typedef Base *(*func)(Arg1, Arg2); - -public: - static std::unique_ptr Create(std::string const& name, Arg1 a1, Arg2 a2) { - auto factory = FactoryBase::Find(name); - return factory ? std::unique_ptr(factory(a1, a2)) : nullptr; + static std::unique_ptr Create(std::string const& name, Args const&... args) { + auto factory = classes().find(name); + if (factory == classes().end()) return nullptr; + return std::unique_ptr(factory->second.second(args...)); } template - static void Register(std::string name, bool hide = false, std::vector subTypes = {}) { - FactoryBase::DoRegister([](Arg1 a1, Arg2 a2) -> Base * { return new T(a1, a2); }, name, hide, subTypes); + static void Register(std::string name, bool hide = false, std::vector subtypes = {}) { + func factory = [](Args const&... args) -> Base * { return new T(args...); }; + if (subtypes.empty()) + classes().insert(std::make_pair(name, std::make_pair(hide, factory))); + else { + for (auto const& subtype : subtypes) + classes().insert(std::make_pair(name + '/' + subtype, std::make_pair(hide, factory))); + } } }; -template -class Factory : public FactoryBase { - typedef Base *(*func)(Arg1); - -public: - static std::unique_ptr Create(std::string const& name, Arg1 a1) { - auto factory = FactoryBase::Find(name); - return factory ? std::unique_ptr(factory(a1)) : nullptr; - } - - template - static void Register(std::string name, bool hide = false, std::vector subTypes = {}) { - FactoryBase::DoRegister([](Arg1 a1) -> Base * { return new T(a1); }, name, hide, subTypes); - } -}; - -template -class Factory : public FactoryBase { - typedef Base *(*func)(); - -public: - static std::unique_ptr Create(std::string const& name) { - auto factory = FactoryBase::Find(name); - return factory ? std::unique_ptr(factory()) : nullptr; - } - - template - static void Register(std::string name, bool hide = false, std::vector subTypes = {}) { - FactoryBase::DoRegister([]() -> Base * { return new T; }, name, hide, subTypes); - } -};