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