Clean up and document ScriptFactory, and add a function to get the full wildcard string for all registered automation engines

Originally committed to SVN as r5624.
This commit is contained in:
Thomas Goyne 2011-09-28 19:46:05 +00:00
parent 7680d6c246
commit 53c0b6ff3a
6 changed files with 97 additions and 168 deletions

View File

@ -994,123 +994,63 @@ namespace Automation4 {
}
// ScriptFactory
/// DOCME
std::vector<ScriptFactory*> *ScriptFactory::factories = 0;
/// @brief DOCME
/// @return
///
const wxString& ScriptFactory::GetEngineName() const
ScriptFactory::ScriptFactory(wxString engine_name, wxString filename_pattern)
: engine_name(engine_name)
, filename_pattern(filename_pattern)
{
return engine_name;
}
/// @brief DOCME
/// @return
///
const wxString& ScriptFactory::GetFilenamePattern() const
{
return filename_pattern;
}
/// @brief DOCME
/// @param factory
///
void ScriptFactory::Register(ScriptFactory *factory)
{
if (!factories)
factories = new std::vector<ScriptFactory*>();
GetFactories();
if (find(factories->begin(), factories->end(), factory) != factories->end())
throw "Automation 4: Attempt to register the same script factory multiple times. This should never happen.";
for (std::vector<ScriptFactory*>::iterator i = factories->begin(); i != factories->end(); ++i) {
if (*i == factory) {
throw "Automation 4: Attempt to register the same script factory multiple times. This should never happen.";
}
}
factories->push_back(factory);
}
/// @brief DOCME
/// @param factory
/// @return
///
void ScriptFactory::Unregister(ScriptFactory *factory)
{
if (!factories)
factories = new std::vector<ScriptFactory*>();
if (!factories) return;
for (std::vector<ScriptFactory*>::iterator i = factories->begin(); i != factories->end(); ++i) {
if (*i == factory) {
factories->erase(i);
if (factories->empty()) delete factories;
return;
}
std::vector<ScriptFactory*>::iterator i = find(factories->begin(), factories->end(), factory);
if (i != factories->end()) {
delete *i;
factories->erase(i);
}
}
/// @brief DOCME
/// @param filename
/// @param log_errors
/// @return
///
Script* ScriptFactory::CreateFromFile(const wxString &filename, bool log_errors)
Script* ScriptFactory::CreateFromFile(wxString const& filename, bool log_errors)
{
if (!factories)
factories = new std::vector<ScriptFactory*>();
GetFactories();
for (std::vector<ScriptFactory*>::iterator i = factories->begin(); i != factories->end(); ++i) {
try {
Script *s = (*i)->Produce(filename);
if (s) {
if (!s->GetLoadedState() && log_errors) {
wxLogError(_("An Automation script failed to load. File name: '%s', error reported:"), filename);
wxLogError(s->GetDescription());
}
return s;
}
}
catch (Script *e) {
// This was the wrong script factory, but it throwing a Script object means it did know what to do about the file
// Use this script object
return e;
Script *s = (*i)->Produce(filename);
if (s) {
if (!s->GetLoadedState() && log_errors)
wxLogError(_("An Automation script failed to load. File name: '%s', error reported: %s"), filename, s->GetDescription());
return s;
}
}
if (log_errors) {
wxLogWarning(_("The file was not recognised as an Automation script: %s"), filename);
}
if (log_errors)
wxLogError(_("The file was not recognised as an Automation script: %s"), filename);
return new UnknownScript(filename);
}
/// @brief DOCME
/// @param filename
/// @return
///
bool ScriptFactory::CanHandleScriptFormat(const wxString &filename)
bool ScriptFactory::CanHandleScriptFormat(wxString const& filename)
{
using std::tr1::placeholders::_1;
// Just make this always return true to bitch about unknown script formats in autoload
if (!factories)
factories = new std::vector<ScriptFactory*>();
for (std::vector<ScriptFactory*>::iterator i = factories->begin(); i != factories->end(); ++i) {
wxString pattern = (*i)->GetFilenamePattern();
if (filename.Matches(pattern)) return true;
}
return false;
GetFactories();
return find_if(factories->begin(), factories->end(),
bind(&wxString::Matches, filename, bind(&ScriptFactory::GetFilenamePattern, _1))) != factories->end();
}
/// @brief DOCME
/// @return
///
const std::vector<ScriptFactory*>& ScriptFactory::GetFactories()
{
if (!factories)
@ -1119,6 +1059,33 @@ namespace Automation4 {
return *factories;
}
wxString ScriptFactory::GetWildcardStr()
{
GetFactories();
wxString fnfilter, catchall;
for (size_t i = 0; i < factories->size(); ++i) {
const ScriptFactory *fact = (*factories)[i];
if (fact->GetEngineName().empty() || fact->GetFilenamePattern().empty())
continue;
fnfilter = wxString::Format("%s%s scripts (%s)|%s|", fnfilter, fact->GetEngineName(), fact->GetFilenamePattern(), fact->GetFilenamePattern());
catchall += fact->GetFilenamePattern() + ";";
}
#ifdef __WINDOWS__
fnfilter += "All files|*.*";
#else
fnfilter += "All files|*";
#endif
if (!catchall.empty())
catchall.RemoveLast();
if (factories->size() > 1)
fnfilter = "All supported scripts|" + catchall + "|" + fnfilter;
return fnfilter;
}
// UnknownScript

View File

@ -511,42 +511,48 @@ namespace Automation4 {
void Reload();
};
/// DOCME
/// @class ScriptFactory
/// @brief DOCME
///
/// DOCME
class ScriptFactory {
private:
/// DOCME
/// Vector of loaded script engines
static std::vector<ScriptFactory*> *factories;
wxString engine_name;
wxString filename_pattern;
/// Load a file, or return NULL if the file is not in a supported
/// format. If the file is in a supported format but is invalid, a
/// script should be returned which returns false from IsLoaded and
/// an appropriate error message from GetDescription.
///
/// This is private as it should only ever be called through
/// CreateFromFile
virtual Script* Produce(wxString const& filename) const = 0;
protected:
/// @brief DOCME
///
ScriptFactory() { }
/// @brief DOCME
///
ScriptFactory(wxString engine_name, wxString filename_pattern);
virtual ~ScriptFactory() { }
/// DOCME
wxString engine_name;
/// DOCME
wxString filename_pattern;
public:
virtual Script* Produce(const wxString &filename) const = 0;
const wxString& GetEngineName() const;
const wxString& GetFilenamePattern() const;
/// Name of this automation engine
const wxString& GetEngineName() const { return engine_name; }
/// Extension which this engine supports
const wxString& GetFilenamePattern() const { return filename_pattern; }
/// Register an automation engine. Calling code retains ownership of pointer
static void Register(ScriptFactory *factory);
/// Unregister and delete an automation engine
static void Unregister(ScriptFactory *factory);
static Script* CreateFromFile(const wxString &filename, bool log_errors);
static bool CanHandleScriptFormat(const wxString &filename);
/// Is there an automation engine registered which can open the file?
static bool CanHandleScriptFormat(wxString const& filename);
/// Get the full wildcard string for all loaded engines
static wxString GetWildcardStr();
/// Load a script from a file
/// @param filename Script to load
/// @param log_errors Should load errors be displayed?
/// @return Always returns a valid Script, even if no engine could load the file
static Script* CreateFromFile(wxString const& filename, bool log_errors);
static const std::vector<ScriptFactory*>& GetFactories();
};

View File

@ -957,28 +957,12 @@ namespace Automation4 {
}
}
/// @brief // Factory methods
///
LuaScriptFactory::LuaScriptFactory() {}
/// @brief DOCME
///
LuaScriptFactory::~LuaScriptFactory() {}
/// @brief DOCME
///
void LuaScriptFactory::RegisterFactory ()
LuaScriptFactory::LuaScriptFactory()
: ScriptFactory("Lua", "*.lua")
{
engine_name = "Lua";
filename_pattern = "*.lua";
Register(this);
}
/// @brief DOCME
/// @param filename
///
Script* LuaScriptFactory::Produce(const wxString &filename) const
{
// Just check if file extension is .lua
@ -989,7 +973,6 @@ namespace Automation4 {
return 0;
}
}
};
#endif // WITH_AUTO4_LUA

View File

@ -34,27 +34,17 @@
/// @ingroup scripting
///
#include "auto4_base.h"
/// DOCME
namespace Automation4 {
/// DOCME
/// @class LuaScriptFactory
/// @brief DOCME
///
/// DOCME
class LuaScriptFactory : public ScriptFactory {
Script* Produce(const wxString &filename) const;
public:
LuaScriptFactory();
~LuaScriptFactory();
void RegisterFactory ();
Script* Produce(const wxString &filename) const;
};
};

View File

@ -43,9 +43,10 @@
#include "plugin_manager.h"
#include "video_provider_manager.h"
#ifdef WITH_AUTO4_LUA
#include "auto4_lua_factory.h"
#endif
/// @brief Constructor
///
PluginManager::PluginManager() {
init = false;
@ -55,9 +56,6 @@ PluginManager::PluginManager() {
}
/// @brief Destructor
///
PluginManager::~PluginManager() {
VideoProviderFactory::Clear();
AudioProviderFactory::Clear();
@ -66,18 +64,11 @@ PluginManager::~PluginManager() {
SpellCheckerFactory::Clear();
#ifdef WITH_AUTO4_LUA
if (lua) {
lua->Unregister(lua);
delete lua;
lua = NULL;
}
Automation4::ScriptFactory::Unregister(lua);
#endif
}
/// @brief Registers all built-in plugins
///
void PluginManager::RegisterBuiltInPlugins() {
if (!init) {
// Managers
@ -90,7 +81,6 @@ void PluginManager::RegisterBuiltInPlugins() {
// Automation languages
#ifdef WITH_AUTO4_LUA
lua = new Automation4::LuaScriptFactory();
lua->RegisterFactory();
#endif
}

View File

@ -34,12 +34,7 @@
/// @ingroup main
///
#ifdef WITH_AUTO4_LUA
#include "auto4_lua_factory.h"
#endif
namespace Automation4 { class ScriptFactory; }
/// DOCME
/// @class PluginManager
@ -53,9 +48,7 @@ private:
bool init;
#ifdef WITH_AUTO4_LUA
/// DOCME
Automation4::LuaScriptFactory *lua;
Automation4::ScriptFactory *lua;
#endif
public: