Modified the action system to be more OO.

Originally committed to SVN as r2065.
This commit is contained in:
Rodrigo Braz Monteiro 2008-03-15 22:02:16 +00:00
parent 3ead72329c
commit da0a10ce99
8 changed files with 228 additions and 205 deletions

View File

@ -154,44 +154,12 @@
</References>
<Files>
<Filter
Name="API"
Name="Include"
>
<File
RelativePath=".\include\aegilib\action.h"
>
</File>
<File
RelativePath=".\include\aegilib\actionlist.h"
>
</File>
<File
RelativePath=".\include\aegilib\colour.h"
>
</File>
<File
RelativePath=".\include\aegilib\controller.h"
>
</File>
<File
RelativePath=".\include\aegilib\exception.h"
>
</File>
<File
RelativePath=".\include\aegilib\fastbuffer.h"
>
</File>
<File
RelativePath=".\include\aegilib\format.h"
>
</File>
<File
RelativePath=".\include\aegilib\format_handler.h"
>
</File>
<File
RelativePath=".\include\aegilib\format_manager.h"
>
</File>
<File
RelativePath=".\include\aegilib\gorgonstring.h"
>
@ -201,7 +169,23 @@
>
</File>
<File
RelativePath=".\include\aegilib\gorgontime.h"
RelativePath=".\include\aegilib\tr1.h"
>
</File>
</Filter>
<Filter
Name="MVC"
>
<File
RelativePath=".\src\controller.cpp"
>
</File>
<File
RelativePath=".\include\aegilib\controller.h"
>
</File>
<File
RelativePath=".\src\model.cpp"
>
</File>
<File
@ -212,62 +196,6 @@
RelativePath=".\include\aegilib\notification.h"
>
</File>
<File
RelativePath=".\include\aegilib\section.h"
>
</File>
<File
RelativePath=".\include\aegilib\section_entry.h"
>
</File>
<File
RelativePath=".\include\aegilib\section_entry_dialogue.h"
>
</File>
<File
RelativePath=".\include\aegilib\section_entry_style.h"
>
</File>
<File
RelativePath=".\include\aegilib\tokenizer.h"
>
</File>
<File
RelativePath=".\include\aegilib\tr1.h"
>
</File>
<File
RelativePath=".\include\aegilib\utils.h"
>
</File>
<File
RelativePath=".\include\aegilib\version.h"
>
</File>
<File
RelativePath=".\include\aegilib\view.h"
>
</File>
</Filter>
<Filter
Name="MVC"
>
<File
RelativePath=".\src\action.cpp"
>
</File>
<File
RelativePath=".\src\actionlist.cpp"
>
</File>
<File
RelativePath=".\src\controller.cpp"
>
</File>
<File
RelativePath=".\src\model.cpp"
>
</File>
<File
RelativePath=".\src\view.cpp"
>
@ -280,6 +208,10 @@
/>
</FileConfiguration>
</File>
<File
RelativePath=".\include\aegilib\view.h"
>
</File>
</Filter>
<Filter
Name="Misc"
@ -288,12 +220,20 @@
RelativePath=".\src\colour.cpp"
>
</File>
<File
RelativePath=".\include\aegilib\colour.h"
>
</File>
<File
RelativePath=".\src\exception.cpp"
>
</File>
<File
RelativePath=".\src\format_manager.cpp"
RelativePath=".\include\aegilib\exception.h"
>
</File>
<File
RelativePath=".\include\aegilib\gorgontime.h"
>
</File>
<File
@ -321,14 +261,6 @@
RelativePath=".\src\prec.h"
>
</File>
<File
RelativePath=".\src\section.cpp"
>
</File>
<File
RelativePath=".\src\section_entry.cpp"
>
</File>
<File
RelativePath=".\src\text_file_reader.cpp"
>
@ -353,18 +285,34 @@
RelativePath=".\src\tokenizer.cpp"
>
</File>
<File
RelativePath=".\include\aegilib\tokenizer.h"
>
</File>
<File
RelativePath=".\src\utils.cpp"
>
</File>
<File
RelativePath=".\include\aegilib\utils.h"
>
</File>
<File
RelativePath=".\src\version.cpp"
>
</File>
<File
RelativePath=".\include\aegilib\version.h"
>
</File>
</Filter>
<Filter
Name="Formats"
>
<File
RelativePath=".\include\aegilib\format.h"
>
</File>
<File
RelativePath=".\src\formats\format_ass.cpp"
>
@ -381,6 +329,66 @@
RelativePath=".\src\formats\format_ass_style.cpp"
>
</File>
<File
RelativePath=".\include\aegilib\format_handler.h"
>
</File>
<File
RelativePath=".\src\format_manager.cpp"
>
</File>
<File
RelativePath=".\include\aegilib\format_manager.h"
>
</File>
</Filter>
<Filter
Name="Actions"
>
<File
RelativePath=".\src\action.cpp"
>
</File>
<File
RelativePath=".\include\aegilib\action.h"
>
</File>
<File
RelativePath=".\src\actionlist.cpp"
>
</File>
<File
RelativePath=".\include\aegilib\actionlist.h"
>
</File>
</Filter>
<Filter
Name="Sections"
>
<File
RelativePath=".\src\section.cpp"
>
</File>
<File
RelativePath=".\include\aegilib\section.h"
>
</File>
<File
RelativePath=".\src\section_entry.cpp"
>
</File>
<File
RelativePath=".\include\aegilib\section_entry.h"
>
</File>
<File
RelativePath=".\include\aegilib\section_entry_dialogue.h"
>
</File>
<File
RelativePath=".\include\aegilib\section_entry_style.h"
>
</File>
</Filter>
</Files>
<Globals>

