Added multiple subtype support for provider factories, in particular, csri.

Originally committed to SVN as r1030.
This commit is contained in:
Rodrigo Braz Monteiro 2007-04-08 16:33:53 +00:00
parent cb75613747
commit ebc0e37a2d
5 changed files with 89 additions and 23 deletions

View File

@ -47,22 +47,51 @@
template <class T>
class AegisubFactory {
protected:
// Static map of all factories
static std::map<wxString,T*> *factories;
void RegisterFactory(wxString name) {
// Register one factory type (with possible subtypes)
void RegisterFactory(wxString name, wxArrayString subTypes=wxArrayString()) {
// Create factories if it doesn't exist
if (factories == NULL) factories = new std::map<wxString,T*>;
factories->insert(std::make_pair(name.Lower(),(T*)this));
// Prepare subtypes
if (subTypes.GetCount() == 0) subTypes.Add(_T(""));
else {
for (unsigned int i=0;i<subTypes.GetCount();i++) {
subTypes[i] = _T("/") + subTypes[i];
}
}
// Insert each subtype
for (unsigned int i=0;i<subTypes.GetCount();i++) {
factories->insert(std::make_pair(name.Lower() + subTypes[i],(T*)this));
}
}
// Get a factory with name
static T *GetFactory(wxString name) {
// No factories
if (factories == NULL) {
factories = new std::map<wxString,T*>;
return NULL;
}
typename std::map<wxString,T*>::iterator res = factories->find(name.Lower());
if (res != factories->end()) return res->second;
// Search for factory that matches
typename std::map<wxString,T*>::iterator cur;
for (cur = factories->begin();cur != factories->end();cur++) {
if (cur->first.StartsWith(name)) return cur->second;
}
// None found
return NULL;
}
public:
// Virtual destructor
virtual ~AegisubFactory() {}
// Get list of all factories, with favourite as first
static wxArrayString GetFactoryList(wxString favourite=_T("")) {
if (factories == NULL) factories = new std::map<wxString,T*>;
wxArrayString list;
@ -73,5 +102,4 @@ public:
}
return list;
}
virtual ~AegisubFactory() {}
};

View File

@ -59,7 +59,10 @@ SubtitlesProvider* SubtitlesProviderFactory::GetProvider() {
wxString error;
for (unsigned int i=0;i<list.Count();i++) {
try {
SubtitlesProvider *provider = GetFactory(list[i])->CreateProvider();
size_t pos = list[i].Find(_T('/'));
wxString name = list[i].Left(pos);
wxString subType = list[i].Mid(pos+1);
SubtitlesProvider *provider = GetFactory(list[i])->CreateProvider(subType);
if (provider) return provider;
}
catch (wxString err) { error += list[i] + _T(" factory: ") + err + _T("\n"); }

View File

@ -66,8 +66,10 @@ public:
// Factory
class SubtitlesProviderFactory : public AegisubFactory<SubtitlesProviderFactory> {
protected:
virtual SubtitlesProvider *CreateProvider()=0;
SubtitlesProviderFactory(wxString name) { RegisterFactory(name); }
virtual SubtitlesProvider *CreateProvider(wxString subType=_T(""))=0;
SubtitlesProviderFactory(wxString name,wxArrayString subTypes=wxArrayString()) {
RegisterFactory(name,subTypes);
}
public:
virtual ~SubtitlesProviderFactory() {}

View File

@ -36,6 +36,7 @@
///////////
// Headers
#include <wx/wxprec.h>
#include "subtitles_provider.h"
#include "ass_file.h"
#include "video_context.h"
@ -56,10 +57,11 @@
// Common Subtitles Rendering Interface provider
class CSRISubtitlesProvider : public SubtitlesProvider {
private:
wxString subType;
csri_inst *instance;
public:
CSRISubtitlesProvider();
CSRISubtitlesProvider(wxString subType);
~CSRISubtitlesProvider();
bool CanRaster() { return true; }
@ -73,14 +75,34 @@ public:
// Factory
class CSRISubtitlesProviderFactory : public SubtitlesProviderFactory {
public:
SubtitlesProvider *CreateProvider() { return new CSRISubtitlesProvider(); }
CSRISubtitlesProviderFactory() : SubtitlesProviderFactory(_T("csri")) {}
SubtitlesProvider *CreateProvider(wxString subType=_T("")) { return new CSRISubtitlesProvider(subType); }
wxArrayString GetSubTypes() {
csri_info *info;
wxArrayString final;
for (csri_rend *cur = csri_renderer_default();cur;cur = csri_renderer_next(cur)) {
// Get renderer name
info = csri_renderer_info(cur);
const char* buffer = info->name;
// wxWidgets isn't initialized, so h4x into a wxString
int len = strlen(buffer);
wxString str;
str.Alloc(len+1);
for (int i=0;i<len;i++) {
str.Append((wxChar)buffer[i]);
}
final.Add(str);
}
return final;
}
CSRISubtitlesProviderFactory() : SubtitlesProviderFactory(_T("csri"),GetSubTypes()) {}
} registerCSRI;
///////////////
// Constructor
CSRISubtitlesProvider::CSRISubtitlesProvider() {
CSRISubtitlesProvider::CSRISubtitlesProvider(wxString type) {
subType = type;
instance = NULL;
}
@ -96,26 +118,37 @@ CSRISubtitlesProvider::~CSRISubtitlesProvider() {
//////////////////
// Load subtitles
void CSRISubtitlesProvider::LoadSubtitles(AssFile *subs) {
csri_rend *renderer;
// Close
if (instance) csri_close(instance);
instance = NULL;
// Prepare subtitles
//wxString subsfilename = VideoContext::Get()->GetTempWorkFile();
//subs->Save(subsfilename,false,false,_T("UTF-8"));
std::vector<char> data;
subs->SaveMemory(data,_T("UTF-8"));
delete subs;
// CSRI variables
csri_rend *cur,*renderer=NULL;
csri_info *info;
// Select renderer
for (cur = csri_renderer_default();cur;cur=csri_renderer_next(cur)) {
info = csri_renderer_info(cur);
wxString name(info->name,wxConvUTF8);
if (name == subType) {
renderer = cur;
break;
}
}
// Matching renderer not found, fallback to default
if (!renderer) {
renderer = csri_renderer_default();
if (!renderer) throw _T("No CSRI renderer available. Try installing one or switch to another subtitle provider.");
}
// Open
//instance = csri_open_file(csri_renderer_default(),subsfilename.mb_str(wxConvUTF8),NULL);
renderer = csri_renderer_default();
if (renderer)
instance = csri_open_mem(renderer,&data[0],data.size(),NULL);
else
throw _T("No CSRI renderer available. Try installing one or switch to another subtitle provider.");
instance = csri_open_mem(renderer,&data[0],data.size(),NULL);
}

View File

@ -76,7 +76,7 @@ ass_library_t* LibassSubtitlesProvider::ass_library;
// Factory
class LibassSubtitlesProviderFactory : public SubtitlesProviderFactory {
public:
SubtitlesProvider *CreateProvider() { return new LibassSubtitlesProvider(); }
SubtitlesProvider *CreateProvider(wxString subType=_T("")) { return new LibassSubtitlesProvider(); }
LibassSubtitlesProviderFactory() : SubtitlesProviderFactory(_T("libass")) {}
} registerLibass;