HaikuDepot: Remove Custom List

Further removal of the use of custom list class;
this time with the generic undo functionality.

Relates To #15534

Change-Id: I804a31abc07f42f4f1695562b6f948feb465db0c
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3739
Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
Andrew Lindesay
2021-02-10 08:22:34 +00:00
parent 99bd3b947f
commit 1403313c7f
8 changed files with 76 additions and 154 deletions
-1
View File
@@ -87,7 +87,6 @@ local textDocumentSources =
CompoundEdit.cpp CompoundEdit.cpp
EditContext.cpp EditContext.cpp
EditManager.cpp EditManager.cpp
EditStack.cpp
UndoableEdit.cpp UndoableEdit.cpp
# textview # textview
@@ -1,5 +1,6 @@
/* /*
* Copyright 2006-2112, Stephan Aßmus <[email protected]> * Copyright 2006-2112, Stephan Aßmus <[email protected]>
* Copyright 2021, Andrew Lindesay <[email protected]>
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@@ -33,10 +34,10 @@ CompoundEdit::Perform(EditContext& context)
{ {
status_t status = B_OK; status_t status = B_OK;
int32 count = fEdits.CountItems(); int32 count = static_cast<int32>(fEdits.size());
int32 i = 0; int32 i = 0;
for (; i < count; i++) { for (; i < count; i++) {
status = fEdits.ItemAtFast(i)->Perform(context); status = fEdits[i]->Perform(context);
if (status != B_OK) if (status != B_OK)
break; break;
} }
@@ -45,7 +46,7 @@ CompoundEdit::Perform(EditContext& context)
// roll back // roll back
i--; i--;
for (; i >= 0; i--) { for (; i >= 0; i--) {
fEdits.ItemAtFast(i)->Undo(context); fEdits[i]->Undo(context);
} }
} }
@@ -58,10 +59,10 @@ CompoundEdit::Undo(EditContext& context)
{ {
status_t status = B_OK; status_t status = B_OK;
int32 count = fEdits.CountItems(); int32 count = static_cast<int32>(fEdits.size());
int32 i = count - 1; int32 i = count - 1;
for (; i >= 0; i--) { for (; i >= 0; i--) {
status = fEdits.ItemAtFast(i)->Undo(context); status = fEdits[i]->Undo(context);
if (status != B_OK) if (status != B_OK)
break; break;
} }
@@ -70,7 +71,7 @@ CompoundEdit::Undo(EditContext& context)
// roll back // roll back
i++; i++;
for (; i < count; i++) { for (; i < count; i++) {
fEdits.ItemAtFast(i)->Redo(context); fEdits[i]->Redo(context);
} }
} }
@@ -83,10 +84,10 @@ CompoundEdit::Redo(EditContext& context)
{ {
status_t status = B_OK; status_t status = B_OK;
int32 count = fEdits.CountItems(); int32 count = static_cast<int32>(fEdits.size());
int32 i = 0; int32 i = 0;
for (; i < count; i++) { for (; i < count; i++) {
status = fEdits.ItemAtFast(i)->Redo(context); status = fEdits[i]->Redo(context);
if (status != B_OK) if (status != B_OK)
break; break;
} }
@@ -95,7 +96,7 @@ CompoundEdit::Redo(EditContext& context)
// roll back // roll back
i--; i--;
for (; i >= 0; i--) { for (; i >= 0; i--) {
fEdits.ItemAtFast(i)->Undo(context); fEdits[i]->Undo(context);
} }
} }
@@ -110,8 +111,8 @@ CompoundEdit::GetName(BString& name)
} }
bool void
CompoundEdit::AppendEdit(const UndoableEditRef& edit) CompoundEdit::AppendEdit(const UndoableEditRef& edit)
{ {
return fEdits.Add(edit); fEdits.push_back(edit);
} }
@@ -1,14 +1,16 @@
/* /*
* Copyright 2006-2112, Stephan Aßmus <[email protected]> * Copyright 2006-2112, Stephan Aßmus <[email protected]>
* Copyright 2021, Andrew Lindesay <[email protected]>
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef COMPOUND_EDIT_H #ifndef COMPOUND_EDIT_H
#define COMPOUND_EDIT_H #define COMPOUND_EDIT_H
#include <vector>
#include <String.h> #include <String.h>
#include "List.h"
#include "UndoableEdit.h" #include "UndoableEdit.h"
class CompoundEdit : public UndoableEdit { class CompoundEdit : public UndoableEdit {
@@ -24,12 +26,11 @@ public:
virtual void GetName(BString& name); virtual void GetName(BString& name);
bool AppendEdit(const UndoableEditRef& edit); void AppendEdit(const UndoableEditRef& edit);
private: private:
typedef List<UndoableEditRef, false, 2> EditList; std::vector<UndoableEditRef>
fEdits;
EditList fEdits;
BString fName; BString fName;
}; };
@@ -1,10 +1,13 @@
/* /*
* Copyright 2006-2012, Stephan Aßmus <[email protected]> * Copyright 2006-2012, Stephan Aßmus <[email protected]>
* Copyright 2021, Andrew Lindesay <[email protected]>
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include "EditManager.h" #include "EditManager.h"
#include <algorithm>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -64,14 +67,14 @@ status_t
EditManager::Undo(EditContext& context) EditManager::Undo(EditContext& context)
{ {
status_t status = B_ERROR; status_t status = B_ERROR;
if (!fUndoHistory.IsEmpty()) { if (!fUndoHistory.empty()) {
UndoableEditRef edit(fUndoHistory.Top()); UndoableEditRef edit(fUndoHistory.top());
fUndoHistory.Pop(); fUndoHistory.pop();
status = edit->Undo(context); status = edit->Undo(context);
if (status == B_OK) if (status == B_OK)
fRedoHistory.Push(edit); fRedoHistory.push(edit);
else else
fUndoHistory.Push(edit); fUndoHistory.push(edit);
} }
_NotifyListeners(); _NotifyListeners();
@@ -84,14 +87,14 @@ status_t
EditManager::Redo(EditContext& context) EditManager::Redo(EditContext& context)
{ {
status_t status = B_ERROR; status_t status = B_ERROR;
if (!fRedoHistory.IsEmpty()) { if (!fRedoHistory.empty()) {
UndoableEditRef edit(fRedoHistory.Top()); UndoableEditRef edit(fRedoHistory.top());
fRedoHistory.Pop(); fRedoHistory.pop();
status = edit->Redo(context); status = edit->Redo(context);
if (status == B_OK) if (status == B_OK)
fUndoHistory.Push(edit); fUndoHistory.push(edit);
else else
fRedoHistory.Push(edit); fRedoHistory.push(edit);
} }
_NotifyListeners(); _NotifyListeners();
@@ -103,9 +106,9 @@ EditManager::Redo(EditContext& context)
bool bool
EditManager::GetUndoName(BString& name) EditManager::GetUndoName(BString& name)
{ {
if (!fUndoHistory.IsEmpty()) { if (!fUndoHistory.empty()) {
name << " "; name << " ";
fUndoHistory.Top()->GetName(name); fUndoHistory.top()->GetName(name);
return true; return true;
} }
return false; return false;
@@ -115,9 +118,9 @@ EditManager::GetUndoName(BString& name)
bool bool
EditManager::GetRedoName(BString& name) EditManager::GetRedoName(BString& name)
{ {
if (!fRedoHistory.IsEmpty()) { if (!fRedoHistory.empty()) {
name << " "; name << " ";
fRedoHistory.Top()->GetName(name); fRedoHistory.top()->GetName(name);
return true; return true;
} }
return false; return false;
@@ -127,10 +130,10 @@ EditManager::GetRedoName(BString& name)
void void
EditManager::Clear() EditManager::Clear()
{ {
while (!fUndoHistory.IsEmpty()) while (!fUndoHistory.empty())
fUndoHistory.Pop(); fUndoHistory.pop();
while (!fRedoHistory.IsEmpty()) while (!fRedoHistory.empty())
fRedoHistory.Pop(); fRedoHistory.pop();
_NotifyListeners(); _NotifyListeners();
} }
@@ -139,8 +142,8 @@ EditManager::Clear()
void void
EditManager::Save() EditManager::Save()
{ {
if (!fUndoHistory.IsEmpty()) if (!fUndoHistory.empty())
fEditAtSave = fUndoHistory.Top(); fEditAtSave = fUndoHistory.top();
_NotifyListeners(); _NotifyListeners();
} }
@@ -149,9 +152,9 @@ EditManager::Save()
bool bool
EditManager::IsSaved() EditManager::IsSaved()
{ {
bool saved = fUndoHistory.IsEmpty(); bool saved = fUndoHistory.empty();
if (fEditAtSave.IsSet() && !saved) { if (fEditAtSave.IsSet() && !saved) {
if (fEditAtSave == fUndoHistory.Top()) if (fEditAtSave == fUndoHistory.top())
saved = true; saved = true;
} }
return saved; return saved;
@@ -161,17 +164,20 @@ EditManager::IsSaved()
// #pragma mark - // #pragma mark -
bool void
EditManager::AddListener(Listener* listener) EditManager::AddListener(Listener* listener)
{ {
return fListeners.Add(listener); return fListeners.push_back(listener);
} }
void void
EditManager::RemoveListener(Listener* listener) EditManager::RemoveListener(Listener* listener)
{ {
fListeners.Remove(listener); fListeners.erase(std::remove(
fListeners.begin(),
fListeners.end(),
listener), fListeners.end());
} }
@@ -184,24 +190,24 @@ EditManager::_AddEdit(const UndoableEditRef& edit)
status_t status = B_OK; status_t status = B_OK;
bool add = true; bool add = true;
if (!fUndoHistory.IsEmpty()) { if (!fUndoHistory.empty()) {
// Try to collapse edits to a single edit // Try to collapse edits to a single edit
// or remove this and the previous edit if // or remove this and the previous edit if
// they reverse each other // they reverse each other
const UndoableEditRef& top = fUndoHistory.Top(); const UndoableEditRef& top = fUndoHistory.top();
if (edit->UndoesPrevious(top.Get())) { if (edit->UndoesPrevious(top.Get())) {
add = false; add = false;
fUndoHistory.Pop(); fUndoHistory.pop();
} else if (top->CombineWithNext(edit.Get())) { } else if (top->CombineWithNext(edit.Get())) {
add = false; add = false;
// After collapsing, the edit might // After collapsing, the edit might
// have changed it's mind about InitCheck() // have changed it's mind about InitCheck()
// (the commands reversed each other) // (the commands reversed each other)
if (top->InitCheck() != B_OK) { if (top->InitCheck() != B_OK) {
fUndoHistory.Pop(); fUndoHistory.pop();
} }
} else if (edit->CombineWithPrevious(top.Get())) { } else if (edit->CombineWithPrevious(top.Get())) {
fUndoHistory.Pop(); fUndoHistory.pop();
// After collapsing, the edit might // After collapsing, the edit might
// have changed it's mind about InitCheck() // have changed it's mind about InitCheck()
// (the commands reversed each other) // (the commands reversed each other)
@@ -210,16 +216,14 @@ EditManager::_AddEdit(const UndoableEditRef& edit)
} }
} }
} }
if (add) { if (add)
if (!fUndoHistory.Push(edit)) fUndoHistory.push(edit);
status = B_NO_MEMORY;
}
if (status == B_OK) { if (status == B_OK) {
// The redo stack needs to be empty // The redo stack needs to be empty
// as soon as an edit was added (also in case of collapsing) // as soon as an edit was added (also in case of collapsing)
while (!fRedoHistory.IsEmpty()) { while (!fRedoHistory.empty()) {
fRedoHistory.Pop(); fRedoHistory.pop();
} }
} }
@@ -230,15 +234,14 @@ EditManager::_AddEdit(const UndoableEditRef& edit)
void void
EditManager::_NotifyListeners() EditManager::_NotifyListeners()
{ {
int32 count = fListeners.CountItems();
if (count == 0)
return;
// Iterate a copy of the list, so we don't crash if listeners // Iterate a copy of the list, so we don't crash if listeners
// detach themselves while being notified. // detach themselves while being notified.
ListenerList listenersCopy(fListeners); std::vector<Listener*> listeners(fListeners);
if (listenersCopy.CountItems() != count)
return; std::vector<Listener*>::const_iterator it;
for (int32 i = 0; i < count; i++) for (it = listeners.begin(); it != listeners.end(); it++) {
listenersCopy.ItemAtFast(i)->EditManagerChanged(this); Listener* listener = *it;
listener->EditManagerChanged(this);
}
} }
@@ -1,11 +1,14 @@
/* /*
* Copyright 2006-2012, Stephan Aßmus <[email protected]> * Copyright 2006-2012, Stephan Aßmus <[email protected]>
* Copyright 2021, Andrew Lindesay <[email protected]>
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef EDIT_MANAGER_H #ifndef EDIT_MANAGER_H
#define EDIT_MANAGER_H #define EDIT_MANAGER_H
#include "EditStack.h" #include <vector>
#include <stack>
#include "UndoableEdit.h" #include "UndoableEdit.h"
class BString; class BString;
@@ -40,7 +43,7 @@ public:
void Save(); void Save();
bool IsSaved(); bool IsSaved();
bool AddListener(Listener* listener); void AddListener(Listener* listener);
void RemoveListener(Listener* listener); void RemoveListener(Listener* listener);
private: private:
@@ -49,12 +52,13 @@ private:
void _NotifyListeners(); void _NotifyListeners();
private: private:
EditStack fUndoHistory; std::stack<UndoableEditRef>
EditStack fRedoHistory; fUndoHistory;
std::stack<UndoableEditRef>
fRedoHistory;
UndoableEditRef fEditAtSave; UndoableEditRef fEditAtSave;
std::vector<Listener*>
typedef List<Listener*, true, 4> ListenerList; fListeners;
ListenerList fListeners;
}; };
#endif // EDIT_MANAGER_H #endif // EDIT_MANAGER_H
@@ -1,49 +0,0 @@
/*
* Copyright 2012, Stephan Aßmus <[email protected]>
* Distributed under the terms of the MIT License.
*/
#include "EditStack.h"
#include <stdio.h>
EditStack::EditStack()
: fEdits()
{
}
EditStack::~EditStack()
{
}
bool
EditStack::Push(const UndoableEditRef& edit)
{
return fEdits.Add(edit);
}
UndoableEditRef
EditStack::Pop()
{
UndoableEditRef edit(Top());
fEdits.Remove();
return edit;
}
const UndoableEditRef&
EditStack::Top() const
{
return fEdits.LastItem();
}
bool
EditStack::IsEmpty() const
{
return fEdits.CountItems() == 0;
}
@@ -1,30 +0,0 @@
/*
* Copyright 2012, Stephan Aßmus <[email protected]>
* Distributed under the terms of the MIT License.
*/
#ifndef EDIT_STACK_H
#define EDIT_STACK_H
#include "List.h"
#include "UndoableEdit.h"
class EditStack {
public:
EditStack();
virtual ~EditStack();
bool Push(const UndoableEditRef& edit);
UndoableEditRef Pop();
const UndoableEditRef& Top() const;
bool IsEmpty() const;
private:
typedef List<UndoableEditRef, false> EditList;
EditList fEdits;
};
#endif // EDIT_STACK_H
@@ -11,22 +11,15 @@
#include <String.h> #include <String.h>
//static int32 sInstanceCount = 0;
UndoableEdit::UndoableEdit() UndoableEdit::UndoableEdit()
: :
fTimeStamp(system_time()) fTimeStamp(system_time())
{ {
// sInstanceCount++;
// printf("UndoableEdits: %ld\n", sInstanceCount);
} }
UndoableEdit::~UndoableEdit() UndoableEdit::~UndoableEdit()
{ {
// sInstanceCount--;
// printf("UndoableEdits: %ld\n", sInstanceCount);
} }