View File

@ -37,28 +37,51 @@
#include "gorgonstring.h"
namespace Gorgonsub {
// The different types of actions available
enum ActionType {
ACTION_INSERT,
ACTION_REMOVE
};
// Prototypes
class Model;
class SectionEntry;
class Action;
class Section;
typedef shared_ptr<Action> ActionPtr;
typedef shared_ptr<Section> SectionPtr;
// Action class
// This is a modification event
// Action interface
class Action {
private:
ActionType type;
shared_ptr<void> data;
String section;
int par1;
protected:
SectionPtr GetSection(const Model &model,const String &name) const;
public:
Action();
Action(ActionType type,shared_ptr<void> data,const String &section,int par1);
virtual ~Action() {}
virtual ActionPtr GetAntiAction(const Model &model) const =0;
virtual void Execute(Model &model) =0;
};
ActionType GetType() const { return type; }
shared_ptr<void> GetData() const { return data; }
int GetLineNumber() const { return par1; }
String GetSection() const { return section; }
// Insert line
class ActionInsert : public Action {
private:
shared_ptr<SectionEntry> entry;
const String section;
int lineNumber;
public:
ActionInsert(shared_ptr<SectionEntry> entry,int line,const String &section);
virtual ~ActionInsert() {}
ActionPtr GetAntiAction(const Model &model) const;
void Execute(Model &model);
};
// Remove line
class ActionRemove : public Action {
private:
const String section;
int lineNumber;
public:
ActionRemove(int line,const String &section);
virtual ~ActionRemove() {}
ActionPtr GetAntiAction(const Model &model) const;
void Execute(Model &model);
};
};

View File

