Some refactoring of Athenasub, mostly related to const correctness.

Originally committed to SVN as r2460.
This commit is contained in:
Rodrigo Braz Monteiro 2008-11-16 00:58:08 +00:00
parent 07a7576547
commit 9280b56e34
16 changed files with 166 additions and 79 deletions

View File

@ -57,6 +57,11 @@ namespace Athenasub {
String(const basic_string<Character>& str);
explicit String(const wchar_t* utf16);
explicit String(const wxString& wxstring);
explicit String(char character);
explicit String(wchar_t character);
explicit String(int integer);
explicit String(float number);
explicit String(double number);
wxString GetWxString() const;

View File

@ -107,10 +107,6 @@ namespace Athenasub {
protected:
virtual void ProcessActionList(CActionList &actionList,int type=0) = 0;
virtual String GetUndoMessage(const String owner="") const = 0;
virtual String GetRedoMessage(const String owner="") const = 0;
virtual bool CanUndo(const String owner="") const = 0;
virtual bool CanRedo(const String owner="") const = 0;
virtual void Undo(const String owner="") = 0;
virtual void Redo(const String owner="") = 0;
virtual void ActivateStack(ActionStack stack,bool isUndo,const String &owner) = 0;
@ -119,22 +115,29 @@ namespace Athenasub {
virtual void Clear() = 0;
virtual void Load(wxInputStream &input,Format format=Format(),const String encoding="") = 0;
virtual void Save(wxOutputStream &output,Format format=Format(),const String encoding="UTF-8") = 0;
virtual void AddSection(String name) = 0;
virtual Section GetSection(String name) = 0;
virtual Section GetSectionByIndex(size_t index) = 0;
virtual Section GetMutableSection(String name) = 0;
virtual Section GetMutableSectionByIndex(size_t index) = 0;
public:
virtual ~IModel() {}
virtual Controller CreateController() = 0;
virtual void AddListener(View listener) = 0;
virtual void Save(wxOutputStream &output,Format format=Format(),const String encoding="UTF-8") const = 0;
virtual String GetUndoMessage(const String owner="") const = 0;
virtual String GetRedoMessage(const String owner="") const = 0;
virtual bool CanUndo(const String owner="") const = 0;
virtual bool CanRedo(const String owner="") const = 0;
virtual ConstSection GetSection(String name) const = 0;
virtual ConstSection GetSectionByIndex(size_t index) const = 0;
virtual size_t GetSectionCount() const = 0;
virtual Controller CreateController()=0;
virtual Format GetFormat() const=0;
virtual void AddListener(View listener)=0;
virtual Format GetFormat() const = 0;
};
@ -314,7 +317,7 @@ namespace Athenasub {
virtual String GetName() const = 0;
virtual StringArray GetReadExtensions() const = 0;
virtual StringArray GetWriteExtensions() const = 0;
virtual FormatHandler GetHandler(IModel &model) const = 0;
virtual FormatHandler GetHandler() const = 0;
virtual bool CanStoreText() const = 0;
virtual bool CanStoreImages() const = 0;
@ -340,8 +343,8 @@ namespace Athenasub {
public:
virtual ~IFormatHandler() {}
virtual void Load(wxInputStream &file,const String encoding) = 0;
virtual void Save(wxOutputStream &file,const String encoding) = 0;
virtual void Load(IModel &model,wxInputStream &file,const String encoding) = 0;
virtual void Save(const IModel &model,wxOutputStream &file,const String encoding) const = 0;
};

View File

@ -49,7 +49,7 @@ namespace Athenasub {
CAction(Model model);
Model GetModel() const { return model; }
Section GetSection(String name) const { return model->GetSection(name); }
Section GetSection(String name) const { return model->GetMutableSection(name); }
};
// Insert line

View File

@ -125,7 +125,7 @@ void CActionList::RemoveLine(int position,const String section)
// Insert a "modify line" action
Entry CActionList::ModifyLine(int position,const String section)
{
Section sect = Model(model)->GetSection(section);
Section sect = Model(model)->GetMutableSection(section);
Entry entry = sect->GetEntry(position)->Clone();
Action action = Action (new ActionModify(model.lock(),entry,position,section,false));
AddAction(action);
@ -138,7 +138,7 @@ Entry CActionList::ModifyLine(int position,const String section)
std::vector<Entry> CActionList::ModifyLines(Selection selection,const String section)
{
// Get section
Section sect = Model(model)->GetSection(section);
Section sect = Model(model)->GetMutableSection(section);
// Generate entries
std::vector<Entry> entries(selection->GetCount());

View File

@ -82,6 +82,39 @@ String::String(const wxString& wxstring)
}
String::String(char character)
{
*this = std::string(character,1);
}
String::String(wchar_t character)
{
wchar_t tmp[2];
tmp[0] = character;
tmp[1] = 0;
*this = String(tmp);
}
String::String(int integer)
{
*this = IntegerToString(integer);
}
String::String(float number)
{
*this = FloatToString(number);
}
String::String(double number)
{
*this = FloatToString(number);
}
Character* String::GetCharPointer(size_t pos)
{
return &operator[](pos);

View File

@ -148,7 +148,7 @@ ConstStyle CController::GetStyle(String name) const
// Get section
Style dummy = CreateStyle();
String section = dummy->GetDefaultGroup();
Section sect = model->GetSection(section);
ConstSection sect = model->GetSection(section);
if (!sect) THROW_ATHENA_EXCEPTION(Exception::Invalid_Section);
// Return from index
@ -160,7 +160,7 @@ ConstStyle CController::GetStyle(String name) const
// Get an entry
ConstEntry CController::GetEntry(size_t n,String section) const
{
Section sect = model->GetSection(section);
ConstSection sect = model->GetSection(section);
if (!sect) THROW_ATHENA_EXCEPTION(Exception::Invalid_Section);
return sect->GetEntry(n);
}

View File

@ -42,24 +42,21 @@ namespace Athenasub {
// Format handler interface
class CFormatHandler : public IFormatHandler {
private:
IModel& model;
protected:
virtual ~CFormatHandler() {}
IModel& GetModel() const { return model; }
void AddSection(String name) { model.AddSection(name); }
Section GetSection(String name) const { return model.GetSection(name); }
Section GetSectionByIndex(size_t index) const { return model.GetSectionByIndex(index); }
size_t GetSectionCount() const { return model.GetSectionCount(); }
void AddSection(IModel &model,String name) const { model.AddSection(name); }
ConstSection GetSection(const IModel &model,String name) const { return model.GetSection(name); }
ConstSection GetSectionByIndex(const IModel &model,size_t index) const { return model.GetSectionByIndex(index); }
Section GetSection(IModel &model,String name) const { return model.GetMutableSection(name); }
Section GetSectionByIndex(IModel &model,size_t index) const { return model.GetMutableSectionByIndex(index); }
size_t GetSectionCount(const IModel &model) const { return model.GetSectionCount(); }
public:
CFormatHandler(IModel& _model) : model(_model) {}
//CFormatHandler(IModel& _model) : model(_model) {}
virtual void Load(wxInputStream &file,const String encoding) = 0;
virtual void Save(wxOutputStream &file,const String encoding) = 0;
virtual void Load(IModel &model,wxInputStream &file,const String encoding) = 0;
virtual void Save(const IModel &model,wxOutputStream &file,const String encoding) const = 0;
};
}

View File

@ -90,8 +90,8 @@ StringArray FormatASS2::GetWriteExtensions() const
///////////////
// Constructor
FormatHandlerASS::FormatHandlerASS(CModel &_model,int version)
: CFormatHandler(_model), formatVersion(version)
FormatHandlerASS::FormatHandlerASS(int version)
: CFormatHandler(), formatVersion(version)
{
}
@ -105,7 +105,7 @@ FormatHandlerASS::~FormatHandlerASS()
///////////////
// Load a file
void FormatHandlerASS::Load(wxInputStream &file,const String encoding)
void FormatHandlerASS::Load(IModel &model,wxInputStream &file,const String encoding)
{
// Make text file reader
TextFileReader reader(file,encoding);
@ -127,10 +127,10 @@ void FormatHandlerASS::Load(wxInputStream &file,const String encoding)
ProcessGroup(cur,curGroup,version);
// Insert group if it doesn't already exist
if (prevGroup != curGroup) section = GetSection(curGroup);
if (prevGroup != curGroup) section = GetSection(model,curGroup);
if (!section) {
AddSection(curGroup);
section = GetSection(curGroup);
AddSection(model,curGroup);
section = GetSection(model,curGroup);
}
// Skip [] lines
@ -142,13 +142,13 @@ void FormatHandlerASS::Load(wxInputStream &file,const String encoding)
}
// Ensure validity
MakeValid();
MakeValid(model);
}
/////////////////////
// Save file to disc
void FormatHandlerASS::Save(wxOutputStream &file,const String encoding)
void FormatHandlerASS::Save(const IModel& model,wxOutputStream &file,const String encoding) const
{
// Make text file writer
TextFileWriter writer(file,encoding);
@ -162,9 +162,9 @@ void FormatHandlerASS::Save(wxOutputStream &file,const String encoding)
sections.push_back("Graphics");
// Look for remaining sections
size_t totalSections = GetSectionCount();
size_t totalSections = GetSectionCount(model);
for (size_t i=0;i<totalSections;i++) {
String name = GetSectionByIndex(i)->GetName();
String name = GetSectionByIndex(model,i)->GetName();
// If not found on the list, add to it
if (find(sections.begin(),sections.end(),name) == sections.end()) {
sections.push_back(name);
@ -175,7 +175,7 @@ void FormatHandlerASS::Save(wxOutputStream &file,const String encoding)
size_t len = sections.size();
for (size_t i=0;i<len;i++) {
// See if it exists
Section section = GetSection(sections[i]);
ConstSection section = GetSection(model,sections[i]);
if (section) {
// Add a spacer
if (i != 0) writer.WriteLineToFile("");
@ -334,7 +334,7 @@ void FormatHandlerASS::ProcessGroup(String cur,String &curGroup,int &version) {
///////////////////////////////
// Write a section to the file
void FormatHandlerASS::WriteSection(TextFileWriter &writer,Section section)
void FormatHandlerASS::WriteSection(TextFileWriter &writer,ConstSection section) const
{
// Write name
String name = section->GetName();
@ -371,15 +371,15 @@ void FormatHandlerASS::WriteSection(TextFileWriter &writer,Section section)
///////////////////////
// Validate the format
void FormatHandlerASS::MakeValid()
void FormatHandlerASS::MakeValid(IModel &model)
{
// Only ASS supported right now
if (formatVersion != 1) THROW_ATHENA_EXCEPTION(Exception::TODO);
// Check for [Script Info]
Section section = GetSection("Script Info");
if (!section) AddSection("Script Info");
section = GetSection("Script Info");
Section section = GetSection(model,"Script Info");
if (!section) AddSection(model,"Script Info");
section = GetSection(model,"Script Info");
if (!section) THROW_ATHENA_EXCEPTION(Exception::Internal_Error);
// Check if necessary variables are available
@ -388,16 +388,16 @@ void FormatHandlerASS::MakeValid()
section->SetProperty("ScriptType","v4.00+");
// Get [V4+ Styles]
section = GetSection("V4+ Styles");
if (!section) AddSection("V4+ Styles");
section = GetSection("V4+ Styles");
section = GetSection(model,"V4+ Styles");
if (!section) AddSection(model,"V4+ Styles");
section = GetSection(model,"V4+ Styles");
if (!section) THROW_ATHENA_EXCEPTION(Exception::Internal_Error);
section->SetProperty("Format","Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding");
// Get [Events]
section = GetSection("Events");
if (!section) AddSection("Events");
section = GetSection("Events");
section = GetSection(model,"Events");
if (!section) AddSection(model,"Events");
section = GetSection(model,"Events");
if (!section) THROW_ATHENA_EXCEPTION(Exception::Internal_Error);
section->SetProperty("Format","Layer, Start, End, Style, Actor, MarginL, MarginR, MarginV, Effect, Text");
}

View File

@ -55,15 +55,15 @@ namespace Athenasub {
Entry MakeEntry(const String &data,Section section,int version);
void ProcessGroup(String cur,String &curGroup,int &version);
void WriteSection(TextFileWriter &writer,Section section);
void MakeValid();
void WriteSection(TextFileWriter &writer,ConstSection section) const;
void MakeValid(IModel &model);
public:
FormatHandlerASS(CModel &model,int version);
FormatHandlerASS(int version);
~FormatHandlerASS();
void Load(wxInputStream &file,const String encoding);
void Save(wxOutputStream &file,const String encoding);
void Load(IModel &model,wxInputStream &file,const String encoding);
void Save(const IModel &model,wxOutputStream &file,const String encoding) const;
};
// Advanced Substation Alpha format base class
@ -92,7 +92,7 @@ namespace Athenasub {
// Substation Alpha
class FormatSSA : public FormatASSFamily {
public:
FormatHandler GetHandler(IModel &model) const { return FormatHandler(new FormatHandlerASS((CModel&)model,0)); }
FormatHandler GetHandler() const { return FormatHandler(new FormatHandlerASS(0)); }
String GetName() const { return "Substation Alpha"; }
StringArray GetReadExtensions() const;
StringArray GetWriteExtensions() const;
@ -101,7 +101,7 @@ namespace Athenasub {
// Advanced Substation Alpha
class FormatASS : public FormatASSFamily {
public:
FormatHandler GetHandler(IModel &model) const { return FormatHandler(new FormatHandlerASS((CModel&)model,1)); }
FormatHandler GetHandler() const { return FormatHandler(new FormatHandlerASS(1)); }
String GetName() const { return "Advanced Substation Alpha"; }
StringArray GetReadExtensions() const;
StringArray GetWriteExtensions() const;
@ -110,7 +110,7 @@ namespace Athenasub {
// Advanced Substation Alpha 2
class FormatASS2 : public FormatASSFamily {
public:
FormatHandler GetHandler(IModel &model) const { return FormatHandler(new FormatHandlerASS((CModel&)model,2)); }
FormatHandler GetHandler() const { return FormatHandler(new FormatHandlerASS(2)); }
String GetName() const { return "Advanced Substation Alpha 2"; }
StringArray GetReadExtensions() const;
StringArray GetWriteExtensions() const;

View File

@ -202,3 +202,22 @@ String DialogueASS::ToText(int version) const
buffer.SetSize(pos-1);
return buffer;
}
////////////////////////
// Overloaded operators
bool DialogueASS::operator==(const DialogueASS& param) const
{
if (time != param.time) return false;
if (text != param.text) return false;
if (margin != param.margin) return false;
if (layer != param.layer) return false;
if (isComment != param.isComment) return false;
return true;
}
bool DialogueASS::operator!=(const DialogueASS& param) const
{
return !(*this == param);
}

View File

@ -93,6 +93,10 @@ namespace Athenasub {
void SetStyle(const String &style) { text[1] = style; }
void SetActor(const String &actor) { text[2] = actor; }
void SetUserField(const String &userField) { text[3] = userField; }
// Operator overloading
bool operator==(const DialogueASS& param) const;
bool operator!=(const DialogueASS& param) const;
};
}

View File

@ -118,14 +118,14 @@ void CModel::Load(wxInputStream &input,const Format _format,const String encodin
}
// Get handler
FormatHandler handler = _format->GetHandler(*this);
FormatHandler handler = _format->GetHandler();
if (!handler) THROW_ATHENA_EXCEPTION(Exception::No_Format_Handler);
// Clear the model first
Clear();
// Load
handler->Load(input,encoding);
handler->Load(*this,input,encoding);
// Set the format
format = _format;
@ -134,7 +134,7 @@ void CModel::Load(wxInputStream &input,const Format _format,const String encodin
//////////////////
// Save subtitles
void CModel::Save(wxOutputStream &output,const Format _format,const String encoding)
void CModel::Save(wxOutputStream &output,const Format _format,const String encoding) const
{
// Use another format
if (_format && _format != format) {
@ -143,11 +143,11 @@ void CModel::Save(wxOutputStream &output,const Format _format,const String encod
}
// Get handler
FormatHandler handler = format->GetHandler(*this);
FormatHandler handler = format->GetHandler();
if (!handler) THROW_ATHENA_EXCEPTION(Exception::No_Format_Handler);
// Load
handler->Save(output,encoding);
handler->Save(*this,output,encoding);
}
@ -155,7 +155,7 @@ void CModel::Save(wxOutputStream &output,const Format _format,const String encod
// Inserts a new section
void CModel::AddSection(String name)
{
Section prev = GetSection(name);
ConstSection prev = GetSection(name);
if (prev) THROW_ATHENA_EXCEPTION(Exception::Section_Already_Exists);
sections.push_back(Section(new CSection(name)));
}
@ -172,7 +172,7 @@ ConstSection CModel::GetSection(String name) const
return SectionPtr();
}
Section CModel::GetSection(String name)
Section CModel::GetMutableSection(String name)
{
size_t len = sections.size();
for (size_t i=0;i<len;i++) {
@ -189,7 +189,7 @@ ConstSection CModel::GetSectionByIndex(size_t index) const
return sections.at(index);
}
Section CModel::GetSectionByIndex(size_t index)
Section CModel::GetMutableSectionByIndex(size_t index)
{
return sections.at(index);
}

View File

@ -51,6 +51,7 @@ namespace Athenasub {
friend class CActionList;
friend class CController;
friend class CAction;
friend class CLibAthenaSub;
private:
weak_ptr<IModel> weakThis;
@ -80,22 +81,24 @@ namespace Athenasub {
void Clear();
void Load(wxInputStream &input,Format format=Format(),const String encoding="");
void Save(wxOutputStream &output,Format format=Format(),const String encoding="UTF-8");
void AddSection(String name);
ConstSection GetSection(String name) const;
Section GetSection(String name);
ConstSection GetSectionByIndex(size_t index) const;
Section GetSectionByIndex(size_t index);
size_t GetSectionCount() const;
Section GetMutableSection(String name);
Section GetMutableSectionByIndex(size_t index);
void SetWeakPtr(weak_ptr<IModel> ptr) { weakThis = ptr; }
public:
CModel();
Controller CreateController();
Format GetFormat() const { return format; }
void AddListener(View listener);
void SetWeakPtr(weak_ptr<IModel> ptr) { weakThis = ptr; }
void AddListener(View listener);
void Save(wxOutputStream &output,Format format=Format(),const String encoding="UTF-8") const;
ConstSection GetSection(String name) const;
ConstSection GetSectionByIndex(size_t index) const;
size_t GetSectionCount() const;
};
typedef shared_ptr<CModel> ModelPtr;

View File

@ -92,9 +92,9 @@ int main()
// Issue an action
#ifdef WXDEBUG
int n = 1000;
#else
int n = 1;
#else
int n = 1000;
#endif
cout << "Executing action " << n << " times... ";
timer.Start();
@ -126,7 +126,7 @@ int main()
cout << "Done in " << timer.Time() << " ms.\n";
// Undo
n = 1000;
n = 10;
cout << "Undoing and redoing " << n << " times... ";
timer.Start();
for (int i=0;i<n;i++) {

View File

@ -78,6 +78,16 @@ public:
CPPUNIT_ASSERT(refDiag.GetText() == "Text, why halo thar?");
DialogueASS diag;
CPPUNIT_ASSERT(diag != refDiag);
diag = refDiag;
CPPUNIT_ASSERT(diag == refDiag);
String text = "Dialogue: 3 , 1:23:45.67 , 2:34:56.78 , style name , actor name , 0001 , 0020 , 3300 , effect field ,Text, why halo thar?";
diag = DialogueASS(text,1);
CPPUNIT_ASSERT(diag == refDiag);
text = "Dialogue: 3,1:23:45.67,2:34:56.78,style name,actor name,1,20,3300,effect field,Text, why halo thar?";
diag = DialogueASS(text,1);
CPPUNIT_ASSERT(diag == refDiag);
}
};

View File

@ -82,6 +82,10 @@ public:
CPPUNIT_ASSERT((e < d) == false);
CPPUNIT_ASSERT(d < c);
CPPUNIT_ASSERT((c < d) == false);
CPPUNIT_ASSERT(c.AsciiCompareNoCase("hello world!"));
CPPUNIT_ASSERT(c.AsciiCompareNoCase("Hello world!"));
CPPUNIT_ASSERT(c.AsciiCompareNoCase("hello world") == false);
}
void testStartEnd()
@ -128,6 +132,15 @@ public:
CPPUNIT_ASSERT_THROW(String("312a").ToInteger(),Athenasub::Exception);
CPPUNIT_ASSERT_THROW(String("3-12").ToInteger(),Athenasub::Exception);
CPPUNIT_ASSERT_THROW(String("3+12").ToInteger(),Athenasub::Exception);
CPPUNIT_ASSERT(String(312) == "312");
CPPUNIT_ASSERT(String(-312) == "-312");
CPPUNIT_ASSERT(String(312.0) == "312");
CPPUNIT_ASSERT(String(312.25) == "312.25");
CPPUNIT_ASSERT(String(-312.25) == "-312.25");
CPPUNIT_ASSERT(String(312.0f) == "312");
CPPUNIT_ASSERT(String(312.25f) == "312.25");
CPPUNIT_ASSERT(String(-312.25f) == "-312.25");
}
};