@ -53,14 +53,14 @@ namespace Gorgonsub {
String actionName;
String owner;
Model &model;
std::list<Action> actions;
std::list<ActionPtr> actions;
bool valid;
bool undoAble;
ActionList(Model &model,const String actionName,const String owner,bool undoAble);
void Start(const String actionName);
void AddAction(const Action &action);
void AddActionStart(const Action &action);
void AddAction(const ActionPtr action);
void AddActionStart(const ActionPtr action);
public:
~ActionList();

View File

@ -55,6 +55,7 @@ namespace Gorgonsub {
friend class FormatHandler;
friend class ActionList;
friend class Controller;
friend class Action;
typedef std::list<ViewPtr> ViewList;
typedef std::stack<ActionListPtr,std::list<ActionListPtr> > ActionStack;
@ -69,8 +70,6 @@ namespace Gorgonsub {
FormatPtr format;
void ProcessActionList(const ActionList &actionList,int type=0);
void DoAction(const Action &action);
Action GetAntiAction(const Action &action);
bool CanUndo(const String owner=L"") const;
bool CanRedo(const String owner=L"") const;

View File

@ -33,23 +33,80 @@
// Contact: mailto:amz@aegisub.net
//
#include "action.h"
#include "gorgonsub.h"
using namespace Gorgonsub;
///////////////////////
// Default constructor
Action::Action()
////////////////////////////////
// Get a section from the model
SectionPtr Action::GetSection(const Model &model,const String &name) const
{
return model.GetSection(name);
}
//////////////////////////////
// Initialization constructor
Action::Action(ActionType _type,shared_ptr<void> _data,const String &_section,int _par1)
/////////////////// Insert line /////////////////////////////
///////////////
// Constructor
ActionInsert::ActionInsert(shared_ptr<SectionEntry> data,int line,const String &sName)
: entry(data), lineNumber(line), section(sName) {}
/////////////////////////////////
// Create anti-action for insert
ActionPtr ActionInsert::GetAntiAction(const Model &model) const
{
type = _type;
data = _data;
par1 = _par1;
section = _section;
(void) model;
String sect = section;
if (section.IsEmpty()) sect = entry->GetDefaultGroup();
return ActionPtr(new ActionRemove(lineNumber,sect));
}
/////////////////////
// Execute insertion
void ActionInsert::Execute(Model &model)
{
// Find the section to insert it on
String sectionName = section;
if (sectionName.IsEmpty()) sectionName = entry->GetDefaultGroup();
SectionPtr sect = GetSection(model,sectionName);
// Insert the line
sect->AddEntry(entry,lineNumber);
}
/////////////////// Remove line /////////////////////////////
///////////////
// Constructor
ActionRemove::ActionRemove(int line,const String &sName)
: lineNumber(line), section(sName) {}
/////////////////////////////////
// Create anti-action for remove
ActionPtr ActionRemove::GetAntiAction(const Model &model) const
{
SectionPtr sect = GetSection(model,section);
SectionEntryPtr entry = sect->GetEntry(lineNumber);
return ActionPtr(new ActionInsert(entry,lineNumber,section));
}
///////////////////
// Execute removal
void ActionRemove::Execute(Model &model)
{
// Find the section to remote it from
String sect = section;
if (sect.IsEmpty()) throw Exception(Exception::TODO); // TODO
SectionPtr section = GetSection(model,sect);
// Remove the line
section->RemoveEntryByIndex(lineNumber);
}

View File

@ -56,7 +56,7 @@ ActionList::~ActionList()
//////////////////////////////
// Add an action to the queue
void ActionList::AddAction(const Action &action)
void ActionList::AddAction(const ActionPtr action)
{
if (!valid) throw Exception(Exception::Invalid_ActionList);
actions.push_back(action);
@ -69,7 +69,7 @@ void ActionList::AddAction(const Action &action)
///////////////////////////////////////////
// Add an action to the start of the queue
void ActionList::AddActionStart(const Action &action)
void ActionList::AddActionStart(const ActionPtr action)
{
if (!valid) throw Exception(Exception::Invalid_ActionList);
actions.push_front(action);
@ -106,7 +106,7 @@ void ActionList::Finish()
// Create an "insert line" action
void ActionList::InsertLine(SectionEntryPtr line,int position,const String section)
{
Action action = Action(ACTION_INSERT,line,section,position);
ActionPtr action = ActionPtr (new ActionInsert(line,position,section));
AddAction(action);
}
@ -115,6 +115,6 @@ void ActionList::InsertLine(SectionEntryPtr line,int position,const String secti
// Create a "remove line" action
void ActionList::RemoveLine(int position,const String section)
{
Action action = Action(ACTION_REMOVE,SectionEntryPtr(),section,position);
ActionPtr action = ActionPtr (new ActionRemove(position,section));
AddAction(action);
}

View File

@ -70,13 +70,13 @@ void Model::ProcessActionList(const ActionList &_actionList,int type)
else stack = &undoStack;
// Execute actions
std::list<Action>::const_iterator cur;
std::list<ActionPtr>::const_iterator cur;
for (cur=actions->actions.begin();cur!=actions->actions.end();cur++) {
// Inserts the opposite into the undo action first
if (actions->undoAble) undo->AddActionStart(GetAntiAction(*cur));
if (actions->undoAble) undo->AddActionStart((*cur)->GetAntiAction(*this));
// Execute the action itself
DoAction(*cur);
(*cur)->Execute(*this);
}
// Insert into undo stack
@ -90,71 +90,6 @@ void Model::ProcessActionList(const ActionList &_actionList,int type)
}
/////////////////////
// Execute an action
void Model::DoAction(const Action &action)
{
switch (action.GetType()) {
// Insert a line
case ACTION_INSERT: {
// Get the line
SectionEntryPtr entry = static_pointer_cast<SectionEntry>(action.GetData());
// Find the section to insert it on
String sectionName = action.GetSection();
if (sectionName.IsEmpty()) sectionName = entry->GetDefaultGroup();
SectionPtr section = GetSection(sectionName);
// Insert the line
section->AddEntry(entry,action.GetLineNumber());
return;
}
// Delete a line
case ACTION_REMOVE: {
// Find the section to remote it from
String sectionName = action.GetSection();
if (sectionName.IsEmpty()) throw Exception(Exception::TODO); // TODO
SectionPtr section = GetSection(sectionName);
// Remove the line
section->RemoveEntryByIndex(action.GetLineNumber());
return;
}
}
}
///////////////////////////////////////////
// Create the action opposite to the input
Action Model::GetAntiAction(const Action &action)
{
switch (action.GetType()) {
// Create a remove
case ACTION_INSERT: {
// Find the section to insert it on
String section = action.GetSection();
if (section.IsEmpty()) {
SectionEntryPtr entry = static_pointer_cast<SectionEntry>(action.GetData());
section = entry->GetDefaultGroup();
}
return Action(ACTION_REMOVE,SectionEntryPtr(),section,action.GetLineNumber());
}
// Create an insert
case ACTION_REMOVE: {
int line = action.GetLineNumber();
const String &sName = action.GetSection();
SectionPtr section = GetSection(sName);
return Action(ACTION_INSERT,section->GetEntry(line),sName,line);
}
}
throw Exception(Exception::Invalid_ActionList);
}
//////////////////
// Load subtitles
void Model::Load(wxInputStream &input,const FormatPtr _format,const String encoding)

View File

@ -97,6 +97,7 @@ int main() {
}
timer.Pause();
cout << "Done in " << timer.Time() << " ms.\n";
control.SaveFile(L"subs_out2.ass",L"UTF-8");
}
catch (std::exception &e) {